Repository: bytecodealliance/wasmtime
Pull request #6079 (2023-03-21 16:06:24)

s390x: Improved TrapIf implementation
Following up on the discussion in
https://github.com/bytecodealliance/wasmtime/pull/6011 this adds an improved implementation of TrapIf for s390x using a single conditional branch instruction.

If the trap conditions is true, we branch into the middle of the branch instruction - those middle two bytes are zero, which matches the encoding of the trap instruction.

<!--

Please ensure that the following steps are all taken care of before submitting
the PR.

- [ ] This has been discussed in issue #..., or if not, please tell us why
  here.
- [ ] A short description of what this does, why it is needed; if the
  description becomes long, the matter should probably be discussed in an issue
  first.
- [ ] This PR contains test cases, if meaningful.
- [ ] A reviewer from the core maintainer team has been assigned for this PR.
  If you don't know who could review this, please indicate so. The list of
  suggested reviewers on the right can help you.

Please ensure all communication adheres to the [code of
conduct](https://github.com/bytecodealliance/wasmtime/blob/master/CODE_OF_CONDUCT.md).
-->



Patch:
diff --git a/Cargo.lock b/Cargo.lock
index 015c7f822..36182b454 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -651,6 +651,7 @@ dependencies = [
  "arbitrary",
  "cranelift",
  "cranelift-native",
+ "once_cell",
  "target-lexicon",
 ]
 
diff --git a/cranelift/README.md b/cranelift/README.md
index acdb579d0..3ca3337da 100644
--- a/cranelift/README.md
+++ b/cranelift/README.md
@@ -44,8 +44,8 @@ active effort to formally verify Cranelift's instruction-selection backends. We
 take security seriously and have a [security policy] as a part of Bytecode
 Alliance.
 
-Cranelift has three backends: x86-64, aarch64 (aka ARM64), and s390x (aka IBM
-Z). All three backends fully support enough functionality for Wasm MVP, and
+Cranelift has four backends: x86-64, aarch64 (aka ARM64), s390x (aka IBM
+Z) and riscv64. All backends fully support enough functionality for Wasm MVP, and
 x86-64 and aarch64 fully support SIMD as well. On x86-64, Cranelift supports
 both the System V AMD64 ABI calling convention used on many platforms and the
 Windows x64 calling convention. On aarch64, Cranelift supports the standard
diff --git a/cranelift/codegen/src/isa/aarch64/inst.isle b/cranelift/codegen/src/isa/aarch64/inst.isle
index aa7b29607..f7239a2ad 100644
--- a/cranelift/codegen/src/isa/aarch64/inst.isle
+++ b/cranelift/codegen/src/isa/aarch64/inst.isle
@@ -1704,9 +1704,6 @@
 (decl fpu_op_ri_sli (u8 u8) FPUOpRIMod)
 (extern constructor fpu_op_ri_sli fpu_op_ri_sli)
 
-(decl imm12_from_negated_u64 (Imm12) u64)
-(extern extractor imm12_from_negated_u64 imm12_from_negated_u64)
-
 (decl pure partial lshr_from_u64 (Type u64) ShiftOpAndAmt)
 (extern constructor lshr_from_u64 lshr_from_u64)
 
@@ -1734,11 +1731,13 @@
   (imm12_from_value n)
   (iconst (u64_from_imm64 (imm12_from_u64 n))))
 
-;; Same as `imm12_from_value`, but tries negating the constant value.
-(decl imm12_from_negated_value (Imm12) Value)
-(extractor
-  (imm12_from_negated_value n)
-  (iconst (u64_from_imm64 (imm12_from_negated_u64 n))))
+;; Conceptually the same as `imm12_from_value`, but tries negating the constant
+;; value (first sign-extending to handle narrow widths).
+(decl pure partial imm12_from_negated_value (Value) Imm12)
+(rule
+  (imm12_from_negated_value (has_type ty (iconst n)))
+  (if-let (imm12_from_u64 imm) (i64_as_u64 (i64_neg (i64_sextend_imm64 ty n))))
+  imm)
 
 ;; Helper type to represent a value and an extend operation fused together.
 (type ExtendedValue extern (enum))
diff --git a/cranelift/codegen/src/isa/aarch64/lower.isle b/cranelift/codegen/src/isa/aarch64/lower.isle
index 9f3025309..bafd73330 100644
--- a/cranelift/codegen/src/isa/aarch64/lower.isle
+++ b/cranelift/codegen/src/isa/aarch64/lower.isle
@@ -56,11 +56,13 @@
 
 ;; Same as the previous special cases, except we can switch the addition to a
 ;; subtraction if the negated immediate fits in 12 bits.
-(rule 2 (lower (has_type (fits_in_64 ty) (iadd x (imm12_from_negated_value y))))
-      (sub_imm ty x y))
+(rule 2 (lower (has_type (fits_in_64 ty) (iadd x y)))
+      (if-let imm12_neg (imm12_from_negated_value y))
+      (sub_imm ty x imm12_neg))
 
-(rule 3 (lower (has_type (fits_in_64 ty) (iadd (imm12_from_negated_value x) y)))
-      (sub_imm ty y x))
+(rule 3 (lower (has_type (fits_in_64 ty) (iadd x y)))
+      (if-let imm12_neg (imm12_from_negated_value x))
+      (sub_imm ty y imm12_neg))
 
 ;; Special cases for when we're adding an extended register where the extending
 ;; operation can get folded into the add itself.
@@ -650,8 +652,9 @@
 
 ;; Same as the previous special case, except we can switch the subtraction to an
 ;; addition if the negated immediate fits in 12 bits.
-(rule 2 (lower (has_type (fits_in_64 ty) (isub x (imm12_from_negated_value y))))
-      (add_imm ty x y))
+(rule 2 (lower (has_type (fits_in_64 ty) (isub x y)))
+      (if-let imm12_neg (imm12_from_negated_value y))
+      (add_imm ty x imm12_neg))
 
 ;; Special cases for when we're subtracting an extended register where the
 ;; extending operation can get folded into the sub itself.
diff --git a/cranelift/codegen/src/isa/aarch64/lower/isle.rs b/cranelift/codegen/src/isa/aarch64/lower/isle.rs
index a3fe4eb02..c5d661d24 100644
--- a/cranelift/codegen/src/isa/aarch64/lower/isle.rs
+++ b/cranelift/codegen/src/isa/aarch64/lower/isle.rs
@@ -126,10 +126,6 @@ impl Context for IsleContext<'_, '_, MInst, AArch64Backend> {
         Imm12::maybe_from_u64(n)
     }
 
-    fn imm12_from_negated_u64(&mut self, n: u64) -> Option<Imm12> {
-        Imm12::maybe_from_u64((n as i64).wrapping_neg() as u64)
-    }
-
     fn imm_shift_from_u8(&mut self, n: u8) -> ImmShift {
         ImmShift::maybe_from_u64(n.into()).unwrap()
     }
diff --git a/cranelift/codegen/src/isa/riscv64/inst.isle b/cranelift/codegen/src/isa/riscv64/inst.isle
index 5eae84301..d4eed1f98 100644
--- a/cranelift/codegen/src/isa/riscv64/inst.isle
+++ b/cranelift/codegen/src/isa/riscv64/inst.isle
@@ -808,6 +808,28 @@
 (decl imm12_from_u64 (Imm12) u64)
 (extern extractor imm12_from_u64 imm12_from_u64)
 
+
+;;;; Instruction Helpers ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+
+;; bseti: Set a single bit in a register, indexed by a constant.
+(decl bseti (Reg u64) Reg)
+(rule (bseti val bit)
+  (if-let $false (has_zbs))
+  (if-let $false (u64_le bit 12))
+  (let ((const Reg (load_u64_constant (u64_shl 1 bit))))
+    (alu_rrr (AluOPRRR.Or) val const)))
+
+(rule (bseti val bit)
+  (if-let $false (has_zbs))
+  (if-let $true (u64_le bit 12))
+  (alu_rr_imm12 (AluOPRRI.Ori) val (imm12_const (u64_as_i32 (u64_shl 1 bit)))))
+
+(rule (bseti val bit)
+  (if-let $true (has_zbs))
+  (alu_rr_imm12 (AluOPRRI.Bseti) val (imm12_const (u64_as_i32 bit))))
+
+
 ;; Float Helpers
 
 (decl gen_default_frm () OptionFloatRoundingMode)
@@ -948,89 +970,103 @@
 
 
 (decl lower_ctz (Type Reg) Reg)
-(rule
-  (lower_ctz ty x)
-  (if-let $false (has_zbb))
+(rule (lower_ctz ty x)
   (gen_cltz $false x ty))
 
-(rule 2
-  (lower_ctz $I64 x)
+(rule 1 (lower_ctz (fits_in_16 ty) x)
   (if-let $true (has_zbb))
-  (alu_rr_funct12 (AluOPRRI.Ctz) x))
+  (let ((tmp Reg (bseti x (ty_bits ty))))
+    (alu_rr_funct12 (AluOPRRI.Ctzw) tmp)))
 
-(rule 2
-  (lower_ctz $I32 x)
+(rule 2 (lower_ctz $I32 x)
   (if-let $true (has_zbb))
   (alu_rr_funct12 (AluOPRRI.Ctzw) x))
 
-;;;; for I8 and I16
-(rule 1
-  (lower_ctz ty x)
+(rule 2 (lower_ctz $I64 x)
   (if-let $true (has_zbb))
-  (if-let $true (has_zbs))
-  (let
-    ((tmp Reg (alu_rr_imm12 (AluOPRRI.Bseti) x (imm12_const (ty_bits ty)))))
-    (alu_rr_funct12 (AluOPRRI.Ctzw) x)))
+  (alu_rr_funct12 (AluOPRRI.Ctz) x))
 
-;;;;
+;; Count trailing zeros from a i128 bit value.
+;; We count both halves separately and conditionally add them if it makes sense.
 (decl lower_ctz_128 (ValueRegs) ValueRegs)
-(rule
-  (lower_ctz_128 x)
-  (let
-    (;; count the low part.
-      (low Reg (lower_ctz $I64 (value_regs_get x 0)))
-      ;; count the high part.
-      (high_part Reg (lower_ctz $I64 (value_regs_get x 1)))
-      ;;;
-      (constant_64 Reg (load_u64_constant 64))
-      ;;;
-      (high Reg (gen_select_reg (IntCC.Equal) constant_64 low high_part (zero_reg)))
+(rule (lower_ctz_128 x)
+  (let ((x_lo Reg (value_regs_get x 0))
+        (x_hi Reg (value_regs_get x 1))
+        ;; Count both halves
+        (high Reg (lower_ctz $I64 x_hi))
+        (low Reg (lower_ctz $I64 x_lo))
+        ;; Only add the top half if the bottom is zero
+        (high Reg (gen_select_reg (IntCC.Equal) x_lo (zero_reg) high (zero_reg)))
+        (result Reg (alu_add low high)))
+    (zext result $I64 $I128)))
+
 
-      ;; add low and high together.
-      (result Reg (alu_add low high)))
-    (value_regs result (load_u64_constant 0))))
 
 (decl lower_clz (Type Reg) Reg)
-(rule
-  (lower_clz ty rs)
-  (if-let $false (has_zbb))
+(rule (lower_clz ty rs)
   (gen_cltz $true rs ty))
-(rule 2
-  (lower_clz $I64 r)
+
+(rule 1 (lower_clz (fits_in_16 ty) r)
   (if-let $true (has_zbb))
-  (alu_rr_funct12 (AluOPRRI.Clz) r))
-(rule 2
-  (lower_clz $I32 r)
+  (let ((tmp Reg (zext r ty $I64))
+        (count Reg (alu_rr_funct12 (AluOPRRI.Clz) tmp))
+        ;; We always do the operation on the full 64-bit register, so subtract 64 from the result.
+        (result Reg (alu_rr_imm12 (AluOPRRI.Addi) count (imm12_const_add (ty_bits ty) -64))))
+    result))
+
+(rule 2 (lower_clz $I32 r)
   (if-let $true (has_zbb))
   (alu_rr_funct12 (AluOPRRI.Clzw) r))
 
-;;; for I8 and I16
-(rule 1
-  (lower_clz ty r)
+(rule 2 (lower_clz $I64 r)
   (if-let $true (has_zbb))
-  (let
-    ( ;; narrow int make all upper bits are zeros.
-      (tmp Reg (ext_int_if_need $false r ty ))
-      ;;
-      (count Reg (alu_rr_funct12 (AluOPRRI.Clz) tmp))
-      ;;make result
-      (result Reg (alu_rr_imm12 (AluOPRRI.Addi) count (imm12_const_add (ty_bits ty) -64))))
-    result))
+  (alu_rr_funct12 (AluOPRRI.Clz) r))
 
+;; Count leading zeros from a i128 bit value.
+;; We count both halves separately and conditionally add them if it makes sense.
 (decl lower_clz_i128 (ValueRegs) ValueRegs)
-(rule
-  (lower_clz_i128 x)
-  (let
-    ( ;; count high part.
-      (high Reg (lower_clz $I64 (value_regs_get x 1)))
-      ;; coumt low part.
-      (low_part Reg (lower_clz $I64 (value_regs_get x 0)))
-      ;;; load constant 64.
-      (constant_64 Reg (load_u64_constant 64))
-      (low Reg (gen_select_reg (IntCC.Equal) constant_64 high low_part (zero_reg)))
-      ;; add low and high together.
-      (result Reg (alu_add high low)))
-    (value_regs result (load_u64_constant 0))))
+(rule (lower_clz_i128 x)
+  (let ((x_lo Reg (value_regs_get x 0))
+        (x_hi Reg (value_regs_get x 1))
+        ;; Count both halves
+        (high Reg (lower_clz $I64 x_hi))
+        (low Reg (lower_clz $I64 x_lo))
+        ;; Only add the bottom zeros if the top half is zero
+        (low Reg (gen_select_reg (IntCC.Equal) x_hi (zero_reg) low (zero_reg)))
+        (result Reg (alu_add high low)))
+    (zext result $I64 $I128)))
+
+
+(decl lower_cls (Type Reg) Reg)
+(rule (lower_cls ty r)
+  (let ((tmp Reg (ext_int_if_need $true r ty))
+        (tmp2 Reg (gen_select_reg (IntCC.SignedLessThan) tmp (zero_reg) (gen_bit_not tmp) tmp))
+        (tmp3 Reg (lower_clz ty tmp2)))
+    (alu_rr_imm12 (AluOPRRI.Addi) tmp3 (imm12_const -1))))
+
+;; If the sign bit is set, we count the leading zeros of the inverted value.
+;; Otherwise we can just count the leading zeros of the original value.
+;; Subtract 1 since the sign bit does not count.
+(decl lower_cls_i128 (ValueRegs) ValueRegs)
+(rule (lower_cls_i128 x)
+  (let ((low Reg (value_regs_get x 0))
+        (high Reg (value_regs_get x 1))
+        (low Reg (gen_select_reg (IntCC.SignedLessThan) high (zero_reg) (gen_bit_not low) low))
+        (high Reg (gen_select_reg (IntCC.SignedLessThan) high (zero_reg) (gen_bit_not high) high))
+        (tmp ValueRegs (lower_clz_i128 (value_regs low high)))
+        (count Reg (value_regs_get tmp 0))
+        (result Reg (alu_rr_imm12 (AluOPRRI.Addi) count (imm12_const -1))))
+    (zext result $I64 $I128)))
+
+
+(decl gen_cltz (bool Reg Type) Reg)
+(rule (gen_cltz leading rs ty)
+  (let ((tmp WritableReg (temp_writable_reg $I64))
+        (step WritableReg (temp_writable_reg $I64))
+        (sum WritableReg (temp_writable_reg $I64))
+        (_ Unit (emit (MInst.Cltz leading sum step tmp rs ty))))
+    sum))
+
   
 ;; Extends an integer if it is smaller than 64 bits.
 (decl ext_int_if_need (bool ValueRegs Type) ValueRegs)
@@ -1267,27 +1303,6 @@
       (part3 Reg (gen_select_reg (IntCC.Equal) shamt (zero_reg) (zero_reg) part2)))
     (alu_rrr (AluOPRRR.Or) part1 part3)))
 
-(decl lower_cls (Reg Type) Reg)
-(rule
-  (lower_cls r ty)
-  (let
-    ( ;; extract sign bit.
-      (tmp Reg (ext_int_if_need $true r ty))
-      ;;
-      (tmp2 Reg (gen_select_reg (IntCC.SignedLessThan) tmp (zero_reg) (gen_bit_not r) r))
-      ;;
-      (tmp3 Reg (lower_clz ty tmp2)))
-    (alu_rr_imm12 (AluOPRRI.Addi) tmp3 (imm12_const -1))))
-
-(decl gen_cltz (bool Reg Type) Reg)
-(rule
-  (gen_cltz leading rs ty)
-  (let
-    ((tmp WritableReg (temp_writable_reg $I64))
-      (step WritableReg (temp_writable_reg $I64))
-      (sum WritableReg (temp_writable_reg $I64))
-      (_ Unit (emit (MInst.Cltz leading sum step tmp rs ty))))
-    (writable_reg_to_reg sum)))
 
 (decl gen_popcnt (Reg Type) Reg)
 (rule
@@ -1454,24 +1469,6 @@
       (gen_select_reg (IntCC.UnsignedGreaterThanOrEqual) shamt_128 const64 high_replacement high))))
 
 
-(decl lower_cls_i128 (ValueRegs) ValueRegs)
-(rule
-  (lower_cls_i128 x)
-  (let
-    ( ;;; we use clz to implement cls
-      ;;; if value is negtive we need inverse all bits.
-      (low Reg
-        (gen_select_reg (IntCC.SignedLessThan) (value_regs_get x 1) (zero_reg) (gen_bit_not (value_regs_get x 0)) (value_regs_get x 0)))
-      ;;;
-       (high Reg
-        (gen_select_reg (IntCC.SignedLessThan) (value_regs_get x 1) (zero_reg) (gen_bit_not (value_regs_get x 1)) (value_regs_get x 1)))
-      ;; count leading zeros.
-      (tmp  ValueRegs (lower_clz_i128 (value_regs low high)))
-      (count Reg (value_regs_get tmp 0))
-      (result Reg (alu_rr_imm12 (AluOPRRI.Addi) count (imm12_const -1))))
-    (value_regs result (load_u64_constant 0))))
-
-
 (decl gen_amode (Reg Offset32 Type) AMode)
 (extern constructor gen_amode gen_amode)
 
diff --git a/cranelift/codegen/src/isa/riscv64/lower.isle b/cranelift/codegen/src/isa/riscv64/lower.isle
index ec74f4555..458b59847 100644
--- a/cranelift/codegen/src/isa/riscv64/lower.isle
+++ b/cranelift/codegen/src/isa/riscv64/lower.isle
@@ -327,14 +327,14 @@
 
 
 ;;;; Rules for `ctz` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-(rule (lower (has_type ty (ctz x)))
+(rule (lower (has_type (fits_in_64 ty) (ctz x)))
   (lower_ctz ty x))
 
 (rule 1 (lower (has_type $I128 (ctz x)))
   (lower_ctz_128 x))
 
 ;;;; Rules for `clz` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-(rule (lower (has_type ty (clz x)))
+(rule (lower (has_type (fits_in_64 ty) (clz x)))
   (lower_clz ty x))
 
 (rule 1 (lower (has_type $I128 (clz x)))
@@ -342,7 +342,7 @@
   
 ;;;; Rules for `cls` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 (rule (lower (has_type (fits_in_64 ty) (cls x)))
-  (lower_cls x ty))
+  (lower_cls ty x))
 
 (rule 1 (lower (has_type $I128 (cls x)))
   (lower_cls_i128 x))
diff --git a/cranelift/codegen/src/isa/s390x/inst/emit.rs b/cranelift/codegen/src/isa/s390x/inst/emit.rs
index 5a811e7a3..4ac01db59 100644
--- a/cranelift/codegen/src/isa/s390x/inst/emit.rs
+++ b/cranelift/codegen/src/isa/s390x/inst/emit.rs
@@ -682,6 +682,7 @@ fn enc_ril_b(opcode: u16, r1: Reg, ri2: u32) -> [u8; 6] {
     let opcode1 = ((opcode >> 4) & 0xff) as u8;
     let opcode2 = (opcode & 0xf) as u8;
     let r1 = machreg_to_gpr(r1) & 0x0f;
+    let ri2 = ri2 >> 1;
 
     enc[0] = opcode1;
     enc[1] = r1 << 4 | opcode2;
@@ -700,6 +701,7 @@ fn enc_ril_c(opcode: u16, m1: u8, ri2: u32) -> [u8; 6] {
     let opcode1 = ((opcode >> 4) & 0xff) as u8;
     let opcode2 = (opcode & 0xf) as u8;
     let m1 = m1 & 0x0f;
+    let ri2 = ri2 >> 1;
 
     enc[0] = opcode1;
     enc[1] = m1 << 4 | opcode2;
@@ -3590,14 +3592,19 @@ impl Inst {
                 put_with_trap(sink, &enc_e(0x0000), trap_code);
             }
             &Inst::TrapIf { cond, trap_code } => {
-                // Branch over trap if condition is false.
-                let opcode = 0xa74; // BCR
-                put(sink, &enc_ri_c(opcode, cond.invert().bits(), 4 + 2));
-                // Now emit the actual trap.
                 if let Some(s) = state.take_stack_map() {
-                    sink.add_stack_map(StackMapExtent::UpcomingBytes(2), s);
+                    sink.add_stack_map(StackMapExtent::UpcomingBytes(6), s);
                 }
-                put_with_trap(sink, &enc_e(0x0000), trap_code);
+                // We implement a TrapIf as a conditional branch into the middle
+                // of the branch (BRCL) instruction itself - those middle two bytes
+                // are zero, which matches the trap instruction itself.
+                let opcode = 0xc04; // BCRL
+                let enc = &enc_ril_c(opcode, cond.bits(), 2);
+                debug_assert!(enc.len() == 6 && enc[2] == 0 && enc[3] == 0);
+                // The trap must be placed on the last byte of the embedded trap
+                // instruction, so we need to emit the encoding in two parts.
+                put_with_trap(sink, &enc[0..4], trap_code);
+                put(sink, &enc[4..6]);
             }
             &Inst::JTSequence { ridx, ref targets } => {
                 let ridx = allocs.next(ridx);
diff --git a/cranelift/codegen/src/isa/s390x/inst/mod.rs b/cranelift/codegen/src/isa/s390x/inst/mod.rs
index f6b22aa46..08ea1ffe9 100644
--- a/cranelift/codegen/src/isa/s390x/inst/mod.rs
+++ b/cranelift/codegen/src/isa/s390x/inst/mod.rs
@@ -3185,11 +3185,13 @@ impl Inst {
                 let cond = cond.pretty_print_default();
                 format!("jg{} {}", cond, target)
             }
-            &Inst::Debugtrap => "debugtrap".to_string(),
-            &Inst::Trap { .. } => "trap".to_string(),
-            &Inst::TrapIf { cond, .. } => {
-                let cond = cond.invert().pretty_print_default();
-                format!("j{} 6 ; trap", cond)
+            &Inst::Debugtrap => ".word 0x0001 # debugtrap".to_string(),
+            &Inst::Trap { trap_code } => {
+                format!(".word 0x0000 # trap={}", trap_code)
+            }
+            &Inst::TrapIf { cond, trap_code } => {
+                let cond = cond.pretty_print_default();
+                format!("jg{} .+2 # trap={}", cond, trap_code)
             }
             &Inst::JTSequence { ridx, ref targets } => {
                 let ridx = pretty_print_reg(ridx, allocs);
diff --git a/cranelift/codegen/src/isa/x64/inst.isle b/cranelift/codegen/src/isa/x64/inst.isle
index b74b9c38c..1fdc6b25c 100644
--- a/cranelift/codegen/src/isa/x64/inst.isle
+++ b/cranelift/codegen/src/isa/x64/inst.isle
@@ -320,6 +320,21 @@
                        (dst WritableGpr)
                        (imm u8))
 
+       ;; XMM (scalar) unary op (from integer to float reg): vmovd, vmovq,
+       ;; vcvtsi2s{s,d}
+       (GprToXmmVex (op AvxOpcode)
+                    (src GprMem)
+                    (dst WritableXmm)
+                    (src_size OperandSize))
+
+       ;; XMM (scalar) unary op (from xmm to integer reg): vmovd, vmovq,
+       ;; vcvtts{s,d}2si
+       (XmmToGprVex (op AvxOpcode)
+                    (src Xmm)
+                    (dst WritableGpr)
+                    (dst_size OperandSize))
+
+
        ;; XMM (scalar or vector) binary op that relies on the EVEX
        ;; prefix. Takes two inputs.
        (XmmRmREvex (op Avx512Opcode)
@@ -1277,6 +1292,13 @@
             Vpbroadcastw
             Vpbroadcastd
             Vbroadcastss
+            Vmovd
+            Vmovq
+            Vmovmskps
+            Vmovmskpd
+            Vpmovmskb
+            Vcvtsi2ss
+            Vcvtsi2sd
           ))
 
 (type Avx512Opcode extern
@@ -1539,6 +1561,10 @@
 (decl lo_gpr (Value) Gpr)
 (rule (lo_gpr regs) (gpr_new (lo_reg regs)))
 
+;; Construct a new `XmmMemImm` from a 32-bit immediate.
+(decl xmi_imm (u32) XmmMemImm)
+(extern constructor xmi_imm xmi_imm)
+
 ;;;; Helpers for Working With Integer Comparison Codes ;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;
 
@@ -1818,10 +1844,7 @@
 (decl mov_rmi_to_xmm (RegMemImm) XmmMemImm)
 (rule (mov_rmi_to_xmm rmi @ (RegMemImm.Mem _)) (xmm_mem_imm_new rmi))
 (rule (mov_rmi_to_xmm rmi @ (RegMemImm.Imm _)) (xmm_mem_imm_new rmi))
-(rule (mov_rmi_to_xmm (RegMemImm.Reg r))
-      (gpr_to_xmm (SseOpcode.Movd)
-                  r
-                  (OperandSize.Size32)))
+(rule (mov_rmi_to_xmm (RegMemImm.Reg r)) (x64_movd_to_xmm r))
 
 ;;;; Helpers for Emitting Calls ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
@@ -1941,9 +1964,37 @@
         (if-let $true (use_avx_simd))
         (xmm_movrm_vex (AvxOpcode.Vmovupd) addr data))
 
-(decl x64_movd (Xmm) Gpr)
-(rule (x64_movd from)
+;; Helper for creating `movd` instructions.
+(decl x64_movd_to_gpr (Xmm) Gpr)
+(rule (x64_movd_to_gpr from)
       (xmm_to_gpr (SseOpcode.Movd) from (OperandSize.Size32)))
+(rule 1 (x64_movd_to_gpr from)
+        (if-let $true (use_avx_simd))
+        (xmm_to_gpr_vex (AvxOpcode.Vmovd) from (OperandSize.Size32)))
+
+;; Helper for creating `movd` instructions.
+(decl x64_movd_to_xmm (GprMem) Xmm)
+(rule (x64_movd_to_xmm from)
+      (gpr_to_xmm (SseOpcode.Movd) from (OperandSize.Size32)))
+(rule 1 (x64_movd_to_xmm from)
+        (if-let $true (use_avx_simd))
+        (gpr_to_xmm_vex (AvxOpcode.Vmovd) from (OperandSize.Size32)))
+
+;; Helper for creating `movq` instructions.
+(decl x64_movq_to_xmm (GprMem) Xmm)
+(rule (x64_movq_to_xmm src)
+      (gpr_to_xmm (SseOpcode.Movq) src (OperandSize.Size64)))
+(rule 1 (x64_movq_to_xmm from)
+        (if-let $true (use_avx_simd))
+        (gpr_to_xmm_vex (AvxOpcode.Vmovq) from (OperandSize.Size64)))
+
+;; Helper for creating `movq` instructions.
+(decl x64_movq_to_gpr (Xmm) Gpr)
+(rule (x64_movq_to_gpr src)
+      (xmm_to_gpr (SseOpcode.Movq) src (OperandSize.Size64)))
+(rule 1 (x64_movq_to_gpr from)
+        (if-let $true (use_avx_simd))
+        (xmm_to_gpr_vex (AvxOpcode.Vmovq) from (OperandSize.Size64)))
 
 (decl x64_movdqu_load (XmmMem) Xmm)
 (rule (x64_movdqu_load from)
@@ -2186,15 +2237,11 @@
 
 ;; `f32` immediates.
 (rule 2 (imm $F32 (u64_nonzero bits))
-      (gpr_to_xmm (SseOpcode.Movd)
-                  (imm $I32 bits)
-                  (OperandSize.Size32)))
+        (x64_movd_to_xmm (imm $I32 bits)))
 
 ;; `f64` immediates.
 (rule 2 (imm $F64 (u64_nonzero bits))
-      (gpr_to_xmm (SseOpcode.Movq)
-                  (imm $I64 bits)
-                  (OperandSize.Size64)))
+        (x64_movq_to_xmm (imm $I64 bits)))
 
 ;; Special case for when a 64-bit immediate fits into 32-bits. We can use a
 ;; 32-bit move that zero-extends the value, which has a smaller encoding.
@@ -3663,20 +3710,44 @@
             (_ Unit (emit (MInst.XmmToGprImmVex op src dst imm))))
         dst))
 
+;; Helper for creating `MInst.XmmToGprVex` instructions.
+(decl xmm_to_gpr_vex (AvxOpcode Xmm OperandSize) Gpr)
+(rule (xmm_to_gpr_vex op src size)
+      (let ((dst WritableGpr (temp_writable_gpr))
+            (_ Unit (emit (MInst.XmmToGprVex op src dst size))))
+        dst))
+
+;; Helper for creating `MInst.GprToXmmVex` instructions.
+(decl gpr_to_xmm_vex (AvxOpcode GprMem OperandSize) Xmm)
+(rule (gpr_to_xmm_vex op src size)
+      (let ((dst WritableXmm (temp_writable_xmm))
+            (_ Unit (emit (MInst.GprToXmmVex op src dst size))))
+        dst))
+
+
 ;; Helper for creating `pmovmskb` instructions.
 (decl x64_pmovmskb (OperandSize Xmm) Gpr)
 (rule (x64_pmovmskb size src)
       (xmm_to_gpr (SseOpcode.Pmovmskb) src size))
+(rule 1 (x64_pmovmskb size src)
+        (if-let $true (use_avx_simd))
+        (xmm_to_gpr_vex (AvxOpcode.Vpmovmskb) src size))
 
 ;; Helper for creating `movmskps` instructions.
 (decl x64_movmskps (OperandSize Xmm) Gpr)
 (rule (x64_movmskps size src)
       (xmm_to_gpr (SseOpcode.Movmskps) src size))
+(rule 1 (x64_movmskps size src)
+        (if-let $true (use_avx_simd))
+        (xmm_to_gpr_vex (AvxOpcode.Vmovmskps) src size))
 
 ;; Helper for creating `movmskpd` instructions.
 (decl x64_movmskpd (OperandSize Xmm) Gpr)
 (rule (x64_movmskpd size src)
       (xmm_to_gpr (SseOpcode.Movmskpd) src size))
+(rule 1 (x64_movmskpd size src)
+        (if-let $true (use_avx_simd))
+        (xmm_to_gpr_vex (AvxOpcode.Vmovmskpd) src size))
 
 ;; Helper for creating `MInst.GprToXmm` instructions.
 (decl gpr_to_xmm (SseOpcode GprMem OperandSize) Xmm)
@@ -3973,11 +4044,17 @@
 (decl x64_cvtsi2ss (Type GprMem) Xmm)
 (rule (x64_cvtsi2ss ty x)
       (gpr_to_xmm (SseOpcode.Cvtsi2ss) x (raw_operand_size_of_type ty)))
+(rule 1 (x64_cvtsi2ss ty x)
+        (if-let $true (use_avx_simd))
+        (gpr_to_xmm_vex (AvxOpcode.Vcvtsi2ss) x (raw_operand_size_of_type ty)))
 
 ;; Helper for creating `cvtsi2sd` instructions.
 (decl x64_cvtsi2sd (Type GprMem) Xmm)
 (rule (x64_cvtsi2sd ty x)
       (gpr_to_xmm (SseOpcode.Cvtsi2sd) x (raw_operand_size_of_type ty)))
+(rule 1 (x64_cvtsi2sd ty x)
+        (if-let $true (use_avx_simd))
+        (gpr_to_xmm_vex (AvxOpcode.Vcvtsi2sd) x (raw_operand_size_of_type ty)))
 
 ;; Helper for creating `cvttps2dq` instructions.
 (decl x64_cvttps2dq (XmmMem) Xmm)
@@ -4486,15 +4563,15 @@
 
 (decl bitcast_xmm_to_gpr (Type Xmm) Gpr)
 (rule (bitcast_xmm_to_gpr $F32 src)
-      (xmm_to_gpr (SseOpcode.Movd) src (OperandSize.Size32)))
+      (x64_movd_to_gpr src))
 (rule (bitcast_xmm_to_gpr $F64 src)
-      (xmm_to_gpr (SseOpcode.Movq) src (OperandSize.Size64)))
+      (x64_movq_to_gpr src))
 
 (decl bitcast_gpr_to_xmm (Type Gpr) Xmm)
 (rule (bitcast_gpr_to_xmm $I32 src)
-      (gpr_to_xmm (SseOpcode.Movd) src (OperandSize.Size32)))
+      (x64_movd_to_xmm src))
 (rule (bitcast_gpr_to_xmm $I64 src)
-      (gpr_to_xmm (SseOpcode.Movq) src (OperandSize.Size64)))
+      (x64_movq_to_xmm src))
 
 ;;;; Stack Addresses ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
@@ -4678,7 +4755,6 @@
 (convert Reg XmmMem reg_to_xmm_mem)
 (convert Reg RegMemImm reg_to_reg_mem_imm)
 (convert RegMem XmmMem reg_mem_to_xmm_mem)
-(convert RegMemImm XmmMemImm mov_rmi_to_xmm)
 (convert Xmm XmmMem xmm_to_xmm_mem)
 (convert Xmm XmmMemImm xmm_to_xmm_mem_imm)
 (convert Xmm XmmMemAligned xmm_to_xmm_mem_aligned)
diff --git a/cranelift/codegen/src/isa/x64/inst/args.rs b/cranelift/codegen/src/isa/x64/inst/args.rs
index d7a851e66..a135fc5af 100644
--- a/cranelift/codegen/src/isa/x64/inst/args.rs
+++ b/cranelift/codegen/src/isa/x64/inst/args.rs
@@ -1715,7 +1715,14 @@ impl AvxOpcode {
             | AvxOpcode::Vpextrq
             | AvxOpcode::Vpblendw
             | AvxOpcode::Vmovddup
-            | AvxOpcode::Vbroadcastss => {
+            | AvxOpcode::Vbroadcastss
+            | AvxOpcode::Vmovd
+            | AvxOpcode::Vmovq
+            | AvxOpcode::Vmovmskps
+            | AvxOpcode::Vmovmskpd
+            | AvxOpcode::Vpmovmskb
+            | AvxOpcode::Vcvtsi2ss
+            | AvxOpcode::Vcvtsi2sd => {
                 smallvec![InstructionSet::AVX]
             }
 
diff --git a/cranelift/codegen/src/isa/x64/inst/emit.rs b/cranelift/codegen/src/isa/x64/inst/emit.rs
index 6c1dfc9fe..2b0f3af08 100644
--- a/cranelift/codegen/src/isa/x64/inst/emit.rs
+++ b/cranelift/codegen/src/isa/x64/inst/emit.rs
@@ -2515,6 +2515,89 @@ pub(crate) fn emit(
                 .encode(sink);
         }
 
+        Inst::XmmToGprVex {
+            op,
+            src,
+            dst,
+            dst_size,
+        } => {
+            let src = allocs.next(src.to_reg());
+            let dst = allocs.next(dst.to_reg().to_reg());
+
+            let (prefix, map, opcode) = match op {
+                // vmovd/vmovq are differentiated by `w`
+                AvxOpcode::Vmovd | AvxOpcode::Vmovq => (LegacyPrefixes::_66, OpcodeMap::_0F, 0x7E),
+                AvxOpcode::Vmovmskps => (LegacyPrefixes::None, OpcodeMap::_0F, 0x50),
+                AvxOpcode::Vmovmskpd => (LegacyPrefixes::_66, OpcodeMap::_0F, 0x50),
+                AvxOpcode::Vpmovmskb => (LegacyPrefixes::_66, OpcodeMap::_0F, 0xD7),
+                _ => unimplemented!("Opcode {:?} not implemented", op),
+            };
+            let w = match dst_size {
+                OperandSize::Size64 => true,
+                _ => false,
+            };
+            let mut vex = VexInstruction::new()
+                .length(VexVectorLength::V128)
+                .w(w)
+                .prefix(prefix)
+                .map(map)
+                .opcode(opcode);
+            vex = match op {
+                // The `vmovq/vmovd` reverse the order of the destination/source
+                // relative to other opcodes using this shape of instruction.
+                AvxOpcode::Vmovd | AvxOpcode::Vmovq => vex
+                    .rm(dst.to_real_reg().unwrap().hw_enc())
+                    .reg(src.to_real_reg().unwrap().hw_enc()),
+                _ => vex
+                    .rm(src.to_real_reg().unwrap().hw_enc())
+                    .reg(dst.to_real_reg().unwrap().hw_enc()),
+            };
+            vex.encode(sink);
+        }
+
+        Inst::GprToXmmVex {
+            op,
+            src,
+            dst,
+            src_size,
+        } => {
+            let dst = allocs.next(dst.to_reg().to_reg());
+            let src = match src.clone().to_reg_mem().with_allocs(allocs) {
+                RegMem::Reg { reg } => {
+                    RegisterOrAmode::Register(reg.to_real_reg().unwrap().hw_enc().into())
+                }
+                RegMem::Mem { addr } => RegisterOrAmode::Amode(addr.finalize(state, sink)),
+            };
+
+            let (prefix, map, opcode) = match op {
+                // vmovd/vmovq are differentiated by `w`
+                AvxOpcode::Vmovd | AvxOpcode::Vmovq => (LegacyPrefixes::_66, OpcodeMap::_0F, 0x6E),
+                AvxOpcode::Vcvtsi2ss => (LegacyPrefixes::_F3, OpcodeMap::_0F, 0x2A),
+                AvxOpcode::Vcvtsi2sd => (LegacyPrefixes::_F2, OpcodeMap::_0F, 0x2A),
+                _ => unimplemented!("Opcode {:?} not implemented", op),
+            };
+            let w = match src_size {
+                OperandSize::Size64 => true,
+                _ => false,
+            };
+            let mut insn = VexInstruction::new()
+                .length(VexVectorLength::V128)
+                .w(w)
+                .prefix(prefix)
+                .map(map)
+                .opcode(opcode)
+                .rm(src)
+                .reg(dst.to_real_reg().unwrap().hw_enc());
+            // These opcodes technically take a second operand which is the
+            // upper bits to preserve during the float conversion. We don't
+            // actually use this in this backend right now so reuse the
+            // destination register. This at least matches what LLVM does.
+            if let AvxOpcode::Vcvtsi2ss | AvxOpcode::Vcvtsi2sd = op {
+                insn = insn.vvvv(dst.to_real_reg().unwrap().hw_enc());
+            }
+            insn.encode(sink);
+        }
+
         Inst::XmmRmREvex {
             op,
             src1,
diff --git a/cranelift/codegen/src/isa/x64/inst/mod.rs b/cranelift/codegen/src/isa/x64/inst/mod.rs
index 179368430..f9dd071dc 100644
--- a/cranelift/codegen/src/isa/x64/inst/mod.rs
+++ b/cranelift/codegen/src/isa/x64/inst/mod.rs
@@ -158,7 +158,9 @@ impl Inst {
             | Inst::XmmUnaryRmRImmVex { op, .. }
             | Inst::XmmMovRMVex { op, .. }
             | Inst::XmmMovRMImmVex { op, .. }
-            | Inst::XmmToGprImmVex { op, .. } => op.available_from(),
+            | Inst::XmmToGprImmVex { op, .. }
+            | Inst::XmmToGprVex { op, .. }
+            | Inst::GprToXmmVex { op, .. } => op.available_from(),
         }
     }
 }
@@ -1202,6 +1204,18 @@ impl PrettyPrint for Inst {
                 format!("{} {}, {}", ljustify(op.to_string()), src, dst)
             }
 
+            Inst::XmmToGprVex {
+                op,
+                src,
+                dst,
+                dst_size,
+            } => {
+                let dst_size = dst_size.to_bytes();
+                let src = pretty_print_reg(src.to_reg(), 8, allocs);
+                let dst = pretty_print_reg(dst.to_reg().to_reg(), dst_size, allocs);
+                format!("{} {src}, {dst}", ljustify(op.to_string()))
+            }
+
             Inst::XmmToGprImm { op, src, dst, imm } => {
                 let src = pretty_print_reg(src.to_reg(), 8, allocs);
                 let dst = pretty_print_reg(dst.to_reg().to_reg(), 8, allocs);
@@ -1225,6 +1239,17 @@ impl PrettyPrint for Inst {
                 format!("{} {}, {}", ljustify(op.to_string()), src, dst)
             }
 
+            Inst::GprToXmmVex {
+                op,
+                src,
+                src_size,
+                dst,
+            } => {
+                let dst = pretty_print_reg(dst.to_reg().to_reg(), 8, allocs);
+                let src = src.pretty_print(src_size.to_bytes(), allocs);
+                format!("{} {src}, {dst}", ljustify(op.to_string()))
+            }
+
             Inst::XmmCmpRmR { op, src, dst } => {
                 let dst = pretty_print_reg(dst.to_reg(), 8, allocs);
                 let src = src.pretty_print(8, allocs);
@@ -2082,12 +2107,13 @@ fn x64_get_operands<F: Fn(VReg) -> VReg>(inst: &Inst, collector: &mut OperandCol
             collector.reg_fixed_nonallocatable(*dst);
         }
         Inst::XmmToGpr { src, dst, .. }
+        | Inst::XmmToGprVex { src, dst, .. }
         | Inst::XmmToGprImm { src, dst, .. }
         | Inst::XmmToGprImmVex { src, dst, .. } => {
             collector.reg_use(src.to_reg());
             collector.reg_def(dst.to_writable_reg());
         }
-        Inst::GprToXmm { src, dst, .. } => {
+        Inst::GprToXmm { src, dst, .. } | Inst::GprToXmmVex { src, dst, .. } => {
             collector.reg_def(dst.to_writable_reg());
             src.get_operands(collector);
         }
diff --git a/cranelift/codegen/src/isa/x64/lower.isle b/cranelift/codegen/src/isa/x64/lower.isle
index 763fc338e..ee7ca827b 100644
--- a/cranelift/codegen/src/isa/x64/lower.isle
+++ b/cranelift/codegen/src/isa/x64/lower.isle
@@ -883,17 +883,17 @@
       (let ((a0 Xmm a)
             (b0 Xmm b)
             ;; a_hi = A >> 32
-            (a_hi Xmm (x64_psrlq a0 (RegMemImm.Imm 32)))
+            (a_hi Xmm (x64_psrlq a0 (xmi_imm 32)))
             ;; ah_bl = Ah * Bl
             (ah_bl Xmm (x64_pmuludq a_hi b0))
             ;; b_hi = B >> 32
-            (b_hi Xmm (x64_psrlq b0 (RegMemImm.Imm 32)))
+            (b_hi Xmm (x64_psrlq b0 (xmi_imm 32)))
             ;; al_bh = Al * Bh
             (al_bh Xmm (x64_pmuludq a0 b_hi))
             ;; aa_bb = ah_bl + al_bh
             (aa_bb Xmm (x64_paddq ah_bl al_bh))
             ;; aa_bb_shifted = aa_bb << 32
-            (aa_bb_shifted Xmm (x64_psllq aa_bb (RegMemImm.Imm 32)))
+            (aa_bb_shifted Xmm (x64_psllq aa_bb (xmi_imm 32)))
             ;; al_bl = Al * Bl
             (al_bl Xmm (x64_pmuludq a0 b0)))
         ;; al_bl + aa_bb_shifted
@@ -1087,14 +1087,12 @@
 ;; Special case for `f32x4.abs`.
 (rule (lower (has_type $F32X4 (fabs x)))
       (x64_andps x
-             (x64_psrld (vector_all_ones)
-                    (RegMemImm.Imm 1))))
+             (x64_psrld (vector_all_ones) (xmi_imm 1))))
 
 ;; Special case for `f64x2.abs`.
 (rule (lower (has_type $F64X2 (fabs x)))
       (x64_andpd x
-             (x64_psrlq (vector_all_ones)
-                    (RegMemImm.Imm 1))))
+             (x64_psrlq (vector_all_ones) (xmi_imm 1))))
 
 ;;;; Rules for `fneg` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
@@ -1106,13 +1104,11 @@
 
 (rule (lower (has_type $F32X4 (fneg x)))
       (x64_xorps x
-             (x64_pslld (vector_all_ones)
-                    (RegMemImm.Imm 31))))
+             (x64_pslld (vector_all_ones) (xmi_imm 31))))
 
 (rule (lower (has_type $F64X2 (fneg x)))
       (x64_xorpd x
-             (x64_psllq (vector_all_ones)
-                    (RegMemImm.Imm 63))))
+             (x64_psllq (vector_all_ones) (xmi_imm 63))))
 
 ;;;; Rules for `bmask` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
@@ -1918,7 +1914,7 @@
             ;; Note that this is a 16x8 shift, but that's OK; we mask
             ;; off anything that traverses from one byte to the next
             ;; with the low_mask below.
-            (shifted_src Xmm (x64_psrlw src (RegMemImm.Imm 4)))
+            (shifted_src Xmm (x64_psrlw src (xmi_imm 4)))
             (high_nibbles Xmm (sse_and $I8X16 shifted_src low_mask))
             (lookup Xmm (x64_xmm_load_const $I8X16 (popcount_4bit_table)))
             (bit_counts_low Xmm (x64_pshufb lookup low_nibbles))
@@ -2237,7 +2233,7 @@
             ;; All-ones for NaN, shifted down to leave 10 top bits (1
             ;; sign, 8 exponent, 1 QNaN bit that must remain set)
             ;; cleared.
-            (nan_fraction_mask Xmm (x64_psrld is_nan_mask (RegMemImm.Imm 10)))
+            (nan_fraction_mask Xmm (x64_psrld is_nan_mask (xmi_imm 10)))
             ;; Do a NAND, so that we retain every bit not set in
             ;; `nan_fraction_mask`. This mask will be all zeroes (so
             ;; we retain every bit) in non-NaN cases, and will have
@@ -2254,7 +2250,7 @@
             (min_or Xmm (x64_orpd min1 min2))
             (is_nan_mask Xmm (x64_cmppd min1 min2 (FcmpImm.Unordered)))
             (min_or_2 Xmm (x64_orpd min_or is_nan_mask))
-            (nan_fraction_mask Xmm (x64_psrlq is_nan_mask (RegMemImm.Imm 13)))
+            (nan_fraction_mask Xmm (x64_psrlq is_nan_mask (xmi_imm 13)))
             (final Xmm (x64_andnpd nan_fraction_mask min_or_2)))
         final))
 
@@ -2302,7 +2298,7 @@
             ;; All-ones for NaN, shifted down to leave 10 top bits (1
             ;; sign, 8 exponent, 1 QNaN bit that must remain set)
             ;; cleared.
-            (nan_fraction_mask Xmm (x64_psrld is_nan_mask (RegMemImm.Imm 10)))
+            (nan_fraction_mask Xmm (x64_psrld is_nan_mask (xmi_imm 10)))
             ;; Do a NAND, so that we retain every bit not set in
             ;; `nan_fraction_mask`. This mask will be all zeroes (so
             ;; we retain every bit) in non-NaN cases, and will have
@@ -2346,7 +2342,7 @@
             ;; All-ones for NaN, shifted down to leave 13 top bits (1
             ;; sign, 11 exponent, 1 QNaN bit that must remain set)
             ;; cleared.
-            (nan_fraction_mask Xmm (x64_psrlq is_nan_mask (RegMemImm.Imm 13)))
+            (nan_fraction_mask Xmm (x64_psrlq is_nan_mask (xmi_imm 13)))
             ;; Do a NAND, so that we retain every bit not set in
             ;; `nan_fraction_mask`. This mask will be all zeroes (so
             ;; we retain every bit) in non-NaN cases, and will have
@@ -3011,8 +3007,8 @@
       (let ((a Xmm val)
 
             ;;  get the low 16 bits
-            (a_lo Xmm (x64_pslld a (RegMemImm.Imm 16)))
-            (a_lo Xmm (x64_psrld a_lo (RegMemImm.Imm 16)))
+            (a_lo Xmm (x64_pslld a (xmi_imm 16)))
+            (a_lo Xmm (x64_psrld a_lo (xmi_imm 16)))
 
             ;; get the high 16 bits
             (a_hi Xmm (x64_psubd a a_lo))
@@ -3022,7 +3018,7 @@
 
             ;; shift the high bits by 1, convert, and double to get the correct
             ;; value
-            (a_hi Xmm (x64_psrld a_hi (RegMemImm.Imm 1)))
+            (a_hi Xmm (x64_psrld a_hi (xmi_imm 1)))
             (a_hi Xmm (x64_cvtdq2ps a_hi))
             (a_hi Xmm (x64_addps a_hi a_hi)))
 
@@ -3060,7 +3056,7 @@
 
             ;; Set top bit only if < 0
             (tmp Xmm (x64_pand dst tmp))
-            (tmp Xmm (x64_psrad tmp (RegMemImm.Imm 31))))
+            (tmp Xmm (x64_psrad tmp (xmi_imm 31))))
 
         ;; On overflow 0x80000000 is returned to a lane.
         ;; Below sets positive overflow lanes to 0x7FFFFFFF
@@ -3130,7 +3126,7 @@
             ;; integer that it can represent. In the case of INT_MAX, this value gets
             ;; represented as 0x4f000000 which is the integer value (INT_MAX+1).
             (tmp2 Xmm (x64_pcmpeqd tmp2 tmp2))
-            (tmp2 Xmm (x64_psrld tmp2 (RegMemImm.Imm 1)))
+            (tmp2 Xmm (x64_psrld tmp2 (xmi_imm 1)))
             (tmp2 Xmm (x64_cvtdq2ps tmp2))
 
             ;; Make a copy of these lanes and then do the first conversion.
diff --git a/cranelift/codegen/src/isa/x64/lower/isle.rs b/cranelift/codegen/src/isa/x64/lower/isle.rs
index 3a397a0eb..1ca927ec3 100644
--- a/cranelift/codegen/src/isa/x64/lower/isle.rs
+++ b/cranelift/codegen/src/isa/x64/lower/isle.rs
@@ -1038,6 +1038,10 @@ impl Context for IsleContext<'_, '_, MInst, X64Backend> {
                 | bit(h, 7)?,
         )
     }
+
+    fn xmi_imm(&mut self, imm: u32) -> XmmMemImm {
+        XmmMemImm::new(RegMemImm::imm(imm)).unwrap()
+    }
 }
 
 impl IsleContext<'_, '_, MInst, X64Backend> {
diff --git a/cranelift/codegen/src/isle_prelude.rs b/cranelift/codegen/src/isle_prelude.rs
index d557d53f9..3de34e436 100644
--- a/cranelift/codegen/src/isle_prelude.rs
+++ b/cranelift/codegen/src/isle_prelude.rs
@@ -38,6 +38,16 @@ macro_rules! isle_common_prelude_methods {
             x as u64
         }
 
+        #[inline]
+        fn u64_as_i32(&mut self, x: u64) -> i32 {
+            x as i32
+        }
+
+        #[inline]
+        fn i64_neg(&mut self, x: i64) -> i64 {
+            x.wrapping_neg()
+        }
+
         #[inline]
         fn u64_add(&mut self, x: u64, y: u64) -> u64 {
             x.wrapping_add(y)
diff --git a/cranelift/codegen/src/opts/algebraic.isle b/cranelift/codegen/src/opts/algebraic.isle
index 6bc049249..8cab77bd4 100644
--- a/cranelift/codegen/src/opts/algebraic.isle
+++ b/cranelift/codegen/src/opts/algebraic.isle
@@ -323,14 +323,12 @@
       (remat x))
 
 ;; Optimize icmp-of-icmp.
-(rule (simplify (icmp ty
-                      (IntCC.NotEqual)
+(rule (simplify (ne ty
                       (uextend _ inner @ (icmp ty _ _ _))
                       (iconst _ (u64_from_imm64 0))))
       (subsume inner))
 
-(rule (simplify (icmp ty
-                      (IntCC.Equal)
+(rule (simplify (eq ty
                       (uextend _ (icmp ty cc x y))
                       (iconst _ (u64_from_imm64 0))))
       (subsume (icmp ty (intcc_inverse cc) x y)))
@@ -346,36 +344,16 @@
 
 ;; `x == x` is always true for integers; `x != x` is false. Strict
 ;; inequalities are false, and loose inequalities are true.
-(rule (simplify
-       (icmp (fits_in_64 (ty_int ty)) (IntCC.Equal) x x))
-      (iconst ty (imm64 1)))
-(rule (simplify
-       (icmp (fits_in_64 (ty_int ty)) (IntCC.NotEqual) x x))
-      (iconst ty (imm64 0)))
-(rule (simplify
-       (icmp (fits_in_64 (ty_int ty)) (IntCC.UnsignedGreaterThan) x x))
-      (iconst ty (imm64 0)))
-(rule (simplify
-       (icmp (fits_in_64 (ty_int ty)) (IntCC.UnsignedGreaterThanOrEqual) x x))
-      (iconst ty (imm64 1)))
-(rule (simplify
-       (icmp (fits_in_64 (ty_int ty)) (IntCC.SignedGreaterThan) x x))
-      (iconst ty (imm64 0)))
-(rule (simplify
-       (icmp (fits_in_64 (ty_int ty)) (IntCC.SignedGreaterThanOrEqual) x x))
-      (iconst ty (imm64 1)))
-(rule (simplify
-       (icmp (fits_in_64 (ty_int ty)) (IntCC.UnsignedLessThan) x x))
-      (iconst ty (imm64 0)))
-(rule (simplify
-       (icmp (fits_in_64 (ty_int ty)) (IntCC.UnsignedLessThanOrEqual) x x))
-      (iconst ty (imm64 1)))
-(rule (simplify
-       (icmp (fits_in_64 (ty_int ty)) (IntCC.SignedLessThan) x x))
-      (iconst ty (imm64 0)))
-(rule (simplify
-       (icmp (fits_in_64 (ty_int ty)) (IntCC.SignedLessThanOrEqual) x x))
-      (iconst ty (imm64 1)))
+(rule (simplify (eq  (fits_in_64 (ty_int ty)) x x)) (iconst ty (imm64 1)))
+(rule (simplify (ne  (fits_in_64 (ty_int ty)) x x)) (iconst ty (imm64 0)))
+(rule (simplify (ugt (fits_in_64 (ty_int ty)) x x)) (iconst ty (imm64 0)))
+(rule (simplify (uge (fits_in_64 (ty_int ty)) x x)) (iconst ty (imm64 1)))
+(rule (simplify (sgt (fits_in_64 (ty_int ty)) x x)) (iconst ty (imm64 0)))
+(rule (simplify (sge (fits_in_64 (ty_int ty)) x x)) (iconst ty (imm64 1)))
+(rule (simplify (ult (fits_in_64 (ty_int ty)) x x)) (iconst ty (imm64 0)))
+(rule (simplify (ule (fits_in_64 (ty_int ty)) x x)) (iconst ty (imm64 1)))
+(rule (simplify (slt (fits_in_64 (ty_int ty)) x x)) (iconst ty (imm64 0)))
+(rule (simplify (sle (fits_in_64 (ty_int ty)) x x)) (iconst ty (imm64 1)))
 
 ;; (x ^ -1) can be replaced with the `bnot` instruction
 (rule (simplify (bxor ty x (iconst ty k)))
@@ -399,215 +377,148 @@
 
 ;; ult(x, 0) == false.
 (rule (simplify
-       (icmp (fits_in_64 (ty_int bty)) (IntCC.UnsignedLessThan) x zero @ (iconst _ (u64_from_imm64 0))))
+       (ult (fits_in_64 (ty_int bty)) x zero @ (iconst _ (u64_from_imm64 0))))
       (subsume (iconst bty (imm64 0))))
 
 ;; ule(x, 0) == eq(x, 0)
 (rule (simplify
-       (icmp (fits_in_64 (ty_int bty)) (IntCC.UnsignedLessThanOrEqual) x zero @ (iconst _ (u64_from_imm64 0))))
-      (icmp bty (IntCC.Equal) x zero))
+       (ule (fits_in_64 (ty_int bty)) x zero @ (iconst _ (u64_from_imm64 0))))
+      (eq bty x zero))
 
 ;; ugt(x, 0) == ne(x, 0).
 (rule (simplify
-       (icmp (fits_in_64 (ty_int bty)) (IntCC.UnsignedGreaterThan) x zero @ (iconst _ (u64_from_imm64 0))))
-      (icmp bty (IntCC.NotEqual) x zero))
+       (ugt (fits_in_64 (ty_int bty)) x zero @ (iconst _ (u64_from_imm64 0))))
+      (ne bty x zero))
 
 ;; uge(x, 0) == true.
 (rule (simplify
-       (icmp (fits_in_64 (ty_int bty)) (IntCC.UnsignedGreaterThanOrEqual) x zero @ (iconst _ (u64_from_imm64 0))))
+       (uge (fits_in_64 (ty_int bty)) x zero @ (iconst _ (u64_from_imm64 0))))
       (subsume (iconst bty (imm64 1))))
 
 ;; ult(x, UMAX) == ne(x, UMAX).
 (rule (simplify
-       (icmp (fits_in_64 (ty_int bty)) (IntCC.UnsignedLessThan) x umax @ (iconst cty (u64_from_imm64 y))))
+       (ult (fits_in_64 (ty_int bty)) x umax @ (iconst cty (u64_from_imm64 y))))
        (if-let $true (u64_eq y (ty_umax cty)))
-       (icmp bty (IntCC.NotEqual) x umax))
+       (ne bty x umax))
 
 ;; ule(x, UMAX) == true.
 (rule (simplify
-       (icmp (fits_in_64 (ty_int bty)) (IntCC.UnsignedLessThanOrEqual) x umax @ (iconst cty (u64_from_imm64 y))))
+       (ule (fits_in_64 (ty_int bty)) x umax @ (iconst cty (u64_from_imm64 y))))
        (if-let $true (u64_eq y (ty_umax cty)))
        (subsume (iconst bty (imm64 1))))
 
 ;; ugt(x, UMAX) == false.
 (rule (simplify
-       (icmp (fits_in_64 (ty_int bty)) (IntCC.UnsignedGreaterThan) x umax @ (iconst cty (u64_from_imm64 y))))
+       (ugt (fits_in_64 (ty_int bty)) x umax @ (iconst cty (u64_from_imm64 y))))
        (if-let $true (u64_eq y (ty_umax cty)))
        (subsume (iconst bty (imm64 0))))
 
 ;; uge(x, UMAX) == eq(x, UMAX).
 (rule (simplify
-       (icmp (fits_in_64 (ty_int bty)) (IntCC.UnsignedGreaterThanOrEqual) x umax @ (iconst cty (u64_from_imm64 y))))
+       (uge (fits_in_64 (ty_int bty)) x umax @ (iconst cty (u64_from_imm64 y))))
        (if-let $true (u64_eq y (ty_umax cty)))
-       (icmp bty (IntCC.Equal) x umax))
+       (eq bty x umax))
 
 ;; slt(x, SMIN) == false.
 (rule (simplify
-       (icmp (fits_in_64 (ty_int bty)) (IntCC.SignedLessThan) x smin @ (iconst cty (u64_from_imm64 y))))
+       (slt (fits_in_64 (ty_int bty)) x smin @ (iconst cty (u64_from_imm64 y))))
        (if-let $true (u64_eq y (ty_smin cty)))
        (subsume (iconst bty (imm64 0))))
 
 ;; sle(x, SMIN) == eq(x, SMIN).
 (rule (simplify
-       (icmp (fits_in_64 (ty_int bty)) (IntCC.SignedLessThanOrEqual) x smin @ (iconst cty (u64_from_imm64 y))))
+       (sle (fits_in_64 (ty_int bty)) x smin @ (iconst cty (u64_from_imm64 y))))
        (if-let $true (u64_eq y (ty_smin cty)))
-       (icmp bty (IntCC.Equal) x smin))
+       (eq bty x smin))
 
 ;; sgt(x, SMIN) == ne(x, SMIN).
 (rule (simplify
-       (icmp (fits_in_64 (ty_int bty)) (IntCC.SignedGreaterThan) x smin @ (iconst cty (u64_from_imm64 y))))
+       (sgt (fits_in_64 (ty_int bty)) x smin @ (iconst cty (u64_from_imm64 y))))
        (if-let $true (u64_eq y (ty_smin cty)))
-       (icmp bty (IntCC.NotEqual) x smin))
+       (ne bty x smin))
 
 ;; sge(x, SMIN) == true.
 (rule (simplify
-       (icmp (fits_in_64 (ty_int bty)) (IntCC.SignedGreaterThanOrEqual) x smin @ (iconst cty (u64_from_imm64 y))))
+       (sge (fits_in_64 (ty_int bty)) x smin @ (iconst cty (u64_from_imm64 y))))
        (if-let $true (u64_eq y (ty_smin cty)))
        (subsume (iconst bty (imm64 1))))
 
 ;; slt(x, SMAX) == ne(x, SMAX).
 (rule (simplify
-       (icmp (fits_in_64 (ty_int bty)) (IntCC.SignedLessThan) x smax @ (iconst cty (u64_from_imm64 y))))
+       (slt (fits_in_64 (ty_int bty)) x smax @ (iconst cty (u64_from_imm64 y))))
        (if-let $true (u64_eq y (ty_smax cty)))
-       (icmp bty (IntCC.NotEqual) x smax))
+       (ne bty x smax))
 
 ;; sle(x, SMAX) == true.
 (rule (simplify
-       (icmp (fits_in_64 (ty_int bty)) (IntCC.SignedLessThanOrEqual) x smax @ (iconst cty (u64_from_imm64 y))))
+       (sle (fits_in_64 (ty_int bty)) x smax @ (iconst cty (u64_from_imm64 y))))
        (if-let $true (u64_eq y (ty_smax cty)))
        (subsume (iconst bty (imm64 1))))
 
 ;; sgt(x, SMAX) == false.
 (rule (simplify
-       (icmp (fits_in_64 (ty_int bty)) (IntCC.SignedGreaterThan) x smax @ (iconst cty (u64_from_imm64 y))))
+       (sgt (fits_in_64 (ty_int bty)) x smax @ (iconst cty (u64_from_imm64 y))))
        (if-let $true (u64_eq y (ty_smax cty)))
        (subsume (iconst bty (imm64 0))))
 
 ;; sge(x, SMAX) == eq(x, SMAX).
 (rule (simplify
-       (icmp (fits_in_64 (ty_int bty)) (IntCC.SignedGreaterThanOrEqual) x smax @ (iconst cty (u64_from_imm64 y))))
+       (sge (fits_in_64 (ty_int bty)) x smax @ (iconst cty (u64_from_imm64 y))))
        (if-let $true (u64_eq y (ty_smax cty)))
-       (icmp bty (IntCC.Equal) x smax))
+       (eq bty x smax))
 
 ;; 32-bit integers zero-extended to 64-bit integers are never negative
 (rule (simplify
-       (icmp (ty_int ty)
-             (IntCC.SignedLessThan)
+       (slt ty
              (uextend $I64 x @ (value_type $I32))
              (iconst _ (u64_from_imm64 0))))
       (iconst ty (imm64 0)))
 (rule (simplify
-       (icmp (ty_int ty)
-             (IntCC.SignedGreaterThanOrEqual)
+       (sge ty
              (uextend $I64 x @ (value_type $I32))
              (iconst _ (u64_from_imm64 0))))
       (iconst ty (imm64 1)))
 
 
 ;; Transform select-of-icmp into {u,s}{min,max} instructions where possible.
-(rule (simplify
-       (select ty (icmp _ (IntCC.SignedGreaterThan) x y) x y))
-      (smax ty x y))
-(rule (simplify
-       (select ty (icmp _ (IntCC.SignedGreaterThanOrEqual) x y) x y))
-      (smax ty x y))
-(rule (simplify
-       (select ty (icmp _ (IntCC.UnsignedGreaterThan) x y) x y))
-      (umax ty x y))
-(rule (simplify
-       (select ty (icmp _ (IntCC.UnsignedGreaterThanOrEqual) x y) x y))
-      (umax ty x y))
-(rule (simplify
-       (select ty (icmp _ (IntCC.SignedLessThan) x y) x y))
-      (smin ty x y))
-(rule (simplify
-       (select ty (icmp _ (IntCC.SignedLessThanOrEqual) x y) x y))
-      (smin ty x y))
-(rule (simplify
-       (select ty (icmp _ (IntCC.UnsignedLessThan) x y) x y))
-      (umin ty x y))
-(rule (simplify
-       (select ty (icmp _ (IntCC.UnsignedLessThanOrEqual) x y) x y))
-      (umin ty x y))
-
+(rule (simplify (select ty (sgt _ x y) x y)) (smax ty x y))
+(rule (simplify (select ty (sge _ x y) x y)) (smax ty x y))
+(rule (simplify (select ty (ugt _ x y) x y)) (umax ty x y))
+(rule (simplify (select ty (uge _ x y) x y)) (umax ty x y))
+(rule (simplify (select ty (slt _ x y) x y)) (smin ty x y))
+(rule (simplify (select ty (sle _ x y) x y)) (smin ty x y))
+(rule (simplify (select ty (ult _ x y) x y)) (umin ty x y))
+(rule (simplify (select ty (ule _ x y) x y)) (umin ty x y))
 
 ;; These are the same rules as above, but when the operands for select are swapped
-(rule (simplify
-       (select ty (icmp _ (IntCC.SignedLessThan) x y) y x))
-      (smax ty x y))
-(rule (simplify
-       (select ty (icmp _ (IntCC.SignedLessThanOrEqual) x y) y x))
-      (smax ty x y))
-(rule (simplify
-       (select ty (icmp _ (IntCC.UnsignedLessThan) x y) y x))
-      (umax ty x y))
-(rule (simplify
-       (select ty (icmp _ (IntCC.UnsignedLessThanOrEqual) x y) y x))
-      (umax ty x y))
-(rule (simplify
-       (select ty (icmp _ (IntCC.SignedGreaterThan) x y) y x))
-      (smin ty x y))
-(rule (simplify
-       (select ty (icmp _ (IntCC.SignedGreaterThanOrEqual) x y) y x))
-      (smin ty x y))
-(rule (simplify
-       (select ty (icmp _ (IntCC.UnsignedGreaterThan) x y) y x))
-      (umin ty x y))
-(rule (simplify
-       (select ty (icmp _ (IntCC.UnsignedGreaterThanOrEqual) x y) y x))
-      (umin ty x y))
+(rule (simplify (select ty (slt _ x y) y x)) (smax ty x y))
+(rule (simplify (select ty (sle _ x y) y x)) (smax ty x y))
+(rule (simplify (select ty (ult _ x y) y x)) (umax ty x y))
+(rule (simplify (select ty (ule _ x y) y x)) (umax ty x y))
+(rule (simplify (select ty (sgt _ x y) y x)) (smin ty x y))
+(rule (simplify (select ty (sge _ x y) y x)) (smin ty x y))
+(rule (simplify (select ty (ugt _ x y) y x)) (umin ty x y))
+(rule (simplify (select ty (uge _ x y) y x)) (umin ty x y))
 
 ;; Transform bitselect-of-icmp into {u,s}{min,max} instructions where possible.
-(rule (simplify
-       (bitselect ty (icmp _ (IntCC.SignedGreaterThan) x y) x y))
-      (smax ty x y))
-(rule (simplify
-       (bitselect ty (icmp _ (IntCC.SignedGreaterThanOrEqual) x y) x y))
-      (smax ty x y))
-(rule (simplify
-       (bitselect ty (icmp _ (IntCC.UnsignedGreaterThan) x y) x y))
-      (umax ty x y))
-(rule (simplify
-       (bitselect ty (icmp _ (IntCC.UnsignedGreaterThanOrEqual) x y) x y))
-      (umax ty x y))
-(rule (simplify
-       (bitselect ty (icmp _ (IntCC.SignedLessThan) x y) x y))
-      (smin ty x y))
-(rule (simplify
-       (bitselect ty (icmp _ (IntCC.SignedLessThanOrEqual) x y) x y))
-      (smin ty x y))
-(rule (simplify
-       (bitselect ty (icmp _ (IntCC.UnsignedLessThan) x y) x y))
-      (umin ty x y))
-(rule (simplify
-       (bitselect ty (icmp _ (IntCC.UnsignedLessThanOrEqual) x y) x y))
-      (umin ty x y))
+(rule (simplify (bitselect ty (sgt _ x y) x y)) (smax ty x y))
+(rule (simplify (bitselect ty (sge _ x y) x y)) (smax ty x y))
+(rule (simplify (bitselect ty (ugt _ x y) x y)) (umax ty x y))
+(rule (simplify (bitselect ty (uge _ x y) x y)) (umax ty x y))
+(rule (simplify (bitselect ty (slt _ x y) x y)) (smin ty x y))
+(rule (simplify (bitselect ty (sle _ x y) x y)) (smin ty x y))
+(rule (simplify (bitselect ty (ult _ x y) x y)) (umin ty x y))
+(rule (simplify (bitselect ty (ule _ x y) x y)) (umin ty x y))
 
 ;; These are the same rules as above, but when the operands for select are swapped
-(rule (simplify
-       (bitselect ty (icmp _ (IntCC.SignedLessThan) x y) y x))
-      (smax ty x y))
-(rule (simplify
-       (bitselect ty (icmp _ (IntCC.SignedLessThanOrEqual) x y) y x))
-      (smax ty x y))
-(rule (simplify
-       (bitselect ty (icmp _ (IntCC.UnsignedLessThan) x y) y x))
-      (umax ty x y))
-(rule (simplify
-       (bitselect ty (icmp _ (IntCC.UnsignedLessThanOrEqual) x y) y x))
-      (umax ty x y))
-(rule (simplify
-       (bitselect ty (icmp _ (IntCC.SignedGreaterThan) x y) y x))
-      (smin ty x y))
-(rule (simplify
-       (bitselect ty (icmp _ (IntCC.SignedGreaterThanOrEqual) x y) y x))
-      (smin ty x y))
-(rule (simplify
-       (bitselect ty (icmp _ (IntCC.UnsignedGreaterThan) x y) y x))
-      (umin ty x y))
-(rule (simplify
-       (bitselect ty (icmp _ (IntCC.UnsignedGreaterThanOrEqual) x y) y x))
-      (umin ty x y))
+(rule (simplify (bitselect ty (slt _ x y) y x)) (smax ty x y))
+(rule (simplify (bitselect ty (sle _ x y) y x)) (smax ty x y))
+(rule (simplify (bitselect ty (ult _ x y) y x)) (umax ty x y))
+(rule (simplify (bitselect ty (ule _ x y) y x)) (umax ty x y))
+(rule (simplify (bitselect ty (sgt _ x y) y x)) (smin ty x y))
+(rule (simplify (bitselect ty (sge _ x y) y x)) (smin ty x y))
+(rule (simplify (bitselect ty (ugt _ x y) y x)) (umin ty x y))
+(rule (simplify (bitselect ty (uge _ x y) y x)) (umin ty x y))
 
 ;; For floats convert fcmp lt into pseudo_min and gt into pseudo_max
 ;;
diff --git a/cranelift/codegen/src/prelude.isle b/cranelift/codegen/src/prelude.isle
index 5461109fd..012d5e29a 100644
--- a/cranelift/codegen/src/prelude.isle
+++ b/cranelift/codegen/src/prelude.isle
@@ -93,12 +93,18 @@
 (decl pure i64_as_u64 (i64) u64)
 (extern constructor i64_as_u64 i64_as_u64)
 
+(decl pure i64_neg (i64) i64)
+(extern constructor i64_neg i64_neg)
+
 (decl u128_as_u64 (u64) u128)
 (extern extractor u128_as_u64 u128_as_u64)
 
 (decl u64_as_u32 (u32) u64)
 (extern extractor u64_as_u32 u64_as_u32)
 
+(decl pure u64_as_i32 (u64) i32)
+(extern constructor u64_as_i32 u64_as_i32)
+
 ;;;; Primitive Arithmetic ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 (decl pure u8_and (u8 u8) u8)
@@ -279,6 +285,36 @@
 
 ;;;; Helper Clif Extractors ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
+(decl eq (Type Value Value) Value)
+(extractor (eq ty x y) (icmp ty (IntCC.Equal) x y))
+
+(decl ne (Type Value Value) Value)
+(extractor (ne ty x y) (icmp ty (IntCC.NotEqual) x y))
+
+(decl ult (Type Value Value) Value)
+(extractor (ult ty x y) (icmp ty (IntCC.UnsignedLessThan) x y))
+
+(decl ule (Type Value Value) Value)
+(extractor (ule ty x y) (icmp ty (IntCC.UnsignedLessThanOrEqual) x y))
+
+(decl ugt (Type Value Value) Value)
+(extractor (ugt ty x y) (icmp ty (IntCC.UnsignedGreaterThan) x y))
+
+(decl uge (Type Value Value) Value)
+(extractor (uge ty x y) (icmp ty (IntCC.UnsignedGreaterThanOrEqual) x y))
+
+(decl slt (Type Value Value) Value)
+(extractor (slt ty x y) (icmp ty (IntCC.SignedLessThan) x y))
+
+(decl sle (Type Value Value) Value)
+(extractor (sle ty x y) (icmp ty (IntCC.SignedLessThanOrEqual) x y))
+
+(decl sgt (Type Value Value) Value)
+(extractor (sgt ty x y) (icmp ty (IntCC.SignedGreaterThan) x y))
+
+(decl sge (Type Value Value) Value)
+(extractor (sge ty x y) (icmp ty (IntCC.SignedGreaterThanOrEqual) x y))
+
 ;; An extractor that only matches types that can fit in 16 bits.
 (decl fits_in_16 (Type) Type)
 (extern extractor fits_in_16 fits_in_16)
diff --git a/cranelift/codegen/src/prelude_opt.isle b/cranelift/codegen/src/prelude_opt.isle
index d3fc0d1bb..099930f5b 100644
--- a/cranelift/codegen/src/prelude_opt.isle
+++ b/cranelift/codegen/src/prelude_opt.isle
@@ -17,6 +17,17 @@
 (decl value_array_3_ctor (Value Value Value) ValueArray3)
 (extern constructor value_array_3_ctor value_array_3_ctor)
 
+(rule (eq ty x y) (icmp ty (IntCC.Equal) x y))
+(rule (ne ty x y) (icmp ty (IntCC.NotEqual) x y))
+(rule (ult ty x y) (icmp ty (IntCC.UnsignedLessThan) x y))
+(rule (ule ty x y) (icmp ty (IntCC.UnsignedLessThanOrEqual) x y))
+(rule (ugt ty x y) (icmp ty (IntCC.UnsignedGreaterThan) x y))
+(rule (uge ty x y) (icmp ty (IntCC.UnsignedGreaterThanOrEqual) x y))
+(rule (slt ty x y) (icmp ty (IntCC.SignedLessThan) x y))
+(rule (sle ty x y) (icmp ty (IntCC.SignedLessThanOrEqual) x y))
+(rule (sgt ty x y) (icmp ty (IntCC.SignedGreaterThan) x y))
+(rule (sge ty x y) (icmp ty (IntCC.SignedGreaterThanOrEqual) x y))
+
 ;;;;; optimization toplevel ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 ;; The main matcher rule invoked by the toplevel driver.
diff --git a/cranelift/entity/src/set.rs b/cranelift/entity/src/set.rs
index a5c8b7b29..60578d6e4 100644
--- a/cranelift/entity/src/set.rs
+++ b/cranelift/entity/src/set.rs
@@ -69,20 +69,14 @@ where
         }
     }
 
-    /// Returns the cardinality of the set.  More precisely, it returns the number of calls to
+    /// Returns the cardinality of the set. More precisely, it returns the number of calls to
     /// `insert` with different key values, that have happened since the the set was most recently
     /// `clear`ed or created with `new`.
     pub fn cardinality(&self) -> usize {
-        let mut n: usize = 0;
-        for idx in 0..self.len / BITS {
-            n += self.elems[idx].count_ones() as usize;
-        }
-        for bit_ix in (self.len / BITS) * BITS..self.len {
-            if (self.elems[bit_ix / BITS] & (1 << (bit_ix % BITS))) != 0 {
-                n += 1;
-            }
-        }
-        n
+        self.elems[..(self.len + (BITS - 1)) / BITS]
+            .iter()
+            .map(|x| x.count_ones() as usize)
+            .sum()
     }
 
     /// Remove all entries from this set.
@@ -254,4 +248,43 @@ mod tests {
 
         assert!(m.is_empty());
     }
+
+    #[test]
+    fn cardinality() {
+        let mut m = EntitySet::new();
+
+        m.insert(E(1));
+        assert!(m.cardinality() == 1);
+
+        m.insert(E(0));
+        assert!(m.cardinality() == 2);
+
+        m.insert(E(1));
+        assert!(m.cardinality() == 2);
+
+        m.insert(E(BITS as u32 - 1));
+        assert!(m.cardinality() == 3);
+
+        m.insert(E(BITS as u32));
+        assert!(m.cardinality() == 4);
+
+        m.insert(E(BITS as u32 - 1));
+        assert!(m.cardinality() == 4);
+
+        assert!(m.pop() == Some(E(BITS as u32)));
+        assert!(m.cardinality() == 3);
+        assert!(m.pop() == Some(E(BITS as u32 - 1)));
+        assert!(m.cardinality() == 2);
+
+        m.insert(E(100));
+        assert!(m.cardinality() == 3);
+
+        assert!(m.pop() == Some(E(100)));
+        assert!(m.cardinality() == 2);
+
+        m.insert(E(100));
+        m.insert(E(101));
+        m.insert(E(102));
+        assert!(m.cardinality() == 5);
+    }
 }
diff --git a/cranelift/fuzzgen/Cargo.toml b/cranelift/fuzzgen/Cargo.toml
index 140b39a12..014d0f076 100644
--- a/cranelift/fuzzgen/Cargo.toml
+++ b/cranelift/fuzzgen/Cargo.toml
@@ -16,4 +16,5 @@ cranelift-native = { workspace = true }
 
 anyhow = { workspace = true }
 arbitrary = "1.0.0"
+once_cell = { workspace = true }
 target-lexicon = { workspace = true, features = ["std"] }
diff --git a/cranelift/fuzzgen/src/cranelift_arbitrary.rs b/cranelift/fuzzgen/src/cranelift_arbitrary.rs
index ebafb55d8..b15622687 100644
--- a/cranelift/fuzzgen/src/cranelift_arbitrary.rs
+++ b/cranelift/fuzzgen/src/cranelift_arbitrary.rs
@@ -23,23 +23,26 @@ pub trait CraneliftArbitrary {
     fn datavalue(&mut self, ty: Type) -> Result<DataValue>;
 }
 
+/// Returns the set of types that are valid for value generation, dependent on architecture.
+pub fn types_for_architecture(architecture: Architecture) -> &'static [Type] {
+    // TODO: It would be nice if we could get these directly from cranelift
+    // TODO: RISCV does not support SIMD yet
+    let supports_simd = !matches!(architecture, Architecture::Riscv64(_));
+    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]
+    }
+}
+
 impl<'a> CraneliftArbitrary for &mut Unstructured<'a> {
     fn _type(&mut self, architecture: Architecture) -> Result<Type> {
-        // TODO: It would be nice if we could get these directly from cranelift
-        // 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][..]
-        };
-
-        Ok(*self.choose(choices)?)
+        Ok(*self.choose(types_for_architecture(architecture))?)
     }
 
     fn callconv(&mut self) -> Result<CallConv> {
diff --git a/cranelift/fuzzgen/src/function_generator.rs b/cranelift/fuzzgen/src/function_generator.rs
index eb0425688..52f89db23 100644
--- a/cranelift/fuzzgen/src/function_generator.rs
+++ b/cranelift/fuzzgen/src/function_generator.rs
@@ -4,12 +4,12 @@ use anyhow::Result;
 use arbitrary::{Arbitrary, Unstructured};
 use cranelift::codegen::data_value::DataValue;
 use cranelift::codegen::ir::immediates::Offset32;
-use cranelift::codegen::ir::instructions::InstructionFormat;
+use cranelift::codegen::ir::instructions::{InstructionFormat, ResolvedConstraint};
 use cranelift::codegen::ir::stackslot::StackSize;
 
 use cranelift::codegen::ir::{
     types::*, AtomicRmwOp, Block, ConstantData, ExternalName, FuncRef, Function, LibCall, Opcode,
-    Signature, StackSlot, Type, UserExternalName, UserFuncName, Value,
+    SigRef, Signature, StackSlot, Type, UserExternalName, UserFuncName, Value,
 };
 use cranelift::codegen::isa::CallConv;
 use cranelift::frontend::{FunctionBuilder, FunctionBuilderContext, Switch, Variable};
@@ -17,6 +17,7 @@ use cranelift::prelude::{
     EntityRef, ExtFuncData, FloatCC, InstBuilder, IntCC, JumpTableData, MemFlags, StackSlotData,
     StackSlotKind,
 };
+use once_cell::sync::Lazy;
 use std::collections::HashMap;
 use std::ops::RangeInclusive;
 use target_lexicon::{Architecture, Triple};
@@ -27,8 +28,8 @@ fn insert_opcode(
     fgen: &mut FunctionGenerator,
     builder: &mut FunctionBuilder,
     opcode: Opcode,
-    args: &'static [Type],
-    rets: &'static [Type],
+    args: &[Type],
+    rets: &[Type],
 ) -> Result<()> {
     let mut vals = Vec::with_capacity(args.len());
     for &arg in args.into_iter() {
@@ -71,18 +72,33 @@ fn insert_call(
     fgen: &mut FunctionGenerator,
     builder: &mut FunctionBuilder,
     opcode: Opcode,
-    _args: &'static [Type],
-    _rets: &'static [Type],
+    args: &[Type],
+    _rets: &[Type],
 ) -> Result<()> {
-    assert_eq!(opcode, Opcode::Call, "only call handled at the moment");
-    let (sig, func_ref) = fgen.u.choose(&fgen.resources.func_refs)?.clone();
+    assert!(matches!(opcode, Opcode::Call | Opcode::CallIndirect));
+    let (sig, sig_ref, func_ref) = fgen.u.choose(&fgen.resources.func_refs)?.clone();
 
     let actuals = fgen.generate_values_for_signature(
         builder,
         sig.params.iter().map(|abi_param| abi_param.value_type),
     )?;
 
-    builder.ins().call(func_ref, &actuals);
+    let call = if opcode == Opcode::Call {
+        builder.ins().call(func_ref, &actuals)
+    } else {
+        let addr_ty = args[0];
+        let addr = builder.ins().func_addr(addr_ty, func_ref);
+        builder.ins().call_indirect(sig_ref, addr, &actuals)
+    };
+
+    // Assign the return values to random variables
+    let ret_values = builder.inst_results(call).to_vec();
+    let ret_types = sig.returns.iter().map(|p| p.value_type);
+    for (ty, val) in ret_types.zip(ret_values) {
+        let var = fgen.get_variable_of_type(ty)?;
+        builder.def_var(var, val);
+    }
+
     Ok(())
 }
 
@@ -90,8 +106,8 @@ fn insert_stack_load(
     fgen: &mut FunctionGenerator,
     builder: &mut FunctionBuilder,
     _opcode: Opcode,
-    _args: &'static [Type],
-    rets: &'static [Type],
+    _args: &[Type],
+    rets: &[Type],
 ) -> Result<()> {
     let typevar = rets[0];
     let type_size = typevar.bytes();
@@ -109,8 +125,8 @@ fn insert_stack_store(
     fgen: &mut FunctionGenerator,
     builder: &mut FunctionBuilder,
     _opcode: Opcode,
-    args: &'static [Type],
-    _rets: &'static [Type],
+    args: &[Type],
+    _rets: &[Type],
 ) -> Result<()> {
     let typevar = args[0];
     let type_size = typevar.bytes();
@@ -128,8 +144,8 @@ fn insert_cmp(
     fgen: &mut FunctionGenerator,
     builder: &mut FunctionBuilder,
     opcode: Opcode,
-    args: &'static [Type],
-    rets: &'static [Type],
+    args: &[Type],
+    rets: &[Type],
 ) -> Result<()> {
     let lhs = fgen.get_variable_of_type(args[0])?;
     let lhs = builder.use_var(lhs);
@@ -179,8 +195,8 @@ fn insert_const(
     fgen: &mut FunctionGenerator,
     builder: &mut FunctionBuilder,
     _opcode: Opcode,
-    _args: &'static [Type],
-    rets: &'static [Type],
+    _args: &[Type],
+    rets: &[Type],
 ) -> Result<()> {
     let typevar = rets[0];
     let var = fgen.get_variable_of_type(typevar)?;
@@ -192,8 +208,8 @@ fn insert_const(
 fn insert_bitcast(
     fgen: &mut FunctionGenerator,
     builder: &mut FunctionBuilder,
-    args: &'static [Type],
-    rets: &'static [Type],
+    args: &[Type],
+    rets: &[Type],
 ) -> Result<()> {
     let from_var = fgen.get_variable_of_type(args[0])?;
     let from_val = builder.use_var(from_var);
@@ -212,8 +228,8 @@ fn insert_load_store(
     fgen: &mut FunctionGenerator,
     builder: &mut FunctionBuilder,
     opcode: Opcode,
-    args: &'static [Type],
-    rets: &'static [Type],
+    args: &[Type],
+    rets: &[Type],
 ) -> Result<()> {
     if opcode == Opcode::Bitcast {
         return insert_bitcast(fgen, builder, args, rets);
@@ -270,8 +286,8 @@ fn insert_atomic_rmw(
     fgen: &mut FunctionGenerator,
     builder: &mut FunctionBuilder,
     _: Opcode,
-    _: &'static [Type],
-    rets: &'static [Type],
+    _: &[Type],
+    rets: &[Type],
 ) -> Result<()> {
     let ctrl_type = *rets.first().unwrap();
     let type_size = ctrl_type.bytes();
@@ -300,8 +316,8 @@ fn insert_atomic_cas(
     fgen: &mut FunctionGenerator,
     builder: &mut FunctionBuilder,
     _: Opcode,
-    _: &'static [Type],
-    rets: &'static [Type],
+    _: &[Type],
+    rets: &[Type],
 ) -> Result<()> {
     let ctrl_type = *rets.first().unwrap();
     let type_size = ctrl_type.bytes();
@@ -330,8 +346,8 @@ fn insert_shuffle(
     fgen: &mut FunctionGenerator,
     builder: &mut FunctionBuilder,
     opcode: Opcode,
-    _: &'static [Type],
-    rets: &'static [Type],
+    _: &[Type],
+    rets: &[Type],
 ) -> Result<()> {
     let ctrl_type = *rets.first().unwrap();
 
@@ -363,8 +379,8 @@ fn insert_ins_ext_lane(
     fgen: &mut FunctionGenerator,
     builder: &mut FunctionBuilder,
     opcode: Opcode,
-    args: &'static [Type],
-    rets: &'static [Type],
+    args: &[Type],
+    rets: &[Type],
 ) -> Result<()> {
     let vector_type = *args.first().unwrap();
     let ret_type = *rets.first().unwrap();
@@ -392,28 +408,63 @@ type OpcodeInserter = fn(
     fgen: &mut FunctionGenerator,
     builder: &mut FunctionBuilder,
     Opcode,
-    &'static [Type],
-    &'static [Type],
+    &[Type],
+    &[Type],
 ) -> Result<()>;
 
+macro_rules! exceptions {
+    ($op:expr, $args:expr, $rets:expr, $(($($cases:pat),*)),* $(,)?) => {
+        match ($op, $args, $rets) {
+            $( ($($cases,)* ..) => return false, )*
+            _ => true,
+        }
+    }
+}
+
 /// Returns true if we believe this `OpcodeSignature` should compile correctly
 /// for the given target triple. We currently have a range of known issues
 /// with specific lowerings on specific backends, and we don't want to get
 /// fuzz bug reports for those. Over time our goal is to eliminate all of these
 /// exceptions.
 fn valid_for_target(triple: &Triple, op: Opcode, args: &[Type], rets: &[Type]) -> bool {
-    macro_rules! exceptions {
-        ( $(($($cases:pat),*)),* $(,)?) => {
-            match (op, args, rets) {
-                $( ($($cases,)* ..) => false, )*
-                _ => true,
+    // Rule out invalid combinations that we don't yet have a good way of rejecting with the
+    // instruction DSL type constraints.
+    match op {
+        Opcode::FcvtToUintSat | Opcode::FcvtToSintSat => {
+            assert_eq!(args.len(), 1);
+            assert_eq!(rets.len(), 1);
+
+            let arg = args[0];
+            let ret = args[0];
+
+            // Vector arguments must produce vector results, and scalar arguments must produce
+            // scalar results.
+            if arg.is_vector() != ret.is_vector() {
+                return false;
+            }
+
+            if arg.is_vector() && arg.is_vector() {
+                // Vector conversions must have the same number of lanes, and the lanes must be the
+                // same bit-width.
+                if arg.lane_count() != ret.lane_count() {
+                    return false;
+                }
+
+                if arg.lane_of().bits() != ret.lane_of().bits() {
+                    return false;
+                }
             }
         }
+
+        _ => {}
     }
 
     match triple.architecture {
         Architecture::X86_64 => {
             exceptions!(
+                op,
+                args,
+                rets,
                 (Opcode::IaddCout, &([I8, I8] | [I16, I16] | [I128, I128])),
                 (Opcode::Imul, &[I8X16, I8X16]),
                 // https://github.com/bytecodealliance/wasmtime/issues/5468
@@ -528,6 +579,9 @@ fn valid_for_target(triple: &Triple, op: Opcode, args: &[Type], rets: &[Type]) -
 
         Architecture::Aarch64(_) => {
             exceptions!(
+                op,
+                args,
+                rets,
                 (Opcode::IaddCout, &[I128, I128]),
                 // https://github.com/bytecodealliance/wasmtime/issues/4864
                 (Opcode::Udiv | Opcode::Sdiv, &[I128, I128]),
@@ -580,6 +634,9 @@ fn valid_for_target(triple: &Triple, op: Opcode, args: &[Type], rets: &[Type]) -
 
         Architecture::S390x => {
             exceptions!(
+                op,
+                args,
+                rets,
                 (Opcode::IaddCout),
                 (
                     Opcode::Udiv | Opcode::Sdiv | Opcode::Urem | Opcode::Srem,
@@ -620,6 +677,9 @@ fn valid_for_target(triple: &Triple, op: Opcode, args: &[Type], rets: &[Type]) -
             }
 
             exceptions!(
+                op,
+                args,
+                rets,
                 // TODO
                 (Opcode::IaddCout),
                 // TODO
@@ -662,935 +722,712 @@ fn valid_for_target(triple: &Triple, op: Opcode, args: &[Type], rets: &[Type]) -
     }
 }
 
-type OpcodeSignature = (
-    Opcode,
-    &'static [Type], // Args
-    &'static [Type], // Rets
-);
-
-// TODO: Derive this from the `cranelift-meta` generator.
-#[rustfmt::skip]
-pub const OPCODE_SIGNATURES: &[OpcodeSignature] = &[
-    (Opcode::Nop, &[], &[]),
-    // Iadd
-    (Opcode::Iadd, &[I8, I8], &[I8]),
-    (Opcode::Iadd, &[I16, I16], &[I16]),
-    (Opcode::Iadd, &[I32, I32], &[I32]),
-    (Opcode::Iadd, &[I64, I64], &[I64]),
-    (Opcode::Iadd, &[I128, I128], &[I128]),
-    (Opcode::Iadd, &[I8X16, I8X16], &[I8X16]),
-    (Opcode::Iadd, &[I16X8, I16X8], &[I16X8]),
-    (Opcode::Iadd, &[I32X4, I32X4], &[I32X4]),
-    (Opcode::Iadd, &[I64X2, I64X2], &[I64X2]),
-    // IaddCout
-    (Opcode::IaddCout, &[I8, I8], &[I8, I8]),
-    (Opcode::IaddCout, &[I16, I16], &[I16, I8]),
-    (Opcode::IaddCout, &[I32, I32], &[I32, I8]),
-    (Opcode::IaddCout, &[I64, I64], &[I64, I8]),
-    (Opcode::IaddCout, &[I128, I128], &[I128, I8]),
-    // UaddSat
-    (Opcode::UaddSat, &[I8X16, I8X16], &[I8X16]),
-    (Opcode::UaddSat, &[I16X8, I16X8], &[I16X8]),
-    (Opcode::UaddSat, &[I32X4, I32X4], &[I32X4]),
-    (Opcode::UaddSat, &[I64X2, I64X2], &[I64X2]),
-    // SaddSat
-    (Opcode::SaddSat, &[I8X16, I8X16], &[I8X16]),
-    (Opcode::SaddSat, &[I16X8, I16X8], &[I16X8]),
-    (Opcode::SaddSat, &[I32X4, I32X4], &[I32X4]),
-    (Opcode::SaddSat, &[I64X2, I64X2], &[I64X2]),
-    // Isub
-    (Opcode::Isub, &[I8, I8], &[I8]),
-    (Opcode::Isub, &[I16, I16], &[I16]),
-    (Opcode::Isub, &[I32, I32], &[I32]),
-    (Opcode::Isub, &[I64, I64], &[I64]),
-    (Opcode::Isub, &[I128, I128], &[I128]),
-    (Opcode::Isub, &[I8X16, I8X16], &[I8X16]),
-    (Opcode::Isub, &[I16X8, I16X8], &[I16X8]),
-    (Opcode::Isub, &[I32X4, I32X4], &[I32X4]),
-    (Opcode::Isub, &[I64X2, I64X2], &[I64X2]),
-    // UsubSat
-    (Opcode::UsubSat, &[I8X16, I8X16], &[I8X16]),
-    (Opcode::UsubSat, &[I16X8, I16X8], &[I16X8]),
-    (Opcode::UsubSat, &[I32X4, I32X4], &[I32X4]),
-    (Opcode::UsubSat, &[I64X2, I64X2], &[I64X2]),
-    // SsubSat
-    (Opcode::SsubSat, &[I8X16, I8X16], &[I8X16]),
-    (Opcode::SsubSat, &[I16X8, I16X8], &[I16X8]),
-    (Opcode::SsubSat, &[I32X4, I32X4], &[I32X4]),
-    (Opcode::SsubSat, &[I64X2, I64X2], &[I64X2]),
-    // Imul
-    (Opcode::Imul, &[I8, I8], &[I8]),
-    (Opcode::Imul, &[I16, I16], &[I16]),
-    (Opcode::Imul, &[I32, I32], &[I32]),
-    (Opcode::Imul, &[I64, I64], &[I64]),
-    (Opcode::Imul, &[I128, I128], &[I128]),
-    (Opcode::Imul, &[I8X16, I8X16], &[I8X16]),
-    (Opcode::Imul, &[I16X8, I16X8], &[I16X8]),
-    (Opcode::Imul, &[I32X4, I32X4], &[I32X4]),
-    (Opcode::Imul, &[I64X2, I64X2], &[I64X2]),
-    // Smulhi
-    (Opcode::Smulhi, &[I8, I8], &[I8]),
-    (Opcode::Smulhi, &[I16, I16], &[I16]),
-    (Opcode::Smulhi, &[I32, I32], &[I32]),
-    (Opcode::Smulhi, &[I64, I64], &[I64]),
-    (Opcode::Smulhi, &[I8X16, I8X16], &[I8X16]),
-    (Opcode::Smulhi, &[I16X8, I16X8], &[I16X8]),
-    (Opcode::Smulhi, &[I32X4, I32X4], &[I32X4]),
-    (Opcode::Smulhi, &[I64X2, I64X2], &[I64X2]),
-    // Umulhi
-    (Opcode::Umulhi, &[I8, I8], &[I8]),
-    (Opcode::Umulhi, &[I16, I16], &[I16]),
-    (Opcode::Umulhi, &[I32, I32], &[I32]),
-    (Opcode::Umulhi, &[I64, I64], &[I64]),
-    (Opcode::Umulhi, &[I8X16, I8X16], &[I8X16]),
-    (Opcode::Umulhi, &[I16X8, I16X8], &[I16X8]),
-    (Opcode::Umulhi, &[I32X4, I32X4], &[I32X4]),
-    (Opcode::Umulhi, &[I64X2, I64X2], &[I64X2]),
-    // Udiv
-    (Opcode::Udiv, &[I8, I8], &[I8]),
-    (Opcode::Udiv, &[I16, I16], &[I16]),
-    (Opcode::Udiv, &[I32, I32], &[I32]),
-    (Opcode::Udiv, &[I64, I64], &[I64]),
-    (Opcode::Udiv, &[I128, I128], &[I128]),
-    // Sdiv
-    (Opcode::Sdiv, &[I8, I8], &[I8]),
-    (Opcode::Sdiv, &[I16, I16], &[I16]),
-    (Opcode::Sdiv, &[I32, I32], &[I32]),
-    (Opcode::Sdiv, &[I64, I64], &[I64]),
-    (Opcode::Sdiv, &[I128, I128], &[I128]),
-    // Urem
-    (Opcode::Urem, &[I8, I8], &[I8]),
-    (Opcode::Urem, &[I16, I16], &[I16]),
-    (Opcode::Urem, &[I32, I32], &[I32]),
-    (Opcode::Urem, &[I64, I64], &[I64]),
-    (Opcode::Urem, &[I128, I128], &[I128]),
-    // Srem
-    (Opcode::Srem, &[I8, I8], &[I8]),
-    (Opcode::Srem, &[I16, I16], &[I16]),
-    (Opcode::Srem, &[I32, I32], &[I32]),
-    (Opcode::Srem, &[I64, I64], &[I64]),
-    (Opcode::Srem, &[I128, I128], &[I128]),
-    // Ineg
-    (Opcode::Ineg, &[I8], &[I8]),
-    (Opcode::Ineg, &[I16], &[I16]),
-    (Opcode::Ineg, &[I32], &[I32]),
-    (Opcode::Ineg, &[I64], &[I64]),
-    (Opcode::Ineg, &[I128], &[I128]),
-    // Iabs
-    (Opcode::Iabs, &[I8], &[I8]),
-    (Opcode::Iabs, &[I16], &[I16]),
-    (Opcode::Iabs, &[I32], &[I32]),
-    (Opcode::Iabs, &[I64], &[I64]),
-    (Opcode::Iabs, &[I128], &[I128]),
-    (Opcode::Iabs, &[I8X16], &[I8X16]),
-    (Opcode::Iabs, &[I16X8], &[I16X8]),
-    (Opcode::Iabs, &[I32X4], &[I32X4]),
-    (Opcode::Iabs, &[I64X2], &[I64X2]),
-    // Smin
-    (Opcode::Smin, &[I8, I8], &[I8]),
-    (Opcode::Smin, &[I16, I16], &[I16]),
-    (Opcode::Smin, &[I32, I32], &[I32]),
-    (Opcode::Smin, &[I64, I64], &[I64]),
-    (Opcode::Smin, &[I128, I128], &[I128]),
-    (Opcode::Smin, &[I8X16, I8X16], &[I8X16]),
-    (Opcode::Smin, &[I16X8, I16X8], &[I16X8]),
-    (Opcode::Smin, &[I32X4, I32X4], &[I32X4]),
-    (Opcode::Smin, &[I64X2, I64X2], &[I64X2]),
-    // Umin
-    (Opcode::Umin, &[I8, I8], &[I8]),
-    (Opcode::Umin, &[I16, I16], &[I16]),
-    (Opcode::Umin, &[I32, I32], &[I32]),
-    (Opcode::Umin, &[I64, I64], &[I64]),
-    (Opcode::Umin, &[I128, I128], &[I128]),
-    (Opcode::Umin, &[I8X16, I8X16], &[I8X16]),
-    (Opcode::Umin, &[I16X8, I16X8], &[I16X8]),
-    (Opcode::Umin, &[I32X4, I32X4], &[I32X4]),
-    (Opcode::Umin, &[I64X2, I64X2], &[I64X2]),
-    // Smax
-    (Opcode::Smax, &[I8, I8], &[I8]),
-    (Opcode::Smax, &[I16, I16], &[I16]),
-    (Opcode::Smax, &[I32, I32], &[I32]),
-    (Opcode::Smax, &[I64, I64], &[I64]),
-    (Opcode::Smax, &[I128, I128], &[I128]),
-    (Opcode::Smax, &[I8X16, I8X16], &[I8X16]),
-    (Opcode::Smax, &[I16X8, I16X8], &[I16X8]),
-    (Opcode::Smax, &[I32X4, I32X4], &[I32X4]),
-    (Opcode::Smax, &[I64X2, I64X2], &[I64X2]),
-    // Umax
-    (Opcode::Umax, &[I8, I8], &[I8]),
-    (Opcode::Umax, &[I16, I16], &[I16]),
-    (Opcode::Umax, &[I32, I32], &[I32]),
-    (Opcode::Umax, &[I64, I64], &[I64]),
-    (Opcode::Umax, &[I128, I128], &[I128]),
-    (Opcode::Umax, &[I8X16, I8X16], &[I8X16]),
-    (Opcode::Umax, &[I16X8, I16X8], &[I16X8]),
-    (Opcode::Umax, &[I32X4, I32X4], &[I32X4]),
-    (Opcode::Umax, &[I64X2, I64X2], &[I64X2]),
-    // Rotr
-    (Opcode::Rotr, &[I8, I8], &[I8]),
-    (Opcode::Rotr, &[I8, I16], &[I8]),
-    (Opcode::Rotr, &[I8, I32], &[I8]),
-    (Opcode::Rotr, &[I8, I64], &[I8]),
-    (Opcode::Rotr, &[I8, I128], &[I8]),
-    (Opcode::Rotr, &[I16, I8], &[I16]),
-    (Opcode::Rotr, &[I16, I16], &[I16]),
-    (Opcode::Rotr, &[I16, I32], &[I16]),
-    (Opcode::Rotr, &[I16, I64], &[I16]),
-    (Opcode::Rotr, &[I16, I128], &[I16]),
-    (Opcode::Rotr, &[I32, I8], &[I32]),
-    (Opcode::Rotr, &[I32, I16], &[I32]),
-    (Opcode::Rotr, &[I32, I32], &[I32]),
-    (Opcode::Rotr, &[I32, I64], &[I32]),
-    (Opcode::Rotr, &[I32, I128], &[I32]),
-    (Opcode::Rotr, &[I64, I8], &[I64]),
-    (Opcode::Rotr, &[I64, I16], &[I64]),
-    (Opcode::Rotr, &[I64, I32], &[I64]),
-    (Opcode::Rotr, &[I64, I64], &[I64]),
-    (Opcode::Rotr, &[I64, I128], &[I64]),
-    (Opcode::Rotr, &[I128, I8], &[I128]),
-    (Opcode::Rotr, &[I128, I16], &[I128]),
-    (Opcode::Rotr, &[I128, I32], &[I128]),
-    (Opcode::Rotr, &[I128, I64], &[I128]),
-    (Opcode::Rotr, &[I128, I128], &[I128]),
-    // Rotl
-    (Opcode::Rotl, &[I8, I8], &[I8]),
-    (Opcode::Rotl, &[I8, I16], &[I8]),
-    (Opcode::Rotl, &[I8, I32], &[I8]),
-    (Opcode::Rotl, &[I8, I64], &[I8]),
-    (Opcode::Rotl, &[I8, I128], &[I8]),
-    (Opcode::Rotl, &[I16, I8], &[I16]),
-    (Opcode::Rotl, &[I16, I16], &[I16]),
-    (Opcode::Rotl, &[I16, I32], &[I16]),
-    (Opcode::Rotl, &[I16, I64], &[I16]),
-    (Opcode::Rotl, &[I16, I128], &[I16]),
-    (Opcode::Rotl, &[I32, I8], &[I32]),
-    (Opcode::Rotl, &[I32, I16], &[I32]),
-    (Opcode::Rotl, &[I32, I32], &[I32]),
-    (Opcode::Rotl, &[I32, I64], &[I32]),
-    (Opcode::Rotl, &[I32, I128], &[I32]),
-    (Opcode::Rotl, &[I64, I8], &[I64]),
-    (Opcode::Rotl, &[I64, I16], &[I64]),
-    (Opcode::Rotl, &[I64, I32], &[I64]),
-    (Opcode::Rotl, &[I64, I64], &[I64]),
-    (Opcode::Rotl, &[I64, I128], &[I64]),
-    (Opcode::Rotl, &[I128, I8], &[I128]),
-    (Opcode::Rotl, &[I128, I16], &[I128]),
-    (Opcode::Rotl, &[I128, I32], &[I128]),
-    (Opcode::Rotl, &[I128, I64], &[I128]),
-    (Opcode::Rotl, &[I128, I128], &[I128]),
-    // Ishl
-    (Opcode::Ishl, &[I8, I8], &[I8]),
-    (Opcode::Ishl, &[I8, I16], &[I8]),
-    (Opcode::Ishl, &[I8, I32], &[I8]),
-    (Opcode::Ishl, &[I8, I64], &[I8]),
-    (Opcode::Ishl, &[I8, I128], &[I8]),
-    (Opcode::Ishl, &[I16, I8], &[I16]),
-    (Opcode::Ishl, &[I16, I16], &[I16]),
-    (Opcode::Ishl, &[I16, I32], &[I16]),
-    (Opcode::Ishl, &[I16, I64], &[I16]),
-    (Opcode::Ishl, &[I16, I128], &[I16]),
-    (Opcode::Ishl, &[I32, I8], &[I32]),
-    (Opcode::Ishl, &[I32, I16], &[I32]),
-    (Opcode::Ishl, &[I32, I32], &[I32]),
-    (Opcode::Ishl, &[I32, I64], &[I32]),
-    (Opcode::Ishl, &[I32, I128], &[I32]),
-    (Opcode::Ishl, &[I64, I8], &[I64]),
-    (Opcode::Ishl, &[I64, I16], &[I64]),
-    (Opcode::Ishl, &[I64, I32], &[I64]),
-    (Opcode::Ishl, &[I64, I64], &[I64]),
-    (Opcode::Ishl, &[I64, I128], &[I64]),
-    (Opcode::Ishl, &[I128, I8], &[I128]),
-    (Opcode::Ishl, &[I128, I16], &[I128]),
-    (Opcode::Ishl, &[I128, I32], &[I128]),
-    (Opcode::Ishl, &[I128, I64], &[I128]),
-    (Opcode::Ishl, &[I128, I128], &[I128]),
-    // Sshr
-    (Opcode::Sshr, &[I8, I8], &[I8]),
-    (Opcode::Sshr, &[I8, I16], &[I8]),
-    (Opcode::Sshr, &[I8, I32], &[I8]),
-    (Opcode::Sshr, &[I8, I64], &[I8]),
-    (Opcode::Sshr, &[I8, I128], &[I8]),
-    (Opcode::Sshr, &[I16, I8], &[I16]),
-    (Opcode::Sshr, &[I16, I16], &[I16]),
-    (Opcode::Sshr, &[I16, I32], &[I16]),
-    (Opcode::Sshr, &[I16, I64], &[I16]),
-    (Opcode::Sshr, &[I16, I128], &[I16]),
-    (Opcode::Sshr, &[I32, I8], &[I32]),
-    (Opcode::Sshr, &[I32, I16], &[I32]),
-    (Opcode::Sshr, &[I32, I32], &[I32]),
-    (Opcode::Sshr, &[I32, I64], &[I32]),
-    (Opcode::Sshr, &[I32, I128], &[I32]),
-    (Opcode::Sshr, &[I64, I8], &[I64]),
-    (Opcode::Sshr, &[I64, I16], &[I64]),
-    (Opcode::Sshr, &[I64, I32], &[I64]),
-    (Opcode::Sshr, &[I64, I64], &[I64]),
-    (Opcode::Sshr, &[I64, I128], &[I64]),
-    (Opcode::Sshr, &[I128, I8], &[I128]),
-    (Opcode::Sshr, &[I128, I16], &[I128]),
-    (Opcode::Sshr, &[I128, I32], &[I128]),
-    (Opcode::Sshr, &[I128, I64], &[I128]),
-    (Opcode::Sshr, &[I128, I128], &[I128]),
-    // Ushr
-    (Opcode::Ushr, &[I8, I8], &[I8]),
-    (Opcode::Ushr, &[I8, I16], &[I8]),
-    (Opcode::Ushr, &[I8, I32], &[I8]),
-    (Opcode::Ushr, &[I8, I64], &[I8]),
-    (Opcode::Ushr, &[I8, I128], &[I8]),
-    (Opcode::Ushr, &[I16, I8], &[I16]),
-    (Opcode::Ushr, &[I16, I16], &[I16]),
-    (Opcode::Ushr, &[I16, I32], &[I16]),
-    (Opcode::Ushr, &[I16, I64], &[I16]),
-    (Opcode::Ushr, &[I16, I128], &[I16]),
-    (Opcode::Ushr, &[I32, I8], &[I32]),
-    (Opcode::Ushr, &[I32, I16], &[I32]),
-    (Opcode::Ushr, &[I32, I32], &[I32]),
-    (Opcode::Ushr, &[I32, I64], &[I32]),
-    (Opcode::Ushr, &[I32, I128], &[I32]),
-    (Opcode::Ushr, &[I64, I8], &[I64]),
-    (Opcode::Ushr, &[I64, I16], &[I64]),
-    (Opcode::Ushr, &[I64, I32], &[I64]),
-    (Opcode::Ushr, &[I64, I64], &[I64]),
-    (Opcode::Ushr, &[I64, I128], &[I64]),
-    (Opcode::Ushr, &[I128, I8], &[I128]),
-    (Opcode::Ushr, &[I128, I16], &[I128]),
-    (Opcode::Ushr, &[I128, I32], &[I128]),
-    (Opcode::Ushr, &[I128, I64], &[I128]),
-    (Opcode::Ushr, &[I128, I128], &[I128]),
-    // Uextend
-    (Opcode::Uextend, &[I8], &[I16]),
-    (Opcode::Uextend, &[I8], &[I32]),
-    (Opcode::Uextend, &[I8], &[I64]),
-    (Opcode::Uextend, &[I8], &[I128]),
-    (Opcode::Uextend, &[I16], &[I32]),
-    (Opcode::Uextend, &[I16], &[I64]),
-    (Opcode::Uextend, &[I16], &[I128]),
-    (Opcode::Uextend, &[I32], &[I64]),
-    (Opcode::Uextend, &[I32], &[I128]),
-    (Opcode::Uextend, &[I64], &[I128]),
-    // Sextend
-    (Opcode::Sextend, &[I8], &[I16]),
-    (Opcode::Sextend, &[I8], &[I32]),
-    (Opcode::Sextend, &[I8], &[I64]),
-    (Opcode::Sextend, &[I8], &[I128]),
-    (Opcode::Sextend, &[I16], &[I32]),
-    (Opcode::Sextend, &[I16], &[I64]),
-    (Opcode::Sextend, &[I16], &[I128]),
-    (Opcode::Sextend, &[I32], &[I64]),
-    (Opcode::Sextend, &[I32], &[I128]),
-    (Opcode::Sextend, &[I64], &[I128]),
-    // Ireduce
-    (Opcode::Ireduce, &[I16], &[I8]),
-    (Opcode::Ireduce, &[I32], &[I8]),
-    (Opcode::Ireduce, &[I32], &[I16]),
-    (Opcode::Ireduce, &[I64], &[I8]),
-    (Opcode::Ireduce, &[I64], &[I16]),
-    (Opcode::Ireduce, &[I64], &[I32]),
-    (Opcode::Ireduce, &[I128], &[I8]),
-    (Opcode::Ireduce, &[I128], &[I16]),
-    (Opcode::Ireduce, &[I128], &[I32]),
-    (Opcode::Ireduce, &[I128], &[I64]),
-    // Isplit
-    (Opcode::Isplit, &[I128], &[I64, I64]),
-    // Iconcat
-    (Opcode::Iconcat, &[I64, I64], &[I128]),
-    // Band
-    (Opcode::Band, &[I8, I8], &[I8]),
-    (Opcode::Band, &[I16, I16], &[I16]),
-    (Opcode::Band, &[I32, I32], &[I32]),
-    (Opcode::Band, &[I64, I64], &[I64]),
-    (Opcode::Band, &[I128, I128], &[I128]),
-    (Opcode::Band, &[F32, F32], &[F32]),
-    (Opcode::Band, &[F64, F64], &[F64]),
-    (Opcode::Band, &[I8X16, I8X16], &[I8X16]),
-    (Opcode::Band, &[I16X8, I16X8], &[I16X8]),
-    (Opcode::Band, &[I32X4, I32X4], &[I32X4]),
-    (Opcode::Band, &[I64X2, I64X2], &[I64X2]),
-    (Opcode::Band, &[F32X4, F32X4], &[F32X4]),
-    (Opcode::Band, &[F64X2, F64X2], &[F64X2]),
-    // Bor
-    (Opcode::Bor, &[I8, I8], &[I8]),
-    (Opcode::Bor, &[I16, I16], &[I16]),
-    (Opcode::Bor, &[I32, I32], &[I32]),
-    (Opcode::Bor, &[I64, I64], &[I64]),
-    (Opcode::Bor, &[I128, I128], &[I128]),
-    (Opcode::Bor, &[F32, F32], &[F32]),
-    (Opcode::Bor, &[F64, F64], &[F64]),
-    (Opcode::Bor, &[I8X16, I8X16], &[I8X16]),
-    (Opcode::Bor, &[I16X8, I16X8], &[I16X8]),
-    (Opcode::Bor, &[I32X4, I32X4], &[I32X4]),
-    (Opcode::Bor, &[I64X2, I64X2], &[I64X2]),
-    (Opcode::Bor, &[F32X4, F32X4], &[F32X4]),
-    (Opcode::Bor, &[F64X2, F64X2], &[F64X2]),
-    // Bxor
-    (Opcode::Bxor, &[I8, I8], &[I8]),
-    (Opcode::Bxor, &[I16, I16], &[I16]),
-    (Opcode::Bxor, &[I32, I32], &[I32]),
-    (Opcode::Bxor, &[I64, I64], &[I64]),
-    (Opcode::Bxor, &[I128, I128], &[I128]),
-    (Opcode::Bxor, &[F32, F32], &[F32]),
-    (Opcode::Bxor, &[F64, F64], &[F64]),
-    (Opcode::Bxor, &[I8X16, I8X16], &[I8X16]),
-    (Opcode::Bxor, &[I16X8, I16X8], &[I16X8]),
-    (Opcode::Bxor, &[I32X4, I32X4], &[I32X4]),
-    (Opcode::Bxor, &[I64X2, I64X2], &[I64X2]),
-    (Opcode::Bxor, &[F32X4, F32X4], &[F32X4]),
-    (Opcode::Bxor, &[F64X2, F64X2], &[F64X2]),
-    // Bnot
-    (Opcode::Bnot, &[I8], &[I8]),
-    (Opcode::Bnot, &[I16], &[I16]),
-    (Opcode::Bnot, &[I32], &[I32]),
-    (Opcode::Bnot, &[I64], &[I64]),
-    (Opcode::Bnot, &[I128], &[I128]),
-    (Opcode::Bnot, &[F32], &[F32]),
-    (Opcode::Bnot, &[F64], &[F64]),
-    (Opcode::Bnot, &[I8X16], &[I8X16]),
-    (Opcode::Bnot, &[I16X8], &[I16X8]),
-    (Opcode::Bnot, &[I32X4], &[I32X4]),
-    (Opcode::Bnot, &[I64X2], &[I64X2]),
-    (Opcode::Bnot, &[F32X4], &[F32X4]),
-    (Opcode::Bnot, &[F64X2], &[F64X2]),
-    // BandNot
-    (Opcode::BandNot, &[I8, I8], &[I8]),
-    (Opcode::BandNot, &[I16, I16], &[I16]),
-    (Opcode::BandNot, &[I32, I32], &[I32]),
-    (Opcode::BandNot, &[I64, I64], &[I64]),
-    (Opcode::BandNot, &[I128, I128], &[I128]),
-    (Opcode::BandNot, &[F32, F32], &[F32]),
-    (Opcode::BandNot, &[F64, F64], &[F64]),
-    (Opcode::BandNot, &[I8X16, I8X16], &[I8X16]),
-    (Opcode::BandNot, &[I16X8, I16X8], &[I16X8]),
-    (Opcode::BandNot, &[I32X4, I32X4], &[I32X4]),
-    (Opcode::BandNot, &[I64X2, I64X2], &[I64X2]),
-    (Opcode::BandNot, &[F32X4, F32X4], &[F32X4]),
-    (Opcode::BandNot, &[F64X2, F64X2], &[F64X2]),
-    // BorNot
-    (Opcode::BorNot, &[I8, I8], &[I8]),
-    (Opcode::BorNot, &[I16, I16], &[I16]),
-    (Opcode::BorNot, &[I32, I32], &[I32]),
-    (Opcode::BorNot, &[I64, I64], &[I64]),
-    (Opcode::BorNot, &[I128, I128], &[I128]),
-    (Opcode::BorNot, &[F32, F32], &[F32]),
-    (Opcode::BorNot, &[F64, F64], &[F64]),
-    (Opcode::BorNot, &[I8X16, I8X16], &[I8X16]),
-    (Opcode::BorNot, &[I16X8, I16X8], &[I16X8]),
-    (Opcode::BorNot, &[I32X4, I32X4], &[I32X4]),
-    (Opcode::BorNot, &[I64X2, I64X2], &[I64X2]),
-    (Opcode::BorNot, &[F32X4, F32X4], &[F32X4]),
-    (Opcode::BorNot, &[F64X2, F64X2], &[F64X2]),
-    // BxorNot
-    (Opcode::BxorNot, &[I8, I8], &[I8]),
-    (Opcode::BxorNot, &[I16, I16], &[I16]),
-    (Opcode::BxorNot, &[I32, I32], &[I32]),
-    (Opcode::BxorNot, &[I64, I64], &[I64]),
-    (Opcode::BxorNot, &[I128, I128], &[I128]),
-    (Opcode::BxorNot, &[F32, F32], &[F32]),
-    (Opcode::BxorNot, &[F64, F64], &[F64]),
-    (Opcode::BxorNot, &[I8X16, I8X16], &[I8X16]),
-    (Opcode::BxorNot, &[I16X8, I16X8], &[I16X8]),
-    (Opcode::BxorNot, &[I32X4, I32X4], &[I32X4]),
-    (Opcode::BxorNot, &[I64X2, I64X2], &[I64X2]),
-    (Opcode::BxorNot, &[F32X4, F32X4], &[F32X4]),
-    (Opcode::BxorNot, &[F64X2, F64X2], &[F64X2]),
-    // Bitrev
-    (Opcode::Bitrev, &[I8], &[I8]),
-    (Opcode::Bitrev, &[I16], &[I16]),
-    (Opcode::Bitrev, &[I32], &[I32]),
-    (Opcode::Bitrev, &[I64], &[I64]),
-    (Opcode::Bitrev, &[I128], &[I128]),
-    // Clz
-    (Opcode::Clz, &[I8], &[I8]),
-    (Opcode::Clz, &[I16], &[I16]),
-    (Opcode::Clz, &[I32], &[I32]),
-    (Opcode::Clz, &[I64], &[I64]),
-    (Opcode::Clz, &[I128], &[I128]),
-    // Cls
-    (Opcode::Cls, &[I8], &[I8]),
-    (Opcode::Cls, &[I16], &[I16]),
-    (Opcode::Cls, &[I32], &[I32]),
-    (Opcode::Cls, &[I64], &[I64]),
-    (Opcode::Cls, &[I128], &[I128]),
-    // Ctz
-    (Opcode::Ctz, &[I8], &[I8]),
-    (Opcode::Ctz, &[I16], &[I16]),
-    (Opcode::Ctz, &[I32], &[I32]),
-    (Opcode::Ctz, &[I64], &[I64]),
-    (Opcode::Ctz, &[I128], &[I128]),
-    // Popcnt
-    (Opcode::Popcnt, &[I8], &[I8]),
-    (Opcode::Popcnt, &[I16], &[I16]),
-    (Opcode::Popcnt, &[I32], &[I32]),
-    (Opcode::Popcnt, &[I64], &[I64]),
-    (Opcode::Popcnt, &[I128], &[I128]),
-    (Opcode::Popcnt, &[I8X16], &[I8X16]),
-    (Opcode::Popcnt, &[I16X8], &[I16X8]),
-    (Opcode::Popcnt, &[I32X4], &[I32X4]),
-    (Opcode::Popcnt, &[I64X2], &[I64X2]),
-    // Bmask
-    (Opcode::Bmask, &[I8], &[I8]),
-    (Opcode::Bmask, &[I16], &[I8]),
-    (Opcode::Bmask, &[I32], &[I8]),
-    (Opcode::Bmask, &[I64], &[I8]),
-    (Opcode::Bmask, &[I128], &[I8]),
-    (Opcode::Bmask, &[I8], &[I16]),
-    (Opcode::Bmask, &[I16], &[I16]),
-    (Opcode::Bmask, &[I32], &[I16]),
-    (Opcode::Bmask, &[I64], &[I16]),
-    (Opcode::Bmask, &[I128], &[I16]),
-    (Opcode::Bmask, &[I8], &[I32]),
-    (Opcode::Bmask, &[I16], &[I32]),
-    (Opcode::Bmask, &[I32], &[I32]),
-    (Opcode::Bmask, &[I64], &[I32]),
-    (Opcode::Bmask, &[I128], &[I32]),
-    (Opcode::Bmask, &[I8], &[I64]),
-    (Opcode::Bmask, &[I16], &[I64]),
-    (Opcode::Bmask, &[I32], &[I64]),
-    (Opcode::Bmask, &[I64], &[I64]),
-    (Opcode::Bmask, &[I128], &[I64]),
-    (Opcode::Bmask, &[I8], &[I128]),
-    (Opcode::Bmask, &[I16], &[I128]),
-    (Opcode::Bmask, &[I32], &[I128]),
-    (Opcode::Bmask, &[I64], &[I128]),
-    (Opcode::Bmask, &[I128], &[I128]),
-    // Bswap
-    (Opcode::Bswap, &[I16], &[I16]),
-    (Opcode::Bswap, &[I32], &[I32]),
-    (Opcode::Bswap, &[I64], &[I64]),
-    (Opcode::Bswap, &[I128], &[I128]),
-    // Bitselect
-    (Opcode::Bitselect, &[I8, I8, I8], &[I8]),
-    (Opcode::Bitselect, &[I16, I16, I16], &[I16]),
-    (Opcode::Bitselect, &[I32, I32, I32], &[I32]),
-    (Opcode::Bitselect, &[I64, I64, I64], &[I64]),
-    (Opcode::Bitselect, &[I128, I128, I128], &[I128]),
-    (Opcode::Bitselect, &[I8X16, I8X16, I8X16], &[I8X16]),
-    (Opcode::Bitselect, &[I16X8, I16X8, I16X8], &[I16X8]),
-    (Opcode::Bitselect, &[I32X4, I32X4, I32X4], &[I32X4]),
-    (Opcode::Bitselect, &[I64X2, I64X2, I64X2], &[I64X2]),
-    // Select
-    (Opcode::Select, &[I8, I8, I8], &[I8]),
-    (Opcode::Select, &[I8, I16, I16], &[I16]),
-    (Opcode::Select, &[I8, I32, I32], &[I32]),
-    (Opcode::Select, &[I8, I64, I64], &[I64]),
-    (Opcode::Select, &[I8, I128, I128], &[I128]),
-    (Opcode::Select, &[I16, I8, I8], &[I8]),
-    (Opcode::Select, &[I16, I16, I16], &[I16]),
-    (Opcode::Select, &[I16, I32, I32], &[I32]),
-    (Opcode::Select, &[I16, I64, I64], &[I64]),
-    (Opcode::Select, &[I16, I128, I128], &[I128]),
-    (Opcode::Select, &[I32, I8, I8], &[I8]),
-    (Opcode::Select, &[I32, I16, I16], &[I16]),
-    (Opcode::Select, &[I32, I32, I32], &[I32]),
-    (Opcode::Select, &[I32, I64, I64], &[I64]),
-    (Opcode::Select, &[I32, I128, I128], &[I128]),
-    (Opcode::Select, &[I64, I8, I8], &[I8]),
-    (Opcode::Select, &[I64, I16, I16], &[I16]),
-    (Opcode::Select, &[I64, I32, I32], &[I32]),
-    (Opcode::Select, &[I64, I64, I64], &[I64]),
-    (Opcode::Select, &[I64, I128, I128], &[I128]),
-    (Opcode::Select, &[I128, I8, I8], &[I8]),
-    (Opcode::Select, &[I128, I16, I16], &[I16]),
-    (Opcode::Select, &[I128, I32, I32], &[I32]),
-    (Opcode::Select, &[I128, I64, I64], &[I64]),
-    (Opcode::Select, &[I128, I128, I128], &[I128]),
-    // SelectSpectreGuard
-    (Opcode::SelectSpectreGuard, &[I8, I8, I8], &[I8]),
-    (Opcode::SelectSpectreGuard, &[I8, I16, I16], &[I16]),
-    (Opcode::SelectSpectreGuard, &[I8, I32, I32], &[I32]),
-    (Opcode::SelectSpectreGuard, &[I8, I64, I64], &[I64]),
-    (Opcode::SelectSpectreGuard, &[I8, I128, I128], &[I128]),
-    (Opcode::SelectSpectreGuard, &[I16, I8, I8], &[I8]),
-    (Opcode::SelectSpectreGuard, &[I16, I16, I16], &[I16]),
-    (Opcode::SelectSpectreGuard, &[I16, I32, I32], &[I32]),
-    (Opcode::SelectSpectreGuard, &[I16, I64, I64], &[I64]),
-    (Opcode::SelectSpectreGuard, &[I16, I128, I128], &[I128]),
-    (Opcode::SelectSpectreGuard, &[I32, I8, I8], &[I8]),
-    (Opcode::SelectSpectreGuard, &[I32, I16, I16], &[I16]),
-    (Opcode::SelectSpectreGuard, &[I32, I32, I32], &[I32]),
-    (Opcode::SelectSpectreGuard, &[I32, I64, I64], &[I64]),
-    (Opcode::SelectSpectreGuard, &[I32, I128, I128], &[I128]),
-    (Opcode::SelectSpectreGuard, &[I64, I8, I8], &[I8]),
-    (Opcode::SelectSpectreGuard, &[I64, I16, I16], &[I16]),
-    (Opcode::SelectSpectreGuard, &[I64, I32, I32], &[I32]),
-    (Opcode::SelectSpectreGuard, &[I64, I64, I64], &[I64]),
-    (Opcode::SelectSpectreGuard, &[I64, I128, I128], &[I128]),
-    (Opcode::SelectSpectreGuard, &[I128, I8, I8], &[I8]),
-    (Opcode::SelectSpectreGuard, &[I128, I16, I16], &[I16]),
-    (Opcode::SelectSpectreGuard, &[I128, I32, I32], &[I32]),
-    (Opcode::SelectSpectreGuard, &[I128, I64, I64], &[I64]),
-    (Opcode::SelectSpectreGuard, &[I128, I128, I128], &[I128]),
-    // Fadd
-    (Opcode::Fadd, &[F32, F32], &[F32]),
-    (Opcode::Fadd, &[F64, F64], &[F64]),
-    (Opcode::Fadd, &[F32X4, F32X4], &[F32X4]),
-    (Opcode::Fadd, &[F64X2, F64X2], &[F64X2]),
-    // Fmul
-    (Opcode::Fmul, &[F32, F32], &[F32]),
-    (Opcode::Fmul, &[F64, F64], &[F64]),
-    (Opcode::Fmul, &[F32X4, F32X4], &[F32X4]),
-    (Opcode::Fmul, &[F64X2, F64X2], &[F64X2]),
-    // Fsub
-    (Opcode::Fsub, &[F32, F32], &[F32]),
-    (Opcode::Fsub, &[F64, F64], &[F64]),
-    (Opcode::Fsub, &[F32X4, F32X4], &[F32X4]),
-    (Opcode::Fsub, &[F64X2, F64X2], &[F64X2]),
-    // Fdiv
-    (Opcode::Fdiv, &[F32, F32], &[F32]),
-    (Opcode::Fdiv, &[F64, F64], &[F64]),
-    (Opcode::Fdiv, &[F32X4, F32X4], &[F32X4]),
-    (Opcode::Fdiv, &[F64X2, F64X2], &[F64X2]),
-    // Fmin
-    (Opcode::Fmin, &[F32, F32], &[F32]),
-    (Opcode::Fmin, &[F64, F64], &[F64]),
-    // Fmax
-    (Opcode::Fmax, &[F32, F32], &[F32]),
-    (Opcode::Fmax, &[F64, F64], &[F64]),
-    // FminPseudo
-    (Opcode::FminPseudo, &[F32, F32], &[F32]),
-    (Opcode::FminPseudo, &[F64, F64], &[F64]),
-    // FmaxPseudo
-    (Opcode::FmaxPseudo, &[F32, F32], &[F32]),
-    (Opcode::FmaxPseudo, &[F64, F64], &[F64]),
-    // Fcopysign
-    (Opcode::Fcopysign, &[F32, F32], &[F32]),
-    (Opcode::Fcopysign, &[F64, F64], &[F64]),
-    (Opcode::Fcopysign, &[F32X4, F32X4], &[F32X4]),
-    (Opcode::Fcopysign, &[F64X2, F64X2], &[F64X2]),
-    // Fma
-    (Opcode::Fma, &[F32, F32, F32], &[F32]),
-    (Opcode::Fma, &[F64, F64, F64], &[F64]),
-    (Opcode::Fma, &[F32X4, F32X4, F32X4], &[F32X4]),
-    (Opcode::Fma, &[F64X2, F64X2, F64X2], &[F64X2]),
-    // Fabs
-    (Opcode::Fabs, &[F32], &[F32]),
-    (Opcode::Fabs, &[F64], &[F64]),
-    (Opcode::Fabs, &[F32X4], &[F32X4]),
-    (Opcode::Fabs, &[F64X2], &[F64X2]),
-    // Fneg
-    (Opcode::Fneg, &[F32], &[F32]),
-    (Opcode::Fneg, &[F64], &[F64]),
-    (Opcode::Fneg, &[F32X4], &[F32X4]),
-    (Opcode::Fneg, &[F64X2], &[F64X2]),
-    // Sqrt
-    (Opcode::Sqrt, &[F32], &[F32]),
-    (Opcode::Sqrt, &[F64], &[F64]),
-    (Opcode::Sqrt, &[F32X4], &[F32X4]),
-    (Opcode::Sqrt, &[F64X2], &[F64X2]),
-    // Ceil
-    (Opcode::Ceil, &[F32], &[F32]),
-    (Opcode::Ceil, &[F64], &[F64]),
-    (Opcode::Ceil, &[F32X4], &[F32X4]),
-    (Opcode::Ceil, &[F64X2], &[F64X2]),
-    // Floor
-    (Opcode::Floor, &[F32], &[F32]),
-    (Opcode::Floor, &[F64], &[F64]),
-    (Opcode::Floor, &[F32X4], &[F32X4]),
-    (Opcode::Floor, &[F64X2], &[F64X2]),
-    // Trunc
-    (Opcode::Trunc, &[F32], &[F32]),
-    (Opcode::Trunc, &[F64], &[F64]),
-    (Opcode::Trunc, &[F32X4], &[F32X4]),
-    (Opcode::Trunc, &[F64X2], &[F64X2]),
-    // Nearest
-    (Opcode::Nearest, &[F32], &[F32]),
-    (Opcode::Nearest, &[F64], &[F64]),
-    (Opcode::Nearest, &[F32X4], &[F32X4]),
-    (Opcode::Nearest, &[F64X2], &[F64X2]),
-    // Fpromote
-    (Opcode::Fpromote, &[F32], &[F64]),
-    // Fdemote
-    (Opcode::Fdemote, &[F64], &[F32]),
-    // FcvtToUint
-    (Opcode::FcvtToUint, &[F32], &[I8]),
-    (Opcode::FcvtToUint, &[F32], &[I16]),
-    (Opcode::FcvtToUint, &[F32], &[I32]),
-    (Opcode::FcvtToUint, &[F32], &[I64]),
-    (Opcode::FcvtToUint, &[F32], &[I128]),
-    (Opcode::FcvtToUint, &[F64], &[I8]),
-    (Opcode::FcvtToUint, &[F64], &[I16]),
-    (Opcode::FcvtToUint, &[F64], &[I32]),
-    (Opcode::FcvtToUint, &[F64], &[I64]),
-    (Opcode::FcvtToUint, &[F64], &[I128]),
-    // FcvtToUintSat
-    (Opcode::FcvtToUintSat, &[F32], &[I8]),
-    (Opcode::FcvtToUintSat, &[F32], &[I16]),
-    (Opcode::FcvtToUintSat, &[F32], &[I32]),
-    (Opcode::FcvtToUintSat, &[F32], &[I64]),
-    (Opcode::FcvtToUintSat, &[F32], &[I128]),
-    (Opcode::FcvtToUintSat, &[F64], &[I8]),
-    (Opcode::FcvtToUintSat, &[F64], &[I16]),
-    (Opcode::FcvtToUintSat, &[F64], &[I32]),
-    (Opcode::FcvtToUintSat, &[F64], &[I64]),
-    (Opcode::FcvtToUintSat, &[F64], &[I128]),
-    (Opcode::FcvtToUintSat, &[F32X4], &[I32X4]),
-    (Opcode::FcvtToUintSat, &[F64X2], &[I64X2]),
-    // FcvtToSint
-    (Opcode::FcvtToSint, &[F32], &[I8]),
-    (Opcode::FcvtToSint, &[F32], &[I16]),
-    (Opcode::FcvtToSint, &[F32], &[I32]),
-    (Opcode::FcvtToSint, &[F32], &[I64]),
-    (Opcode::FcvtToSint, &[F32], &[I128]),
-    (Opcode::FcvtToSint, &[F64], &[I8]),
-    (Opcode::FcvtToSint, &[F64], &[I16]),
-    (Opcode::FcvtToSint, &[F64], &[I32]),
-    (Opcode::FcvtToSint, &[F64], &[I64]),
-    (Opcode::FcvtToSint, &[F64], &[I128]),
-    // FcvtToSintSat
-    (Opcode::FcvtToSintSat, &[F32], &[I8]),
-    (Opcode::FcvtToSintSat, &[F32], &[I16]),
-    (Opcode::FcvtToSintSat, &[F32], &[I32]),
-    (Opcode::FcvtToSintSat, &[F32], &[I64]),
-    (Opcode::FcvtToSintSat, &[F32], &[I128]),
-    (Opcode::FcvtToSintSat, &[F64], &[I8]),
-    (Opcode::FcvtToSintSat, &[F64], &[I16]),
-    (Opcode::FcvtToSintSat, &[F64], &[I32]),
-    (Opcode::FcvtToSintSat, &[F64], &[I64]),
-    (Opcode::FcvtToSintSat, &[F64], &[I128]),
-    (Opcode::FcvtToSintSat, &[F32X4], &[I32X4]),
-    (Opcode::FcvtToSintSat, &[F64X2], &[I64X2]),
-    // FcvtFromUint
-    (Opcode::FcvtFromUint, &[I8], &[F32]),
-    (Opcode::FcvtFromUint, &[I16], &[F32]),
-    (Opcode::FcvtFromUint, &[I32], &[F32]),
-    (Opcode::FcvtFromUint, &[I64], &[F32]),
-    (Opcode::FcvtFromUint, &[I128], &[F32]),
-    (Opcode::FcvtFromUint, &[I8], &[F64]),
-    (Opcode::FcvtFromUint, &[I16], &[F64]),
-    (Opcode::FcvtFromUint, &[I32], &[F64]),
-    (Opcode::FcvtFromUint, &[I64], &[F64]),
-    (Opcode::FcvtFromUint, &[I128], &[F64]),
-    (Opcode::FcvtFromUint, &[I32X4], &[F32X4]),
-    (Opcode::FcvtFromUint, &[I64X2], &[F64X2]),
-    // FcvtFromSint
-    (Opcode::FcvtFromSint, &[I8], &[F32]),
-    (Opcode::FcvtFromSint, &[I16], &[F32]),
-    (Opcode::FcvtFromSint, &[I32], &[F32]),
-    (Opcode::FcvtFromSint, &[I64], &[F32]),
-    (Opcode::FcvtFromSint, &[I128], &[F32]),
-    (Opcode::FcvtFromSint, &[I8], &[F64]),
-    (Opcode::FcvtFromSint, &[I16], &[F64]),
-    (Opcode::FcvtFromSint, &[I32], &[F64]),
-    (Opcode::FcvtFromSint, &[I64], &[F64]),
-    (Opcode::FcvtFromSint, &[I128], &[F64]),
-    (Opcode::FcvtFromSint, &[I32X4], &[F32X4]),
-    (Opcode::FcvtFromSint, &[I64X2], &[F64X2]),
-    // FcvtLowFromSint
-    (Opcode::FcvtLowFromSint, &[I32X4], &[F64X2]),
-    // FvpromoteLow
-    (Opcode::FvpromoteLow, &[F32X4], &[F64X2]),
-    // Fvdemote
-    (Opcode::Fvdemote, &[F64X2], &[F32X4]),
-    // Fcmp
-    (Opcode::Fcmp, &[F32, F32], &[I8]),
-    (Opcode::Fcmp, &[F64, F64], &[I8]),
-    (Opcode::Fcmp, &[F32X4, F32X4], &[I32X4]),
-    (Opcode::Fcmp, &[F64X2, F64X2], &[I64X2]),
-    // Icmp
-    (Opcode::Icmp, &[I8, I8], &[I8]),
-    (Opcode::Icmp, &[I16, I16], &[I8]),
-    (Opcode::Icmp, &[I32, I32], &[I8]),
-    (Opcode::Icmp, &[I64, I64], &[I8]),
-    (Opcode::Icmp, &[I128, I128], &[I8]),
-    (Opcode::Icmp, &[I8X16, I8X16], &[I8X16]),
-    (Opcode::Icmp, &[I16X8, I16X8], &[I16X8]),
-    (Opcode::Icmp, &[I32X4, I32X4], &[I32X4]),
-    (Opcode::Icmp, &[I64X2, I64X2], &[I64X2]),
-    // Fence
-    (Opcode::Fence, &[], &[]),
-    // Stack Access
-    (Opcode::StackStore, &[I8], &[]),
-    (Opcode::StackStore, &[I16], &[]),
-    (Opcode::StackStore, &[I32], &[]),
-    (Opcode::StackStore, &[I64], &[]),
-    (Opcode::StackStore, &[I128], &[]),
-    (Opcode::StackStore, &[F32], &[]),
-    (Opcode::StackStore, &[F64], &[]),
-    (Opcode::StackStore, &[I8X16], &[]),
-    (Opcode::StackStore, &[I16X8], &[]),
-    (Opcode::StackStore, &[I32X4], &[]),
-    (Opcode::StackStore, &[I64X2], &[]),
-    (Opcode::StackStore, &[F32X4], &[]),
-    (Opcode::StackStore, &[F64X2], &[]),
-    (Opcode::StackLoad, &[], &[I8]),
-    (Opcode::StackLoad, &[], &[I16]),
-    (Opcode::StackLoad, &[], &[I32]),
-    (Opcode::StackLoad, &[], &[I64]),
-    (Opcode::StackLoad, &[], &[I128]),
-    (Opcode::StackLoad, &[], &[F32]),
-    (Opcode::StackLoad, &[], &[F64]),
-    (Opcode::StackLoad, &[], &[I8X16]),
-    (Opcode::StackLoad, &[], &[I16X8]),
-    (Opcode::StackLoad, &[], &[I32X4]),
-    (Opcode::StackLoad, &[], &[I64X2]),
-    (Opcode::StackLoad, &[], &[F32X4]),
-    (Opcode::StackLoad, &[], &[F64X2]),
-    // Loads
-    (Opcode::Load, &[], &[I8]),
-    (Opcode::Load, &[], &[I16]),
-    (Opcode::Load, &[], &[I32]),
-    (Opcode::Load, &[], &[I64]),
-    (Opcode::Load, &[], &[I128]),
-    (Opcode::Load, &[], &[F32]),
-    (Opcode::Load, &[], &[F64]),
-    (Opcode::Load, &[], &[I8X16]),
-    (Opcode::Load, &[], &[I16X8]),
-    (Opcode::Load, &[], &[I32X4]),
-    (Opcode::Load, &[], &[I64X2]),
-    (Opcode::Load, &[], &[F32X4]),
-    (Opcode::Load, &[], &[F64X2]),
-    // Special Loads
-    (Opcode::Uload8, &[], &[I16]),
-    (Opcode::Uload8, &[], &[I32]),
-    (Opcode::Uload8, &[], &[I64]),
-    (Opcode::Uload16, &[], &[I32]),
-    (Opcode::Uload16, &[], &[I64]),
-    (Opcode::Uload32, &[], &[I64]),
-    (Opcode::Sload8, &[], &[I16]),
-    (Opcode::Sload8, &[], &[I32]),
-    (Opcode::Sload8, &[], &[I64]),
-    (Opcode::Sload16, &[], &[I32]),
-    (Opcode::Sload16, &[], &[I64]),
-    (Opcode::Sload32, &[], &[I64]),
-    // TODO: Unimplemented in the interpreter
-    // Opcode::Uload8x8
-    // Opcode::Sload8x8
-    // Opcode::Uload16x4
-    // Opcode::Sload16x4
-    // Opcode::Uload32x2
-    // Opcode::Sload32x2
-    // AtomicLoad
-    (Opcode::AtomicLoad, &[], &[I8]),
-    (Opcode::AtomicLoad, &[], &[I16]),
-    (Opcode::AtomicLoad, &[], &[I32]),
-    (Opcode::AtomicLoad, &[], &[I64]),
-    // Stores
-    (Opcode::Store, &[I8], &[]),
-    (Opcode::Store, &[I16], &[]),
-    (Opcode::Store, &[I32], &[]),
-    (Opcode::Store, &[I64], &[]),
-    (Opcode::Store, &[I128], &[]),
-    (Opcode::Store, &[F32], &[]),
-    (Opcode::Store, &[F64], &[]),
-    (Opcode::Store, &[I8X16], &[]),
-    (Opcode::Store, &[I16X8], &[]),
-    (Opcode::Store, &[I32X4], &[]),
-    (Opcode::Store, &[I64X2], &[]),
-    (Opcode::Store, &[F32X4], &[]),
-    (Opcode::Store, &[F64X2], &[]),
-    // Special Stores
-    (Opcode::Istore8, &[I16], &[]),
-    (Opcode::Istore8, &[I32], &[]),
-    (Opcode::Istore8, &[I64], &[]),
-    (Opcode::Istore16, &[I32], &[]),
-    (Opcode::Istore16, &[I64], &[]),
-    (Opcode::Istore32, &[I64], &[]),
-    // AtomicStore
-    (Opcode::AtomicStore, &[I8], &[]),
-    (Opcode::AtomicStore, &[I16], &[]),
-    (Opcode::AtomicStore, &[I32], &[]),
-    (Opcode::AtomicStore, &[I64], &[]),
-    // AtomicRMW
-    (Opcode::AtomicRmw, &[I8, I8], &[I8]),
-    (Opcode::AtomicRmw, &[I16, I16], &[I16]),
-    (Opcode::AtomicRmw, &[I32, I32], &[I32]),
-    (Opcode::AtomicRmw, &[I64, I64], &[I64]),
-    // AtomicCas
-    (Opcode::AtomicCas, &[I8, I8], &[I8]),
-    (Opcode::AtomicCas, &[I16, I16], &[I16]),
-    (Opcode::AtomicCas, &[I32, I32], &[I32]),
-    (Opcode::AtomicCas, &[I64, I64], &[I64]),
-    // Bitcast
-    (Opcode::Bitcast, &[F32], &[I32]),
-    (Opcode::Bitcast, &[I32], &[F32]),
-    (Opcode::Bitcast, &[F64], &[I64]),
-    (Opcode::Bitcast, &[I64], &[F64]),
-    // Shuffle
-    (Opcode::Shuffle, &[I8X16, I8X16], &[I8X16]),
-    // Swizzle
-    (Opcode::Swizzle, &[I8X16, I8X16], &[I8X16]),
-    // Splat
-    (Opcode::Splat, &[I8], &[I8X16]),
-    (Opcode::Splat, &[I16], &[I16X8]),
-    (Opcode::Splat, &[I32], &[I32X4]),
-    (Opcode::Splat, &[I64], &[I64X2]),
-    (Opcode::Splat, &[F32], &[F32X4]),
-    (Opcode::Splat, &[F64], &[F64X2]),
-    // Insert Lane
-    (Opcode::Insertlane, &[I8X16, I8], &[I8X16]),
-    (Opcode::Insertlane, &[I16X8, I16], &[I16X8]),
-    (Opcode::Insertlane, &[I32X4, I32], &[I32X4]),
-    (Opcode::Insertlane, &[I64X2, I64], &[I64X2]),
-    (Opcode::Insertlane, &[F32X4, F32], &[F32X4]),
-    (Opcode::Insertlane, &[F64X2, F64], &[F64X2]),
-    // Extract Lane
-    (Opcode::Extractlane, &[I8X16], &[I8]),
-    (Opcode::Extractlane, &[I16X8], &[I16]),
-    (Opcode::Extractlane, &[I32X4], &[I32]),
-    (Opcode::Extractlane, &[I64X2], &[I64]),
-    (Opcode::Extractlane, &[F32X4], &[F32]),
-    (Opcode::Extractlane, &[F64X2], &[F64]),
-    // Snarrow
-    (Opcode::Snarrow, &[I64X2, I64X2], &[I32X4]),
-    (Opcode::Snarrow, &[I32X4, I32X4], &[I16X8]),
-    (Opcode::Snarrow, &[I16X8, I16X8], &[I8X16]),
-    // Unarrow
-    (Opcode::Unarrow, &[I64X2, I64X2], &[I32X4]),
-    (Opcode::Unarrow, &[I32X4, I32X4], &[I16X8]),
-    (Opcode::Unarrow, &[I16X8, I16X8], &[I8X16]),
-    // Uunarrow
-    (Opcode::Uunarrow, &[I64X2, I64X2], &[I32X4]),
-    (Opcode::Uunarrow, &[I32X4, I32X4], &[I16X8]),
-    (Opcode::Uunarrow, &[I16X8, I16X8], &[I8X16]),
-    // VhighBits
-    (Opcode::VhighBits, &[I8X16], &[I8]),
-    (Opcode::VhighBits, &[I16X8], &[I8]),
-    (Opcode::VhighBits, &[I32X4], &[I8]),
-    (Opcode::VhighBits, &[I64X2], &[I8]),
-    // VanyTrue
-    (Opcode::VanyTrue, &[I8X16], &[I8]),
-    (Opcode::VanyTrue, &[I16X8], &[I8]),
-    (Opcode::VanyTrue, &[I32X4], &[I8]),
-    (Opcode::VanyTrue, &[I64X2], &[I8]),
-    // SwidenLow
-    (Opcode::SwidenLow, &[I8X16], &[I16X8]),
-    (Opcode::SwidenLow, &[I16X8], &[I32X4]),
-    (Opcode::SwidenLow, &[I32X4], &[I64X2]),
-    // SwidenHigh
-    (Opcode::SwidenHigh, &[I8X16], &[I16X8]),
-    (Opcode::SwidenHigh, &[I16X8], &[I32X4]),
-    (Opcode::SwidenHigh, &[I32X4], &[I64X2]),
-    // UwidenLow
-    (Opcode::UwidenLow, &[I8X16], &[I16X8]),
-    (Opcode::UwidenLow, &[I16X8], &[I32X4]),
-    (Opcode::UwidenLow, &[I32X4], &[I64X2]),
-    // UwidenHigh
-    (Opcode::UwidenHigh, &[I8X16], &[I16X8]),
-    (Opcode::UwidenHigh, &[I16X8], &[I32X4]),
-    (Opcode::UwidenHigh, &[I32X4], &[I64X2]),
-    // SqmulRoundSat
-    (Opcode::SqmulRoundSat, &[I16X8, I16X8], &[I16X8]),
-    (Opcode::SqmulRoundSat, &[I32X4, I32X4], &[I32X4]),
-    // IaddPairwise
-    (Opcode::IaddPairwise, &[I8X16, I8X16], &[I8X16]),
-    (Opcode::IaddPairwise, &[I16X8, I16X8], &[I16X8]),
-    (Opcode::IaddPairwise, &[I32X4, I32X4], &[I32X4]),
-    // Integer Consts
-    (Opcode::Iconst, &[], &[I8]),
-    (Opcode::Iconst, &[], &[I16]),
-    (Opcode::Iconst, &[], &[I32]),
-    (Opcode::Iconst, &[], &[I64]),
-    // Float Consts
-    (Opcode::F32const, &[], &[F32]),
-    (Opcode::F64const, &[], &[F64]),
-    // Vector Consts
-    (Opcode::Vconst, &[], &[I8X16]),
-    (Opcode::Vconst, &[], &[I16X8]),
-    (Opcode::Vconst, &[], &[I32X4]),
-    (Opcode::Vconst, &[], &[I64X2]),
-    (Opcode::Vconst, &[], &[F32X4]),
-    (Opcode::Vconst, &[], &[F64X2]),
-    // Call
-    (Opcode::Call, &[], &[]),
-];
+type OpcodeSignature = (Opcode, Vec<Type>, Vec<Type>);
+
+static OPCODE_SIGNATURES: Lazy<Vec<OpcodeSignature>> = Lazy::new(|| {
+    let types = &[
+        I8, I16, I32, I64, I128, // Scalar Integers
+        F32, F64, // Scalar Floats
+        I8X16, I16X8, I32X4, I64X2, // SIMD Integers
+        F32X4, F64X2, // SIMD Floats
+    ];
+
+    Opcode::all()
+        .iter()
+        .filter(|op| {
+            match op {
+                // Control flow opcodes should not be generated through `generate_instructions`.
+                Opcode::BrTable | Opcode::Brif | Opcode::Jump | Opcode::Return => false,
+
+                // Constants are generated outside of `generate_instructions`
+                Opcode::Iconst => false,
+
+                // TODO: extract_vector raises exceptions during return type generation becuase it
+                // uses dynamic vectors.
+                Opcode::ExtractVector => false,
+
+                _ => true,
+            }
+        })
+        .flat_map(|op| {
+            let constraints = op.constraints();
+
+            let ctrl_types = if let Some(ctrls) = constraints.ctrl_typeset() {
+                Vec::from_iter(types.iter().copied().filter(|ty| ctrls.contains(*ty)))
+            } else {
+                vec![INVALID]
+            };
+
+            ctrl_types.into_iter().flat_map(move |ctrl_type| {
+                let rets = Vec::from_iter(
+                    (0..constraints.num_fixed_results())
+                        .map(|i| constraints.result_type(i, ctrl_type)),
+                );
+
+                // Cols is a vector whose length will match `num_fixed_value_arguments`, and whose
+                // elements will be vectors of types that are valid for that fixed argument
+                // position.
+                let mut cols = vec![];
+
+                for i in 0..constraints.num_fixed_value_arguments() {
+                    match constraints.value_argument_constraint(i, ctrl_type) {
+                        ResolvedConstraint::Bound(ty) => cols.push(Vec::from([ty])),
+                        ResolvedConstraint::Free(tys) => cols.push(Vec::from_iter(
+                            types.iter().copied().filter(|ty| tys.contains(*ty)),
+                        )),
+                    }
+                }
+
+                // Generate the cartesian product of cols to produce a vector of argument lists,
+                // argss. The argss vector is seeded with the empty argument list, so there's an
+                // initial value to be extended in the loop below.
+                let mut argss = vec![vec![]];
+                let mut cols = cols.as_slice();
+                while let Some((col, rest)) = cols.split_last() {
+                    cols = rest;
+
+                    let mut next = vec![];
+                    for current in argss.iter() {
+                        // Extend the front of each argument candidate with every type in `col`.
+                        for ty in col {
+                            let mut args = vec![*ty];
+                            args.extend_from_slice(&current);
+                            next.push(args);
+                        }
+                    }
+
+                    let _ = std::mem::replace(&mut argss, next);
+                }
+
+                argss.into_iter().map(move |args| (*op, args, rets.clone()))
+            })
+        })
+        .filter(|(op, args, rets)| {
+            // These op/signature combinations need to be vetted
+            exceptions!(
+                op,
+                args.as_slice(),
+                rets.as_slice(),
+                (Opcode::Debugtrap),
+                (Opcode::Trap),
+                (Opcode::Trapz),
+                (Opcode::ResumableTrap),
+                (Opcode::Trapnz),
+                (Opcode::ResumableTrapnz),
+                (Opcode::CallIndirect, &[I32]),
+                (Opcode::ReturnCall),
+                (Opcode::ReturnCallIndirect),
+                (Opcode::FuncAddr),
+                (Opcode::X86Pshufb),
+                (Opcode::AvgRound),
+                (Opcode::Uload8x8),
+                (Opcode::Sload8x8),
+                (Opcode::Uload16x4),
+                (Opcode::Sload16x4),
+                (Opcode::Uload32x2),
+                (Opcode::Sload32x2),
+                (Opcode::StackAddr),
+                (Opcode::DynamicStackLoad),
+                (Opcode::DynamicStackStore),
+                (Opcode::DynamicStackAddr),
+                (Opcode::GlobalValue),
+                (Opcode::SymbolValue),
+                (Opcode::TlsValue),
+                (Opcode::GetPinnedReg),
+                (Opcode::SetPinnedReg),
+                (Opcode::GetFramePointer),
+                (Opcode::GetStackPointer),
+                (Opcode::GetReturnAddress),
+                (Opcode::TableAddr),
+                (Opcode::Null),
+                (Opcode::X86Blendv),
+                (Opcode::VallTrue),
+                (Opcode::IcmpImm),
+                (Opcode::X86Pmulhrsw),
+                (Opcode::IaddImm),
+                (Opcode::ImulImm),
+                (Opcode::UdivImm),
+                (Opcode::SdivImm),
+                (Opcode::UremImm),
+                (Opcode::SremImm),
+                (Opcode::IrsubImm),
+                (Opcode::IaddCin),
+                (Opcode::IaddCarry),
+                (Opcode::UaddOverflowTrap),
+                (Opcode::IsubBin),
+                (Opcode::IsubBout),
+                (Opcode::IsubBorrow),
+                (Opcode::BandImm),
+                (Opcode::BorImm),
+                (Opcode::BxorImm),
+                (Opcode::RotlImm),
+                (Opcode::RotrImm),
+                (Opcode::IshlImm),
+                (Opcode::UshrImm),
+                (Opcode::SshrImm),
+                (Opcode::IsNull),
+                (Opcode::IsInvalid),
+                (Opcode::ScalarToVector),
+                (Opcode::X86Pmaddubsw),
+                (Opcode::X86Cvtt2dq),
+                (Opcode::Select, &[I8, F32, F32], &[F32]),
+                (Opcode::Select, &[I16, F32, F32], &[F32]),
+                (Opcode::Select, &[I32, F32, F32], &[F32]),
+                (Opcode::Select, &[I64, F32, F32], &[F32]),
+                (Opcode::Select, &[I128, F32, F32], &[F32]),
+                (Opcode::Select, &[I8, F64, F64], &[F64]),
+                (Opcode::Select, &[I16, F64, F64], &[F64]),
+                (Opcode::Select, &[I32, F64, F64], &[F64]),
+                (Opcode::Select, &[I64, F64, F64], &[F64]),
+                (Opcode::Select, &[I128, F64, F64], &[F64]),
+                (Opcode::Select, &[I8, I8X16, I8X16], &[I8X16]),
+                (Opcode::Select, &[I16, I8X16, I8X16], &[I8X16]),
+                (Opcode::Select, &[I32, I8X16, I8X16], &[I8X16]),
+                (Opcode::Select, &[I64, I8X16, I8X16], &[I8X16]),
+                (Opcode::Select, &[I128, I8X16, I8X16], &[I8X16]),
+                (Opcode::Select, &[I8, I16X8, I16X8], &[I16X8]),
+                (Opcode::Select, &[I16, I16X8, I16X8], &[I16X8]),
+                (Opcode::Select, &[I32, I16X8, I16X8], &[I16X8]),
+                (Opcode::Select, &[I64, I16X8, I16X8], &[I16X8]),
+                (Opcode::Select, &[I128, I16X8, I16X8], &[I16X8]),
+                (Opcode::Select, &[I8, I32X4, I32X4], &[I32X4]),
+                (Opcode::Select, &[I16, I32X4, I32X4], &[I32X4]),
+                (Opcode::Select, &[I32, I32X4, I32X4], &[I32X4]),
+                (Opcode::Select, &[I64, I32X4, I32X4], &[I32X4]),
+                (Opcode::Select, &[I128, I32X4, I32X4], &[I32X4]),
+                (Opcode::Select, &[I8, I64X2, I64X2], &[I64X2]),
+                (Opcode::Select, &[I16, I64X2, I64X2], &[I64X2]),
+                (Opcode::Select, &[I32, I64X2, I64X2], &[I64X2]),
+                (Opcode::Select, &[I64, I64X2, I64X2], &[I64X2]),
+                (Opcode::Select, &[I128, I64X2, I64X2], &[I64X2]),
+                (Opcode::Select, &[I8, F32X4, F32X4], &[F32X4]),
+                (Opcode::Select, &[I16, F32X4, F32X4], &[F32X4]),
+                (Opcode::Select, &[I32, F32X4, F32X4], &[F32X4]),
+                (Opcode::Select, &[I64, F32X4, F32X4], &[F32X4]),
+                (Opcode::Select, &[I128, F32X4, F32X4], &[F32X4]),
+                (Opcode::Select, &[I8, F64X2, F64X2], &[F64X2]),
+                (Opcode::Select, &[I16, F64X2, F64X2], &[F64X2]),
+                (Opcode::Select, &[I32, F64X2, F64X2], &[F64X2]),
+                (Opcode::Select, &[I64, F64X2, F64X2], &[F64X2]),
+                (Opcode::Select, &[I128, F64X2, F64X2], &[F64X2]),
+                (Opcode::SelectSpectreGuard, &[I8, F32, F32], &[F32]),
+                (Opcode::SelectSpectreGuard, &[I16, F32, F32], &[F32]),
+                (Opcode::SelectSpectreGuard, &[I32, F32, F32], &[F32]),
+                (Opcode::SelectSpectreGuard, &[I64, F32, F32], &[F32]),
+                (Opcode::SelectSpectreGuard, &[I128, F32, F32], &[F32]),
+                (Opcode::SelectSpectreGuard, &[I8, F64, F64], &[F64]),
+                (Opcode::SelectSpectreGuard, &[I16, F64, F64], &[F64]),
+                (Opcode::SelectSpectreGuard, &[I32, F64, F64], &[F64]),
+                (Opcode::SelectSpectreGuard, &[I64, F64, F64], &[F64]),
+                (Opcode::SelectSpectreGuard, &[I128, F64, F64], &[F64]),
+                (Opcode::SelectSpectreGuard, &[I8, I8X16, I8X16], &[I8X16]),
+                (Opcode::SelectSpectreGuard, &[I16, I8X16, I8X16], &[I8X16]),
+                (Opcode::SelectSpectreGuard, &[I32, I8X16, I8X16], &[I8X16]),
+                (Opcode::SelectSpectreGuard, &[I64, I8X16, I8X16], &[I8X16]),
+                (Opcode::SelectSpectreGuard, &[I128, I8X16, I8X16], &[I8X16]),
+                (Opcode::SelectSpectreGuard, &[I8, I16X8, I16X8], &[I16X8]),
+                (Opcode::SelectSpectreGuard, &[I16, I16X8, I16X8], &[I16X8]),
+                (Opcode::SelectSpectreGuard, &[I32, I16X8, I16X8], &[I16X8]),
+                (Opcode::SelectSpectreGuard, &[I64, I16X8, I16X8], &[I16X8]),
+                (Opcode::SelectSpectreGuard, &[I128, I16X8, I16X8], &[I16X8]),
+                (Opcode::SelectSpectreGuard, &[I8, I32X4, I32X4], &[I32X4]),
+                (Opcode::SelectSpectreGuard, &[I16, I32X4, I32X4], &[I32X4]),
+                (Opcode::SelectSpectreGuard, &[I32, I32X4, I32X4], &[I32X4]),
+                (Opcode::SelectSpectreGuard, &[I64, I32X4, I32X4], &[I32X4]),
+                (Opcode::SelectSpectreGuard, &[I128, I32X4, I32X4], &[I32X4]),
+                (Opcode::SelectSpectreGuard, &[I8, I64X2, I64X2], &[I64X2]),
+                (Opcode::SelectSpectreGuard, &[I16, I64X2, I64X2], &[I64X2]),
+                (Opcode::SelectSpectreGuard, &[I32, I64X2, I64X2], &[I64X2]),
+                (Opcode::SelectSpectreGuard, &[I64, I64X2, I64X2], &[I64X2]),
+                (Opcode::SelectSpectreGuard, &[I128, I64X2, I64X2], &[I64X2]),
+                (Opcode::SelectSpectreGuard, &[I8, F32X4, F32X4], &[F32X4]),
+                (Opcode::SelectSpectreGuard, &[I16, F32X4, F32X4], &[F32X4]),
+                (Opcode::SelectSpectreGuard, &[I32, F32X4, F32X4], &[F32X4]),
+                (Opcode::SelectSpectreGuard, &[I64, F32X4, F32X4], &[F32X4]),
+                (Opcode::SelectSpectreGuard, &[I128, F32X4, F32X4], &[F32X4]),
+                (Opcode::SelectSpectreGuard, &[I8, F64X2, F64X2], &[F64X2]),
+                (Opcode::SelectSpectreGuard, &[I16, F64X2, F64X2], &[F64X2]),
+                (Opcode::SelectSpectreGuard, &[I32, F64X2, F64X2], &[F64X2]),
+                (Opcode::SelectSpectreGuard, &[I64, F64X2, F64X2], &[F64X2]),
+                (Opcode::SelectSpectreGuard, &[I128, F64X2, F64X2], &[F64X2]),
+                (Opcode::Bitselect, &[F32, F32, F32], &[F32]),
+                (Opcode::Bitselect, &[F64, F64, F64], &[F64]),
+                (Opcode::Bitselect, &[F32X4, F32X4, F32X4], &[F32X4]),
+                (Opcode::Bitselect, &[F64X2, F64X2, F64X2], &[F64X2]),
+                (Opcode::VanyTrue, &[F32X4], &[I8]),
+                (Opcode::VanyTrue, &[F64X2], &[I8]),
+                (Opcode::VhighBits, &[F32X4], &[I8]),
+                (Opcode::VhighBits, &[F64X2], &[I8]),
+                (Opcode::VhighBits, &[I8X16], &[I16]),
+                (Opcode::VhighBits, &[I16X8], &[I16]),
+                (Opcode::VhighBits, &[I32X4], &[I16]),
+                (Opcode::VhighBits, &[I64X2], &[I16]),
+                (Opcode::VhighBits, &[F32X4], &[I16]),
+                (Opcode::VhighBits, &[F64X2], &[I16]),
+                (Opcode::VhighBits, &[I8X16], &[I32]),
+                (Opcode::VhighBits, &[I16X8], &[I32]),
+                (Opcode::VhighBits, &[I32X4], &[I32]),
+                (Opcode::VhighBits, &[I64X2], &[I32]),
+                (Opcode::VhighBits, &[F32X4], &[I32]),
+                (Opcode::VhighBits, &[F64X2], &[I32]),
+                (Opcode::VhighBits, &[I8X16], &[I64]),
+                (Opcode::VhighBits, &[I16X8], &[I64]),
+                (Opcode::VhighBits, &[I32X4], &[I64]),
+                (Opcode::VhighBits, &[I64X2], &[I64]),
+                (Opcode::VhighBits, &[F32X4], &[I64]),
+                (Opcode::VhighBits, &[F64X2], &[I64]),
+                (Opcode::VhighBits, &[I8X16], &[I128]),
+                (Opcode::VhighBits, &[I16X8], &[I128]),
+                (Opcode::VhighBits, &[I32X4], &[I128]),
+                (Opcode::VhighBits, &[I64X2], &[I128]),
+                (Opcode::VhighBits, &[F32X4], &[I128]),
+                (Opcode::VhighBits, &[F64X2], &[I128]),
+                (Opcode::VhighBits, &[I8X16], &[I8X16]),
+                (Opcode::VhighBits, &[I16X8], &[I8X16]),
+                (Opcode::VhighBits, &[I32X4], &[I8X16]),
+                (Opcode::VhighBits, &[I64X2], &[I8X16]),
+                (Opcode::VhighBits, &[F32X4], &[I8X16]),
+                (Opcode::VhighBits, &[F64X2], &[I8X16]),
+                (Opcode::VhighBits, &[I8X16], &[I16X8]),
+                (Opcode::VhighBits, &[I16X8], &[I16X8]),
+                (Opcode::VhighBits, &[I32X4], &[I16X8]),
+                (Opcode::VhighBits, &[I64X2], &[I16X8]),
+                (Opcode::VhighBits, &[F32X4], &[I16X8]),
+                (Opcode::VhighBits, &[F64X2], &[I16X8]),
+                (Opcode::VhighBits, &[I8X16], &[I32X4]),
+                (Opcode::VhighBits, &[I16X8], &[I32X4]),
+                (Opcode::VhighBits, &[I32X4], &[I32X4]),
+                (Opcode::VhighBits, &[I64X2], &[I32X4]),
+                (Opcode::VhighBits, &[F32X4], &[I32X4]),
+                (Opcode::VhighBits, &[F64X2], &[I32X4]),
+                (Opcode::VhighBits, &[I8X16], &[I64X2]),
+                (Opcode::VhighBits, &[I16X8], &[I64X2]),
+                (Opcode::VhighBits, &[I32X4], &[I64X2]),
+                (Opcode::VhighBits, &[I64X2], &[I64X2]),
+                (Opcode::VhighBits, &[F32X4], &[I64X2]),
+                (Opcode::VhighBits, &[F64X2], &[I64X2]),
+                (Opcode::Ineg, &[I8X16], &[I8X16]),
+                (Opcode::Ineg, &[I16X8], &[I16X8]),
+                (Opcode::Ineg, &[I32X4], &[I32X4]),
+                (Opcode::Ineg, &[I64X2], &[I64X2]),
+                (Opcode::Umulhi, &[I128, I128], &[I128]),
+                (Opcode::Smulhi, &[I128, I128], &[I128]),
+                // https://github.com/bytecodealliance/wasmtime/issues/6073
+                (Opcode::Iconcat, &[I32, I32], &[I64]),
+                (Opcode::Iconcat, &[I16, I16], &[I32]),
+                (Opcode::Iconcat, &[I8, I8], &[I16]),
+                // https://github.com/bytecodealliance/wasmtime/issues/6073
+                (Opcode::Isplit, &[I64], &[I32, I32]),
+                (Opcode::Isplit, &[I32], &[I16, I16]),
+                (Opcode::Isplit, &[I16], &[I8, I8]),
+                (Opcode::Rotl, &[I8X16, I8], &[I8X16]),
+                (Opcode::Rotl, &[I8X16, I16], &[I8X16]),
+                (Opcode::Rotl, &[I8X16, I32], &[I8X16]),
+                (Opcode::Rotl, &[I8X16, I64], &[I8X16]),
+                (Opcode::Rotl, &[I8X16, I128], &[I8X16]),
+                (Opcode::Rotl, &[I16X8, I8], &[I16X8]),
+                (Opcode::Rotl, &[I16X8, I16], &[I16X8]),
+                (Opcode::Rotl, &[I16X8, I32], &[I16X8]),
+                (Opcode::Rotl, &[I16X8, I64], &[I16X8]),
+                (Opcode::Rotl, &[I16X8, I128], &[I16X8]),
+                (Opcode::Rotl, &[I32X4, I8], &[I32X4]),
+                (Opcode::Rotl, &[I32X4, I16], &[I32X4]),
+                (Opcode::Rotl, &[I32X4, I32], &[I32X4]),
+                (Opcode::Rotl, &[I32X4, I64], &[I32X4]),
+                (Opcode::Rotl, &[I32X4, I128], &[I32X4]),
+                (Opcode::Rotl, &[I64X2, I8], &[I64X2]),
+                (Opcode::Rotl, &[I64X2, I16], &[I64X2]),
+                (Opcode::Rotl, &[I64X2, I32], &[I64X2]),
+                (Opcode::Rotl, &[I64X2, I64], &[I64X2]),
+                (Opcode::Rotl, &[I64X2, I128], &[I64X2]),
+                (Opcode::Rotr, &[I8X16, I8], &[I8X16]),
+                (Opcode::Rotr, &[I8X16, I16], &[I8X16]),
+                (Opcode::Rotr, &[I8X16, I32], &[I8X16]),
+                (Opcode::Rotr, &[I8X16, I64], &[I8X16]),
+                (Opcode::Rotr, &[I8X16, I128], &[I8X16]),
+                (Opcode::Rotr, &[I16X8, I8], &[I16X8]),
+                (Opcode::Rotr, &[I16X8, I16], &[I16X8]),
+                (Opcode::Rotr, &[I16X8, I32], &[I16X8]),
+                (Opcode::Rotr, &[I16X8, I64], &[I16X8]),
+                (Opcode::Rotr, &[I16X8, I128], &[I16X8]),
+                (Opcode::Rotr, &[I32X4, I8], &[I32X4]),
+                (Opcode::Rotr, &[I32X4, I16], &[I32X4]),
+                (Opcode::Rotr, &[I32X4, I32], &[I32X4]),
+                (Opcode::Rotr, &[I32X4, I64], &[I32X4]),
+                (Opcode::Rotr, &[I32X4, I128], &[I32X4]),
+                (Opcode::Rotr, &[I64X2, I8], &[I64X2]),
+                (Opcode::Rotr, &[I64X2, I16], &[I64X2]),
+                (Opcode::Rotr, &[I64X2, I32], &[I64X2]),
+                (Opcode::Rotr, &[I64X2, I64], &[I64X2]),
+                (Opcode::Rotr, &[I64X2, I128], &[I64X2]),
+                (Opcode::Ishl, &[I8X16, I8], &[I8X16]),
+                (Opcode::Ishl, &[I8X16, I16], &[I8X16]),
+                (Opcode::Ishl, &[I8X16, I32], &[I8X16]),
+                (Opcode::Ishl, &[I8X16, I64], &[I8X16]),
+                (Opcode::Ishl, &[I8X16, I128], &[I8X16]),
+                (Opcode::Ishl, &[I16X8, I8], &[I16X8]),
+                (Opcode::Ishl, &[I16X8, I16], &[I16X8]),
+                (Opcode::Ishl, &[I16X8, I32], &[I16X8]),
+                (Opcode::Ishl, &[I16X8, I64], &[I16X8]),
+                (Opcode::Ishl, &[I16X8, I128], &[I16X8]),
+                (Opcode::Ishl, &[I32X4, I8], &[I32X4]),
+                (Opcode::Ishl, &[I32X4, I16], &[I32X4]),
+                (Opcode::Ishl, &[I32X4, I32], &[I32X4]),
+                (Opcode::Ishl, &[I32X4, I64], &[I32X4]),
+                (Opcode::Ishl, &[I32X4, I128], &[I32X4]),
+                (Opcode::Ishl, &[I64X2, I8], &[I64X2]),
+                (Opcode::Ishl, &[I64X2, I16], &[I64X2]),
+                (Opcode::Ishl, &[I64X2, I32], &[I64X2]),
+                (Opcode::Ishl, &[I64X2, I64], &[I64X2]),
+                (Opcode::Ishl, &[I64X2, I128], &[I64X2]),
+                (Opcode::Ushr, &[I8X16, I8], &[I8X16]),
+                (Opcode::Ushr, &[I8X16, I16], &[I8X16]),
+                (Opcode::Ushr, &[I8X16, I32], &[I8X16]),
+                (Opcode::Ushr, &[I8X16, I64], &[I8X16]),
+                (Opcode::Ushr, &[I8X16, I128], &[I8X16]),
+                (Opcode::Ushr, &[I16X8, I8], &[I16X8]),
+                (Opcode::Ushr, &[I16X8, I16], &[I16X8]),
+                (Opcode::Ushr, &[I16X8, I32], &[I16X8]),
+                (Opcode::Ushr, &[I16X8, I64], &[I16X8]),
+                (Opcode::Ushr, &[I16X8, I128], &[I16X8]),
+                (Opcode::Ushr, &[I32X4, I8], &[I32X4]),
+                (Opcode::Ushr, &[I32X4, I16], &[I32X4]),
+                (Opcode::Ushr, &[I32X4, I32], &[I32X4]),
+                (Opcode::Ushr, &[I32X4, I64], &[I32X4]),
+                (Opcode::Ushr, &[I32X4, I128], &[I32X4]),
+                (Opcode::Ushr, &[I64X2, I8], &[I64X2]),
+                (Opcode::Ushr, &[I64X2, I16], &[I64X2]),
+                (Opcode::Ushr, &[I64X2, I32], &[I64X2]),
+                (Opcode::Ushr, &[I64X2, I64], &[I64X2]),
+                (Opcode::Ushr, &[I64X2, I128], &[I64X2]),
+                (Opcode::Sshr, &[I8X16, I8], &[I8X16]),
+                (Opcode::Sshr, &[I8X16, I16], &[I8X16]),
+                (Opcode::Sshr, &[I8X16, I32], &[I8X16]),
+                (Opcode::Sshr, &[I8X16, I64], &[I8X16]),
+                (Opcode::Sshr, &[I8X16, I128], &[I8X16]),
+                (Opcode::Sshr, &[I16X8, I8], &[I16X8]),
+                (Opcode::Sshr, &[I16X8, I16], &[I16X8]),
+                (Opcode::Sshr, &[I16X8, I32], &[I16X8]),
+                (Opcode::Sshr, &[I16X8, I64], &[I16X8]),
+                (Opcode::Sshr, &[I16X8, I128], &[I16X8]),
+                (Opcode::Sshr, &[I32X4, I8], &[I32X4]),
+                (Opcode::Sshr, &[I32X4, I16], &[I32X4]),
+                (Opcode::Sshr, &[I32X4, I32], &[I32X4]),
+                (Opcode::Sshr, &[I32X4, I64], &[I32X4]),
+                (Opcode::Sshr, &[I32X4, I128], &[I32X4]),
+                (Opcode::Sshr, &[I64X2, I8], &[I64X2]),
+                (Opcode::Sshr, &[I64X2, I16], &[I64X2]),
+                (Opcode::Sshr, &[I64X2, I32], &[I64X2]),
+                (Opcode::Sshr, &[I64X2, I64], &[I64X2]),
+                (Opcode::Sshr, &[I64X2, I128], &[I64X2]),
+                (Opcode::Fmin, &[F32X4, F32X4], &[F32X4]),
+                (Opcode::Fmin, &[F64X2, F64X2], &[F64X2]),
+                (Opcode::FminPseudo, &[F32X4, F32X4], &[F32X4]),
+                (Opcode::FminPseudo, &[F64X2, F64X2], &[F64X2]),
+                (Opcode::Fmax, &[F32X4, F32X4], &[F32X4]),
+                (Opcode::Fmax, &[F64X2, F64X2], &[F64X2]),
+                (Opcode::FmaxPseudo, &[F32X4, F32X4], &[F32X4]),
+                (Opcode::FmaxPseudo, &[F64X2, F64X2], &[F64X2]),
+                (Opcode::Bitcast, &[I8], &[I8]),
+                (Opcode::Bitcast, &[I16], &[I8]),
+                (Opcode::Bitcast, &[I32], &[I8]),
+                (Opcode::Bitcast, &[I64], &[I8]),
+                (Opcode::Bitcast, &[I128], &[I8]),
+                (Opcode::Bitcast, &[F32], &[I8]),
+                (Opcode::Bitcast, &[F64], &[I8]),
+                (Opcode::Bitcast, &[I8X16], &[I8]),
+                (Opcode::Bitcast, &[I16X8], &[I8]),
+                (Opcode::Bitcast, &[I32X4], &[I8]),
+                (Opcode::Bitcast, &[I64X2], &[I8]),
+                (Opcode::Bitcast, &[F32X4], &[I8]),
+                (Opcode::Bitcast, &[F64X2], &[I8]),
+                (Opcode::Bitcast, &[I8], &[I16]),
+                (Opcode::Bitcast, &[I16], &[I16]),
+                (Opcode::Bitcast, &[I32], &[I16]),
+                (Opcode::Bitcast, &[I64], &[I16]),
+                (Opcode::Bitcast, &[I128], &[I16]),
+                (Opcode::Bitcast, &[F32], &[I16]),
+                (Opcode::Bitcast, &[F64], &[I16]),
+                (Opcode::Bitcast, &[I8X16], &[I16]),
+                (Opcode::Bitcast, &[I16X8], &[I16]),
+                (Opcode::Bitcast, &[I32X4], &[I16]),
+                (Opcode::Bitcast, &[I64X2], &[I16]),
+                (Opcode::Bitcast, &[F32X4], &[I16]),
+                (Opcode::Bitcast, &[F64X2], &[I16]),
+                (Opcode::Bitcast, &[I8], &[I32]),
+                (Opcode::Bitcast, &[I16], &[I32]),
+                (Opcode::Bitcast, &[I32], &[I32]),
+                (Opcode::Bitcast, &[I64], &[I32]),
+                (Opcode::Bitcast, &[I128], &[I32]),
+                (Opcode::Bitcast, &[F64], &[I32]),
+                (Opcode::Bitcast, &[I8X16], &[I32]),
+                (Opcode::Bitcast, &[I16X8], &[I32]),
+                (Opcode::Bitcast, &[I32X4], &[I32]),
+                (Opcode::Bitcast, &[I64X2], &[I32]),
+                (Opcode::Bitcast, &[F32X4], &[I32]),
+                (Opcode::Bitcast, &[F64X2], &[I32]),
+                (Opcode::Bitcast, &[I8], &[I64]),
+                (Opcode::Bitcast, &[I16], &[I64]),
+                (Opcode::Bitcast, &[I32], &[I64]),
+                (Opcode::Bitcast, &[I64], &[I64]),
+                (Opcode::Bitcast, &[I128], &[I64]),
+                (Opcode::Bitcast, &[F32], &[I64]),
+                (Opcode::Bitcast, &[I8X16], &[I64]),
+                (Opcode::Bitcast, &[I16X8], &[I64]),
+                (Opcode::Bitcast, &[I32X4], &[I64]),
+                (Opcode::Bitcast, &[I64X2], &[I64]),
+                (Opcode::Bitcast, &[F32X4], &[I64]),
+                (Opcode::Bitcast, &[F64X2], &[I64]),
+                (Opcode::Bitcast, &[I8], &[I128]),
+                (Opcode::Bitcast, &[I16], &[I128]),
+                (Opcode::Bitcast, &[I32], &[I128]),
+                (Opcode::Bitcast, &[I64], &[I128]),
+                (Opcode::Bitcast, &[I128], &[I128]),
+                (Opcode::Bitcast, &[F32], &[I128]),
+                (Opcode::Bitcast, &[F64], &[I128]),
+                (Opcode::Bitcast, &[I8X16], &[I128]),
+                (Opcode::Bitcast, &[I16X8], &[I128]),
+                (Opcode::Bitcast, &[I32X4], &[I128]),
+                (Opcode::Bitcast, &[I64X2], &[I128]),
+                (Opcode::Bitcast, &[F32X4], &[I128]),
+                (Opcode::Bitcast, &[F64X2], &[I128]),
+                (Opcode::Bitcast, &[I8], &[F32]),
+                (Opcode::Bitcast, &[I16], &[F32]),
+                (Opcode::Bitcast, &[I64], &[F32]),
+                (Opcode::Bitcast, &[I128], &[F32]),
+                (Opcode::Bitcast, &[F32], &[F32]),
+                (Opcode::Bitcast, &[F64], &[F32]),
+                (Opcode::Bitcast, &[I8X16], &[F32]),
+                (Opcode::Bitcast, &[I16X8], &[F32]),
+                (Opcode::Bitcast, &[I32X4], &[F32]),
+                (Opcode::Bitcast, &[I64X2], &[F32]),
+                (Opcode::Bitcast, &[F32X4], &[F32]),
+                (Opcode::Bitcast, &[F64X2], &[F32]),
+                (Opcode::Bitcast, &[I8], &[F64]),
+                (Opcode::Bitcast, &[I16], &[F64]),
+                (Opcode::Bitcast, &[I32], &[F64]),
+                (Opcode::Bitcast, &[I128], &[F64]),
+                (Opcode::Bitcast, &[F32], &[F64]),
+                (Opcode::Bitcast, &[F64], &[F64]),
+                (Opcode::Bitcast, &[I8X16], &[F64]),
+                (Opcode::Bitcast, &[I16X8], &[F64]),
+                (Opcode::Bitcast, &[I32X4], &[F64]),
+                (Opcode::Bitcast, &[I64X2], &[F64]),
+                (Opcode::Bitcast, &[F32X4], &[F64]),
+                (Opcode::Bitcast, &[F64X2], &[F64]),
+                (Opcode::Bitcast, &[I8], &[I8X16]),
+                (Opcode::Bitcast, &[I16], &[I8X16]),
+                (Opcode::Bitcast, &[I32], &[I8X16]),
+                (Opcode::Bitcast, &[I64], &[I8X16]),
+                (Opcode::Bitcast, &[I128], &[I8X16]),
+                (Opcode::Bitcast, &[F32], &[I8X16]),
+                (Opcode::Bitcast, &[F64], &[I8X16]),
+                (Opcode::Bitcast, &[I8X16], &[I8X16]),
+                (Opcode::Bitcast, &[I16X8], &[I8X16]),
+                (Opcode::Bitcast, &[I32X4], &[I8X16]),
+                (Opcode::Bitcast, &[I64X2], &[I8X16]),
+                (Opcode::Bitcast, &[F32X4], &[I8X16]),
+                (Opcode::Bitcast, &[F64X2], &[I8X16]),
+                (Opcode::Bitcast, &[I8], &[I16X8]),
+                (Opcode::Bitcast, &[I16], &[I16X8]),
+                (Opcode::Bitcast, &[I32], &[I16X8]),
+                (Opcode::Bitcast, &[I64], &[I16X8]),
+                (Opcode::Bitcast, &[I128], &[I16X8]),
+                (Opcode::Bitcast, &[F32], &[I16X8]),
+                (Opcode::Bitcast, &[F64], &[I16X8]),
+                (Opcode::Bitcast, &[I8X16], &[I16X8]),
+                (Opcode::Bitcast, &[I16X8], &[I16X8]),
+                (Opcode::Bitcast, &[I32X4], &[I16X8]),
+                (Opcode::Bitcast, &[I64X2], &[I16X8]),
+                (Opcode::Bitcast, &[F32X4], &[I16X8]),
+                (Opcode::Bitcast, &[F64X2], &[I16X8]),
+                (Opcode::Bitcast, &[I8], &[I32X4]),
+                (Opcode::Bitcast, &[I16], &[I32X4]),
+                (Opcode::Bitcast, &[I32], &[I32X4]),
+                (Opcode::Bitcast, &[I64], &[I32X4]),
+                (Opcode::Bitcast, &[I128], &[I32X4]),
+                (Opcode::Bitcast, &[F32], &[I32X4]),
+                (Opcode::Bitcast, &[F64], &[I32X4]),
+                (Opcode::Bitcast, &[I8X16], &[I32X4]),
+                (Opcode::Bitcast, &[I16X8], &[I32X4]),
+                (Opcode::Bitcast, &[I32X4], &[I32X4]),
+                (Opcode::Bitcast, &[I64X2], &[I32X4]),
+                (Opcode::Bitcast, &[F32X4], &[I32X4]),
+                (Opcode::Bitcast, &[F64X2], &[I32X4]),
+                (Opcode::Bitcast, &[I8], &[I64X2]),
+                (Opcode::Bitcast, &[I16], &[I64X2]),
+                (Opcode::Bitcast, &[I32], &[I64X2]),
+                (Opcode::Bitcast, &[I64], &[I64X2]),
+                (Opcode::Bitcast, &[I128], &[I64X2]),
+                (Opcode::Bitcast, &[F32], &[I64X2]),
+                (Opcode::Bitcast, &[F64], &[I64X2]),
+                (Opcode::Bitcast, &[I8X16], &[I64X2]),
+                (Opcode::Bitcast, &[I16X8], &[I64X2]),
+                (Opcode::Bitcast, &[I32X4], &[I64X2]),
+                (Opcode::Bitcast, &[I64X2], &[I64X2]),
+                (Opcode::Bitcast, &[F32X4], &[I64X2]),
+                (Opcode::Bitcast, &[F64X2], &[I64X2]),
+                (Opcode::Bitcast, &[I8], &[F32X4]),
+                (Opcode::Bitcast, &[I16], &[F32X4]),
+                (Opcode::Bitcast, &[I32], &[F32X4]),
+                (Opcode::Bitcast, &[I64], &[F32X4]),
+                (Opcode::Bitcast, &[I128], &[F32X4]),
+                (Opcode::Bitcast, &[F32], &[F32X4]),
+                (Opcode::Bitcast, &[F64], &[F32X4]),
+                (Opcode::Bitcast, &[I8X16], &[F32X4]),
+                (Opcode::Bitcast, &[I16X8], &[F32X4]),
+                (Opcode::Bitcast, &[I32X4], &[F32X4]),
+                (Opcode::Bitcast, &[I64X2], &[F32X4]),
+                (Opcode::Bitcast, &[F32X4], &[F32X4]),
+                (Opcode::Bitcast, &[F64X2], &[F32X4]),
+                (Opcode::Bitcast, &[I8], &[F64X2]),
+                (Opcode::Bitcast, &[I16], &[F64X2]),
+                (Opcode::Bitcast, &[I32], &[F64X2]),
+                (Opcode::Bitcast, &[I64], &[F64X2]),
+                (Opcode::Bitcast, &[I128], &[F64X2]),
+                (Opcode::Bitcast, &[F32], &[F64X2]),
+                (Opcode::Bitcast, &[F64], &[F64X2]),
+                (Opcode::Bitcast, &[I8X16], &[F64X2]),
+                (Opcode::Bitcast, &[I16X8], &[F64X2]),
+                (Opcode::Bitcast, &[I32X4], &[F64X2]),
+                (Opcode::Bitcast, &[I64X2], &[F64X2]),
+                (Opcode::Bitcast, &[F32X4], &[F64X2]),
+                (Opcode::Bitcast, &[F64X2], &[F64X2]),
+                (Opcode::FcvtToUintSat, &[F32X4], &[I8]),
+                (Opcode::FcvtToUintSat, &[F64X2], &[I8]),
+                (Opcode::FcvtToUintSat, &[F32X4], &[I16]),
+                (Opcode::FcvtToUintSat, &[F64X2], &[I16]),
+                (Opcode::FcvtToUintSat, &[F32X4], &[I32]),
+                (Opcode::FcvtToUintSat, &[F64X2], &[I32]),
+                (Opcode::FcvtToUintSat, &[F32X4], &[I64]),
+                (Opcode::FcvtToUintSat, &[F64X2], &[I64]),
+                (Opcode::FcvtToUintSat, &[F32X4], &[I128]),
+                (Opcode::FcvtToUintSat, &[F64X2], &[I128]),
+                (Opcode::FcvtToUintSat, &[F32], &[I8X16]),
+                (Opcode::FcvtToUintSat, &[F64], &[I8X16]),
+                (Opcode::FcvtToUintSat, &[F32X4], &[I8X16]),
+                (Opcode::FcvtToUintSat, &[F64X2], &[I8X16]),
+                (Opcode::FcvtToUintSat, &[F32], &[I16X8]),
+                (Opcode::FcvtToUintSat, &[F64], &[I16X8]),
+                (Opcode::FcvtToUintSat, &[F32X4], &[I16X8]),
+                (Opcode::FcvtToUintSat, &[F64X2], &[I16X8]),
+                (Opcode::FcvtToUintSat, &[F32], &[I32X4]),
+                (Opcode::FcvtToUintSat, &[F64], &[I32X4]),
+                (Opcode::FcvtToUintSat, &[F64X2], &[I32X4]),
+                (Opcode::FcvtToUintSat, &[F32], &[I64X2]),
+                (Opcode::FcvtToUintSat, &[F64], &[I64X2]),
+                (Opcode::FcvtToUintSat, &[F32X4], &[I64X2]),
+                (Opcode::FcvtToSintSat, &[F32X4], &[I8]),
+                (Opcode::FcvtToSintSat, &[F64X2], &[I8]),
+                (Opcode::FcvtToSintSat, &[F32X4], &[I16]),
+                (Opcode::FcvtToSintSat, &[F64X2], &[I16]),
+                (Opcode::FcvtToSintSat, &[F32X4], &[I32]),
+                (Opcode::FcvtToSintSat, &[F64X2], &[I32]),
+                (Opcode::FcvtToSintSat, &[F32X4], &[I64]),
+                (Opcode::FcvtToSintSat, &[F64X2], &[I64]),
+                (Opcode::FcvtToSintSat, &[F32X4], &[I128]),
+                (Opcode::FcvtToSintSat, &[F64X2], &[I128]),
+                (Opcode::FcvtToSintSat, &[F32], &[I8X16]),
+                (Opcode::FcvtToSintSat, &[F64], &[I8X16]),
+                (Opcode::FcvtToSintSat, &[F32X4], &[I8X16]),
+                (Opcode::FcvtToSintSat, &[F64X2], &[I8X16]),
+                (Opcode::FcvtToSintSat, &[F32], &[I16X8]),
+                (Opcode::FcvtToSintSat, &[F64], &[I16X8]),
+                (Opcode::FcvtToSintSat, &[F32X4], &[I16X8]),
+                (Opcode::FcvtToSintSat, &[F64X2], &[I16X8]),
+                (Opcode::FcvtToSintSat, &[F32], &[I32X4]),
+                (Opcode::FcvtToSintSat, &[F64], &[I32X4]),
+                (Opcode::FcvtToSintSat, &[F64X2], &[I32X4]),
+                (Opcode::FcvtToSintSat, &[F32], &[I64X2]),
+                (Opcode::FcvtToSintSat, &[F64], &[I64X2]),
+                (Opcode::FcvtToSintSat, &[F32X4], &[I64X2]),
+                (Opcode::FcvtFromUint, &[I8X16], &[F32]),
+                (Opcode::FcvtFromUint, &[I16X8], &[F32]),
+                (Opcode::FcvtFromUint, &[I32X4], &[F32]),
+                (Opcode::FcvtFromUint, &[I64X2], &[F32]),
+                (Opcode::FcvtFromUint, &[I8X16], &[F64]),
+                (Opcode::FcvtFromUint, &[I16X8], &[F64]),
+                (Opcode::FcvtFromUint, &[I32X4], &[F64]),
+                (Opcode::FcvtFromUint, &[I64X2], &[F64]),
+                (Opcode::FcvtFromUint, &[I8], &[F32X4]),
+                (Opcode::FcvtFromUint, &[I16], &[F32X4]),
+                (Opcode::FcvtFromUint, &[I32], &[F32X4]),
+                (Opcode::FcvtFromUint, &[I64], &[F32X4]),
+                (Opcode::FcvtFromUint, &[I128], &[F32X4]),
+                (Opcode::FcvtFromUint, &[I8X16], &[F32X4]),
+                (Opcode::FcvtFromUint, &[I16X8], &[F32X4]),
+                (Opcode::FcvtFromUint, &[I64X2], &[F32X4]),
+                (Opcode::FcvtFromUint, &[I8], &[F64X2]),
+                (Opcode::FcvtFromUint, &[I16], &[F64X2]),
+                (Opcode::FcvtFromUint, &[I32], &[F64X2]),
+                (Opcode::FcvtFromUint, &[I64], &[F64X2]),
+                (Opcode::FcvtFromUint, &[I128], &[F64X2]),
+                (Opcode::FcvtFromUint, &[I8X16], &[F64X2]),
+                (Opcode::FcvtFromUint, &[I16X8], &[F64X2]),
+                (Opcode::FcvtFromUint, &[I32X4], &[F64X2]),
+                (Opcode::FcvtFromSint, &[I8X16], &[F32]),
+                (Opcode::FcvtFromSint, &[I16X8], &[F32]),
+                (Opcode::FcvtFromSint, &[I32X4], &[F32]),
+                (Opcode::FcvtFromSint, &[I64X2], &[F32]),
+                (Opcode::FcvtFromSint, &[I8X16], &[F64]),
+                (Opcode::FcvtFromSint, &[I16X8], &[F64]),
+                (Opcode::FcvtFromSint, &[I32X4], &[F64]),
+                (Opcode::FcvtFromSint, &[I64X2], &[F64]),
+                (Opcode::FcvtFromSint, &[I8], &[F32X4]),
+                (Opcode::FcvtFromSint, &[I16], &[F32X4]),
+                (Opcode::FcvtFromSint, &[I32], &[F32X4]),
+                (Opcode::FcvtFromSint, &[I64], &[F32X4]),
+                (Opcode::FcvtFromSint, &[I128], &[F32X4]),
+                (Opcode::FcvtFromSint, &[I8X16], &[F32X4]),
+                (Opcode::FcvtFromSint, &[I16X8], &[F32X4]),
+                (Opcode::FcvtFromSint, &[I64X2], &[F32X4]),
+                (Opcode::FcvtFromSint, &[I8], &[F64X2]),
+                (Opcode::FcvtFromSint, &[I16], &[F64X2]),
+                (Opcode::FcvtFromSint, &[I32], &[F64X2]),
+                (Opcode::FcvtFromSint, &[I64], &[F64X2]),
+                (Opcode::FcvtFromSint, &[I128], &[F64X2]),
+                (Opcode::FcvtFromSint, &[I8X16], &[F64X2]),
+                (Opcode::FcvtFromSint, &[I16X8], &[F64X2]),
+                (Opcode::FcvtFromSint, &[I32X4], &[F64X2]),
+                (Opcode::FcvtLowFromSint, &[I8], &[F32]),
+                (Opcode::FcvtLowFromSint, &[I16], &[F32]),
+                (Opcode::FcvtLowFromSint, &[I32], &[F32]),
+                (Opcode::FcvtLowFromSint, &[I64], &[F32]),
+                (Opcode::FcvtLowFromSint, &[I128], &[F32]),
+                (Opcode::FcvtLowFromSint, &[I8X16], &[F32]),
+                (Opcode::FcvtLowFromSint, &[I16X8], &[F32]),
+                (Opcode::FcvtLowFromSint, &[I32X4], &[F32]),
+                (Opcode::FcvtLowFromSint, &[I64X2], &[F32]),
+                (Opcode::FcvtLowFromSint, &[I8], &[F64]),
+                (Opcode::FcvtLowFromSint, &[I16], &[F64]),
+                (Opcode::FcvtLowFromSint, &[I32], &[F64]),
+                (Opcode::FcvtLowFromSint, &[I64], &[F64]),
+                (Opcode::FcvtLowFromSint, &[I128], &[F64]),
+                (Opcode::FcvtLowFromSint, &[I8X16], &[F64]),
+                (Opcode::FcvtLowFromSint, &[I16X8], &[F64]),
+                (Opcode::FcvtLowFromSint, &[I32X4], &[F64]),
+                (Opcode::FcvtLowFromSint, &[I64X2], &[F64]),
+                (Opcode::FcvtLowFromSint, &[I8], &[F32X4]),
+                (Opcode::FcvtLowFromSint, &[I16], &[F32X4]),
+                (Opcode::FcvtLowFromSint, &[I32], &[F32X4]),
+                (Opcode::FcvtLowFromSint, &[I64], &[F32X4]),
+                (Opcode::FcvtLowFromSint, &[I128], &[F32X4]),
+                (Opcode::FcvtLowFromSint, &[I8X16], &[F32X4]),
+                (Opcode::FcvtLowFromSint, &[I16X8], &[F32X4]),
+                (Opcode::FcvtLowFromSint, &[I32X4], &[F32X4]),
+                (Opcode::FcvtLowFromSint, &[I64X2], &[F32X4]),
+                (Opcode::FcvtLowFromSint, &[I8], &[F64X2]),
+                (Opcode::FcvtLowFromSint, &[I16], &[F64X2]),
+                (Opcode::FcvtLowFromSint, &[I32], &[F64X2]),
+                (Opcode::FcvtLowFromSint, &[I64], &[F64X2]),
+                (Opcode::FcvtLowFromSint, &[I128], &[F64X2]),
+                (Opcode::FcvtLowFromSint, &[I8X16], &[F64X2]),
+                (Opcode::FcvtLowFromSint, &[I16X8], &[F64X2]),
+                (Opcode::FcvtLowFromSint, &[I64X2], &[F64X2]),
+            )
+        })
+        .collect()
+});
 
 fn inserter_for_format(fmt: InstructionFormat) -> OpcodeInserter {
     match fmt {
@@ -1632,7 +1469,10 @@ fn inserter_for_format(fmt: InstructionFormat) -> OpcodeInserter {
         | InstructionFormat::Brif
         | InstructionFormat::Jump
         | InstructionFormat::MultiAry => {
-            panic!("Control-flow instructions should be handled by 'insert_terminator'")
+            panic!(
+                "Control-flow instructions should be handled by 'insert_terminator': {:?}",
+                fmt
+            )
         }
     }
 }
@@ -1673,7 +1513,7 @@ struct Resources {
     blocks: Vec<(Block, BlockSignature)>,
     blocks_without_params: Vec<Block>,
     block_terminators: Vec<BlockTerminator>,
-    func_refs: Vec<(Signature, FuncRef)>,
+    func_refs: Vec<(Signature, SigRef, FuncRef)>,
     stack_slots: Vec<(StackSlot, StackSize)>,
     usercalls: Vec<(UserExternalName, Signature)>,
     libcalls: Vec<LibCall>,
@@ -1989,17 +1829,17 @@ where
     /// Fills the current block with random instructions
     fn generate_instructions(&mut self, builder: &mut FunctionBuilder) -> Result<()> {
         for _ in 0..self.param(&self.config.instructions_per_block)? {
-            let (op, args, rets) = *self.u.choose(OPCODE_SIGNATURES)?;
+            let (op, args, rets) = self.u.choose(&OPCODE_SIGNATURES)?;
 
             // We filter out instructions that aren't supported by the target at this point instead
             // of building a single vector of valid instructions at the beginning of function
             // generation, to avoid invalidating the corpus when instructions are enabled/disabled.
-            if !valid_for_target(&self.target_triple, op, args, rets) {
+            if !valid_for_target(&self.target_triple, *op, &args, &rets) {
                 return Err(arbitrary::Error::IncorrectFormat.into());
             }
 
             let inserter = inserter_for_format(op.format());
-            inserter(self, builder, op, args, rets)?;
+            inserter(self, builder, *op, &args, &rets)?;
         }
 
         Ok(())
@@ -2037,7 +1877,9 @@ where
                 colocated: self.u.arbitrary()?,
             });
 
-            self.resources.func_refs.push((signature, func_ref));
+            self.resources
+                .func_refs
+                .push((signature, sig_ref, func_ref));
         }
 
         Ok(())
@@ -2340,191 +2182,3 @@ where
         Ok(func)
     }
 }
-
-#[cfg(test)]
-mod tests {
-
-    use super::OPCODE_SIGNATURES;
-    use cranelift::codegen::ir::{instructions::ResolvedConstraint, types::*, Opcode, Type};
-    use std::collections::HashMap;
-
-    /// The list of opcodes that we exclude from the analysis. This should only be instructions
-    /// that affect control flow, as everything else should be handled by the general machinery in
-    /// function_generator.
-    ///
-    /// NOTE: This list should not grow, and ultimately should just be the set of instructions that
-    /// need special handling outside of `generate_instructions`.
-    const SKIPPED_OPCODES: &[Opcode] = &[
-        // These opcodes have special handling in cranelift-fuzzgen
-        Opcode::Call,
-        Opcode::Return,
-        Opcode::Jump,
-        Opcode::Brif,
-        Opcode::BrTable,
-        // TODO: ExtractVector produces dynamic vectors, and those cause a panic in
-        // `constraint.result_type`.
-        Opcode::ExtractVector,
-        // These opcodes are known to have invalid signatures, but the specific types chosen are
-        // not used by the insertion strategy for that format. They can be removed when their
-        // entries in OPCODE_SIGNATURES have been fixed
-        Opcode::Load,
-        Opcode::Store,
-        Opcode::AtomicLoad,
-        Opcode::AtomicStore,
-        Opcode::AtomicCas,
-        Opcode::AtomicRmw,
-        Opcode::Sload8,
-        Opcode::Sload16,
-        Opcode::Sload32,
-        Opcode::Uload8,
-        Opcode::Uload16,
-        Opcode::Uload32,
-        Opcode::Istore8,
-        Opcode::Istore16,
-        Opcode::Istore32,
-    ];
-
-    /// This is the set of types that we know how to fuzz in cranelift. It's not specialized by
-    /// targets, as we expect any target-specific support for things like SIMD to be expressed in
-    /// the `function_generator::valid_for_target` predicate instead.
-    const TYPES: &[Type] = &[
-        I8, I16, I32, I64, I128, // Scalar Integers
-        F32, F64, // Scalar Floats
-        I8X16, I16X8, I32X4, I64X2, // SIMD Integers
-        F32X4, F64X2, // SIMD Floats
-    ];
-
-    /// Generate all instantiations of all opcodes in cranelift, minus those named in
-    /// [SKIPPED_OPCODES].
-    fn instruction_instantiations<'a>() -> Vec<(Opcode, Vec<Type>, Vec<Type>)> {
-        let mut insts = vec![];
-
-        for op in Opcode::all() {
-            if SKIPPED_OPCODES.contains(op) {
-                continue;
-            }
-
-            let constraints = op.constraints();
-
-            let ctrl_types = if let Some(ctrls) = constraints.ctrl_typeset() {
-                Vec::from_iter(TYPES.iter().copied().filter(|ty| ctrls.contains(*ty)))
-            } else {
-                vec![INVALID]
-            };
-
-            for ctrl_type in ctrl_types {
-                let rets = Vec::from_iter(
-                    (0..constraints.num_fixed_results())
-                        .map(|i| constraints.result_type(i, ctrl_type)),
-                );
-
-                // Cols is a vector whose length will match `num_fixed_value_arguments`, and whose
-                // elements will be vectors of types that are valid for that fixed argument
-                // position.
-                let mut cols = vec![];
-
-                for i in 0..constraints.num_fixed_value_arguments() {
-                    match constraints.value_argument_constraint(i, ctrl_type) {
-                        ResolvedConstraint::Bound(ty) => cols.push(Vec::from([ty])),
-                        ResolvedConstraint::Free(tys) => cols.push(Vec::from_iter(
-                            TYPES.iter().copied().filter(|ty| tys.contains(*ty)),
-                        )),
-                    }
-                }
-
-                // Generate the cartesian product of cols to produce a vector of argument lists,
-                // argss. The argss vector is seeded with the empty argument list, so there's an
-                // initial value to be extended in the loop below.
-                let mut argss = vec![vec![]];
-                let mut cols = cols.as_slice();
-                while let Some((col, rest)) = cols.split_last() {
-                    cols = rest;
-
-                    let mut next = vec![];
-                    for current in argss.iter() {
-                        // Extend the front of each argument candidate with every type in `col`.
-                        for ty in col {
-                            let mut args = vec![*ty];
-                            args.extend_from_slice(&current);
-                            next.push(args);
-                        }
-                    }
-
-                    let _ = std::mem::replace(&mut argss, next);
-                }
-
-                for args in argss {
-                    insts.push((*op, args, rets.clone()));
-                }
-            }
-        }
-
-        insts
-    }
-
-    #[derive(Eq, PartialEq, Debug)]
-    struct Inst<'a> {
-        args: &'a [Type],
-        rets: &'a [Type],
-    }
-
-    fn build_sig_map<'a, T>(sigs: &'a [(Opcode, T, T)]) -> HashMap<Opcode, Vec<Inst<'a>>>
-    where
-        T: AsRef<[Type]>,
-    {
-        let mut insts = HashMap::<Opcode, Vec<Inst<'a>>>::default();
-
-        for (op, args, rets) in sigs {
-            insts.entry(*op).or_default().push(Inst {
-                args: args.as_ref(),
-                rets: rets.as_ref(),
-            });
-        }
-
-        insts
-    }
-
-    #[test]
-    fn validate_opcode_signatures() {
-        // We could instead use the instruction constraints to validate the entries in
-        // OPCODE_SIGNATURES directly, but generating all instantiations gives us the ability to
-        // also generate the complement of signatures that we don't currently handle in the future.
-        let all_ops = instruction_instantiations();
-        let everything = build_sig_map(&all_ops);
-        let fuzzed = build_sig_map(OPCODE_SIGNATURES);
-
-        let mut found_errs = false;
-        let mut unknown = vec![];
-        for (op, insts) in fuzzed.iter() {
-            if let Some(known_insts) = everything.get(op) {
-                let invalid =
-                    Vec::from_iter(insts.iter().filter(|inst| !known_insts.contains(inst)));
-                if !invalid.is_empty() {
-                    found_errs = true;
-                    println!("# Invalid instantiations for Opcode::{:?}", op);
-                    for inst in invalid {
-                        println!("- args: `{:?}`, rets: `{:?}`", inst.args, inst.rets);
-                    }
-                }
-            } else {
-                if !SKIPPED_OPCODES.contains(op) {
-                    unknown.push(*op);
-                }
-            }
-        }
-
-        if !unknown.is_empty() {
-            found_errs = true;
-            println!();
-            println!("# Instructions without known instantiations");
-            for op in unknown {
-                println!("- Opcode::{:?}", op);
-            }
-        }
-
-        assert!(
-            !found_errs,
-            "Discovered inconsistent entries in OPCODE_SIGNATURES"
-        );
-    }
-}
diff --git a/cranelift/fuzzgen/src/lib.rs b/cranelift/fuzzgen/src/lib.rs
index 26cca8363..e8e649314 100644
--- a/cranelift/fuzzgen/src/lib.rs
+++ b/cranelift/fuzzgen/src/lib.rs
@@ -6,7 +6,9 @@ use arbitrary::{Arbitrary, Unstructured};
 use cranelift::codegen::data_value::DataValue;
 use cranelift::codegen::ir::{types::*, UserExternalName, UserFuncName};
 use cranelift::codegen::ir::{Function, LibCall};
+use cranelift::codegen::isa::{self, Builder};
 use cranelift::codegen::Context;
+use cranelift::prelude::settings::SettingKind;
 use cranelift::prelude::*;
 use cranelift_arbitrary::CraneliftArbitrary;
 use cranelift_native::builder_with_options;
@@ -22,6 +24,15 @@ pub use print::PrintableTestCase;
 
 pub type TestCaseInput = Vec<DataValue>;
 
+pub enum IsaFlagGen {
+    /// When generating ISA flags, ensure that they are all supported by
+    /// the current host.
+    Host,
+    /// All flags available in cranelift are allowed to be generated.
+    /// We also allow generating all possible values for each enum flag.
+    All,
+}
+
 pub struct FuzzGen<'r, 'data>
 where
     'data: 'r,
@@ -228,4 +239,56 @@ where
 
         Ok(Flags::new(builder))
     }
+
+    /// Generate a random set of ISA flags and apply them to a Builder.
+    ///
+    /// Based on `mode` we can either allow all flags, or just the subset that is
+    /// supported by the current host.
+    ///
+    /// In all cases only a subset of the allowed flags is applied to the builder.
+    pub fn set_isa_flags(&mut self, builder: &mut Builder, mode: IsaFlagGen) -> Result<()> {
+        // `max_isa` is the maximal set of flags that we can use.
+        let max_builder = match mode {
+            IsaFlagGen::All => {
+                let mut max_builder = isa::lookup(builder.triple().clone())?;
+
+                for flag in max_builder.iter() {
+                    match flag.kind {
+                        SettingKind::Bool => {
+                            max_builder.enable(flag.name)?;
+                        }
+                        SettingKind::Enum => {
+                            // Since these are enums there isn't a "max" value per se, pick one at random.
+                            let value = self.u.choose(flag.values.unwrap())?;
+                            max_builder.set(flag.name, value)?;
+                        }
+                        SettingKind::Preset => {
+                            // Presets are just special flags that combine other flags, we don't
+                            // want to enable them directly, just the underlying flags.
+                        }
+                        _ => todo!(),
+                    };
+                }
+                max_builder
+            }
+            // Use `cranelift-native` to do feature detection for us.
+            IsaFlagGen::Host => builder_with_options(true)
+                .expect("Unable to build a TargetIsa for the current host"),
+        };
+        // Cranelift has a somwhat weird API for this, but we need to build the final `TargetIsa` to be able
+        // to extract the values for the ISA flags. We need that to use the `string_value()` that formats
+        // the values so that we can pass it into the builder again.
+        let max_isa = max_builder.finish(Flags::new(settings::builder()))?;
+
+        // We give each of the flags a chance of being copied over. Otherwise we keep the default.
+        for value in max_isa.isa_flags().iter() {
+            let should_copy = bool::arbitrary(self.u)?;
+            if !should_copy {
+                continue;
+            }
+            builder.set(value.name, &value.value_string())?;
+        }
+
+        Ok(())
+    }
 }
diff --git a/cranelift/fuzzgen/src/print.rs b/cranelift/fuzzgen/src/print.rs
index e74f0f3a8..238f92fcf 100644
--- a/cranelift/fuzzgen/src/print.rs
+++ b/cranelift/fuzzgen/src/print.rs
@@ -1,6 +1,6 @@
 use cranelift::codegen::data_value::DataValue;
 use cranelift::codegen::ir::Function;
-use cranelift::prelude::settings;
+use cranelift::prelude::settings::{self, SettingKind};
 use cranelift::prelude::*;
 use std::fmt;
 
@@ -70,7 +70,9 @@ impl<'a> fmt::Debug for PrintableTestCase<'a> {
 
         write_non_default_flags(f, self.isa.flags())?;
 
-        writeln!(f, "target {}\n", self.isa.triple().architecture)?;
+        write!(f, "target {} ", self.isa.triple().architecture)?;
+        write_non_default_isa_flags(f, &self.isa)?;
+        write!(f, "\n\n")?;
 
         // Print the functions backwards, so that the main function is printed last
         // and near the test inputs for run test cases.
@@ -128,3 +130,33 @@ fn write_non_default_flags(f: &mut fmt::Formatter<'_>, flags: &settings::Flags)
 
     Ok(())
 }
+
+/// Print non default ISA flags in a single line, as used in `target` declarations.
+fn write_non_default_isa_flags(
+    f: &mut fmt::Formatter<'_>,
+    isa: &isa::OwnedTargetIsa,
+) -> fmt::Result {
+    let default_isa = isa::lookup(isa.triple().clone())
+        .unwrap()
+        .finish(isa.flags().clone())
+        .unwrap();
+
+    for (default, flag) in default_isa.isa_flags().iter().zip(isa.isa_flags()) {
+        assert_eq!(default.name, flag.name);
+
+        // Skip default flags, putting them all out there is too verbose.
+        if default.value_string() == flag.value_string() {
+            continue;
+        }
+
+        // On boolean flags we can use the shorthand syntax instead of just specifying the flag name.
+        // This is slightly neater than the full syntax.
+        if flag.kind() == SettingKind::Bool && flag.value_string() == "true" {
+            write!(f, "{} ", flag.name)?;
+        } else {
+            write!(f, "{}={} ", flag.name, flag.value_string())?;
+        }
+    }
+
+    Ok(())
+}
diff --git a/cranelift/isle/docs/language-reference.md b/cranelift/isle/docs/language-reference.md
index c3f9558be..0f430e411 100644
--- a/cranelift/isle/docs/language-reference.md
+++ b/cranelift/isle/docs/language-reference.md
@@ -1028,6 +1028,24 @@ after the above declaration instead of the `extern`), the right-hand
 side expression of each rule that rewrites the term is also checked
 for purity.
 
+#### `partial` Expressions
+
+ISLE's `partial` keyword on a term indicates that the term's 
+constructors may fail to match, otherwise, the ISLE compiler assumes 
+the term's constructors are infallible.
+
+For example, the following term's constructor only matches if the value
+is zero:
+
+```
+;; Match any zero value.
+(decl pure partial is_zero_value (Value) Value)
+(extern constructor is_zero_value is_zero_value)
+```
+
+Internal constructors without the `partial` keyword can 
+only use other constructors that also do not have the `partial` keyword.
+
 #### `if` Shorthand
 
 It is a fairly common idiom that if-let clauses are used as predicates
@@ -1106,7 +1124,7 @@ Rust. The basic principles are:
    commit and start to invoke constructors to build the right-hand
    side.
    
-   Said another way, the principle is that left-hand sides are
+   Said another way, the principle is that left-hand sides can be
    fallible, and have no side-effects as they execute; right-hand
    sides, in contrast, are infallible. This simplifies the control
    flow and makes reasoning about side-effects (especially with
@@ -1162,13 +1180,12 @@ and returns a `U`.
 
 External constructors are infallible: that is, they must succeed, and
 always return their return type. In contrast, internal constructors
-are fallible because they are implemented by a list of rules whose
-patterns may not cover the entire domain. If fallible behavior is
-needed when invoking external Rust code, that behavior should occur in
-an extractor (see below) instead: only pattern left-hand sides are
-meant to be fallible. Note, incidentally, that fallibility in a
-constructor does not backtrack to try other rules; instead it just
-trickles the `None` failure all the way up.
+can be fallible because they are implemented by a list of rules whose
+patterns may not cover the entire domain (in which case, the term 
+should be marked `partial`). If fallible behavior is needed when 
+invoking external Rust code, that behavior should occur in an extractor 
+(see below) instead: only pattern left-hand sides are meant to be 
+fallible. 
 
 #### Extractors
 
diff --git a/crates/wasmtime/src/store.rs b/crates/wasmtime/src/store.rs
index 9a322fd6a..8b7f5f3e6 100644
--- a/crates/wasmtime/src/store.rs
+++ b/crates/wasmtime/src/store.rs
@@ -425,11 +425,13 @@ enum OutOfGas {
 
 /// What to do when the engine epoch reaches the deadline for a Store
 /// during execution of a function using that store.
+#[derive(Default)]
 enum EpochDeadline<T> {
     /// Return early with a trap.
+    #[default]
     Trap,
     /// Call a custom deadline handler.
-    Callback(Box<dyn FnMut(&mut T) -> Result<u64> + Send + Sync>),
+    Callback(Box<dyn FnMut(StoreContextMut<T>) -> Result<u64> + Send + Sync>),
     /// Extend the deadline by the specified number of ticks after
     /// yielding to the async executor loop.
     #[cfg(feature = "async")]
@@ -932,7 +934,7 @@ impl<T> Store<T> {
     /// for an introduction to epoch-based interruption.
     pub fn epoch_deadline_callback(
         &mut self,
-        callback: impl FnMut(&mut T) -> Result<u64> + Send + Sync + 'static,
+        callback: impl FnMut(StoreContextMut<T>) -> Result<u64> + Send + Sync + 'static,
     ) {
         self.inner.epoch_deadline_callback(Box::new(callback));
     }
@@ -1975,10 +1977,13 @@ unsafe impl<T> wasmtime_runtime::Store for StoreInner<T> {
     }
 
     fn new_epoch(&mut self) -> Result<u64, anyhow::Error> {
-        return match &mut self.epoch_deadline_behavior {
+        // Temporarily take the configured behavior to avoid mutably borrowing
+        // multiple times.
+        let mut behavior = std::mem::take(&mut self.epoch_deadline_behavior);
+        let delta_result = match &mut behavior {
             EpochDeadline::Trap => Err(Trap::Interrupt.into()),
             EpochDeadline::Callback(callback) => {
-                let delta = callback(&mut self.data)?;
+                let delta = callback((&mut *self).as_context_mut())?;
                 // Set a new deadline and return the new epoch deadline so
                 // the Wasm code doesn't have to reload it.
                 self.set_epoch_deadline(delta);
@@ -1998,6 +2003,10 @@ unsafe impl<T> wasmtime_runtime::Store for StoreInner<T> {
                 Ok(self.get_epoch_deadline())
             }
         };
+
+        // Put back the original behavior which was replaced by `take`.
+        self.epoch_deadline_behavior = behavior;
+        delta_result
     }
 }
 
@@ -2022,7 +2031,7 @@ impl<T> StoreInner<T> {
 
     fn epoch_deadline_callback(
         &mut self,
-        callback: Box<dyn FnMut(&mut T) -> Result<u64> + Send + Sync>,
+        callback: Box<dyn FnMut(StoreContextMut<T>) -> Result<u64> + Send + Sync>,
     ) {
         self.epoch_deadline_behavior = EpochDeadline::Callback(callback);
     }
diff --git a/fuzz/fuzz_targets/cranelift-fuzzgen.rs b/fuzz/fuzz_targets/cranelift-fuzzgen.rs
index b20755509..addf4f71f 100644
--- a/fuzz/fuzz_targets/cranelift-fuzzgen.rs
+++ b/fuzz/fuzz_targets/cranelift-fuzzgen.rs
@@ -179,9 +179,10 @@ impl TestCase {
 
         // TestCase is meant to be consumed by a runner, so we make the assumption here that we're
         // generating a TargetIsa for the host.
-        let builder =
+        let mut builder =
             builder_with_options(true).expect("Unable to build a TargetIsa for the current host");
         let flags = gen.generate_flags(builder.triple().architecture)?;
+        gen.set_isa_flags(&mut builder, IsaFlagGen::Host)?;
         let isa = builder.finish(flags)?;
 
         // When generating functions, we allow each function to call any function that has
diff --git a/fuzz/fuzz_targets/cranelift-icache.rs b/fuzz/fuzz_targets/cranelift-icache.rs
index 886d158ac..aa4dc7c79 100644
--- a/fuzz/fuzz_targets/cranelift-icache.rs
+++ b/fuzz/fuzz_targets/cranelift-icache.rs
@@ -48,13 +48,15 @@ impl FunctionWithIsa {
         // a supported one, so that the same fuzz input works across different build
         // configurations.
         let target = u.choose(isa::ALL_ARCHITECTURES)?;
-        let builder = isa::lookup_by_name(target).map_err(|_| arbitrary::Error::IncorrectFormat)?;
+        let mut builder =
+            isa::lookup_by_name(target).map_err(|_| arbitrary::Error::IncorrectFormat)?;
         let architecture = builder.triple().architecture;
 
         let mut gen = FuzzGen::new(u);
         let flags = gen
             .generate_flags(architecture)
             .map_err(|_| arbitrary::Error::IncorrectFormat)?;
+        gen.set_isa_flags(&mut builder, IsaFlagGen::All)?;
         let isa = builder
             .finish(flags)
             .map_err(|_| arbitrary::Error::IncorrectFormat)?;


Test patch:
diff --git a/cranelift/codegen/src/isa/s390x/inst/emit_tests.rs b/cranelift/codegen/src/isa/s390x/inst/emit_tests.rs
index 003365cc0..c33f48964 100644
--- a/cranelift/codegen/src/isa/s390x/inst/emit_tests.rs
+++ b/cranelift/codegen/src/isa/s390x/inst/emit_tests.rs
@@ -7027,22 +7027,22 @@ fn test_s390x_binemit() {
         "br %r14",
     ));
 
-    insns.push((Inst::Debugtrap, "0001", "debugtrap"));
+    insns.push((Inst::Debugtrap, "0001", ".word 0x0001 # debugtrap"));
 
     insns.push((
         Inst::Trap {
             trap_code: TrapCode::StackOverflow,
         },
         "0000",
-        "trap",
+        ".word 0x0000 # trap=stk_ovf",
     ));
     insns.push((
         Inst::TrapIf {
             cond: Cond::from_mask(1),
             trap_code: TrapCode::StackOverflow,
         },
-        "A7E400030000",
-        "jno 6 ; trap",
+        "C01400000001",
+        "jgo .+2 # trap=stk_ovf",
     ));
 
     insns.push((
diff --git a/cranelift/filetests/filetests/isa/aarch64/iconst-imm12_from_negated.isle b/cranelift/filetests/filetests/isa/aarch64/iconst-imm12_from_negated.isle
index 61067e316..1b9f21058 100644
--- a/cranelift/filetests/filetests/isa/aarch64/iconst-imm12_from_negated.isle
+++ b/cranelift/filetests/filetests/isa/aarch64/iconst-imm12_from_negated.isle
@@ -24,7 +24,6 @@ block0(v0: i64):
 ;   ret
 
 ;; 4294967295 is zero-extended i32 -1
-;; Result should use immediate but currently doesn't
 function %b(i32) -> i32 {
 block0(v0: i32):
     v1 = iconst.i32 4294967295 
@@ -34,18 +33,15 @@ block0(v0: i32):
 
 ; VCode:
 ; block0:
-;   movn w2, #0
-;   add w0, w0, w2
+;   sub w0, w0, #1
 ;   ret
 ; 
 ; Disassembled:
 ; block0: ; offset 0x0
-;   mov w2, #-1
-;   add w0, w0, w2
+;   sub w0, w0, #1
 ;   ret
 
 ;; 65535 is zero-extended i16 -1
-;; Result should use immediate but currently doesn't
 function %a(i16) -> i16 {
 block0(v0: i16):
     v1 = iconst.i16 65535
@@ -55,12 +51,122 @@ block0(v0: i16):
 
 ; VCode:
 ; block0:
-;   movz w2, #65535
-;   add w0, w0, w2
+;   sub w0, w0, #1
 ;   ret
 ; 
 ; Disassembled:
 ; block0: ; offset 0x0
-;   mov w2, #0xffff
-;   add w0, w0, w2
+;   sub w0, w0, #1
+;   ret
+
+;; Swapped order to trigger commutative rule
+function %c(i64) -> i64 {
+block0(v0: i64):
+    v1 = iconst.i64 -1
+    v3 = iadd v1, v0
+    return v3
+}
+
+; VCode:
+; block0:
+;   sub x0, x0, #1
+;   ret
+; 
+; Disassembled:
+; block0: ; offset 0x0
+;   sub x0, x0, #1
+;   ret
+
+;; Swapped order to trigger commutative rule
+;; 4294967295 is zero-extended i32 -1
+function %b(i32) -> i32 {
+block0(v0: i32):
+    v1 = iconst.i32 4294967295 
+    v3 = iadd v1, v0
+    return v3
+}
+
+; VCode:
+; block0:
+;   sub w0, w0, #1
+;   ret
+; 
+; Disassembled:
+; block0: ; offset 0x0
+;   sub w0, w0, #1
+;   ret
+
+;; Swapped order to trigger commutative rule
+;; 65535 is zero-extended i16 -1
+function %a(i16) -> i16 {
+block0(v0: i16):
+    v1 = iconst.i16 65535
+    v3 = iadd v1, v0
+    return v3
+}
+
+; VCode:
+; block0:
+;   sub w0, w0, #1
+;   ret
+; 
+; Disassembled:
+; block0: ; offset 0x0
+;   sub w0, w0, #1
+;   ret
+
+;; Version sub -> add
+function %c(i64) -> i64 {
+block0(v0: i64):
+    v1 = iconst.i64 -1
+    v3 = isub v0, v1
+    return v3
+}
+
+; VCode:
+; block0:
+;   add x0, x0, #1
+;   ret
+; 
+; Disassembled:
+; block0: ; offset 0x0
+;   add x0, x0, #1
+;   ret
+
+;; Version sub -> add
+;; 4294967295 is zero-extended i32 -1
+function %b(i32) -> i32 {
+block0(v0: i32):
+    v1 = iconst.i32 4294967295 
+    v3 = isub v0, v1
+    return v3
+}
+
+; VCode:
+; block0:
+;   add w0, w0, #1
+;   ret
+; 
+; Disassembled:
+; block0: ; offset 0x0
+;   add w0, w0, #1
+;   ret
+
+;; Version sub -> add
+;; 65535 is zero-extended i16 -1
+function %a(i16) -> i16 {
+block0(v0: i16):
+    v1 = iconst.i16 65535
+    v3 = isub v0, v1
+    return v3
+}
+
+; VCode:
+; block0:
+;   add w0, w0, #1
+;   ret
+; 
+; Disassembled:
+; block0: ; offset 0x0
+;   add w0, w0, #1
 ;   ret
diff --git a/cranelift/filetests/filetests/isa/riscv64/bitops.clif b/cranelift/filetests/filetests/isa/riscv64/bitops.clif
index afe894948..23aaa6ba5 100644
--- a/cranelift/filetests/filetests/isa/riscv64/bitops.clif
+++ b/cranelift/filetests/filetests/isa/riscv64/bitops.clif
@@ -385,28 +385,25 @@ block0(v0: i128):
 
 ; VCode:
 ; block0:
-;   mv t0,a1
-;   clz a2,t0##ty=i64 tmp=a3 step=a1
+;   clz a2,a1##ty=i64 tmp=a4 step=a3
 ;   clz a6,a0##ty=i64 tmp=a4 step=a5
-;   li t3,64
-;   select_reg t0,a6,zero##condition=(t3 eq a2)
-;   add a0,a2,t0
+;   select_reg t3,a6,zero##condition=(a1 eq zero)
+;   add a0,a2,t3
 ;   li a1,0
 ;   ret
 ; 
 ; Disassembled:
 ; block0: ; offset 0x0
-;   ori t0, a1, 0
 ;   ori a2, zero, 0
-;   addi a1, zero, 0x40
-;   addi a3, zero, 1
-;   slli a3, a3, 0x3f
-;   blez a1, 0x1c
-;   and t5, a3, t0
+;   addi a3, zero, 0x40
+;   addi a4, zero, 1
+;   slli a4, a4, 0x3f
+;   blez a3, 0x1c
+;   and t5, a4, a1
 ;   bne zero, t5, 0x14
 ;   addi a2, a2, 1
-;   addi a1, a1, -1
-;   srli a3, a3, 1
+;   addi a3, a3, -1
+;   srli a4, a4, 1
 ;   j -0x18
 ;   ori a6, zero, 0
 ;   addi a5, zero, 0x40
@@ -419,12 +416,11 @@ block0(v0: i128):
 ;   addi a5, a5, -1
 ;   srli a4, a4, 1
 ;   j -0x18
-;   addi t3, zero, 0x40
-;   beq t3, a2, 0xc
-;   ori t0, zero, 0
+;   beqz a1, 0xc
+;   ori t3, zero, 0
 ;   j 8
-;   ori t0, a6, 0
-;   add a0, a2, t0
+;   ori t3, a6, 0
+;   add a0, a2, t3
 ;   mv a1, zero
 ;   ret
 
@@ -438,8 +434,8 @@ block0(v0: i8):
 ; block0:
 ;   slli t2,a0,56
 ;   srai a1,t2,56
-;   not a3,a0
-;   select_reg a5,a3,a0##condition=(a1 slt zero)
+;   not a3,a1
+;   select_reg a5,a3,a1##condition=(a1 slt zero)
 ;   clz t4,a5##ty=i8 tmp=a7 step=t3
 ;   addi a0,t4,-1
 ;   ret
@@ -448,9 +444,9 @@ block0(v0: i8):
 ; block0: ; offset 0x0
 ;   slli t2, a0, 0x38
 ;   srai a1, t2, 0x38
-;   not a3, a0
+;   not a3, a1
 ;   bltz a1, 0xc
-;   ori a5, a0, 0
+;   ori a5, a1, 0
 ;   j 8
 ;   ori a5, a3, 0
 ;   ori t4, zero, 0
@@ -477,8 +473,8 @@ block0(v0: i16):
 ; block0:
 ;   slli t2,a0,48
 ;   srai a1,t2,48
-;   not a3,a0
-;   select_reg a5,a3,a0##condition=(a1 slt zero)
+;   not a3,a1
+;   select_reg a5,a3,a1##condition=(a1 slt zero)
 ;   clz t4,a5##ty=i16 tmp=a7 step=t3
 ;   addi a0,t4,-1
 ;   ret
@@ -487,9 +483,9 @@ block0(v0: i16):
 ; block0: ; offset 0x0
 ;   slli t2, a0, 0x30
 ;   srai a1, t2, 0x30
-;   not a3, a0
+;   not a3, a1
 ;   bltz a1, 0xc
-;   ori a5, a0, 0
+;   ori a5, a1, 0
 ;   j 8
 ;   ori a5, a3, 0
 ;   ori t4, zero, 0
@@ -515,8 +511,8 @@ block0(v0: i32):
 ; VCode:
 ; block0:
 ;   sext.w t2,a0
-;   not a1,a0
-;   select_reg a3,a1,a0##condition=(t2 slt zero)
+;   not a1,t2
+;   select_reg a3,a1,t2##condition=(t2 slt zero)
 ;   clz a7,a3##ty=i32 tmp=a5 step=a6
 ;   addi a0,a7,-1
 ;   ret
@@ -524,9 +520,9 @@ block0(v0: i32):
 ; Disassembled:
 ; block0: ; offset 0x0
 ;   sext.w t2, a0
-;   not a1, a0
+;   not a1, t2
 ;   bltz t2, 0xc
-;   ori a3, a0, 0
+;   ori a3, t2, 0
 ;   j 8
 ;   ori a3, a1, 0
 ;   ori a7, zero, 0
@@ -592,11 +588,10 @@ block0(v0: i128):
 ;   select_reg a6,a4,a1##condition=(a1 slt zero)
 ;   clz t0,a6##ty=i64 tmp=t3 step=t4
 ;   clz a1,a2##ty=i64 tmp=t2 step=a0
-;   li a3,64
-;   select_reg a5,a1,zero##condition=(a3 eq t0)
-;   add a7,t0,a5
-;   li t4,0
-;   addi a0,a7,-1
+;   select_reg a3,a1,zero##condition=(a6 eq zero)
+;   add a5,t0,a3
+;   li a7,0
+;   addi a0,a5,-1
 ;   li a1,0
 ;   ret
 ; 
@@ -632,14 +627,13 @@ block0(v0: i128):
 ;   addi a0, a0, -1
 ;   srli t2, t2, 1
 ;   j -0x18
-;   addi a3, zero, 0x40
-;   beq a3, t0, 0xc
-;   ori a5, zero, 0
+;   beqz a6, 0xc
+;   ori a3, zero, 0
 ;   j 8
-;   ori a5, a1, 0
-;   add a7, t0, a5
-;   mv t4, zero
-;   addi a0, a7, -1
+;   ori a3, a1, 0
+;   add a5, t0, a3
+;   mv a7, zero
+;   addi a0, a5, -1
 ;   mv a1, zero
 ;   ret
 
@@ -759,44 +753,42 @@ block0(v0: i128):
 
 ; VCode:
 ; block0:
-;   mv t0,a0
-;   ctz a2,t0##ty=i64 tmp=a0 step=a3
-;   ctz a6,a1##ty=i64 tmp=a4 step=a5
-;   li t3,64
-;   select_reg t0,a6,zero##condition=(t3 eq a2)
-;   add a0,a2,t0
+;   mv t4,a1
+;   ctz a2,t4##ty=i64 tmp=a3 step=a1
+;   ctz a6,a0##ty=i64 tmp=a4 step=a5
+;   select_reg t3,a2,zero##condition=(a0 eq zero)
+;   add a0,a6,t3
 ;   li a1,0
 ;   ret
 ; 
 ; Disassembled:
 ; block0: ; offset 0x0
-;   ori t0, a0, 0
+;   ori t4, a1, 0
 ;   ori a2, zero, 0
-;   addi a3, zero, 0x40
-;   addi a0, zero, 1
-;   blez a3, 0x1c
-;   and t5, a0, t0
+;   addi a1, zero, 0x40
+;   addi a3, zero, 1
+;   blez a1, 0x1c
+;   and t5, a3, t4
 ;   bne zero, t5, 0x14
 ;   addi a2, a2, 1
-;   addi a3, a3, -1
-;   slli a0, a0, 1
+;   addi a1, a1, -1
+;   slli a3, a3, 1
 ;   j -0x18
 ;   ori a6, zero, 0
 ;   addi a5, zero, 0x40
 ;   addi a4, zero, 1
 ;   blez a5, 0x1c
-;   and t5, a4, a1
+;   and t5, a4, a0
 ;   bne zero, t5, 0x14
 ;   addi a6, a6, 1
 ;   addi a5, a5, -1
 ;   slli a4, a4, 1
 ;   j -0x18
-;   addi t3, zero, 0x40
-;   beq t3, a2, 0xc
-;   ori t0, zero, 0
+;   beqz a0, 0xc
+;   ori t3, zero, 0
 ;   j 8
-;   ori t0, a6, 0
-;   add a0, a2, t0
+;   ori t3, a2, 0
+;   add a0, a6, t3
 ;   mv a1, zero
 ;   ret
 
diff --git a/cranelift/filetests/filetests/isa/riscv64/cls-zbb.clif b/cranelift/filetests/filetests/isa/riscv64/cls-zbb.clif
new file mode 100644
index 000000000..d6683cbe9
--- /dev/null
+++ b/cranelift/filetests/filetests/isa/riscv64/cls-zbb.clif
@@ -0,0 +1,162 @@
+test compile precise-output
+set unwind_info=false
+target riscv64 has_zbb
+
+
+function %cls_i8(i8) -> i8 {
+block0(v0: i8):
+    v1 = cls v0
+    return v1
+}
+
+; VCode:
+; block0:
+;   sext.b t2,a0
+;   not a1,t2
+;   select_reg a3,a1,t2##condition=(t2 slt zero)
+;   andi a5,a3,255
+;   clz a7,a5
+;   addi t4,a7,-56
+;   addi a0,t4,-1
+;   ret
+; 
+; Disassembled:
+; block0: ; offset 0x0
+;   .byte 0x93, 0x13, 0x45, 0x60
+;   not a1, t2
+;   bltz t2, 0xc
+;   ori a3, t2, 0
+;   j 8
+;   ori a3, a1, 0
+;   andi a5, a3, 0xff
+;   .byte 0x93, 0x98, 0x07, 0x60
+;   addi t4, a7, -0x38
+;   addi a0, t4, -1
+;   ret
+
+function %cls_i16(i16) -> i16 {
+block0(v0: i16):
+    v1 = cls v0
+    return v1
+}
+
+; VCode:
+; block0:
+;   sext.h t2,a0
+;   not a1,t2
+;   select_reg a3,a1,t2##condition=(t2 slt zero)
+;   zext.h a5,a3
+;   clz a7,a5
+;   addi t4,a7,-48
+;   addi a0,t4,-1
+;   ret
+; 
+; Disassembled:
+; block0: ; offset 0x0
+;   .byte 0x93, 0x13, 0x55, 0x60
+;   not a1, t2
+;   bltz t2, 0xc
+;   ori a3, t2, 0
+;   j 8
+;   ori a3, a1, 0
+;   .byte 0xbb, 0xc7, 0x06, 0x08
+;   .byte 0x93, 0x98, 0x07, 0x60
+;   addi t4, a7, -0x30
+;   addi a0, t4, -1
+;   ret
+
+function %cls_i32(i32) -> i32 {
+block0(v0: i32):
+    v1 = cls v0
+    return v1
+}
+
+; VCode:
+; block0:
+;   sext.w t2,a0
+;   not a1,t2
+;   select_reg a3,a1,t2##condition=(t2 slt zero)
+;   clzw a5,a3
+;   addi a0,a5,-1
+;   ret
+; 
+; Disassembled:
+; block0: ; offset 0x0
+;   sext.w t2, a0
+;   not a1, t2
+;   bltz t2, 0xc
+;   ori a3, t2, 0
+;   j 8
+;   ori a3, a1, 0
+;   .byte 0x9b, 0x97, 0x06, 0x60
+;   addi a0, a5, -1
+;   ret
+
+function %cls_i64(i64) -> i64 {
+block0(v0: i64):
+    v1 = cls v0
+    return v1
+}
+
+; VCode:
+; block0:
+;   not t2,a0
+;   select_reg a1,t2,a0##condition=(a0 slt zero)
+;   clz a3,a1
+;   addi a0,a3,-1
+;   ret
+; 
+; Disassembled:
+; block0: ; offset 0x0
+;   not t2, a0
+;   bltz a0, 0xc
+;   ori a1, a0, 0
+;   j 8
+;   ori a1, t2, 0
+;   .byte 0x93, 0x96, 0x05, 0x60
+;   addi a0, a3, -1
+;   ret
+
+function %cls_i128(i128) -> i128 {
+block0(v0: i128):
+    v1 = cls v0
+    return v1
+}
+
+; VCode:
+; block0:
+;   not a2,a0
+;   select_reg a2,a2,a0##condition=(a1 slt zero)
+;   not a4,a1
+;   select_reg a6,a4,a1##condition=(a1 slt zero)
+;   clz t3,a6
+;   clz t0,a2
+;   select_reg t2,t0,zero##condition=(a6 eq zero)
+;   add a1,t3,t2
+;   li a3,0
+;   addi a0,a1,-1
+;   li a1,0
+;   ret
+; 
+; Disassembled:
+; block0: ; offset 0x0
+;   not a2, a0
+;   bltz a1, 8
+;   ori a2, a0, 0
+;   not a4, a1
+;   bltz a1, 0xc
+;   ori a6, a1, 0
+;   j 8
+;   ori a6, a4, 0
+;   .byte 0x13, 0x1e, 0x08, 0x60
+;   .byte 0x93, 0x12, 0x06, 0x60
+;   beqz a6, 0xc
+;   ori t2, zero, 0
+;   j 8
+;   ori t2, t0, 0
+;   add a1, t3, t2
+;   mv a3, zero
+;   addi a0, a1, -1
+;   mv a1, zero
+;   ret
+
diff --git a/cranelift/filetests/filetests/isa/riscv64/clz-zbb.clif b/cranelift/filetests/filetests/isa/riscv64/clz-zbb.clif
new file mode 100644
index 000000000..ff9e83530
--- /dev/null
+++ b/cranelift/filetests/filetests/isa/riscv64/clz-zbb.clif
@@ -0,0 +1,103 @@
+test compile precise-output
+set unwind_info=false
+target riscv64 has_zbb
+
+function %clz_i8(i8) -> i8 {
+block0(v0: i8):
+    v1 = clz v0
+    return v1
+}
+
+; VCode:
+; block0:
+;   andi t2,a0,255
+;   clz a1,t2
+;   addi a0,a1,-56
+;   ret
+; 
+; Disassembled:
+; block0: ; offset 0x0
+;   andi t2, a0, 0xff
+;   .byte 0x93, 0x95, 0x03, 0x60
+;   addi a0, a1, -0x38
+;   ret
+
+function %clz_i16(i16) -> i16 {
+block0(v0: i16):
+    v1 = clz v0
+    return v1
+}
+
+; VCode:
+; block0:
+;   zext.h t2,a0
+;   clz a1,t2
+;   addi a0,a1,-48
+;   ret
+; 
+; Disassembled:
+; block0: ; offset 0x0
+;   .byte 0xbb, 0x43, 0x05, 0x08
+;   .byte 0x93, 0x95, 0x03, 0x60
+;   addi a0, a1, -0x30
+;   ret
+
+function %clz_i32(i32) -> i32 {
+block0(v0: i32):
+    v1 = clz v0
+    return v1
+}
+
+; VCode:
+; block0:
+;   clzw a0,a0
+;   ret
+; 
+; Disassembled:
+; block0: ; offset 0x0
+;   .byte 0x1b, 0x15, 0x05, 0x60
+;   ret
+
+function %clz_i64(i64) -> i64 {
+block0(v0: i64):
+    v1 = clz v0
+    return v1
+}
+
+; VCode:
+; block0:
+;   clz a0,a0
+;   ret
+; 
+; Disassembled:
+; block0: ; offset 0x0
+;   .byte 0x13, 0x15, 0x05, 0x60
+;   ret
+
+function %clz_i128(i128) -> i128 {
+block0(v0: i128):
+    v1 = clz v0
+    return v1
+}
+
+; VCode:
+; block0:
+;   clz a2,a1
+;   clz a3,a0
+;   select_reg a4,a3,zero##condition=(a1 eq zero)
+;   add a0,a2,a4
+;   li a1,0
+;   ret
+; 
+; Disassembled:
+; block0: ; offset 0x0
+;   .byte 0x13, 0x96, 0x05, 0x60
+;   .byte 0x93, 0x16, 0x05, 0x60
+;   beqz a1, 0xc
+;   ori a4, zero, 0
+;   j 8
+;   ori a4, a3, 0
+;   add a0, a2, a4
+;   mv a1, zero
+;   ret
+
diff --git a/cranelift/filetests/filetests/isa/riscv64/ctz-zbb-zbs.clif b/cranelift/filetests/filetests/isa/riscv64/ctz-zbb-zbs.clif
new file mode 100644
index 000000000..50e3137af
--- /dev/null
+++ b/cranelift/filetests/filetests/isa/riscv64/ctz-zbb-zbs.clif
@@ -0,0 +1,71 @@
+test compile precise-output
+set unwind_info=false
+target riscv64 has_zbb has_zbs
+
+function %ctz_i8(i8) -> i8 {
+block0(v0: i8):
+    v1 = ctz v0
+    return v1
+}
+
+; VCode:
+; block0:
+;   bseti t2,a0,8
+;   ctzw a0,t2
+;   ret
+; 
+; Disassembled:
+; block0: ; offset 0x0
+;   .byte 0x93, 0x13, 0x85, 0x28
+;   .byte 0x1b, 0x95, 0x13, 0x60
+;   ret
+
+function %ctz_i16(i16) -> i16 {
+block0(v0: i16):
+    v1 = ctz v0
+    return v1
+}
+
+; VCode:
+; block0:
+;   bseti t2,a0,16
+;   ctzw a0,t2
+;   ret
+; 
+; Disassembled:
+; block0: ; offset 0x0
+;   .byte 0x93, 0x13, 0x05, 0x29
+;   .byte 0x1b, 0x95, 0x13, 0x60
+;   ret
+
+function %ctz_i32(i32) -> i32 {
+block0(v0: i32):
+    v1 = ctz v0
+    return v1
+}
+
+; VCode:
+; block0:
+;   ctzw a0,a0
+;   ret
+; 
+; Disassembled:
+; block0: ; offset 0x0
+;   .byte 0x1b, 0x15, 0x15, 0x60
+;   ret
+
+function %ctz_i64(i64) -> i64 {
+block0(v0: i64):
+    v1 = ctz v0
+    return v1
+}
+
+; VCode:
+; block0:
+;   ctz a0,a0
+;   ret
+; 
+; Disassembled:
+; block0: ; offset 0x0
+;   .byte 0x13, 0x15, 0x15, 0x60
+;   ret
diff --git a/cranelift/filetests/filetests/isa/riscv64/ctz-zbb.clif b/cranelift/filetests/filetests/isa/riscv64/ctz-zbb.clif
new file mode 100644
index 000000000..8ff7579b4
--- /dev/null
+++ b/cranelift/filetests/filetests/isa/riscv64/ctz-zbb.clif
@@ -0,0 +1,102 @@
+test compile precise-output
+set unwind_info=false
+target riscv64 has_zbb
+
+
+function %ctz_i8(i8) -> i8 {
+block0(v0: i8):
+    v1 = ctz v0
+    return v1
+}
+
+; VCode:
+; block0:
+;   ori t2,a0,256
+;   ctzw a0,t2
+;   ret
+; 
+; Disassembled:
+; block0: ; offset 0x0
+;   ori t2, a0, 0x100
+;   .byte 0x1b, 0x95, 0x13, 0x60
+;   ret
+
+function %ctz_i16(i16) -> i16 {
+block0(v0: i16):
+    v1 = ctz v0
+    return v1
+}
+
+; VCode:
+; block0:
+;   lui t2,16
+;   or a1,a0,t2
+;   ctzw a0,a1
+;   ret
+; 
+; Disassembled:
+; block0: ; offset 0x0
+;   lui t2, 0x10
+;   or a1, a0, t2
+;   .byte 0x1b, 0x95, 0x15, 0x60
+;   ret
+
+function %ctz_i32(i32) -> i32 {
+block0(v0: i32):
+    v1 = ctz v0
+    return v1
+}
+
+; VCode:
+; block0:
+;   ctzw a0,a0
+;   ret
+; 
+; Disassembled:
+; block0: ; offset 0x0
+;   .byte 0x1b, 0x15, 0x15, 0x60
+;   ret
+
+function %ctz_i64(i64) -> i64 {
+block0(v0: i64):
+    v1 = ctz v0
+    return v1
+}
+
+; VCode:
+; block0:
+;   ctz a0,a0
+;   ret
+; 
+; Disassembled:
+; block0: ; offset 0x0
+;   .byte 0x13, 0x15, 0x15, 0x60
+;   ret
+
+function %ctz_i128(i128) -> i128 {
+block0(v0: i128):
+    v1 = ctz v0
+    return v1
+}
+
+; VCode:
+; block0:
+;   ctz a1,a1
+;   ctz a2,a0
+;   select_reg a4,a1,zero##condition=(a0 eq zero)
+;   add a0,a2,a4
+;   li a1,0
+;   ret
+; 
+; Disassembled:
+; block0: ; offset 0x0
+;   .byte 0x93, 0x95, 0x15, 0x60
+;   .byte 0x13, 0x16, 0x15, 0x60
+;   beqz a0, 0xc
+;   ori a4, zero, 0
+;   j 8
+;   ori a4, a1, 0
+;   add a0, a2, a4
+;   mv a1, zero
+;   ret
+
diff --git a/cranelift/filetests/filetests/isa/s390x/call.clif b/cranelift/filetests/filetests/isa/s390x/call.clif
index 88044bd38..8db535d46 100644
--- a/cranelift/filetests/filetests/isa/s390x/call.clif
+++ b/cranelift/filetests/filetests/isa/s390x/call.clif
@@ -382,7 +382,7 @@ block0:
 ; block0:
 ;   lghi %r2, 0
 ;   brasl %r14, %g
-;   trap
+;   .word 0x0000 # trap=user0
 ; 
 ; Disassembled:
 ; block0: ; offset 0x0
diff --git a/cranelift/filetests/filetests/isa/s390x/floating-point-arch13.clif b/cranelift/filetests/filetests/isa/s390x/floating-point-arch13.clif
index b111bf062..29f7648fe 100644
--- a/cranelift/filetests/filetests/isa/s390x/floating-point-arch13.clif
+++ b/cranelift/filetests/filetests/isa/s390x/floating-point-arch13.clif
@@ -10,13 +10,13 @@ block0(v0: f32):
 ; VCode:
 ; block0:
 ;   cebr %f0, %f0
-;   jno 6 ; trap
+;   jgo .+2 # trap=bad_toint
 ;   bras %r1, 8 ; data.f32 256 ; le %f4, 0(%r1)
 ;   cebr %f0, %f4
-;   jnhe 6 ; trap
+;   jghe .+2 # trap=int_ovf
 ;   bras %r1, 8 ; data.f32 -1 ; vlef %v16, 0(%r1), 0
 ;   wfcsb %f0, %v16
-;   jnle 6 ; trap
+;   jgle .+2 # trap=int_ovf
 ;   wclfeb %v20, %f0, 0, 5
 ;   vlgvf %r2, %v20, 0
 ;   br %r14
@@ -24,20 +24,17 @@ block0(v0: f32):
 ; Disassembled:
 ; block0: ; offset 0x0
 ;   cebr %f0, %f0
-;   jno 0xa
-;   .byte 0x00, 0x00 ; trap: bad_toint
+;   jgo 6 ; trap: bad_toint
 ;   bras %r1, 0x12
 ;   ic %r8, 0
 ;   le %f4, 0(%r1)
 ;   cebr %f0, %f4
-;   jnhe 0x20
-;   .byte 0x00, 0x00 ; trap: int_ovf
+;   jghe 0x1c ; trap: int_ovf
 ;   bras %r1, 0x28
 ;   icm %r8, 0, 0
 ;   vlef %v16, 0(%r1), 0
 ;   wfcsb %f0, %v16
-;   jnle 0x3a
-;   .byte 0x00, 0x00 ; trap: int_ovf
+;   jgle 0x36 ; trap: int_ovf
 ;   vclgd %v20, %v0, 2, 8, 5
 ;   vlgvf %r2, %v20, 0
 ;   br %r14
@@ -51,13 +48,13 @@ block0(v0: f32):
 ; VCode:
 ; block0:
 ;   cebr %f0, %f0
-;   jno 6 ; trap
+;   jgo .+2 # trap=bad_toint
 ;   bras %r1, 8 ; data.f32 128 ; le %f4, 0(%r1)
 ;   cebr %f0, %f4
-;   jnhe 6 ; trap
+;   jghe .+2 # trap=int_ovf
 ;   bras %r1, 8 ; data.f32 -129 ; vlef %v16, 0(%r1), 0
 ;   wfcsb %f0, %v16
-;   jnle 6 ; trap
+;   jgle .+2 # trap=int_ovf
 ;   wcfeb %v20, %f0, 0, 5
 ;   vlgvf %r2, %v20, 0
 ;   br %r14
@@ -65,21 +62,18 @@ block0(v0: f32):
 ; Disassembled:
 ; block0: ; offset 0x0
 ;   cebr %f0, %f0
-;   jno 0xa
-;   .byte 0x00, 0x00 ; trap: bad_toint
+;   jgo 6 ; trap: bad_toint
 ;   bras %r1, 0x12
 ;   ic %r0, 0
 ;   le %f4, 0(%r1)
 ;   cebr %f0, %f4
-;   jnhe 0x20
-;   .byte 0x00, 0x00 ; trap: int_ovf
+;   jghe 0x1c ; trap: int_ovf
 ;   bras %r1, 0x28
 ;   .byte 0xc3, 0x01
 ;   .byte 0x00, 0x00
 ;   vlef %v16, 0(%r1), 0
 ;   wfcsb %f0, %v16
-;   jnle 0x3a
-;   .byte 0x00, 0x00 ; trap: int_ovf
+;   jgle 0x36 ; trap: int_ovf
 ;   vcgd %v20, %v0, 2, 8, 5
 ;   vlgvf %r2, %v20, 0
 ;   br %r14
@@ -93,13 +87,13 @@ block0(v0: f32):
 ; VCode:
 ; block0:
 ;   cebr %f0, %f0
-;   jno 6 ; trap
+;   jgo .+2 # trap=bad_toint
 ;   bras %r1, 8 ; data.f32 65536 ; le %f4, 0(%r1)
 ;   cebr %f0, %f4
-;   jnhe 6 ; trap
+;   jghe .+2 # trap=int_ovf
 ;   bras %r1, 8 ; data.f32 -1 ; vlef %v16, 0(%r1), 0
 ;   wfcsb %f0, %v16
-;   jnle 6 ; trap
+;   jgle .+2 # trap=int_ovf
 ;   wclfeb %v20, %f0, 0, 5
 ;   vlgvf %r2, %v20, 0
 ;   br %r14
@@ -107,20 +101,17 @@ block0(v0: f32):
 ; Disassembled:
 ; block0: ; offset 0x0
 ;   cebr %f0, %f0
-;   jno 0xa
-;   .byte 0x00, 0x00 ; trap: bad_toint
+;   jgo 6 ; trap: bad_toint
 ;   bras %r1, 0x12
 ;   be 0
 ;   le %f4, 0(%r1)
 ;   cebr %f0, %f4
-;   jnhe 0x20
-;   .byte 0x00, 0x00 ; trap: int_ovf
+;   jghe 0x1c ; trap: int_ovf
 ;   bras %r1, 0x28
 ;   icm %r8, 0, 0
 ;   vlef %v16, 0(%r1), 0
 ;   wfcsb %f0, %v16
-;   jnle 0x3a
-;   .byte 0x00, 0x00 ; trap: int_ovf
+;   jgle 0x36 ; trap: int_ovf
 ;   vclgd %v20, %v0, 2, 8, 5
 ;   vlgvf %r2, %v20, 0
 ;   br %r14
@@ -134,13 +125,13 @@ block0(v0: f32):
 ; VCode:
 ; block0:
 ;   cebr %f0, %f0
-;   jno 6 ; trap
+;   jgo .+2 # trap=bad_toint
 ;   bras %r1, 8 ; data.f32 32768 ; le %f4, 0(%r1)
 ;   cebr %f0, %f4
-;   jnhe 6 ; trap
+;   jghe .+2 # trap=int_ovf
 ;   bras %r1, 8 ; data.f32 -32769 ; vlef %v16, 0(%r1), 0
 ;   wfcsb %f0, %v16
-;   jnle 6 ; trap
+;   jgle .+2 # trap=int_ovf
 ;   wcfeb %v20, %f0, 0, 5
 ;   vlgvf %r2, %v20, 0
 ;   br %r14
@@ -148,21 +139,18 @@ block0(v0: f32):
 ; Disassembled:
 ; block0: ; offset 0x0
 ;   cebr %f0, %f0
-;   jno 0xa
-;   .byte 0x00, 0x00 ; trap: bad_toint
+;   jgo 6 ; trap: bad_toint
 ;   bras %r1, 0x12
 ;   bc 0, 0
 ;   le %f4, 0(%r1)
 ;   cebr %f0, %f4
-;   jnhe 0x20
-;   .byte 0x00, 0x00 ; trap: int_ovf
+;   jghe 0x1c ; trap: int_ovf
 ;   bras %r1, 0x28
 ;   bpp 0, -0x31dc, 0x100
 ;   lpr %r0, %r0
 ;   .byte 0x08, 0x03
 ;   wfcsb %f0, %v16
-;   jnle 0x3a
-;   .byte 0x00, 0x00 ; trap: int_ovf
+;   jgle 0x36 ; trap: int_ovf
 ;   vcgd %v20, %v0, 2, 8, 5
 ;   vlgvf %r2, %v20, 0
 ;   br %r14
@@ -176,13 +164,13 @@ block0(v0: f32):
 ; VCode:
 ; block0:
 ;   cebr %f0, %f0
-;   jno 6 ; trap
+;   jgo .+2 # trap=bad_toint
 ;   bras %r1, 8 ; data.f32 4294967300 ; le %f4, 0(%r1)
 ;   cebr %f0, %f4
-;   jnhe 6 ; trap
+;   jghe .+2 # trap=int_ovf
 ;   bras %r1, 8 ; data.f32 -1 ; vlef %v16, 0(%r1), 0
 ;   wfcsb %f0, %v16
-;   jnle 6 ; trap
+;   jgle .+2 # trap=int_ovf
 ;   wclfeb %v20, %f0, 0, 5
 ;   vlgvf %r2, %v20, 0
 ;   br %r14
@@ -190,20 +178,17 @@ block0(v0: f32):
 ; Disassembled:
 ; block0: ; offset 0x0
 ;   cebr %f0, %f0
-;   jno 0xa
-;   .byte 0x00, 0x00 ; trap: bad_toint
+;   jgo 6 ; trap: bad_toint
 ;   bras %r1, 0x12
 ;   cvb %r8, 0
 ;   le %f4, 0(%r1)
 ;   cebr %f0, %f4
-;   jnhe 0x20
-;   .byte 0x00, 0x00 ; trap: int_ovf
+;   jghe 0x1c ; trap: int_ovf
 ;   bras %r1, 0x28
 ;   icm %r8, 0, 0
 ;   vlef %v16, 0(%r1), 0
 ;   wfcsb %f0, %v16
-;   jnle 0x3a
-;   .byte 0x00, 0x00 ; trap: int_ovf
+;   jgle 0x36 ; trap: int_ovf
 ;   vclgd %v20, %v0, 2, 8, 5
 ;   vlgvf %r2, %v20, 0
 ;   br %r14
@@ -217,13 +202,13 @@ block0(v0: f32):
 ; VCode:
 ; block0:
 ;   cebr %f0, %f0
-;   jno 6 ; trap
+;   jgo .+2 # trap=bad_toint
 ;   bras %r1, 8 ; data.f32 2147483600 ; le %f4, 0(%r1)
 ;   cebr %f0, %f4
-;   jnhe 6 ; trap
+;   jghe .+2 # trap=int_ovf
 ;   bras %r1, 8 ; data.f32 -2147484000 ; vlef %v16, 0(%r1), 0
 ;   wfcsb %f0, %v16
-;   jnle 6 ; trap
+;   jgle .+2 # trap=int_ovf
 ;   wcfeb %v20, %f0, 0, 5
 ;   vlgvf %r2, %v20, 0
 ;   br %r14
@@ -231,21 +216,18 @@ block0(v0: f32):
 ; Disassembled:
 ; block0: ; offset 0x0
 ;   cebr %f0, %f0
-;   jno 0xa
-;   .byte 0x00, 0x00 ; trap: bad_toint
+;   jgo 6 ; trap: bad_toint
 ;   bras %r1, 0x12
 ;   cvb %r0, 0
 ;   le %f4, 0(%r1)
 ;   cebr %f0, %f4
-;   jnhe 0x20
-;   .byte 0x00, 0x00 ; trap: int_ovf
+;   jghe 0x1c ; trap: int_ovf
 ;   bras %r1, 0x28
 ;   .byte 0xcf, 0x00
 ;   .byte 0x00, 0x01
 ;   vlef %v16, 0(%r1), 0
 ;   wfcsb %f0, %v16
-;   jnle 0x3a
-;   .byte 0x00, 0x00 ; trap: int_ovf
+;   jgle 0x36 ; trap: int_ovf
 ;   vcgd %v20, %v0, 2, 8, 5
 ;   vlgvf %r2, %v20, 0
 ;   br %r14
@@ -259,13 +241,13 @@ block0(v0: f32):
 ; VCode:
 ; block0:
 ;   cebr %f0, %f0
-;   jno 6 ; trap
+;   jgo .+2 # trap=bad_toint
 ;   bras %r1, 8 ; data.f32 18446744000000000000 ; le %f4, 0(%r1)
 ;   cebr %f0, %f4
-;   jnhe 6 ; trap
+;   jghe .+2 # trap=int_ovf
 ;   bras %r1, 8 ; data.f32 -1 ; vlef %v16, 0(%r1), 0
 ;   wfcsb %f0, %v16
-;   jnle 6 ; trap
+;   jgle .+2 # trap=int_ovf
 ;   wldeb %v20, %f0
 ;   wclgdb %v22, %v20, 0, 5
 ;   vlgvg %r2, %v22, 0
@@ -274,20 +256,17 @@ block0(v0: f32):
 ; Disassembled:
 ; block0: ; offset 0x0
 ;   cebr %f0, %f0
-;   jno 0xa
-;   .byte 0x00, 0x00 ; trap: bad_toint
+;   jgo 6 ; trap: bad_toint
 ;   bras %r1, 0x12
 ;   sl %r8, 0
 ;   le %f4, 0(%r1)
 ;   cebr %f0, %f4
-;   jnhe 0x20
-;   .byte 0x00, 0x00 ; trap: int_ovf
+;   jghe 0x1c ; trap: int_ovf
 ;   bras %r1, 0x28
 ;   icm %r8, 0, 0
 ;   vlef %v16, 0(%r1), 0
 ;   wfcsb %f0, %v16
-;   jnle 0x3a
-;   .byte 0x00, 0x00 ; trap: int_ovf
+;   jgle 0x36 ; trap: int_ovf
 ;   wldeb %v20, %f0
 ;   wclgdb %v22, %v20, 0, 5
 ;   vlgvg %r2, %v22, 0
@@ -302,13 +281,13 @@ block0(v0: f32):
 ; VCode:
 ; block0:
 ;   cebr %f0, %f0
-;   jno 6 ; trap
+;   jgo .+2 # trap=bad_toint
 ;   bras %r1, 8 ; data.f32 9223372000000000000 ; le %f4, 0(%r1)
 ;   cebr %f0, %f4
-;   jnhe 6 ; trap
+;   jghe .+2 # trap=int_ovf
 ;   bras %r1, 8 ; data.f32 -9223373000000000000 ; vlef %v16, 0(%r1), 0
 ;   wfcsb %f0, %v16
-;   jnle 6 ; trap
+;   jgle .+2 # trap=int_ovf
 ;   wldeb %v20, %f0
 ;   wcgdb %v22, %v20, 0, 5
 ;   vlgvg %r2, %v22, 0
@@ -317,21 +296,18 @@ block0(v0: f32):
 ; Disassembled:
 ; block0: ; offset 0x0
 ;   cebr %f0, %f0
-;   jno 0xa
-;   .byte 0x00, 0x00 ; trap: bad_toint
+;   jgo 6 ; trap: bad_toint
 ;   bras %r1, 0x12
 ;   sl %r0, 0
 ;   le %f4, 0(%r1)
 ;   cebr %f0, %f4
-;   jnhe 0x20
-;   .byte 0x00, 0x00 ; trap: int_ovf
+;   jghe 0x1c ; trap: int_ovf
 ;   bras %r1, 0x28
 ;   edmk 1(1), 0x700(%r14)
 ;   lpr %r0, %r0
 ;   .byte 0x08, 0x03
 ;   wfcsb %f0, %v16
-;   jnle 0x3a
-;   .byte 0x00, 0x00 ; trap: int_ovf
+;   jgle 0x36 ; trap: int_ovf
 ;   wldeb %v20, %f0
 ;   wcgdb %v22, %v20, 0, 5
 ;   vlgvg %r2, %v22, 0
@@ -346,13 +322,13 @@ block0(v0: f64):
 ; VCode:
 ; block0:
 ;   cdbr %f0, %f0
-;   jno 6 ; trap
+;   jgo .+2 # trap=bad_toint
 ;   bras %r1, 12 ; data.f64 256 ; ld %f4, 0(%r1)
 ;   cdbr %f0, %f4
-;   jnhe 6 ; trap
+;   jghe .+2 # trap=int_ovf
 ;   bras %r1, 12 ; data.f64 -1 ; vleg %v16, 0(%r1), 0
 ;   wfcdb %f0, %v16
-;   jnle 6 ; trap
+;   jgle .+2 # trap=int_ovf
 ;   wclgdb %v20, %f0, 0, 5
 ;   vlgvg %r2, %v20, 0
 ;   br %r14
@@ -360,24 +336,21 @@ block0(v0: f64):
 ; Disassembled:
 ; block0: ; offset 0x0
 ;   cdbr %f0, %f0
-;   jno 0xa
-;   .byte 0x00, 0x00 ; trap: bad_toint
+;   jgo 6 ; trap: bad_toint
 ;   bras %r1, 0x16
 ;   sth %r7, 0
 ;   .byte 0x00, 0x00
 ;   .byte 0x00, 0x00
 ;   ld %f4, 0(%r1)
 ;   cdbr %f0, %f4
-;   jnhe 0x24
-;   .byte 0x00, 0x00 ; trap: int_ovf
+;   jghe 0x20 ; trap: int_ovf
 ;   bras %r1, 0x30
 ;   icm %r15, 0, 0
 ;   .byte 0x00, 0x00
 ;   .byte 0x00, 0x00
 ;   vleg %v16, 0(%r1), 0
 ;   wfcdb %f0, %v16
-;   jnle 0x42
-;   .byte 0x00, 0x00 ; trap: int_ovf
+;   jgle 0x3e ; trap: int_ovf
 ;   wclgdb %v20, %f0, 0, 5
 ;   vlgvg %r2, %v20, 0
 ;   br %r14
@@ -391,13 +364,13 @@ block0(v0: f64):
 ; VCode:
 ; block0:
 ;   cdbr %f0, %f0
-;   jno 6 ; trap
+;   jgo .+2 # trap=bad_toint
 ;   bras %r1, 12 ; data.f64 128 ; ld %f4, 0(%r1)
 ;   cdbr %f0, %f4
-;   jnhe 6 ; trap
+;   jghe .+2 # trap=int_ovf
 ;   bras %r1, 12 ; data.f64 -129 ; vleg %v16, 0(%r1), 0
 ;   wfcdb %f0, %v16
-;   jnle 6 ; trap
+;   jgle .+2 # trap=int_ovf
 ;   wcgdb %v20, %f0, 0, 5
 ;   vlgvg %r2, %v20, 0
 ;   br %r14
@@ -405,23 +378,20 @@ block0(v0: f64):
 ; Disassembled:
 ; block0: ; offset 0x0
 ;   cdbr %f0, %f0
-;   jno 0xa
-;   .byte 0x00, 0x00 ; trap: bad_toint
+;   jgo 6 ; trap: bad_toint
 ;   bras %r1, 0x16
 ;   sth %r6, 0
 ;   .byte 0x00, 0x00
 ;   .byte 0x00, 0x00
 ;   ld %f4, 0(%r1)
 ;   cdbr %f0, %f4
-;   jnhe 0x24
-;   .byte 0x00, 0x00 ; trap: int_ovf
+;   jghe 0x20 ; trap: int_ovf
 ;   bras %r1, 0x30
 ;   larl %r6, 0x40000028
 ;   .byte 0x00, 0x00
 ;   vleg %v16, 0(%r1), 0
 ;   wfcdb %f0, %v16
-;   jnle 0x42
-;   .byte 0x00, 0x00 ; trap: int_ovf
+;   jgle 0x3e ; trap: int_ovf
 ;   wcgdb %v20, %f0, 0, 5
 ;   vlgvg %r2, %v20, 0
 ;   br %r14
@@ -435,13 +405,13 @@ block0(v0: f64):
 ; VCode:
 ; block0:
 ;   cdbr %f0, %f0
-;   jno 6 ; trap
+;   jgo .+2 # trap=bad_toint
 ;   bras %r1, 12 ; data.f64 65536 ; ld %f4, 0(%r1)
 ;   cdbr %f0, %f4
-;   jnhe 6 ; trap
+;   jghe .+2 # trap=int_ovf
 ;   bras %r1, 12 ; data.f64 -1 ; vleg %v16, 0(%r1), 0
 ;   wfcdb %f0, %v16
-;   jnle 6 ; trap
+;   jgle .+2 # trap=int_ovf
 ;   wclgdb %v20, %f0, 0, 5
 ;   vlgvg %r2, %v20, 0
 ;   br %r14
@@ -449,24 +419,21 @@ block0(v0: f64):
 ; Disassembled:
 ; block0: ; offset 0x0
 ;   cdbr %f0, %f0
-;   jno 0xa
-;   .byte 0x00, 0x00 ; trap: bad_toint
+;   jgo 6 ; trap: bad_toint
 ;   bras %r1, 0x16
 ;   sth %r15, 0
 ;   .byte 0x00, 0x00
 ;   .byte 0x00, 0x00
 ;   ld %f4, 0(%r1)
 ;   cdbr %f0, %f4
-;   jnhe 0x24
-;   .byte 0x00, 0x00 ; trap: int_ovf
+;   jghe 0x20 ; trap: int_ovf
 ;   bras %r1, 0x30
 ;   icm %r15, 0, 0
 ;   .byte 0x00, 0x00
 ;   .byte 0x00, 0x00
 ;   vleg %v16, 0(%r1), 0
 ;   wfcdb %f0, %v16
-;   jnle 0x42
-;   .byte 0x00, 0x00 ; trap: int_ovf
+;   jgle 0x3e ; trap: int_ovf
 ;   wclgdb %v20, %f0, 0, 5
 ;   vlgvg %r2, %v20, 0
 ;   br %r14
@@ -480,13 +447,13 @@ block0(v0: f64):
 ; VCode:
 ; block0:
 ;   cdbr %f0, %f0
-;   jno 6 ; trap
+;   jgo .+2 # trap=bad_toint
 ;   bras %r1, 12 ; data.f64 32768 ; ld %f4, 0(%r1)
 ;   cdbr %f0, %f4
-;   jnhe 6 ; trap
+;   jghe .+2 # trap=int_ovf
 ;   bras %r1, 12 ; data.f64 -32769 ; vleg %v16, 0(%r1), 0
 ;   wfcdb %f0, %v16
-;   jnle 6 ; trap
+;   jgle .+2 # trap=int_ovf
 ;   wcgdb %v20, %f0, 0, 5
 ;   vlgvg %r2, %v20, 0
 ;   br %r14
@@ -494,23 +461,20 @@ block0(v0: f64):
 ; Disassembled:
 ; block0: ; offset 0x0
 ;   cdbr %f0, %f0
-;   jno 0xa
-;   .byte 0x00, 0x00 ; trap: bad_toint
+;   jgo 6 ; trap: bad_toint
 ;   bras %r1, 0x16
 ;   sth %r14, 0
 ;   .byte 0x00, 0x00
 ;   .byte 0x00, 0x00
 ;   ld %f4, 0(%r1)
 ;   cdbr %f0, %f4
-;   jnhe 0x24
-;   .byte 0x00, 0x00 ; trap: int_ovf
+;   jghe 0x20 ; trap: int_ovf
 ;   bras %r1, 0x30
 ;   larl %r14, 0x400028
 ;   .byte 0x00, 0x00
 ;   vleg %v16, 0(%r1), 0
 ;   wfcdb %f0, %v16
-;   jnle 0x42
-;   .byte 0x00, 0x00 ; trap: int_ovf
+;   jgle 0x3e ; trap: int_ovf
 ;   wcgdb %v20, %f0, 0, 5
 ;   vlgvg %r2, %v20, 0
 ;   br %r14
@@ -524,13 +488,13 @@ block0(v0: f64):
 ; VCode:
 ; block0:
 ;   cdbr %f0, %f0
-;   jno 6 ; trap
+;   jgo .+2 # trap=bad_toint
 ;   bras %r1, 12 ; data.f64 4294967296 ; ld %f4, 0(%r1)
 ;   cdbr %f0, %f4
-;   jnhe 6 ; trap
+;   jghe .+2 # trap=int_ovf
 ;   bras %r1, 12 ; data.f64 -1 ; vleg %v16, 0(%r1), 0
 ;   wfcdb %f0, %v16
-;   jnle 6 ; trap
+;   jgle .+2 # trap=int_ovf
 ;   wclgdb %v20, %f0, 0, 5
 ;   vlgvg %r2, %v20, 0
 ;   br %r14
@@ -538,24 +502,21 @@ block0(v0: f64):
 ; Disassembled:
 ; block0: ; offset 0x0
 ;   cdbr %f0, %f0
-;   jno 0xa
-;   .byte 0x00, 0x00 ; trap: bad_toint
+;   jgo 6 ; trap: bad_toint
 ;   bras %r1, 0x16
 ;   la %r15, 0
 ;   .byte 0x00, 0x00
 ;   .byte 0x00, 0x00
 ;   ld %f4, 0(%r1)
 ;   cdbr %f0, %f4
-;   jnhe 0x24
-;   .byte 0x00, 0x00 ; trap: int_ovf
+;   jghe 0x20 ; trap: int_ovf
 ;   bras %r1, 0x30
 ;   icm %r15, 0, 0
 ;   .byte 0x00, 0x00
 ;   .byte 0x00, 0x00
 ;   vleg %v16, 0(%r1), 0
 ;   wfcdb %f0, %v16
-;   jnle 0x42
-;   .byte 0x00, 0x00 ; trap: int_ovf
+;   jgle 0x3e ; trap: int_ovf
 ;   wclgdb %v20, %f0, 0, 5
 ;   vlgvg %r2, %v20, 0
 ;   br %r14
@@ -569,13 +530,13 @@ block0(v0: f64):
 ; VCode:
 ; block0:
 ;   cdbr %f0, %f0
-;   jno 6 ; trap
+;   jgo .+2 # trap=bad_toint
 ;   bras %r1, 12 ; data.f64 2147483648 ; ld %f4, 0(%r1)
 ;   cdbr %f0, %f4
-;   jnhe 6 ; trap
+;   jghe .+2 # trap=int_ovf
 ;   bras %r1, 12 ; data.f64 -2147483649 ; vleg %v16, 0(%r1), 0
 ;   wfcdb %f0, %v16
-;   jnle 6 ; trap
+;   jgle .+2 # trap=int_ovf
 ;   wcgdb %v20, %f0, 0, 5
 ;   vlgvg %r2, %v20, 0
 ;   br %r14
@@ -583,16 +544,14 @@ block0(v0: f64):
 ; Disassembled:
 ; block0: ; offset 0x0
 ;   cdbr %f0, %f0
-;   jno 0xa
-;   .byte 0x00, 0x00 ; trap: bad_toint
+;   jgo 6 ; trap: bad_toint
 ;   bras %r1, 0x16
 ;   la %r14, 0
 ;   .byte 0x00, 0x00
 ;   .byte 0x00, 0x00
 ;   ld %f4, 0(%r1)
 ;   cdbr %f0, %f4
-;   jnhe 0x24
-;   .byte 0x00, 0x00 ; trap: int_ovf
+;   jghe 0x20 ; trap: int_ovf
 ;   bras %r1, 0x30
 ;   .byte 0xc1, 0xe0
 ;   .byte 0x00, 0x00
@@ -600,8 +559,7 @@ block0(v0: f64):
 ;   .byte 0x00, 0x00
 ;   vleg %v16, 0(%r1), 0
 ;   wfcdb %f0, %v16
-;   jnle 0x42
-;   .byte 0x00, 0x00 ; trap: int_ovf
+;   jgle 0x3e ; trap: int_ovf
 ;   wcgdb %v20, %f0, 0, 5
 ;   vlgvg %r2, %v20, 0
 ;   br %r14
@@ -615,13 +573,13 @@ block0(v0: f64):
 ; VCode:
 ; block0:
 ;   cdbr %f0, %f0
-;   jno 6 ; trap
+;   jgo .+2 # trap=bad_toint
 ;   bras %r1, 12 ; data.f64 18446744073709552000 ; ld %f4, 0(%r1)
 ;   cdbr %f0, %f4
-;   jnhe 6 ; trap
+;   jghe .+2 # trap=int_ovf
 ;   bras %r1, 12 ; data.f64 -1 ; vleg %v16, 0(%r1), 0
 ;   wfcdb %f0, %v16
-;   jnle 6 ; trap
+;   jgle .+2 # trap=int_ovf
 ;   wclgdb %v20, %f0, 0, 5
 ;   vlgvg %r2, %v20, 0
 ;   br %r14
@@ -629,24 +587,21 @@ block0(v0: f64):
 ; Disassembled:
 ; block0: ; offset 0x0
 ;   cdbr %f0, %f0
-;   jno 0xa
-;   .byte 0x00, 0x00 ; trap: bad_toint
+;   jgo 6 ; trap: bad_toint
 ;   bras %r1, 0x16
 ;   ic %r15, 0
 ;   .byte 0x00, 0x00
 ;   .byte 0x00, 0x00
 ;   ld %f4, 0(%r1)
 ;   cdbr %f0, %f4
-;   jnhe 0x24
-;   .byte 0x00, 0x00 ; trap: int_ovf
+;   jghe 0x20 ; trap: int_ovf
 ;   bras %r1, 0x30
 ;   icm %r15, 0, 0
 ;   .byte 0x00, 0x00
 ;   .byte 0x00, 0x00
 ;   vleg %v16, 0(%r1), 0
 ;   wfcdb %f0, %v16
-;   jnle 0x42
-;   .byte 0x00, 0x00 ; trap: int_ovf
+;   jgle 0x3e ; trap: int_ovf
 ;   wclgdb %v20, %f0, 0, 5
 ;   vlgvg %r2, %v20, 0
 ;   br %r14
@@ -660,13 +615,13 @@ block0(v0: f64):
 ; VCode:
 ; block0:
 ;   cdbr %f0, %f0
-;   jno 6 ; trap
+;   jgo .+2 # trap=bad_toint
 ;   bras %r1, 12 ; data.f64 9223372036854776000 ; ld %f4, 0(%r1)
 ;   cdbr %f0, %f4
-;   jnhe 6 ; trap
+;   jghe .+2 # trap=int_ovf
 ;   bras %r1, 12 ; data.f64 -9223372036854778000 ; vleg %v16, 0(%r1), 0
 ;   wfcdb %f0, %v16
-;   jnle 6 ; trap
+;   jgle .+2 # trap=int_ovf
 ;   wcgdb %v20, %f0, 0, 5
 ;   vlgvg %r2, %v20, 0
 ;   br %r14
@@ -674,16 +629,14 @@ block0(v0: f64):
 ; Disassembled:
 ; block0: ; offset 0x0
 ;   cdbr %f0, %f0
-;   jno 0xa
-;   .byte 0x00, 0x00 ; trap: bad_toint
+;   jgo 6 ; trap: bad_toint
 ;   bras %r1, 0x16
 ;   ic %r14, 0
 ;   .byte 0x00, 0x00
 ;   .byte 0x00, 0x00
 ;   ld %f4, 0(%r1)
 ;   cdbr %f0, %f4
-;   jnhe 0x24
-;   .byte 0x00, 0x00 ; trap: int_ovf
+;   jghe 0x20 ; trap: int_ovf
 ;   bras %r1, 0x30
 ;   .byte 0xc3, 0xe0
 ;   .byte 0x00, 0x00
@@ -691,8 +644,7 @@ block0(v0: f64):
 ;   .byte 0x00, 0x01
 ;   vleg %v16, 0(%r1), 0
 ;   wfcdb %f0, %v16
-;   jnle 0x42
-;   .byte 0x00, 0x00 ; trap: int_ovf
+;   jgle 0x3e ; trap: int_ovf
 ;   wcgdb %v20, %f0, 0, 5
 ;   vlgvg %r2, %v20, 0
 ;   br %r14
diff --git a/cranelift/filetests/filetests/isa/s390x/floating-point.clif b/cranelift/filetests/filetests/isa/s390x/floating-point.clif
index 0181ffdd3..75b5474da 100644
--- a/cranelift/filetests/filetests/isa/s390x/floating-point.clif
+++ b/cranelift/filetests/filetests/isa/s390x/floating-point.clif
@@ -683,13 +683,13 @@ block0(v0: f32):
 ; VCode:
 ; block0:
 ;   cebr %f0, %f0
-;   jno 6 ; trap
+;   jgo .+2 # trap=bad_toint
 ;   bras %r1, 8 ; data.f32 256 ; le %f4, 0(%r1)
 ;   cebr %f0, %f4
-;   jnhe 6 ; trap
+;   jghe .+2 # trap=int_ovf
 ;   bras %r1, 8 ; data.f32 -1 ; vlef %v16, 0(%r1), 0
 ;   wfcsb %f0, %v16
-;   jnle 6 ; trap
+;   jgle .+2 # trap=int_ovf
 ;   wldeb %v20, %f0
 ;   wclgdb %v22, %v20, 0, 5
 ;   vlgvg %r2, %v22, 0
@@ -698,20 +698,17 @@ block0(v0: f32):
 ; Disassembled:
 ; block0: ; offset 0x0
 ;   cebr %f0, %f0
-;   jno 0xa
-;   .byte 0x00, 0x00 ; trap: bad_toint
+;   jgo 6 ; trap: bad_toint
 ;   bras %r1, 0x12
 ;   ic %r8, 0
 ;   le %f4, 0(%r1)
 ;   cebr %f0, %f4
-;   jnhe 0x20
-;   .byte 0x00, 0x00 ; trap: int_ovf
+;   jghe 0x1c ; trap: int_ovf
 ;   bras %r1, 0x28
 ;   icm %r8, 0, 0
 ;   vlef %v16, 0(%r1), 0
 ;   wfcsb %f0, %v16
-;   jnle 0x3a
-;   .byte 0x00, 0x00 ; trap: int_ovf
+;   jgle 0x36 ; trap: int_ovf
 ;   wldeb %v20, %f0
 ;   wclgdb %v22, %v20, 0, 5
 ;   vlgvg %r2, %v22, 0
@@ -726,13 +723,13 @@ block0(v0: f32):
 ; VCode:
 ; block0:
 ;   cebr %f0, %f0
-;   jno 6 ; trap
+;   jgo .+2 # trap=bad_toint
 ;   bras %r1, 8 ; data.f32 128 ; le %f4, 0(%r1)
 ;   cebr %f0, %f4
-;   jnhe 6 ; trap
+;   jghe .+2 # trap=int_ovf
 ;   bras %r1, 8 ; data.f32 -129 ; vlef %v16, 0(%r1), 0
 ;   wfcsb %f0, %v16
-;   jnle 6 ; trap
+;   jgle .+2 # trap=int_ovf
 ;   wldeb %v20, %f0
 ;   wcgdb %v22, %v20, 0, 5
 ;   vlgvg %r2, %v22, 0
@@ -741,21 +738,18 @@ block0(v0: f32):
 ; Disassembled:
 ; block0: ; offset 0x0
 ;   cebr %f0, %f0
-;   jno 0xa
-;   .byte 0x00, 0x00 ; trap: bad_toint
+;   jgo 6 ; trap: bad_toint
 ;   bras %r1, 0x12
 ;   ic %r0, 0
 ;   le %f4, 0(%r1)
 ;   cebr %f0, %f4
-;   jnhe 0x20
-;   .byte 0x00, 0x00 ; trap: int_ovf
+;   jghe 0x1c ; trap: int_ovf
 ;   bras %r1, 0x28
 ;   .byte 0xc3, 0x01
 ;   .byte 0x00, 0x00
 ;   vlef %v16, 0(%r1), 0
 ;   wfcsb %f0, %v16
-;   jnle 0x3a
-;   .byte 0x00, 0x00 ; trap: int_ovf
+;   jgle 0x36 ; trap: int_ovf
 ;   wldeb %v20, %f0
 ;   wcgdb %v22, %v20, 0, 5
 ;   vlgvg %r2, %v22, 0
@@ -770,13 +764,13 @@ block0(v0: f32):
 ; VCode:
 ; block0:
 ;   cebr %f0, %f0
-;   jno 6 ; trap
+;   jgo .+2 # trap=bad_toint
 ;   bras %r1, 8 ; data.f32 65536 ; le %f4, 0(%r1)
 ;   cebr %f0, %f4
-;   jnhe 6 ; trap
+;   jghe .+2 # trap=int_ovf
 ;   bras %r1, 8 ; data.f32 -1 ; vlef %v16, 0(%r1), 0
 ;   wfcsb %f0, %v16
-;   jnle 6 ; trap
+;   jgle .+2 # trap=int_ovf
 ;   wldeb %v20, %f0
 ;   wclgdb %v22, %v20, 0, 5
 ;   vlgvg %r2, %v22, 0
@@ -785,20 +779,17 @@ block0(v0: f32):
 ; Disassembled:
 ; block0: ; offset 0x0
 ;   cebr %f0, %f0
-;   jno 0xa
-;   .byte 0x00, 0x00 ; trap: bad_toint
+;   jgo 6 ; trap: bad_toint
 ;   bras %r1, 0x12
 ;   be 0
 ;   le %f4, 0(%r1)
 ;   cebr %f0, %f4
-;   jnhe 0x20
-;   .byte 0x00, 0x00 ; trap: int_ovf
+;   jghe 0x1c ; trap: int_ovf
 ;   bras %r1, 0x28
 ;   icm %r8, 0, 0
 ;   vlef %v16, 0(%r1), 0
 ;   wfcsb %f0, %v16
-;   jnle 0x3a
-;   .byte 0x00, 0x00 ; trap: int_ovf
+;   jgle 0x36 ; trap: int_ovf
 ;   wldeb %v20, %f0
 ;   wclgdb %v22, %v20, 0, 5
 ;   vlgvg %r2, %v22, 0
@@ -813,13 +804,13 @@ block0(v0: f32):
 ; VCode:
 ; block0:
 ;   cebr %f0, %f0
-;   jno 6 ; trap
+;   jgo .+2 # trap=bad_toint
 ;   bras %r1, 8 ; data.f32 32768 ; le %f4, 0(%r1)
 ;   cebr %f0, %f4
-;   jnhe 6 ; trap
+;   jghe .+2 # trap=int_ovf
 ;   bras %r1, 8 ; data.f32 -32769 ; vlef %v16, 0(%r1), 0
 ;   wfcsb %f0, %v16
-;   jnle 6 ; trap
+;   jgle .+2 # trap=int_ovf
 ;   wldeb %v20, %f0
 ;   wcgdb %v22, %v20, 0, 5
 ;   vlgvg %r2, %v22, 0
@@ -828,21 +819,18 @@ block0(v0: f32):
 ; Disassembled:
 ; block0: ; offset 0x0
 ;   cebr %f0, %f0
-;   jno 0xa
-;   .byte 0x00, 0x00 ; trap: bad_toint
+;   jgo 6 ; trap: bad_toint
 ;   bras %r1, 0x12
 ;   bc 0, 0
 ;   le %f4, 0(%r1)
 ;   cebr %f0, %f4
-;   jnhe 0x20
-;   .byte 0x00, 0x00 ; trap: int_ovf
+;   jghe 0x1c ; trap: int_ovf
 ;   bras %r1, 0x28
 ;   bpp 0, -0x31dc, 0x100
 ;   lpr %r0, %r0
 ;   .byte 0x08, 0x03
 ;   wfcsb %f0, %v16
-;   jnle 0x3a
-;   .byte 0x00, 0x00 ; trap: int_ovf
+;   jgle 0x36 ; trap: int_ovf
 ;   wldeb %v20, %f0
 ;   wcgdb %v22, %v20, 0, 5
 ;   vlgvg %r2, %v22, 0
@@ -857,13 +845,13 @@ block0(v0: f32):
 ; VCode:
 ; block0:
 ;   cebr %f0, %f0
-;   jno 6 ; trap
+;   jgo .+2 # trap=bad_toint
 ;   bras %r1, 8 ; data.f32 4294967300 ; le %f4, 0(%r1)
 ;   cebr %f0, %f4
-;   jnhe 6 ; trap
+;   jghe .+2 # trap=int_ovf
 ;   bras %r1, 8 ; data.f32 -1 ; vlef %v16, 0(%r1), 0
 ;   wfcsb %f0, %v16
-;   jnle 6 ; trap
+;   jgle .+2 # trap=int_ovf
 ;   wldeb %v20, %f0
 ;   wclgdb %v22, %v20, 0, 5
 ;   vlgvg %r2, %v22, 0
@@ -872,20 +860,17 @@ block0(v0: f32):
 ; Disassembled:
 ; block0: ; offset 0x0
 ;   cebr %f0, %f0
-;   jno 0xa
-;   .byte 0x00, 0x00 ; trap: bad_toint
+;   jgo 6 ; trap: bad_toint
 ;   bras %r1, 0x12
 ;   cvb %r8, 0
 ;   le %f4, 0(%r1)
 ;   cebr %f0, %f4
-;   jnhe 0x20
-;   .byte 0x00, 0x00 ; trap: int_ovf
+;   jghe 0x1c ; trap: int_ovf
 ;   bras %r1, 0x28
 ;   icm %r8, 0, 0
 ;   vlef %v16, 0(%r1), 0
 ;   wfcsb %f0, %v16
-;   jnle 0x3a
-;   .byte 0x00, 0x00 ; trap: int_ovf
+;   jgle 0x36 ; trap: int_ovf
 ;   wldeb %v20, %f0
 ;   wclgdb %v22, %v20, 0, 5
 ;   vlgvg %r2, %v22, 0
@@ -900,13 +885,13 @@ block0(v0: f32):
 ; VCode:
 ; block0:
 ;   cebr %f0, %f0
-;   jno 6 ; trap
+;   jgo .+2 # trap=bad_toint
 ;   bras %r1, 8 ; data.f32 2147483600 ; le %f4, 0(%r1)
 ;   cebr %f0, %f4
-;   jnhe 6 ; trap
+;   jghe .+2 # trap=int_ovf
 ;   bras %r1, 8 ; data.f32 -2147484000 ; vlef %v16, 0(%r1), 0
 ;   wfcsb %f0, %v16
-;   jnle 6 ; trap
+;   jgle .+2 # trap=int_ovf
 ;   wldeb %v20, %f0
 ;   wcgdb %v22, %v20, 0, 5
 ;   vlgvg %r2, %v22, 0
@@ -915,21 +900,18 @@ block0(v0: f32):
 ; Disassembled:
 ; block0: ; offset 0x0
 ;   cebr %f0, %f0
-;   jno 0xa
-;   .byte 0x00, 0x00 ; trap: bad_toint
+;   jgo 6 ; trap: bad_toint
 ;   bras %r1, 0x12
 ;   cvb %r0, 0
 ;   le %f4, 0(%r1)
 ;   cebr %f0, %f4
-;   jnhe 0x20
-;   .byte 0x00, 0x00 ; trap: int_ovf
+;   jghe 0x1c ; trap: int_ovf
 ;   bras %r1, 0x28
 ;   .byte 0xcf, 0x00
 ;   .byte 0x00, 0x01
 ;   vlef %v16, 0(%r1), 0
 ;   wfcsb %f0, %v16
-;   jnle 0x3a
-;   .byte 0x00, 0x00 ; trap: int_ovf
+;   jgle 0x36 ; trap: int_ovf
 ;   wldeb %v20, %f0
 ;   wcgdb %v22, %v20, 0, 5
 ;   vlgvg %r2, %v22, 0
@@ -944,13 +926,13 @@ block0(v0: f32):
 ; VCode:
 ; block0:
 ;   cebr %f0, %f0
-;   jno 6 ; trap
+;   jgo .+2 # trap=bad_toint
 ;   bras %r1, 8 ; data.f32 18446744000000000000 ; le %f4, 0(%r1)
 ;   cebr %f0, %f4
-;   jnhe 6 ; trap
+;   jghe .+2 # trap=int_ovf
 ;   bras %r1, 8 ; data.f32 -1 ; vlef %v16, 0(%r1), 0
 ;   wfcsb %f0, %v16
-;   jnle 6 ; trap
+;   jgle .+2 # trap=int_ovf
 ;   wldeb %v20, %f0
 ;   wclgdb %v22, %v20, 0, 5
 ;   vlgvg %r2, %v22, 0
@@ -959,20 +941,17 @@ block0(v0: f32):
 ; Disassembled:
 ; block0: ; offset 0x0
 ;   cebr %f0, %f0
-;   jno 0xa
-;   .byte 0x00, 0x00 ; trap: bad_toint
+;   jgo 6 ; trap: bad_toint
 ;   bras %r1, 0x12
 ;   sl %r8, 0
 ;   le %f4, 0(%r1)
 ;   cebr %f0, %f4
-;   jnhe 0x20
-;   .byte 0x00, 0x00 ; trap: int_ovf
+;   jghe 0x1c ; trap: int_ovf
 ;   bras %r1, 0x28
 ;   icm %r8, 0, 0
 ;   vlef %v16, 0(%r1), 0
 ;   wfcsb %f0, %v16
-;   jnle 0x3a
-;   .byte 0x00, 0x00 ; trap: int_ovf
+;   jgle 0x36 ; trap: int_ovf
 ;   wldeb %v20, %f0
 ;   wclgdb %v22, %v20, 0, 5
 ;   vlgvg %r2, %v22, 0
@@ -987,13 +966,13 @@ block0(v0: f32):
 ; VCode:
 ; block0:
 ;   cebr %f0, %f0
-;   jno 6 ; trap
+;   jgo .+2 # trap=bad_toint
 ;   bras %r1, 8 ; data.f32 9223372000000000000 ; le %f4, 0(%r1)
 ;   cebr %f0, %f4
-;   jnhe 6 ; trap
+;   jghe .+2 # trap=int_ovf
 ;   bras %r1, 8 ; data.f32 -9223373000000000000 ; vlef %v16, 0(%r1), 0
 ;   wfcsb %f0, %v16
-;   jnle 6 ; trap
+;   jgle .+2 # trap=int_ovf
 ;   wldeb %v20, %f0
 ;   wcgdb %v22, %v20, 0, 5
 ;   vlgvg %r2, %v22, 0
@@ -1002,21 +981,18 @@ block0(v0: f32):
 ; Disassembled:
 ; block0: ; offset 0x0
 ;   cebr %f0, %f0
-;   jno 0xa
-;   .byte 0x00, 0x00 ; trap: bad_toint
+;   jgo 6 ; trap: bad_toint
 ;   bras %r1, 0x12
 ;   sl %r0, 0
 ;   le %f4, 0(%r1)
 ;   cebr %f0, %f4
-;   jnhe 0x20
-;   .byte 0x00, 0x00 ; trap: int_ovf
+;   jghe 0x1c ; trap: int_ovf
 ;   bras %r1, 0x28
 ;   edmk 1(1), 0x700(%r14)
 ;   lpr %r0, %r0
 ;   .byte 0x08, 0x03
 ;   wfcsb %f0, %v16
-;   jnle 0x3a
-;   .byte 0x00, 0x00 ; trap: int_ovf
+;   jgle 0x36 ; trap: int_ovf
 ;   wldeb %v20, %f0
 ;   wcgdb %v22, %v20, 0, 5
 ;   vlgvg %r2, %v22, 0
@@ -1031,13 +1007,13 @@ block0(v0: f64):
 ; VCode:
 ; block0:
 ;   cdbr %f0, %f0
-;   jno 6 ; trap
+;   jgo .+2 # trap=bad_toint
 ;   bras %r1, 12 ; data.f64 256 ; ld %f4, 0(%r1)
 ;   cdbr %f0, %f4
-;   jnhe 6 ; trap
+;   jghe .+2 # trap=int_ovf
 ;   bras %r1, 12 ; data.f64 -1 ; vleg %v16, 0(%r1), 0
 ;   wfcdb %f0, %v16
-;   jnle 6 ; trap
+;   jgle .+2 # trap=int_ovf
 ;   wclgdb %v20, %f0, 0, 5
 ;   vlgvg %r2, %v20, 0
 ;   br %r14
@@ -1045,24 +1021,21 @@ block0(v0: f64):
 ; Disassembled:
 ; block0: ; offset 0x0
 ;   cdbr %f0, %f0
-;   jno 0xa
-;   .byte 0x00, 0x00 ; trap: bad_toint
+;   jgo 6 ; trap: bad_toint
 ;   bras %r1, 0x16
 ;   sth %r7, 0
 ;   .byte 0x00, 0x00
 ;   .byte 0x00, 0x00
 ;   ld %f4, 0(%r1)
 ;   cdbr %f0, %f4
-;   jnhe 0x24
-;   .byte 0x00, 0x00 ; trap: int_ovf
+;   jghe 0x20 ; trap: int_ovf
 ;   bras %r1, 0x30
 ;   icm %r15, 0, 0
 ;   .byte 0x00, 0x00
 ;   .byte 0x00, 0x00
 ;   vleg %v16, 0(%r1), 0
 ;   wfcdb %f0, %v16
-;   jnle 0x42
-;   .byte 0x00, 0x00 ; trap: int_ovf
+;   jgle 0x3e ; trap: int_ovf
 ;   wclgdb %v20, %f0, 0, 5
 ;   vlgvg %r2, %v20, 0
 ;   br %r14
@@ -1076,13 +1049,13 @@ block0(v0: f64):
 ; VCode:
 ; block0:
 ;   cdbr %f0, %f0
-;   jno 6 ; trap
+;   jgo .+2 # trap=bad_toint
 ;   bras %r1, 12 ; data.f64 128 ; ld %f4, 0(%r1)
 ;   cdbr %f0, %f4
-;   jnhe 6 ; trap
+;   jghe .+2 # trap=int_ovf
 ;   bras %r1, 12 ; data.f64 -129 ; vleg %v16, 0(%r1), 0
 ;   wfcdb %f0, %v16
-;   jnle 6 ; trap
+;   jgle .+2 # trap=int_ovf
 ;   wcgdb %v20, %f0, 0, 5
 ;   vlgvg %r2, %v20, 0
 ;   br %r14
@@ -1090,23 +1063,20 @@ block0(v0: f64):
 ; Disassembled:
 ; block0: ; offset 0x0
 ;   cdbr %f0, %f0
-;   jno 0xa
-;   .byte 0x00, 0x00 ; trap: bad_toint
+;   jgo 6 ; trap: bad_toint
 ;   bras %r1, 0x16
 ;   sth %r6, 0
 ;   .byte 0x00, 0x00
 ;   .byte 0x00, 0x00
 ;   ld %f4, 0(%r1)
 ;   cdbr %f0, %f4
-;   jnhe 0x24
-;   .byte 0x00, 0x00 ; trap: int_ovf
+;   jghe 0x20 ; trap: int_ovf
 ;   bras %r1, 0x30
 ;   larl %r6, 0x40000028
 ;   .byte 0x00, 0x00
 ;   vleg %v16, 0(%r1), 0
 ;   wfcdb %f0, %v16
-;   jnle 0x42
-;   .byte 0x00, 0x00 ; trap: int_ovf
+;   jgle 0x3e ; trap: int_ovf
 ;   wcgdb %v20, %f0, 0, 5
 ;   vlgvg %r2, %v20, 0
 ;   br %r14
@@ -1120,13 +1090,13 @@ block0(v0: f64):
 ; VCode:
 ; block0:
 ;   cdbr %f0, %f0
-;   jno 6 ; trap
+;   jgo .+2 # trap=bad_toint
 ;   bras %r1, 12 ; data.f64 65536 ; ld %f4, 0(%r1)
 ;   cdbr %f0, %f4
-;   jnhe 6 ; trap
+;   jghe .+2 # trap=int_ovf
 ;   bras %r1, 12 ; data.f64 -1 ; vleg %v16, 0(%r1), 0
 ;   wfcdb %f0, %v16
-;   jnle 6 ; trap
+;   jgle .+2 # trap=int_ovf
 ;   wclgdb %v20, %f0, 0, 5
 ;   vlgvg %r2, %v20, 0
 ;   br %r14
@@ -1134,24 +1104,21 @@ block0(v0: f64):
 ; Disassembled:
 ; block0: ; offset 0x0
 ;   cdbr %f0, %f0
-;   jno 0xa
-;   .byte 0x00, 0x00 ; trap: bad_toint
+;   jgo 6 ; trap: bad_toint
 ;   bras %r1, 0x16
 ;   sth %r15, 0
 ;   .byte 0x00, 0x00
 ;   .byte 0x00, 0x00
 ;   ld %f4, 0(%r1)
 ;   cdbr %f0, %f4
-;   jnhe 0x24
-;   .byte 0x00, 0x00 ; trap: int_ovf
+;   jghe 0x20 ; trap: int_ovf
 ;   bras %r1, 0x30
 ;   icm %r15, 0, 0
 ;   .byte 0x00, 0x00
 ;   .byte 0x00, 0x00
 ;   vleg %v16, 0(%r1), 0
 ;   wfcdb %f0, %v16
-;   jnle 0x42
-;   .byte 0x00, 0x00 ; trap: int_ovf
+;   jgle 0x3e ; trap: int_ovf
 ;   wclgdb %v20, %f0, 0, 5
 ;   vlgvg %r2, %v20, 0
 ;   br %r14
@@ -1165,13 +1132,13 @@ block0(v0: f64):
 ; VCode:
 ; block0:
 ;   cdbr %f0, %f0
-;   jno 6 ; trap
+;   jgo .+2 # trap=bad_toint
 ;   bras %r1, 12 ; data.f64 32768 ; ld %f4, 0(%r1)
 ;   cdbr %f0, %f4
-;   jnhe 6 ; trap
+;   jghe .+2 # trap=int_ovf
 ;   bras %r1, 12 ; data.f64 -32769 ; vleg %v16, 0(%r1), 0
 ;   wfcdb %f0, %v16
-;   jnle 6 ; trap
+;   jgle .+2 # trap=int_ovf
 ;   wcgdb %v20, %f0, 0, 5
 ;   vlgvg %r2, %v20, 0
 ;   br %r14
@@ -1179,23 +1146,20 @@ block0(v0: f64):
 ; Disassembled:
 ; block0: ; offset 0x0
 ;   cdbr %f0, %f0
-;   jno 0xa
-;   .byte 0x00, 0x00 ; trap: bad_toint
+;   jgo 6 ; trap: bad_toint
 ;   bras %r1, 0x16
 ;   sth %r14, 0
 ;   .byte 0x00, 0x00
 ;   .byte 0x00, 0x00
 ;   ld %f4, 0(%r1)
 ;   cdbr %f0, %f4
-;   jnhe 0x24
-;   .byte 0x00, 0x00 ; trap: int_ovf
+;   jghe 0x20 ; trap: int_ovf
 ;   bras %r1, 0x30
 ;   larl %r14, 0x400028
 ;   .byte 0x00, 0x00
 ;   vleg %v16, 0(%r1), 0
 ;   wfcdb %f0, %v16
-;   jnle 0x42
-;   .byte 0x00, 0x00 ; trap: int_ovf
+;   jgle 0x3e ; trap: int_ovf
 ;   wcgdb %v20, %f0, 0, 5
 ;   vlgvg %r2, %v20, 0
 ;   br %r14
@@ -1209,13 +1173,13 @@ block0(v0: f64):
 ; VCode:
 ; block0:
 ;   cdbr %f0, %f0
-;   jno 6 ; trap
+;   jgo .+2 # trap=bad_toint
 ;   bras %r1, 12 ; data.f64 4294967296 ; ld %f4, 0(%r1)
 ;   cdbr %f0, %f4
-;   jnhe 6 ; trap
+;   jghe .+2 # trap=int_ovf
 ;   bras %r1, 12 ; data.f64 -1 ; vleg %v16, 0(%r1), 0
 ;   wfcdb %f0, %v16
-;   jnle 6 ; trap
+;   jgle .+2 # trap=int_ovf
 ;   wclgdb %v20, %f0, 0, 5
 ;   vlgvg %r2, %v20, 0
 ;   br %r14
@@ -1223,24 +1187,21 @@ block0(v0: f64):
 ; Disassembled:
 ; block0: ; offset 0x0
 ;   cdbr %f0, %f0
-;   jno 0xa
-;   .byte 0x00, 0x00 ; trap: bad_toint
+;   jgo 6 ; trap: bad_toint
 ;   bras %r1, 0x16
 ;   la %r15, 0
 ;   .byte 0x00, 0x00
 ;   .byte 0x00, 0x00
 ;   ld %f4, 0(%r1)
 ;   cdbr %f0, %f4
-;   jnhe 0x24
-;   .byte 0x00, 0x00 ; trap: int_ovf
+;   jghe 0x20 ; trap: int_ovf
 ;   bras %r1, 0x30
 ;   icm %r15, 0, 0
 ;   .byte 0x00, 0x00
 ;   .byte 0x00, 0x00
 ;   vleg %v16, 0(%r1), 0
 ;   wfcdb %f0, %v16
-;   jnle 0x42
-;   .byte 0x00, 0x00 ; trap: int_ovf
+;   jgle 0x3e ; trap: int_ovf
 ;   wclgdb %v20, %f0, 0, 5
 ;   vlgvg %r2, %v20, 0
 ;   br %r14
@@ -1254,13 +1215,13 @@ block0(v0: f64):
 ; VCode:
 ; block0:
 ;   cdbr %f0, %f0
-;   jno 6 ; trap
+;   jgo .+2 # trap=bad_toint
 ;   bras %r1, 12 ; data.f64 2147483648 ; ld %f4, 0(%r1)
 ;   cdbr %f0, %f4
-;   jnhe 6 ; trap
+;   jghe .+2 # trap=int_ovf
 ;   bras %r1, 12 ; data.f64 -2147483649 ; vleg %v16, 0(%r1), 0
 ;   wfcdb %f0, %v16
-;   jnle 6 ; trap
+;   jgle .+2 # trap=int_ovf
 ;   wcgdb %v20, %f0, 0, 5
 ;   vlgvg %r2, %v20, 0
 ;   br %r14
@@ -1268,16 +1229,14 @@ block0(v0: f64):
 ; Disassembled:
 ; block0: ; offset 0x0
 ;   cdbr %f0, %f0
-;   jno 0xa
-;   .byte 0x00, 0x00 ; trap: bad_toint
+;   jgo 6 ; trap: bad_toint
 ;   bras %r1, 0x16
 ;   la %r14, 0
 ;   .byte 0x00, 0x00
 ;   .byte 0x00, 0x00
 ;   ld %f4, 0(%r1)
 ;   cdbr %f0, %f4
-;   jnhe 0x24
-;   .byte 0x00, 0x00 ; trap: int_ovf
+;   jghe 0x20 ; trap: int_ovf
 ;   bras %r1, 0x30
 ;   .byte 0xc1, 0xe0
 ;   .byte 0x00, 0x00
@@ -1285,8 +1244,7 @@ block0(v0: f64):
 ;   .byte 0x00, 0x00
 ;   vleg %v16, 0(%r1), 0
 ;   wfcdb %f0, %v16
-;   jnle 0x42
-;   .byte 0x00, 0x00 ; trap: int_ovf
+;   jgle 0x3e ; trap: int_ovf
 ;   wcgdb %v20, %f0, 0, 5
 ;   vlgvg %r2, %v20, 0
 ;   br %r14
@@ -1300,13 +1258,13 @@ block0(v0: f64):
 ; VCode:
 ; block0:
 ;   cdbr %f0, %f0
-;   jno 6 ; trap
+;   jgo .+2 # trap=bad_toint
 ;   bras %r1, 12 ; data.f64 18446744073709552000 ; ld %f4, 0(%r1)
 ;   cdbr %f0, %f4
-;   jnhe 6 ; trap
+;   jghe .+2 # trap=int_ovf
 ;   bras %r1, 12 ; data.f64 -1 ; vleg %v16, 0(%r1), 0
 ;   wfcdb %f0, %v16
-;   jnle 6 ; trap
+;   jgle .+2 # trap=int_ovf
 ;   wclgdb %v20, %f0, 0, 5
 ;   vlgvg %r2, %v20, 0
 ;   br %r14
@@ -1314,24 +1272,21 @@ block0(v0: f64):
 ; Disassembled:
 ; block0: ; offset 0x0
 ;   cdbr %f0, %f0
-;   jno 0xa
-;   .byte 0x00, 0x00 ; trap: bad_toint
+;   jgo 6 ; trap: bad_toint
 ;   bras %r1, 0x16
 ;   ic %r15, 0
 ;   .byte 0x00, 0x00
 ;   .byte 0x00, 0x00
 ;   ld %f4, 0(%r1)
 ;   cdbr %f0, %f4
-;   jnhe 0x24
-;   .byte 0x00, 0x00 ; trap: int_ovf
+;   jghe 0x20 ; trap: int_ovf
 ;   bras %r1, 0x30
 ;   icm %r15, 0, 0
 ;   .byte 0x00, 0x00
 ;   .byte 0x00, 0x00
 ;   vleg %v16, 0(%r1), 0
 ;   wfcdb %f0, %v16
-;   jnle 0x42
-;   .byte 0x00, 0x00 ; trap: int_ovf
+;   jgle 0x3e ; trap: int_ovf
 ;   wclgdb %v20, %f0, 0, 5
 ;   vlgvg %r2, %v20, 0
 ;   br %r14
@@ -1345,13 +1300,13 @@ block0(v0: f64):
 ; VCode:
 ; block0:
 ;   cdbr %f0, %f0
-;   jno 6 ; trap
+;   jgo .+2 # trap=bad_toint
 ;   bras %r1, 12 ; data.f64 9223372036854776000 ; ld %f4, 0(%r1)
 ;   cdbr %f0, %f4
-;   jnhe 6 ; trap
+;   jghe .+2 # trap=int_ovf
 ;   bras %r1, 12 ; data.f64 -9223372036854778000 ; vleg %v16, 0(%r1), 0
 ;   wfcdb %f0, %v16
-;   jnle 6 ; trap
+;   jgle .+2 # trap=int_ovf
 ;   wcgdb %v20, %f0, 0, 5
 ;   vlgvg %r2, %v20, 0
 ;   br %r14
@@ -1359,16 +1314,14 @@ block0(v0: f64):
 ; Disassembled:
 ; block0: ; offset 0x0
 ;   cdbr %f0, %f0
-;   jno 0xa
-;   .byte 0x00, 0x00 ; trap: bad_toint
+;   jgo 6 ; trap: bad_toint
 ;   bras %r1, 0x16
 ;   ic %r14, 0
 ;   .byte 0x00, 0x00
 ;   .byte 0x00, 0x00
 ;   ld %f4, 0(%r1)
 ;   cdbr %f0, %f4
-;   jnhe 0x24
-;   .byte 0x00, 0x00 ; trap: int_ovf
+;   jghe 0x20 ; trap: int_ovf
 ;   bras %r1, 0x30
 ;   .byte 0xc3, 0xe0
 ;   .byte 0x00, 0x00
@@ -1376,8 +1329,7 @@ block0(v0: f64):
 ;   .byte 0x00, 0x01
 ;   vleg %v16, 0(%r1), 0
 ;   wfcdb %f0, %v16
-;   jnle 0x42
-;   .byte 0x00, 0x00 ; trap: int_ovf
+;   jgle 0x3e ; trap: int_ovf
 ;   wcgdb %v20, %f0, 0, 5
 ;   vlgvg %r2, %v20, 0
 ;   br %r14
diff --git a/cranelift/filetests/filetests/isa/s390x/traps.clif b/cranelift/filetests/filetests/isa/s390x/traps.clif
index 101a17946..7759f6c8e 100644
--- a/cranelift/filetests/filetests/isa/s390x/traps.clif
+++ b/cranelift/filetests/filetests/isa/s390x/traps.clif
@@ -12,7 +12,7 @@ block0:
 
 ; VCode:
 ; block0:
-;   trap
+;   .word 0x0000 # trap=user0
 ; 
 ; Disassembled:
 ; block0: ; offset 0x0
@@ -25,7 +25,7 @@ block0:
 
 ; VCode:
 ; block0:
-;   trap
+;   .word 0x0000 # trap=user0
 ; 
 ; Disassembled:
 ; block0: ; offset 0x0
@@ -46,7 +46,7 @@ block0(v0: i64):
 ; block2:
 ;   br %r14
 ; block1:
-;   trap
+;   .word 0x0000 # trap=user0
 ; 
 ; Disassembled:
 ; block0: ; offset 0x0
@@ -72,7 +72,7 @@ block0(v0: i64):
 ; block1:
 ;   br %r14
 ; block2:
-;   trap
+;   .word 0x0000 # trap=user0
 ; 
 ; Disassembled:
 ; block0: ; offset 0x0
@@ -98,7 +98,7 @@ block0(v0: i64):
 ; block1:
 ;   br %r14
 ; block2:
-;   trap
+;   .word 0x0000 # trap=user0
 ; 
 ; Disassembled:
 ; block0: ; offset 0x0
@@ -117,7 +117,7 @@ block0:
 
 ; VCode:
 ; block0:
-;   debugtrap
+;   .word 0x0001 # debugtrap
 ;   br %r14
 ; 
 ; Disassembled:
diff --git a/cranelift/filetests/filetests/isa/s390x/uadd_overflow_trap.clif b/cranelift/filetests/filetests/isa/s390x/uadd_overflow_trap.clif
index f49a40590..dd5f8f798 100644
--- a/cranelift/filetests/filetests/isa/s390x/uadd_overflow_trap.clif
+++ b/cranelift/filetests/filetests/isa/s390x/uadd_overflow_trap.clif
@@ -11,14 +11,13 @@ block0(v0: i32):
 ; VCode:
 ; block0:
 ;   alfi %r2, 127
-;   jle 6 ; trap
+;   jgnle .+2 # trap=user0
 ;   br %r14
 ; 
 ; Disassembled:
 ; block0: ; offset 0x0
 ;   alfi %r2, 0x7f
-;   jle 0xc
-;   .byte 0x00, 0x00 ; trap: user0
+;   jgnle 8 ; trap: user0
 ;   br %r14
 
 function %f1(i32) -> i32 {
@@ -31,14 +30,13 @@ block0(v0: i32):
 ; VCode:
 ; block0:
 ;   alfi %r2, 127
-;   jle 6 ; trap
+;   jgnle .+2 # trap=user0
 ;   br %r14
 ; 
 ; Disassembled:
 ; block0: ; offset 0x0
 ;   alfi %r2, 0x7f
-;   jle 0xc
-;   .byte 0x00, 0x00 ; trap: user0
+;   jgnle 8 ; trap: user0
 ;   br %r14
 
 function %f2(i32, i32) -> i32 {
@@ -50,14 +48,13 @@ block0(v0: i32, v1: i32):
 ; VCode:
 ; block0:
 ;   alr %r2, %r3
-;   jle 6 ; trap
+;   jgnle .+2 # trap=user0
 ;   br %r14
 ; 
 ; Disassembled:
 ; block0: ; offset 0x0
 ;   alr %r2, %r3
-;   jle 8
-;   .byte 0x00, 0x00 ; trap: user0
+;   jgnle 4 ; trap: user0
 ;   br %r14
 
 function %f3(i64) -> i64 {
@@ -70,14 +67,13 @@ block0(v0: i64):
 ; VCode:
 ; block0:
 ;   algfi %r2, 127
-;   jle 6 ; trap
+;   jgnle .+2 # trap=user0
 ;   br %r14
 ; 
 ; Disassembled:
 ; block0: ; offset 0x0
 ;   algfi %r2, 0x7f
-;   jle 0xc
-;   .byte 0x00, 0x00 ; trap: user0
+;   jgnle 8 ; trap: user0
 ;   br %r14
 
 function %f3(i64) -> i64 {
@@ -90,14 +86,13 @@ block0(v0: i64):
 ; VCode:
 ; block0:
 ;   algfi %r2, 127
-;   jle 6 ; trap
+;   jgnle .+2 # trap=user0
 ;   br %r14
 ; 
 ; Disassembled:
 ; block0: ; offset 0x0
 ;   algfi %r2, 0x7f
-;   jle 0xc
-;   .byte 0x00, 0x00 ; trap: user0
+;   jgnle 8 ; trap: user0
 ;   br %r14
 
 function %f4(i64, i64) -> i64 {
@@ -109,14 +104,13 @@ block0(v0: i64, v1: i64):
 ; VCode:
 ; block0:
 ;   algr %r2, %r3
-;   jle 6 ; trap
+;   jgnle .+2 # trap=user0
 ;   br %r14
 ; 
 ; Disassembled:
 ; block0: ; offset 0x0
 ;   algr %r2, %r3
-;   jle 0xa
-;   .byte 0x00, 0x00 ; trap: user0
+;   jgnle 6 ; trap: user0
 ;   br %r14
 
 function %f5(i64, i32) -> i64 {
@@ -129,13 +123,12 @@ block0(v0: i64, v1: i32):
 ; VCode:
 ; block0:
 ;   algfr %r2, %r3
-;   jle 6 ; trap
+;   jgnle .+2 # trap=user0
 ;   br %r14
 ; 
 ; Disassembled:
 ; block0: ; offset 0x0
 ;   algfr %r2, %r3
-;   jle 0xa
-;   .byte 0x00, 0x00 ; trap: user0
+;   jgnle 6 ; trap: user0
 ;   br %r14
 
diff --git a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i32_index_0_guard_no_spectre_i32_access_0_offset.wat b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i32_index_0_guard_no_spectre_i32_access_0_offset.wat
index 44a3712ac..58e5f0894 100644
--- a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i32_index_0_guard_no_spectre_i32_access_0_offset.wat
+++ b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i32_index_0_guard_no_spectre_i32_access_0_offset.wat
@@ -55,7 +55,7 @@
 ;; block2:
 ;;   br %r14
 ;; block3:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
 ;;
 ;; function u0:1:
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 160, offset_downward_to_clobbers: 0 }
@@ -73,4 +73,4 @@
 ;; block2:
 ;;   br %r14
 ;; block3:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
diff --git a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i32_index_0_guard_no_spectre_i32_access_0x1000_offset.wat b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i32_index_0_guard_no_spectre_i32_access_0x1000_offset.wat
index b4f3e24f8..709818f96 100644
--- a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i32_index_0_guard_no_spectre_i32_access_0x1000_offset.wat
+++ b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i32_index_0_guard_no_spectre_i32_access_0x1000_offset.wat
@@ -57,7 +57,7 @@
 ;; block2:
 ;;   br %r14
 ;; block3:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
 ;;
 ;; function u0:1:
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 160, offset_downward_to_clobbers: 0 }
@@ -78,4 +78,4 @@
 ;; block2:
 ;;   br %r14
 ;; block3:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
diff --git a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i32_index_0_guard_no_spectre_i32_access_0xffff0000_offset.wat b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i32_index_0_guard_no_spectre_i32_access_0xffff0000_offset.wat
index 3b19386e2..36dc8ac55 100644
--- a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i32_index_0_guard_no_spectre_i32_access_0xffff0000_offset.wat
+++ b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i32_index_0_guard_no_spectre_i32_access_0xffff0000_offset.wat
@@ -58,7 +58,7 @@
 ;;   lgr %r5, %r2
 ;;   llilf %r2, 4294901764
 ;;   algfr %r2, %r5
-;;   jle 6 ; trap
+;;   jgnle .+2 # trap=heap_oob
 ;;   lgr %r5, %r7
 ;;   lg %r7, 8(%r5)
 ;;   clgr %r2, %r7
@@ -72,7 +72,7 @@
 ;;   lmg %r7, %r15, 56(%r15)
 ;;   br %r14
 ;; block3:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
 ;;
 ;; function u0:1:
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 160, offset_downward_to_clobbers: 0 }
@@ -82,7 +82,7 @@
 ;;   llgfr %r3, %r2
 ;;   llilf %r5, 4294901764
 ;;   algfr %r5, %r2
-;;   jle 6 ; trap
+;;   jgnle .+2 # trap=heap_oob
 ;;   lg %r2, 8(%r4)
 ;;   clgr %r5, %r2
 ;;   jgh label3 ; jg label1
@@ -94,4 +94,4 @@
 ;; block2:
 ;;   br %r14
 ;; block3:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
diff --git a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i32_index_0_guard_no_spectre_i8_access_0_offset.wat b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i32_index_0_guard_no_spectre_i8_access_0_offset.wat
index 5e29e4117..8d2f03cd7 100644
--- a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i32_index_0_guard_no_spectre_i8_access_0_offset.wat
+++ b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i32_index_0_guard_no_spectre_i8_access_0_offset.wat
@@ -56,7 +56,7 @@
 ;; block2:
 ;;   br %r14
 ;; block3:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
 ;;
 ;; function u0:1:
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 160, offset_downward_to_clobbers: 0 }
@@ -73,4 +73,4 @@
 ;; block2:
 ;;   br %r14
 ;; block3:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
diff --git a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i32_index_0_guard_no_spectre_i8_access_0x1000_offset.wat b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i32_index_0_guard_no_spectre_i8_access_0x1000_offset.wat
index 502af723d..2b7e0f548 100644
--- a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i32_index_0_guard_no_spectre_i8_access_0x1000_offset.wat
+++ b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i32_index_0_guard_no_spectre_i8_access_0x1000_offset.wat
@@ -57,7 +57,7 @@
 ;; block2:
 ;;   br %r14
 ;; block3:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
 ;;
 ;; function u0:1:
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 160, offset_downward_to_clobbers: 0 }
@@ -78,4 +78,4 @@
 ;; block2:
 ;;   br %r14
 ;; block3:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
diff --git a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i32_index_0_guard_no_spectre_i8_access_0xffff0000_offset.wat b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i32_index_0_guard_no_spectre_i8_access_0xffff0000_offset.wat
index 08084f5b1..2c17d1cc0 100644
--- a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i32_index_0_guard_no_spectre_i8_access_0xffff0000_offset.wat
+++ b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i32_index_0_guard_no_spectre_i8_access_0xffff0000_offset.wat
@@ -58,7 +58,7 @@
 ;;   lgr %r5, %r2
 ;;   llilf %r2, 4294901761
 ;;   algfr %r2, %r5
-;;   jle 6 ; trap
+;;   jgnle .+2 # trap=heap_oob
 ;;   lgr %r5, %r7
 ;;   lg %r7, 8(%r5)
 ;;   clgr %r2, %r7
@@ -72,7 +72,7 @@
 ;;   lmg %r7, %r15, 56(%r15)
 ;;   br %r14
 ;; block3:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
 ;;
 ;; function u0:1:
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 160, offset_downward_to_clobbers: 0 }
@@ -82,7 +82,7 @@
 ;;   llgfr %r3, %r2
 ;;   llilf %r5, 4294901761
 ;;   algfr %r5, %r2
-;;   jle 6 ; trap
+;;   jgnle .+2 # trap=heap_oob
 ;;   lg %r2, 8(%r4)
 ;;   clgr %r5, %r2
 ;;   jgh label3 ; jg label1
@@ -94,4 +94,4 @@
 ;; block2:
 ;;   br %r14
 ;; block3:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
diff --git a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i32_index_0_guard_yes_spectre_i32_access_0xffff0000_offset.wat b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i32_index_0_guard_yes_spectre_i32_access_0xffff0000_offset.wat
index 1c1a1189a..bd864d0c6 100644
--- a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i32_index_0_guard_yes_spectre_i32_access_0xffff0000_offset.wat
+++ b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i32_index_0_guard_yes_spectre_i32_access_0xffff0000_offset.wat
@@ -55,7 +55,7 @@
 ;;   llgfr %r4, %r2
 ;;   llilf %r9, 4294901764
 ;;   algfr %r9, %r2
-;;   jle 6 ; trap
+;;   jgnle .+2 # trap=heap_oob
 ;;   lgr %r2, %r5
 ;;   lg %r5, 8(%r2)
 ;;   ag %r4, 0(%r2)
@@ -78,7 +78,7 @@
 ;;   llgfr %r3, %r2
 ;;   llilf %r5, 4294901764
 ;;   algfr %r5, %r2
-;;   jle 6 ; trap
+;;   jgnle .+2 # trap=heap_oob
 ;;   lgr %r2, %r4
 ;;   lg %r4, 8(%r2)
 ;;   ag %r3, 0(%r2)
diff --git a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i32_index_0_guard_yes_spectre_i8_access_0xffff0000_offset.wat b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i32_index_0_guard_yes_spectre_i8_access_0xffff0000_offset.wat
index 9741ef2df..9f0e71fb6 100644
--- a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i32_index_0_guard_yes_spectre_i8_access_0xffff0000_offset.wat
+++ b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i32_index_0_guard_yes_spectre_i8_access_0xffff0000_offset.wat
@@ -55,7 +55,7 @@
 ;;   llgfr %r4, %r2
 ;;   llilf %r9, 4294901761
 ;;   algfr %r9, %r2
-;;   jle 6 ; trap
+;;   jgnle .+2 # trap=heap_oob
 ;;   lgr %r2, %r5
 ;;   lg %r5, 8(%r2)
 ;;   ag %r4, 0(%r2)
@@ -78,7 +78,7 @@
 ;;   llgfr %r3, %r2
 ;;   llilf %r5, 4294901761
 ;;   algfr %r5, %r2
-;;   jle 6 ; trap
+;;   jgnle .+2 # trap=heap_oob
 ;;   lgr %r2, %r4
 ;;   lg %r4, 8(%r2)
 ;;   ag %r3, 0(%r2)
diff --git a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i32_index_0xffffffff_guard_no_spectre_i32_access_0_offset.wat b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i32_index_0xffffffff_guard_no_spectre_i32_access_0_offset.wat
index 708e4bfe8..a746643e2 100644
--- a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i32_index_0xffffffff_guard_no_spectre_i32_access_0_offset.wat
+++ b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i32_index_0xffffffff_guard_no_spectre_i32_access_0_offset.wat
@@ -56,7 +56,7 @@
 ;; block2:
 ;;   br %r14
 ;; block3:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
 ;;
 ;; function u0:1:
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 160, offset_downward_to_clobbers: 0 }
@@ -73,4 +73,4 @@
 ;; block2:
 ;;   br %r14
 ;; block3:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
diff --git a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i32_index_0xffffffff_guard_no_spectre_i32_access_0x1000_offset.wat b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i32_index_0xffffffff_guard_no_spectre_i32_access_0x1000_offset.wat
index d7f0c5361..d9e076100 100644
--- a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i32_index_0xffffffff_guard_no_spectre_i32_access_0x1000_offset.wat
+++ b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i32_index_0xffffffff_guard_no_spectre_i32_access_0x1000_offset.wat
@@ -56,7 +56,7 @@
 ;; block2:
 ;;   br %r14
 ;; block3:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
 ;;
 ;; function u0:1:
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 160, offset_downward_to_clobbers: 0 }
@@ -75,4 +75,4 @@
 ;; block2:
 ;;   br %r14
 ;; block3:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
diff --git a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i32_index_0xffffffff_guard_no_spectre_i32_access_0xffff0000_offset.wat b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i32_index_0xffffffff_guard_no_spectre_i32_access_0xffff0000_offset.wat
index efe0b2cd1..4be98bd7a 100644
--- a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i32_index_0xffffffff_guard_no_spectre_i32_access_0xffff0000_offset.wat
+++ b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i32_index_0xffffffff_guard_no_spectre_i32_access_0xffff0000_offset.wat
@@ -56,7 +56,7 @@
 ;; block2:
 ;;   br %r14
 ;; block3:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
 ;;
 ;; function u0:1:
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 160, offset_downward_to_clobbers: 0 }
@@ -75,4 +75,4 @@
 ;; block2:
 ;;   br %r14
 ;; block3:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
diff --git a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i32_index_0xffffffff_guard_no_spectre_i8_access_0_offset.wat b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i32_index_0xffffffff_guard_no_spectre_i8_access_0_offset.wat
index 18bdd868a..306699d99 100644
--- a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i32_index_0xffffffff_guard_no_spectre_i8_access_0_offset.wat
+++ b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i32_index_0xffffffff_guard_no_spectre_i8_access_0_offset.wat
@@ -56,7 +56,7 @@
 ;; block2:
 ;;   br %r14
 ;; block3:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
 ;;
 ;; function u0:1:
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 160, offset_downward_to_clobbers: 0 }
@@ -73,4 +73,4 @@
 ;; block2:
 ;;   br %r14
 ;; block3:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
diff --git a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i32_index_0xffffffff_guard_no_spectre_i8_access_0x1000_offset.wat b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i32_index_0xffffffff_guard_no_spectre_i8_access_0x1000_offset.wat
index 4288c8491..fa1828b95 100644
--- a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i32_index_0xffffffff_guard_no_spectre_i8_access_0x1000_offset.wat
+++ b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i32_index_0xffffffff_guard_no_spectre_i8_access_0x1000_offset.wat
@@ -56,7 +56,7 @@
 ;; block2:
 ;;   br %r14
 ;; block3:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
 ;;
 ;; function u0:1:
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 160, offset_downward_to_clobbers: 0 }
@@ -75,4 +75,4 @@
 ;; block2:
 ;;   br %r14
 ;; block3:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
diff --git a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i32_index_0xffffffff_guard_no_spectre_i8_access_0xffff0000_offset.wat b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i32_index_0xffffffff_guard_no_spectre_i8_access_0xffff0000_offset.wat
index 2c0ddb02e..49d92de1a 100644
--- a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i32_index_0xffffffff_guard_no_spectre_i8_access_0xffff0000_offset.wat
+++ b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i32_index_0xffffffff_guard_no_spectre_i8_access_0xffff0000_offset.wat
@@ -56,7 +56,7 @@
 ;; block2:
 ;;   br %r14
 ;; block3:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
 ;;
 ;; function u0:1:
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 160, offset_downward_to_clobbers: 0 }
@@ -75,4 +75,4 @@
 ;; block2:
 ;;   br %r14
 ;; block3:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
diff --git a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i64_index_0_guard_no_spectre_i32_access_0_offset.wat b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i64_index_0_guard_no_spectre_i32_access_0_offset.wat
index 40b318783..7c7974d27 100644
--- a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i64_index_0_guard_no_spectre_i32_access_0_offset.wat
+++ b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i64_index_0_guard_no_spectre_i32_access_0_offset.wat
@@ -54,7 +54,7 @@
 ;; block2:
 ;;   br %r14
 ;; block3:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
 ;;
 ;; function u0:1:
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 160, offset_downward_to_clobbers: 0 }
@@ -71,4 +71,4 @@
 ;; block2:
 ;;   br %r14
 ;; block3:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
diff --git a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i64_index_0_guard_no_spectre_i32_access_0x1000_offset.wat b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i64_index_0_guard_no_spectre_i32_access_0x1000_offset.wat
index b40b27c87..536d2560c 100644
--- a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i64_index_0_guard_no_spectre_i32_access_0x1000_offset.wat
+++ b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i64_index_0_guard_no_spectre_i32_access_0x1000_offset.wat
@@ -56,7 +56,7 @@
 ;; block2:
 ;;   br %r14
 ;; block3:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
 ;;
 ;; function u0:1:
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 160, offset_downward_to_clobbers: 0 }
@@ -75,4 +75,4 @@
 ;; block2:
 ;;   br %r14
 ;; block3:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
diff --git a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i64_index_0_guard_no_spectre_i32_access_0xffff0000_offset.wat b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i64_index_0_guard_no_spectre_i32_access_0xffff0000_offset.wat
index 1a8a615d1..0abec009a 100644
--- a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i64_index_0_guard_no_spectre_i32_access_0xffff0000_offset.wat
+++ b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i64_index_0_guard_no_spectre_i32_access_0xffff0000_offset.wat
@@ -48,7 +48,7 @@
 ;; block0:
 ;;   lgr %r5, %r2
 ;;   algfi %r5, 4294901764
-;;   jle 6 ; trap
+;;   jgnle .+2 # trap=heap_oob
 ;;   lg %r14, 8(%r4)
 ;;   clgr %r5, %r14
 ;;   jgh label3 ; jg label1
@@ -62,7 +62,7 @@
 ;;   lmg %r14, %r15, 112(%r15)
 ;;   br %r14
 ;; block3:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
 ;;
 ;; function u0:1:
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 160, offset_downward_to_clobbers: 0 }
@@ -70,7 +70,7 @@
 ;; block0:
 ;;   lgr %r5, %r2
 ;;   algfi %r5, 4294901764
-;;   jle 6 ; trap
+;;   jgnle .+2 # trap=heap_oob
 ;;   lg %r4, 8(%r3)
 ;;   clgr %r5, %r4
 ;;   jgh label3 ; jg label1
@@ -83,4 +83,4 @@
 ;; block2:
 ;;   br %r14
 ;; block3:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
diff --git a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i64_index_0_guard_no_spectre_i8_access_0_offset.wat b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i64_index_0_guard_no_spectre_i8_access_0_offset.wat
index 71895085c..2a46594c5 100644
--- a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i64_index_0_guard_no_spectre_i8_access_0_offset.wat
+++ b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i64_index_0_guard_no_spectre_i8_access_0_offset.wat
@@ -53,7 +53,7 @@
 ;; block2:
 ;;   br %r14
 ;; block3:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
 ;;
 ;; function u0:1:
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 160, offset_downward_to_clobbers: 0 }
@@ -69,4 +69,4 @@
 ;; block2:
 ;;   br %r14
 ;; block3:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
diff --git a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i64_index_0_guard_no_spectre_i8_access_0x1000_offset.wat b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i64_index_0_guard_no_spectre_i8_access_0x1000_offset.wat
index b5829de08..65a74304e 100644
--- a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i64_index_0_guard_no_spectre_i8_access_0x1000_offset.wat
+++ b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i64_index_0_guard_no_spectre_i8_access_0x1000_offset.wat
@@ -56,7 +56,7 @@
 ;; block2:
 ;;   br %r14
 ;; block3:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
 ;;
 ;; function u0:1:
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 160, offset_downward_to_clobbers: 0 }
@@ -75,4 +75,4 @@
 ;; block2:
 ;;   br %r14
 ;; block3:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
diff --git a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i64_index_0_guard_no_spectre_i8_access_0xffff0000_offset.wat b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i64_index_0_guard_no_spectre_i8_access_0xffff0000_offset.wat
index 2c591ee9b..5cbdc6a00 100644
--- a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i64_index_0_guard_no_spectre_i8_access_0xffff0000_offset.wat
+++ b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i64_index_0_guard_no_spectre_i8_access_0xffff0000_offset.wat
@@ -48,7 +48,7 @@
 ;; block0:
 ;;   lgr %r5, %r2
 ;;   algfi %r5, 4294901761
-;;   jle 6 ; trap
+;;   jgnle .+2 # trap=heap_oob
 ;;   lg %r14, 8(%r4)
 ;;   clgr %r5, %r14
 ;;   jgh label3 ; jg label1
@@ -62,7 +62,7 @@
 ;;   lmg %r14, %r15, 112(%r15)
 ;;   br %r14
 ;; block3:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
 ;;
 ;; function u0:1:
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 160, offset_downward_to_clobbers: 0 }
@@ -70,7 +70,7 @@
 ;; block0:
 ;;   lgr %r5, %r2
 ;;   algfi %r5, 4294901761
-;;   jle 6 ; trap
+;;   jgnle .+2 # trap=heap_oob
 ;;   lg %r4, 8(%r3)
 ;;   clgr %r5, %r4
 ;;   jgh label3 ; jg label1
@@ -83,4 +83,4 @@
 ;; block2:
 ;;   br %r14
 ;; block3:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
diff --git a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i64_index_0_guard_yes_spectre_i32_access_0xffff0000_offset.wat b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i64_index_0_guard_yes_spectre_i32_access_0xffff0000_offset.wat
index 86cec29b9..a2df1b01c 100644
--- a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i64_index_0_guard_yes_spectre_i32_access_0xffff0000_offset.wat
+++ b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i64_index_0_guard_yes_spectre_i32_access_0xffff0000_offset.wat
@@ -55,7 +55,7 @@
 ;; block0:
 ;;   lgr %r7, %r2
 ;;   algfi %r7, 4294901764
-;;   jle 6 ; trap
+;;   jgnle .+2 # trap=heap_oob
 ;;   lg %r5, 8(%r4)
 ;;   ag %r2, 0(%r4)
 ;;   llilh %r4, 65535
@@ -75,7 +75,7 @@
 ;; block0:
 ;;   lgr %r4, %r2
 ;;   algfi %r4, 4294901764
-;;   jle 6 ; trap
+;;   jgnle .+2 # trap=heap_oob
 ;;   lg %r5, 8(%r3)
 ;;   ag %r2, 0(%r3)
 ;;   llilh %r3, 65535
diff --git a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i64_index_0_guard_yes_spectre_i8_access_0xffff0000_offset.wat b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i64_index_0_guard_yes_spectre_i8_access_0xffff0000_offset.wat
index be29d3526..ae1caf963 100644
--- a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i64_index_0_guard_yes_spectre_i8_access_0xffff0000_offset.wat
+++ b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i64_index_0_guard_yes_spectre_i8_access_0xffff0000_offset.wat
@@ -55,7 +55,7 @@
 ;; block0:
 ;;   lgr %r7, %r2
 ;;   algfi %r7, 4294901761
-;;   jle 6 ; trap
+;;   jgnle .+2 # trap=heap_oob
 ;;   lg %r5, 8(%r4)
 ;;   ag %r2, 0(%r4)
 ;;   llilh %r4, 65535
@@ -75,7 +75,7 @@
 ;; block0:
 ;;   lgr %r4, %r2
 ;;   algfi %r4, 4294901761
-;;   jle 6 ; trap
+;;   jgnle .+2 # trap=heap_oob
 ;;   lg %r5, 8(%r3)
 ;;   ag %r2, 0(%r3)
 ;;   llilh %r3, 65535
diff --git a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i64_index_0xffffffff_guard_no_spectre_i32_access_0_offset.wat b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i64_index_0xffffffff_guard_no_spectre_i32_access_0_offset.wat
index cf7df8397..b16a1ef87 100644
--- a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i64_index_0xffffffff_guard_no_spectre_i32_access_0_offset.wat
+++ b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i64_index_0xffffffff_guard_no_spectre_i32_access_0_offset.wat
@@ -53,7 +53,7 @@
 ;; block2:
 ;;   br %r14
 ;; block3:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
 ;;
 ;; function u0:1:
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 160, offset_downward_to_clobbers: 0 }
@@ -69,4 +69,4 @@
 ;; block2:
 ;;   br %r14
 ;; block3:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
diff --git a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i64_index_0xffffffff_guard_no_spectre_i32_access_0x1000_offset.wat b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i64_index_0xffffffff_guard_no_spectre_i32_access_0x1000_offset.wat
index 47d32bb98..57f3aeb37 100644
--- a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i64_index_0xffffffff_guard_no_spectre_i32_access_0x1000_offset.wat
+++ b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i64_index_0xffffffff_guard_no_spectre_i32_access_0x1000_offset.wat
@@ -54,7 +54,7 @@
 ;; block2:
 ;;   br %r14
 ;; block3:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
 ;;
 ;; function u0:1:
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 160, offset_downward_to_clobbers: 0 }
@@ -71,4 +71,4 @@
 ;; block2:
 ;;   br %r14
 ;; block3:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
diff --git a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i64_index_0xffffffff_guard_no_spectre_i32_access_0xffff0000_offset.wat b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i64_index_0xffffffff_guard_no_spectre_i32_access_0xffff0000_offset.wat
index 434de2925..217b1336a 100644
--- a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i64_index_0xffffffff_guard_no_spectre_i32_access_0xffff0000_offset.wat
+++ b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i64_index_0xffffffff_guard_no_spectre_i32_access_0xffff0000_offset.wat
@@ -54,7 +54,7 @@
 ;; block2:
 ;;   br %r14
 ;; block3:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
 ;;
 ;; function u0:1:
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 160, offset_downward_to_clobbers: 0 }
@@ -71,4 +71,4 @@
 ;; block2:
 ;;   br %r14
 ;; block3:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
diff --git a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i64_index_0xffffffff_guard_no_spectre_i8_access_0_offset.wat b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i64_index_0xffffffff_guard_no_spectre_i8_access_0_offset.wat
index 6678fe619..437423679 100644
--- a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i64_index_0xffffffff_guard_no_spectre_i8_access_0_offset.wat
+++ b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i64_index_0xffffffff_guard_no_spectre_i8_access_0_offset.wat
@@ -53,7 +53,7 @@
 ;; block2:
 ;;   br %r14
 ;; block3:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
 ;;
 ;; function u0:1:
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 160, offset_downward_to_clobbers: 0 }
@@ -69,4 +69,4 @@
 ;; block2:
 ;;   br %r14
 ;; block3:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
diff --git a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i64_index_0xffffffff_guard_no_spectre_i8_access_0x1000_offset.wat b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i64_index_0xffffffff_guard_no_spectre_i8_access_0x1000_offset.wat
index 9782d3a0d..afc2bcf33 100644
--- a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i64_index_0xffffffff_guard_no_spectre_i8_access_0x1000_offset.wat
+++ b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i64_index_0xffffffff_guard_no_spectre_i8_access_0x1000_offset.wat
@@ -54,7 +54,7 @@
 ;; block2:
 ;;   br %r14
 ;; block3:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
 ;;
 ;; function u0:1:
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 160, offset_downward_to_clobbers: 0 }
@@ -71,4 +71,4 @@
 ;; block2:
 ;;   br %r14
 ;; block3:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
diff --git a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i64_index_0xffffffff_guard_no_spectre_i8_access_0xffff0000_offset.wat b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i64_index_0xffffffff_guard_no_spectre_i8_access_0xffff0000_offset.wat
index 2e68c2e53..65808bc9c 100644
--- a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i64_index_0xffffffff_guard_no_spectre_i8_access_0xffff0000_offset.wat
+++ b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_dynamic_kind_i64_index_0xffffffff_guard_no_spectre_i8_access_0xffff0000_offset.wat
@@ -54,7 +54,7 @@
 ;; block2:
 ;;   br %r14
 ;; block3:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
 ;;
 ;; function u0:1:
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 160, offset_downward_to_clobbers: 0 }
@@ -71,4 +71,4 @@
 ;; block2:
 ;;   br %r14
 ;; block3:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
diff --git a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i32_index_0_guard_no_spectre_i32_access_0_offset.wat b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i32_index_0_guard_no_spectre_i32_access_0_offset.wat
index 8a58d7550..8526bb67e 100644
--- a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i32_index_0_guard_no_spectre_i32_access_0_offset.wat
+++ b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i32_index_0_guard_no_spectre_i32_access_0_offset.wat
@@ -52,7 +52,7 @@
 ;; block2:
 ;;   br %r14
 ;; block3:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
 ;;
 ;; function u0:1:
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 160, offset_downward_to_clobbers: 0 }
@@ -69,4 +69,4 @@
 ;; block2:
 ;;   br %r14
 ;; block3:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
diff --git a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i32_index_0_guard_no_spectre_i32_access_0x1000_offset.wat b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i32_index_0_guard_no_spectre_i32_access_0x1000_offset.wat
index 9319fb85a..1d76ee44d 100644
--- a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i32_index_0_guard_no_spectre_i32_access_0x1000_offset.wat
+++ b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i32_index_0_guard_no_spectre_i32_access_0x1000_offset.wat
@@ -53,7 +53,7 @@
 ;; block2:
 ;;   br %r14
 ;; block3:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
 ;;
 ;; function u0:1:
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 160, offset_downward_to_clobbers: 0 }
@@ -72,4 +72,4 @@
 ;; block2:
 ;;   br %r14
 ;; block3:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
diff --git a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i32_index_0_guard_no_spectre_i32_access_0xffff0000_offset.wat b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i32_index_0_guard_no_spectre_i32_access_0xffff0000_offset.wat
index 08ecbb170..66463fee1 100644
--- a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i32_index_0_guard_no_spectre_i32_access_0xffff0000_offset.wat
+++ b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i32_index_0_guard_no_spectre_i32_access_0xffff0000_offset.wat
@@ -41,10 +41,10 @@
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 160, offset_downward_to_clobbers: 0 }
 ;;   unwind StackAlloc { size: 0 }
 ;; block0:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
 ;;
 ;; function u0:1:
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 160, offset_downward_to_clobbers: 0 }
 ;;   unwind StackAlloc { size: 0 }
 ;; block0:
-;;   trap
\ No newline at end of file
+;;   .word 0x0000 # trap=heap_oob
diff --git a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i32_index_0_guard_no_spectre_i8_access_0_offset.wat b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i32_index_0_guard_no_spectre_i8_access_0_offset.wat
index 02ea029a5..fd2169564 100644
--- a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i32_index_0_guard_no_spectre_i8_access_0_offset.wat
+++ b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i32_index_0_guard_no_spectre_i8_access_0_offset.wat
@@ -52,7 +52,7 @@
 ;; block2:
 ;;   br %r14
 ;; block3:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
 ;;
 ;; function u0:1:
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 160, offset_downward_to_clobbers: 0 }
@@ -69,4 +69,4 @@
 ;; block2:
 ;;   br %r14
 ;; block3:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
diff --git a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i32_index_0_guard_no_spectre_i8_access_0x1000_offset.wat b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i32_index_0_guard_no_spectre_i8_access_0x1000_offset.wat
index 9a2216619..1b1d767c7 100644
--- a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i32_index_0_guard_no_spectre_i8_access_0x1000_offset.wat
+++ b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i32_index_0_guard_no_spectre_i8_access_0x1000_offset.wat
@@ -53,7 +53,7 @@
 ;; block2:
 ;;   br %r14
 ;; block3:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
 ;;
 ;; function u0:1:
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 160, offset_downward_to_clobbers: 0 }
@@ -72,4 +72,4 @@
 ;; block2:
 ;;   br %r14
 ;; block3:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
diff --git a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i32_index_0_guard_no_spectre_i8_access_0xffff0000_offset.wat b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i32_index_0_guard_no_spectre_i8_access_0xffff0000_offset.wat
index b1906ca85..2f85b8cdf 100644
--- a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i32_index_0_guard_no_spectre_i8_access_0xffff0000_offset.wat
+++ b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i32_index_0_guard_no_spectre_i8_access_0xffff0000_offset.wat
@@ -41,10 +41,10 @@
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 160, offset_downward_to_clobbers: 0 }
 ;;   unwind StackAlloc { size: 0 }
 ;; block0:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
 ;;
 ;; function u0:1:
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 160, offset_downward_to_clobbers: 0 }
 ;;   unwind StackAlloc { size: 0 }
 ;; block0:
-;;   trap
\ No newline at end of file
+;;   .word 0x0000 # trap=heap_oob
diff --git a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i32_index_0_guard_yes_spectre_i32_access_0xffff0000_offset.wat b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i32_index_0_guard_yes_spectre_i32_access_0xffff0000_offset.wat
index d8f39931c..36579daec 100644
--- a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i32_index_0_guard_yes_spectre_i32_access_0xffff0000_offset.wat
+++ b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i32_index_0_guard_yes_spectre_i32_access_0xffff0000_offset.wat
@@ -41,10 +41,10 @@
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 160, offset_downward_to_clobbers: 0 }
 ;;   unwind StackAlloc { size: 0 }
 ;; block0:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
 ;;
 ;; function u0:1:
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 160, offset_downward_to_clobbers: 0 }
 ;;   unwind StackAlloc { size: 0 }
 ;; block0:
-;;   trap
\ No newline at end of file
+;;   .word 0x0000 # trap=heap_oob
diff --git a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i32_index_0_guard_yes_spectre_i8_access_0xffff0000_offset.wat b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i32_index_0_guard_yes_spectre_i8_access_0xffff0000_offset.wat
index 9291d34ee..648929ef8 100644
--- a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i32_index_0_guard_yes_spectre_i8_access_0xffff0000_offset.wat
+++ b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i32_index_0_guard_yes_spectre_i8_access_0xffff0000_offset.wat
@@ -41,10 +41,10 @@
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 160, offset_downward_to_clobbers: 0 }
 ;;   unwind StackAlloc { size: 0 }
 ;; block0:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
 ;;
 ;; function u0:1:
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 160, offset_downward_to_clobbers: 0 }
 ;;   unwind StackAlloc { size: 0 }
 ;; block0:
-;;   trap
\ No newline at end of file
+;;   .word 0x0000 # trap=heap_oob
diff --git a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i32_index_0xffffffff_guard_no_spectre_i32_access_0xffff0000_offset.wat b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i32_index_0xffffffff_guard_no_spectre_i32_access_0xffff0000_offset.wat
index ae231d776..4ba9e532a 100644
--- a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i32_index_0xffffffff_guard_no_spectre_i32_access_0xffff0000_offset.wat
+++ b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i32_index_0xffffffff_guard_no_spectre_i32_access_0xffff0000_offset.wat
@@ -41,10 +41,10 @@
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 160, offset_downward_to_clobbers: 0 }
 ;;   unwind StackAlloc { size: 0 }
 ;; block0:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
 ;;
 ;; function u0:1:
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 160, offset_downward_to_clobbers: 0 }
 ;;   unwind StackAlloc { size: 0 }
 ;; block0:
-;;   trap
\ No newline at end of file
+;;   .word 0x0000 # trap=heap_oob
diff --git a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i32_index_0xffffffff_guard_no_spectre_i8_access_0xffff0000_offset.wat b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i32_index_0xffffffff_guard_no_spectre_i8_access_0xffff0000_offset.wat
index e20bfe70d..6ffce7d78 100644
--- a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i32_index_0xffffffff_guard_no_spectre_i8_access_0xffff0000_offset.wat
+++ b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i32_index_0xffffffff_guard_no_spectre_i8_access_0xffff0000_offset.wat
@@ -41,10 +41,10 @@
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 160, offset_downward_to_clobbers: 0 }
 ;;   unwind StackAlloc { size: 0 }
 ;; block0:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
 ;;
 ;; function u0:1:
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 160, offset_downward_to_clobbers: 0 }
 ;;   unwind StackAlloc { size: 0 }
 ;; block0:
-;;   trap
\ No newline at end of file
+;;   .word 0x0000 # trap=heap_oob
diff --git a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i32_index_0xffffffff_guard_yes_spectre_i32_access_0xffff0000_offset.wat b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i32_index_0xffffffff_guard_yes_spectre_i32_access_0xffff0000_offset.wat
index bda2d224e..9c1d577ce 100644
--- a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i32_index_0xffffffff_guard_yes_spectre_i32_access_0xffff0000_offset.wat
+++ b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i32_index_0xffffffff_guard_yes_spectre_i32_access_0xffff0000_offset.wat
@@ -41,10 +41,10 @@
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 160, offset_downward_to_clobbers: 0 }
 ;;   unwind StackAlloc { size: 0 }
 ;; block0:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
 ;;
 ;; function u0:1:
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 160, offset_downward_to_clobbers: 0 }
 ;;   unwind StackAlloc { size: 0 }
 ;; block0:
-;;   trap
\ No newline at end of file
+;;   .word 0x0000 # trap=heap_oob
diff --git a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i32_index_0xffffffff_guard_yes_spectre_i8_access_0xffff0000_offset.wat b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i32_index_0xffffffff_guard_yes_spectre_i8_access_0xffff0000_offset.wat
index 99282dbdc..a66de6355 100644
--- a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i32_index_0xffffffff_guard_yes_spectre_i8_access_0xffff0000_offset.wat
+++ b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i32_index_0xffffffff_guard_yes_spectre_i8_access_0xffff0000_offset.wat
@@ -41,10 +41,10 @@
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 160, offset_downward_to_clobbers: 0 }
 ;;   unwind StackAlloc { size: 0 }
 ;; block0:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
 ;;
 ;; function u0:1:
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 160, offset_downward_to_clobbers: 0 }
 ;;   unwind StackAlloc { size: 0 }
 ;; block0:
-;;   trap
\ No newline at end of file
+;;   .word 0x0000 # trap=heap_oob
diff --git a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i64_index_0_guard_no_spectre_i32_access_0_offset.wat b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i64_index_0_guard_no_spectre_i32_access_0_offset.wat
index 75df18787..ac557b60a 100644
--- a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i64_index_0_guard_no_spectre_i32_access_0_offset.wat
+++ b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i64_index_0_guard_no_spectre_i32_access_0_offset.wat
@@ -50,7 +50,7 @@
 ;; block2:
 ;;   br %r14
 ;; block3:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
 ;;
 ;; function u0:1:
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 160, offset_downward_to_clobbers: 0 }
@@ -65,4 +65,4 @@
 ;; block2:
 ;;   br %r14
 ;; block3:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
diff --git a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i64_index_0_guard_no_spectre_i32_access_0x1000_offset.wat b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i64_index_0_guard_no_spectre_i32_access_0x1000_offset.wat
index 6a0cc56bb..23b2ddf63 100644
--- a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i64_index_0_guard_no_spectre_i32_access_0x1000_offset.wat
+++ b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i64_index_0_guard_no_spectre_i32_access_0x1000_offset.wat
@@ -52,7 +52,7 @@
 ;; block2:
 ;;   br %r14
 ;; block3:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
 ;;
 ;; function u0:1:
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 160, offset_downward_to_clobbers: 0 }
@@ -69,4 +69,4 @@
 ;; block2:
 ;;   br %r14
 ;; block3:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
diff --git a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i64_index_0_guard_no_spectre_i32_access_0xffff0000_offset.wat b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i64_index_0_guard_no_spectre_i32_access_0xffff0000_offset.wat
index 3e7443260..be3e0b57a 100644
--- a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i64_index_0_guard_no_spectre_i32_access_0xffff0000_offset.wat
+++ b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i64_index_0_guard_no_spectre_i32_access_0xffff0000_offset.wat
@@ -41,10 +41,10 @@
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 160, offset_downward_to_clobbers: 0 }
 ;;   unwind StackAlloc { size: 0 }
 ;; block0:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
 ;;
 ;; function u0:1:
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 160, offset_downward_to_clobbers: 0 }
 ;;   unwind StackAlloc { size: 0 }
 ;; block0:
-;;   trap
\ No newline at end of file
+;;   .word 0x0000 # trap=heap_oob
diff --git a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i64_index_0_guard_no_spectre_i8_access_0_offset.wat b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i64_index_0_guard_no_spectre_i8_access_0_offset.wat
index 939fa2008..66f1a626f 100644
--- a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i64_index_0_guard_no_spectre_i8_access_0_offset.wat
+++ b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i64_index_0_guard_no_spectre_i8_access_0_offset.wat
@@ -50,7 +50,7 @@
 ;; block2:
 ;;   br %r14
 ;; block3:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
 ;;
 ;; function u0:1:
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 160, offset_downward_to_clobbers: 0 }
@@ -65,4 +65,4 @@
 ;; block2:
 ;;   br %r14
 ;; block3:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
diff --git a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i64_index_0_guard_no_spectre_i8_access_0x1000_offset.wat b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i64_index_0_guard_no_spectre_i8_access_0x1000_offset.wat
index dac7fdc73..19cdeed46 100644
--- a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i64_index_0_guard_no_spectre_i8_access_0x1000_offset.wat
+++ b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i64_index_0_guard_no_spectre_i8_access_0x1000_offset.wat
@@ -52,7 +52,7 @@
 ;; block2:
 ;;   br %r14
 ;; block3:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
 ;;
 ;; function u0:1:
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 160, offset_downward_to_clobbers: 0 }
@@ -69,4 +69,4 @@
 ;; block2:
 ;;   br %r14
 ;; block3:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
diff --git a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i64_index_0_guard_no_spectre_i8_access_0xffff0000_offset.wat b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i64_index_0_guard_no_spectre_i8_access_0xffff0000_offset.wat
index f6265c4a6..2a0585aaa 100644
--- a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i64_index_0_guard_no_spectre_i8_access_0xffff0000_offset.wat
+++ b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i64_index_0_guard_no_spectre_i8_access_0xffff0000_offset.wat
@@ -41,10 +41,10 @@
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 160, offset_downward_to_clobbers: 0 }
 ;;   unwind StackAlloc { size: 0 }
 ;; block0:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
 ;;
 ;; function u0:1:
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 160, offset_downward_to_clobbers: 0 }
 ;;   unwind StackAlloc { size: 0 }
 ;; block0:
-;;   trap
\ No newline at end of file
+;;   .word 0x0000 # trap=heap_oob
diff --git a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i64_index_0_guard_yes_spectre_i32_access_0xffff0000_offset.wat b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i64_index_0_guard_yes_spectre_i32_access_0xffff0000_offset.wat
index ce99d89d1..99cd316b7 100644
--- a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i64_index_0_guard_yes_spectre_i32_access_0xffff0000_offset.wat
+++ b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i64_index_0_guard_yes_spectre_i32_access_0xffff0000_offset.wat
@@ -41,10 +41,10 @@
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 160, offset_downward_to_clobbers: 0 }
 ;;   unwind StackAlloc { size: 0 }
 ;; block0:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
 ;;
 ;; function u0:1:
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 160, offset_downward_to_clobbers: 0 }
 ;;   unwind StackAlloc { size: 0 }
 ;; block0:
-;;   trap
\ No newline at end of file
+;;   .word 0x0000 # trap=heap_oob
diff --git a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i64_index_0_guard_yes_spectre_i8_access_0xffff0000_offset.wat b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i64_index_0_guard_yes_spectre_i8_access_0xffff0000_offset.wat
index 12c007b40..aa942f5c2 100644
--- a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i64_index_0_guard_yes_spectre_i8_access_0xffff0000_offset.wat
+++ b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i64_index_0_guard_yes_spectre_i8_access_0xffff0000_offset.wat
@@ -41,10 +41,10 @@
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 160, offset_downward_to_clobbers: 0 }
 ;;   unwind StackAlloc { size: 0 }
 ;; block0:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
 ;;
 ;; function u0:1:
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 160, offset_downward_to_clobbers: 0 }
 ;;   unwind StackAlloc { size: 0 }
 ;; block0:
-;;   trap
\ No newline at end of file
+;;   .word 0x0000 # trap=heap_oob
diff --git a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i64_index_0xffffffff_guard_no_spectre_i32_access_0_offset.wat b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i64_index_0xffffffff_guard_no_spectre_i32_access_0_offset.wat
index 7a8607456..2e53bc16d 100644
--- a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i64_index_0xffffffff_guard_no_spectre_i32_access_0_offset.wat
+++ b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i64_index_0xffffffff_guard_no_spectre_i32_access_0_offset.wat
@@ -50,7 +50,7 @@
 ;; block2:
 ;;   br %r14
 ;; block3:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
 ;;
 ;; function u0:1:
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 160, offset_downward_to_clobbers: 0 }
@@ -65,4 +65,4 @@
 ;; block2:
 ;;   br %r14
 ;; block3:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
diff --git a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i64_index_0xffffffff_guard_no_spectre_i32_access_0x1000_offset.wat b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i64_index_0xffffffff_guard_no_spectre_i32_access_0x1000_offset.wat
index 99cfa8102..46fb88b46 100644
--- a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i64_index_0xffffffff_guard_no_spectre_i32_access_0x1000_offset.wat
+++ b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i64_index_0xffffffff_guard_no_spectre_i32_access_0x1000_offset.wat
@@ -52,7 +52,7 @@
 ;; block2:
 ;;   br %r14
 ;; block3:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
 ;;
 ;; function u0:1:
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 160, offset_downward_to_clobbers: 0 }
@@ -69,4 +69,4 @@
 ;; block2:
 ;;   br %r14
 ;; block3:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
diff --git a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i64_index_0xffffffff_guard_no_spectre_i32_access_0xffff0000_offset.wat b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i64_index_0xffffffff_guard_no_spectre_i32_access_0xffff0000_offset.wat
index ca723b335..79d407bf5 100644
--- a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i64_index_0xffffffff_guard_no_spectre_i32_access_0xffff0000_offset.wat
+++ b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i64_index_0xffffffff_guard_no_spectre_i32_access_0xffff0000_offset.wat
@@ -41,10 +41,10 @@
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 160, offset_downward_to_clobbers: 0 }
 ;;   unwind StackAlloc { size: 0 }
 ;; block0:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
 ;;
 ;; function u0:1:
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 160, offset_downward_to_clobbers: 0 }
 ;;   unwind StackAlloc { size: 0 }
 ;; block0:
-;;   trap
\ No newline at end of file
+;;   .word 0x0000 # trap=heap_oob
diff --git a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i64_index_0xffffffff_guard_no_spectre_i8_access_0_offset.wat b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i64_index_0xffffffff_guard_no_spectre_i8_access_0_offset.wat
index b0f253d5c..4c98b41e5 100644
--- a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i64_index_0xffffffff_guard_no_spectre_i8_access_0_offset.wat
+++ b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i64_index_0xffffffff_guard_no_spectre_i8_access_0_offset.wat
@@ -50,7 +50,7 @@
 ;; block2:
 ;;   br %r14
 ;; block3:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
 ;;
 ;; function u0:1:
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 160, offset_downward_to_clobbers: 0 }
@@ -65,4 +65,4 @@
 ;; block2:
 ;;   br %r14
 ;; block3:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
diff --git a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i64_index_0xffffffff_guard_no_spectre_i8_access_0x1000_offset.wat b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i64_index_0xffffffff_guard_no_spectre_i8_access_0x1000_offset.wat
index 367b7a519..db9cf08ae 100644
--- a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i64_index_0xffffffff_guard_no_spectre_i8_access_0x1000_offset.wat
+++ b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i64_index_0xffffffff_guard_no_spectre_i8_access_0x1000_offset.wat
@@ -52,7 +52,7 @@
 ;; block2:
 ;;   br %r14
 ;; block3:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
 ;;
 ;; function u0:1:
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 160, offset_downward_to_clobbers: 0 }
@@ -69,4 +69,4 @@
 ;; block2:
 ;;   br %r14
 ;; block3:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
diff --git a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i64_index_0xffffffff_guard_no_spectre_i8_access_0xffff0000_offset.wat b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i64_index_0xffffffff_guard_no_spectre_i8_access_0xffff0000_offset.wat
index 93a0dc186..c154ac31a 100644
--- a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i64_index_0xffffffff_guard_no_spectre_i8_access_0xffff0000_offset.wat
+++ b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i64_index_0xffffffff_guard_no_spectre_i8_access_0xffff0000_offset.wat
@@ -41,10 +41,10 @@
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 160, offset_downward_to_clobbers: 0 }
 ;;   unwind StackAlloc { size: 0 }
 ;; block0:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
 ;;
 ;; function u0:1:
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 160, offset_downward_to_clobbers: 0 }
 ;;   unwind StackAlloc { size: 0 }
 ;; block0:
-;;   trap
\ No newline at end of file
+;;   .word 0x0000 # trap=heap_oob
diff --git a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i64_index_0xffffffff_guard_yes_spectre_i32_access_0xffff0000_offset.wat b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i64_index_0xffffffff_guard_yes_spectre_i32_access_0xffff0000_offset.wat
index 59a805178..a346794bc 100644
--- a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i64_index_0xffffffff_guard_yes_spectre_i32_access_0xffff0000_offset.wat
+++ b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i64_index_0xffffffff_guard_yes_spectre_i32_access_0xffff0000_offset.wat
@@ -41,10 +41,10 @@
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 160, offset_downward_to_clobbers: 0 }
 ;;   unwind StackAlloc { size: 0 }
 ;; block0:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
 ;;
 ;; function u0:1:
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 160, offset_downward_to_clobbers: 0 }
 ;;   unwind StackAlloc { size: 0 }
 ;; block0:
-;;   trap
\ No newline at end of file
+;;   .word 0x0000 # trap=heap_oob
diff --git a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i64_index_0xffffffff_guard_yes_spectre_i8_access_0xffff0000_offset.wat b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i64_index_0xffffffff_guard_yes_spectre_i8_access_0xffff0000_offset.wat
index f9ef02672..f69fb1447 100644
--- a/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i64_index_0xffffffff_guard_yes_spectre_i8_access_0xffff0000_offset.wat
+++ b/cranelift/filetests/filetests/isa/s390x/wasm/load_store_static_kind_i64_index_0xffffffff_guard_yes_spectre_i8_access_0xffff0000_offset.wat
@@ -41,10 +41,10 @@
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 160, offset_downward_to_clobbers: 0 }
 ;;   unwind StackAlloc { size: 0 }
 ;; block0:
-;;   trap
+;;   .word 0x0000 # trap=heap_oob
 ;;
 ;; function u0:1:
 ;;   unwind DefineNewFrame { offset_upward_to_caller_sp: 160, offset_downward_to_clobbers: 0 }
 ;;   unwind StackAlloc { size: 0 }
 ;; block0:
-;;   trap
\ No newline at end of file
+;;   .word 0x0000 # trap=heap_oob
diff --git a/cranelift/filetests/filetests/isa/x64/fcvt-avx.clif b/cranelift/filetests/filetests/isa/x64/fcvt-avx.clif
new file mode 100644
index 000000000..dbdd6cd18
--- /dev/null
+++ b/cranelift/filetests/filetests/isa/x64/fcvt-avx.clif
@@ -0,0 +1,104 @@
+test compile precise-output
+set enable_simd
+target x86_64 has_avx
+
+function %f3(i32) -> f32 {
+block0(v0: i32):
+  v1 = fcvt_from_sint.f32 v0
+  return v1
+}
+
+; VCode:
+;   pushq   %rbp
+;   movq    %rsp, %rbp
+; block0:
+;   vcvtsi2ss %edi, %xmm0
+;   movq    %rbp, %rsp
+;   popq    %rbp
+;   ret
+; 
+; Disassembled:
+; block0: ; offset 0x0
+;   pushq %rbp
+;   movq %rsp, %rbp
+; block1: ; offset 0x4
+;   vcvtsi2ssl %edi, %xmm0, %xmm0
+;   movq %rbp, %rsp
+;   popq %rbp
+;   retq
+
+function %f4(i64) -> f32 {
+block0(v0: i64):
+  v1 = fcvt_from_sint.f32 v0
+  return v1
+}
+
+; VCode:
+;   pushq   %rbp
+;   movq    %rsp, %rbp
+; block0:
+;   vcvtsi2ss %rdi, %xmm0
+;   movq    %rbp, %rsp
+;   popq    %rbp
+;   ret
+; 
+; Disassembled:
+; block0: ; offset 0x0
+;   pushq %rbp
+;   movq %rsp, %rbp
+; block1: ; offset 0x4
+;   vcvtsi2ssq %rdi, %xmm0, %xmm0
+;   movq %rbp, %rsp
+;   popq %rbp
+;   retq
+
+function %f7(i32) -> f64 {
+block0(v0: i32):
+  v1 = fcvt_from_sint.f64 v0
+  return v1
+}
+
+; VCode:
+;   pushq   %rbp
+;   movq    %rsp, %rbp
+; block0:
+;   vcvtsi2sd %edi, %xmm0
+;   movq    %rbp, %rsp
+;   popq    %rbp
+;   ret
+; 
+; Disassembled:
+; block0: ; offset 0x0
+;   pushq %rbp
+;   movq %rsp, %rbp
+; block1: ; offset 0x4
+;   vcvtsi2sdl %edi, %xmm0, %xmm0
+;   movq %rbp, %rsp
+;   popq %rbp
+;   retq
+
+function %f8(i64) -> f64 {
+block0(v0: i64):
+  v1 = fcvt_from_sint.f64 v0
+  return v1
+}
+
+; VCode:
+;   pushq   %rbp
+;   movq    %rsp, %rbp
+; block0:
+;   vcvtsi2sd %rdi, %xmm0
+;   movq    %rbp, %rsp
+;   popq    %rbp
+;   ret
+; 
+; Disassembled:
+; block0: ; offset 0x0
+;   pushq %rbp
+;   movq %rsp, %rbp
+; block1: ; offset 0x4
+;   vcvtsi2sdq %rdi, %xmm0, %xmm0
+;   movq %rbp, %rsp
+;   popq %rbp
+;   retq
+
diff --git a/cranelift/filetests/filetests/isa/x64/float-bitcast-avx.clif b/cranelift/filetests/filetests/isa/x64/float-bitcast-avx.clif
new file mode 100644
index 000000000..4a08cb345
--- /dev/null
+++ b/cranelift/filetests/filetests/isa/x64/float-bitcast-avx.clif
@@ -0,0 +1,104 @@
+test compile precise-output
+set enable_simd
+target x86_64 has_avx
+
+function %i32_to_f32(i32) -> f32 {
+block0(v0: i32):
+  v1 = bitcast.f32 v0
+  return v1
+}
+
+; VCode:
+;   pushq   %rbp
+;   movq    %rsp, %rbp
+; block0:
+;   vmovd   %edi, %xmm0
+;   movq    %rbp, %rsp
+;   popq    %rbp
+;   ret
+; 
+; Disassembled:
+; block0: ; offset 0x0
+;   pushq %rbp
+;   movq %rsp, %rbp
+; block1: ; offset 0x4
+;   vmovd %edi, %xmm0
+;   movq %rbp, %rsp
+;   popq %rbp
+;   retq
+
+function %i64_to_f64(i64) -> f64 {
+block0(v0: i64):
+  v1 = bitcast.f64 v0
+  return v1
+}
+
+; VCode:
+;   pushq   %rbp
+;   movq    %rsp, %rbp
+; block0:
+;   vmovq   %rdi, %xmm0
+;   movq    %rbp, %rsp
+;   popq    %rbp
+;   ret
+; 
+; Disassembled:
+; block0: ; offset 0x0
+;   pushq %rbp
+;   movq %rsp, %rbp
+; block1: ; offset 0x4
+;   vmovq %rdi, %xmm0
+;   movq %rbp, %rsp
+;   popq %rbp
+;   retq
+
+function %f32_to_i32(f32) -> i32 {
+block0(v0: f32):
+  v1 = bitcast.i32 v0
+  return v1
+}
+
+; VCode:
+;   pushq   %rbp
+;   movq    %rsp, %rbp
+; block0:
+;   vmovd   %xmm0, %eax
+;   movq    %rbp, %rsp
+;   popq    %rbp
+;   ret
+; 
+; Disassembled:
+; block0: ; offset 0x0
+;   pushq %rbp
+;   movq %rsp, %rbp
+; block1: ; offset 0x4
+;   vmovd %xmm0, %eax
+;   movq %rbp, %rsp
+;   popq %rbp
+;   retq
+
+function %f64_to_i64(f64) -> i64 {
+block0(v0: f64):
+  v1 = bitcast.i64 v0
+  return v1
+}
+
+; VCode:
+;   pushq   %rbp
+;   movq    %rsp, %rbp
+; block0:
+;   vmovq   %xmm0, %rax
+;   movq    %rbp, %rsp
+;   popq    %rbp
+;   ret
+; 
+; Disassembled:
+; block0: ; offset 0x0
+;   pushq %rbp
+;   movq %rsp, %rbp
+; block1: ; offset 0x4
+;   vmovq %xmm0, %rax
+;   movq %rbp, %rsp
+;   popq %rbp
+;   retq
+
diff --git a/cranelift/filetests/filetests/isa/x64/float-bitcast.clif b/cranelift/filetests/filetests/isa/x64/float-bitcast.clif
new file mode 100644
index 000000000..ec29ebc05
--- /dev/null
+++ b/cranelift/filetests/filetests/isa/x64/float-bitcast.clif
@@ -0,0 +1,104 @@
+test compile precise-output
+set enable_simd
+target x86_64
+
+function %i32_to_f32(i32) -> f32 {
+block0(v0: i32):
+  v1 = bitcast.f32 v0
+  return v1
+}
+
+; VCode:
+;   pushq   %rbp
+;   movq    %rsp, %rbp
+; block0:
+;   movd    %edi, %xmm0
+;   movq    %rbp, %rsp
+;   popq    %rbp
+;   ret
+; 
+; Disassembled:
+; block0: ; offset 0x0
+;   pushq %rbp
+;   movq %rsp, %rbp
+; block1: ; offset 0x4
+;   movd %edi, %xmm0
+;   movq %rbp, %rsp
+;   popq %rbp
+;   retq
+
+function %i64_to_f64(i64) -> f64 {
+block0(v0: i64):
+  v1 = bitcast.f64 v0
+  return v1
+}
+
+; VCode:
+;   pushq   %rbp
+;   movq    %rsp, %rbp
+; block0:
+;   movq    %rdi, %xmm0
+;   movq    %rbp, %rsp
+;   popq    %rbp
+;   ret
+; 
+; Disassembled:
+; block0: ; offset 0x0
+;   pushq %rbp
+;   movq %rsp, %rbp
+; block1: ; offset 0x4
+;   movq %rdi, %xmm0
+;   movq %rbp, %rsp
+;   popq %rbp
+;   retq
+
+function %f32_to_i32(f32) -> i32 {
+block0(v0: f32):
+  v1 = bitcast.i32 v0
+  return v1
+}
+
+; VCode:
+;   pushq   %rbp
+;   movq    %rsp, %rbp
+; block0:
+;   movd    %xmm0, %eax
+;   movq    %rbp, %rsp
+;   popq    %rbp
+;   ret
+; 
+; Disassembled:
+; block0: ; offset 0x0
+;   pushq %rbp
+;   movq %rsp, %rbp
+; block1: ; offset 0x4
+;   movd %xmm0, %eax
+;   movq %rbp, %rsp
+;   popq %rbp
+;   retq
+
+function %f64_to_i64(f64) -> i64 {
+block0(v0: f64):
+  v1 = bitcast.i64 v0
+  return v1
+}
+
+; VCode:
+;   pushq   %rbp
+;   movq    %rsp, %rbp
+; block0:
+;   movq    %xmm0, %rax
+;   movq    %rbp, %rsp
+;   popq    %rbp
+;   ret
+; 
+; Disassembled:
+; block0: ; offset 0x0
+;   pushq %rbp
+;   movq %rsp, %rbp
+; block1: ; offset 0x4
+;   movq %xmm0, %rax
+;   movq %rbp, %rsp
+;   popq %rbp
+;   retq
+
diff --git a/cranelift/filetests/filetests/isa/x64/simd-arith-avx.clif b/cranelift/filetests/filetests/isa/x64/simd-arith-avx.clif
index 15f5c84d1..547cbaf39 100644
--- a/cranelift/filetests/filetests/isa/x64/simd-arith-avx.clif
+++ b/cranelift/filetests/filetests/isa/x64/simd-arith-avx.clif
@@ -920,7 +920,7 @@ block0(v0: i8x16, v1: i32):
 ;   vpunpcklbw %xmm0, %xmm0, %xmm5
 ;   vpunpckhbw %xmm0, %xmm0, %xmm7
 ;   addl    %r9d, $8, %r9d
-;   movd    %r9d, %xmm11
+;   vmovd   %r9d, %xmm11
 ;   vpsraw  %xmm5, %xmm11, %xmm13
 ;   vpsraw  %xmm7, %xmm11, %xmm15
 ;   vpacksswb %xmm13, %xmm15, %xmm0
@@ -938,7 +938,7 @@ block0(v0: i8x16, v1: i32):
 ;   vpunpcklbw %xmm0, %xmm0, %xmm5
 ;   vpunpckhbw %xmm0, %xmm0, %xmm7
 ;   addl $8, %r9d
-;   movd %r9d, %xmm11
+;   vmovd %r9d, %xmm11
 ;   vpsraw %xmm11, %xmm5, %xmm13
 ;   vpsraw %xmm11, %xmm7, %xmm15
 ;   vpacksswb %xmm15, %xmm13, %xmm0
@@ -992,7 +992,7 @@ block0(v0: i16x8, v1: i32):
 ; block0:
 ;   movq    %rdi, %rcx
 ;   andq    %rcx, $15, %rcx
-;   movd    %ecx, %xmm5
+;   vmovd   %ecx, %xmm5
 ;   vpsraw  %xmm0, %xmm5, %xmm0
 ;   movq    %rbp, %rsp
 ;   popq    %rbp
@@ -1005,7 +1005,7 @@ block0(v0: i16x8, v1: i32):
 ; block1: ; offset 0x4
 ;   movq %rdi, %rcx
 ;   andq $0xf, %rcx
-;   movd %ecx, %xmm5
+;   vmovd %ecx, %xmm5
 ;   vpsraw %xmm5, %xmm0, %xmm0
 ;   movq %rbp, %rsp
 ;   popq %rbp
@@ -1049,7 +1049,7 @@ block0(v0: i32x4, v1: i32):
 ; block0:
 ;   movq    %rdi, %rcx
 ;   andq    %rcx, $31, %rcx
-;   movd    %ecx, %xmm5
+;   vmovd   %ecx, %xmm5
 ;   vpsrad  %xmm0, %xmm5, %xmm0
 ;   movq    %rbp, %rsp
 ;   popq    %rbp
@@ -1062,7 +1062,7 @@ block0(v0: i32x4, v1: i32):
 ; block1: ; offset 0x4
 ;   movq %rdi, %rcx
 ;   andq $0x1f, %rcx
-;   movd %ecx, %xmm5
+;   vmovd %ecx, %xmm5
 ;   vpsrad %xmm5, %xmm0, %xmm0
 ;   movq %rbp, %rsp
 ;   popq %rbp
@@ -1315,7 +1315,7 @@ block0(v0: i8):
 ;   pushq   %rbp
 ;   movq    %rsp, %rbp
 ; block0:
-;   movd    %edi, %xmm2
+;   vmovd   %edi, %xmm2
 ;   uninit  %xmm4
 ;   vpxor   %xmm4, %xmm4, %xmm6
 ;   vpshufb %xmm2, %xmm6, %xmm0
@@ -1328,7 +1328,7 @@ block0(v0: i8):
 ;   pushq %rbp
 ;   movq %rsp, %rbp
 ; block1: ; offset 0x4
-;   movd %edi, %xmm2
+;   vmovd %edi, %xmm2
 ;   vpxor %xmm4, %xmm4, %xmm6
 ;   vpshufb %xmm6, %xmm2, %xmm0
 ;   movq %rbp, %rsp
@@ -1389,7 +1389,7 @@ block0(v0: i8x16, v1: i32):
 ; block0:
 ;   movq    %rdi, %r10
 ;   andq    %r10, $7, %r10
-;   movd    %r10d, %xmm5
+;   vmovd   %r10d, %xmm5
 ;   vpsllw  %xmm0, %xmm5, %xmm7
 ;   lea     const(0), %rsi
 ;   shlq    $4, %r10, %r10
@@ -1406,7 +1406,7 @@ block0(v0: i8x16, v1: i32):
 ; block1: ; offset 0x4
 ;   movq %rdi, %r10
 ;   andq $7, %r10
-;   movd %r10d, %xmm5
+;   vmovd %r10d, %xmm5
 ;   vpsllw %xmm5, %xmm0, %xmm7
 ;   leaq 0x15(%rip), %rsi
 ;   shlq $4, %r10
@@ -1461,7 +1461,7 @@ block0(v0: i16x8, v1: i32):
 ; block0:
 ;   movq    %rdi, %rcx
 ;   andq    %rcx, $15, %rcx
-;   movd    %ecx, %xmm5
+;   vmovd   %ecx, %xmm5
 ;   vpsllw  %xmm0, %xmm5, %xmm0
 ;   movq    %rbp, %rsp
 ;   popq    %rbp
@@ -1474,7 +1474,7 @@ block0(v0: i16x8, v1: i32):
 ; block1: ; offset 0x4
 ;   movq %rdi, %rcx
 ;   andq $0xf, %rcx
-;   movd %ecx, %xmm5
+;   vmovd %ecx, %xmm5
 ;   vpsllw %xmm5, %xmm0, %xmm0
 ;   movq %rbp, %rsp
 ;   popq %rbp
@@ -1518,7 +1518,7 @@ block0(v0: i32x4, v1: i32):
 ; block0:
 ;   movq    %rdi, %rcx
 ;   andq    %rcx, $31, %rcx
-;   movd    %ecx, %xmm5
+;   vmovd   %ecx, %xmm5
 ;   vpslld  %xmm0, %xmm5, %xmm0
 ;   movq    %rbp, %rsp
 ;   popq    %rbp
@@ -1531,7 +1531,7 @@ block0(v0: i32x4, v1: i32):
 ; block1: ; offset 0x4
 ;   movq %rdi, %rcx
 ;   andq $0x1f, %rcx
-;   movd %ecx, %xmm5
+;   vmovd %ecx, %xmm5
 ;   vpslld %xmm5, %xmm0, %xmm0
 ;   movq %rbp, %rsp
 ;   popq %rbp
@@ -1575,7 +1575,7 @@ block0(v0: i64x2, v1: i32):
 ; block0:
 ;   movq    %rdi, %rcx
 ;   andq    %rcx, $63, %rcx
-;   movd    %ecx, %xmm5
+;   vmovd   %ecx, %xmm5
 ;   vpsllq  %xmm0, %xmm5, %xmm0
 ;   movq    %rbp, %rsp
 ;   popq    %rbp
@@ -1588,7 +1588,7 @@ block0(v0: i64x2, v1: i32):
 ; block1: ; offset 0x4
 ;   movq %rdi, %rcx
 ;   andq $0x3f, %rcx
-;   movd %ecx, %xmm5
+;   vmovd %ecx, %xmm5
 ;   vpsllq %xmm5, %xmm0, %xmm0
 ;   movq %rbp, %rsp
 ;   popq %rbp
@@ -1632,7 +1632,7 @@ block0(v0: i8x16, v1: i32):
 ; block0:
 ;   movq    %rdi, %r10
 ;   andq    %r10, $7, %r10
-;   movd    %r10d, %xmm5
+;   vmovd   %r10d, %xmm5
 ;   vpsrlw  %xmm0, %xmm5, %xmm7
 ;   lea     const(0), %rsi
 ;   shlq    $4, %r10, %r10
@@ -1648,7 +1648,7 @@ block0(v0: i8x16, v1: i32):
 ; block1: ; offset 0x4
 ;   movq %rdi, %r10
 ;   andq $7, %r10
-;   movd %r10d, %xmm5
+;   vmovd %r10d, %xmm5
 ;   vpsrlw %xmm5, %xmm0, %xmm7
 ;   leaq 0x15(%rip), %rsi
 ;   shlq $4, %r10
@@ -1713,7 +1713,7 @@ block0(v0: i16x8, v1: i32):
 ; block0:
 ;   movq    %rdi, %rcx
 ;   andq    %rcx, $15, %rcx
-;   movd    %ecx, %xmm5
+;   vmovd   %ecx, %xmm5
 ;   vpsrlw  %xmm0, %xmm5, %xmm0
 ;   movq    %rbp, %rsp
 ;   popq    %rbp
@@ -1726,7 +1726,7 @@ block0(v0: i16x8, v1: i32):
 ; block1: ; offset 0x4
 ;   movq %rdi, %rcx
 ;   andq $0xf, %rcx
-;   movd %ecx, %xmm5
+;   vmovd %ecx, %xmm5
 ;   vpsrlw %xmm5, %xmm0, %xmm0
 ;   movq %rbp, %rsp
 ;   popq %rbp
@@ -1770,7 +1770,7 @@ block0(v0: i32x4, v1: i32):
 ; block0:
 ;   movq    %rdi, %rcx
 ;   andq    %rcx, $31, %rcx
-;   movd    %ecx, %xmm5
+;   vmovd   %ecx, %xmm5
 ;   vpsrld  %xmm0, %xmm5, %xmm0
 ;   movq    %rbp, %rsp
 ;   popq    %rbp
@@ -1783,7 +1783,7 @@ block0(v0: i32x4, v1: i32):
 ; block1: ; offset 0x4
 ;   movq %rdi, %rcx
 ;   andq $0x1f, %rcx
-;   movd %ecx, %xmm5
+;   vmovd %ecx, %xmm5
 ;   vpsrld %xmm5, %xmm0, %xmm0
 ;   movq %rbp, %rsp
 ;   popq %rbp
@@ -1827,7 +1827,7 @@ block0(v0: i64x2, v1: i32):
 ; block0:
 ;   movq    %rdi, %rcx
 ;   andq    %rcx, $63, %rcx
-;   movd    %ecx, %xmm5
+;   vmovd   %ecx, %xmm5
 ;   vpsrlq  %xmm0, %xmm5, %xmm0
 ;   movq    %rbp, %rsp
 ;   popq    %rbp
@@ -1840,7 +1840,7 @@ block0(v0: i64x2, v1: i32):
 ; block1: ; offset 0x4
 ;   movq %rdi, %rcx
 ;   andq $0x3f, %rcx
-;   movd %ecx, %xmm5
+;   vmovd %ecx, %xmm5
 ;   vpsrlq %xmm5, %xmm0, %xmm0
 ;   movq %rbp, %rsp
 ;   popq %rbp
diff --git a/cranelift/filetests/filetests/isa/x64/simd-bitwise-avx.clif b/cranelift/filetests/filetests/isa/x64/simd-bitwise-avx.clif
index 023d52d81..a6e32237e 100644
--- a/cranelift/filetests/filetests/isa/x64/simd-bitwise-avx.clif
+++ b/cranelift/filetests/filetests/isa/x64/simd-bitwise-avx.clif
@@ -41,7 +41,7 @@ block0(v0: i64):
 ;   movq    %rsp, %rbp
 ; block0:
 ;   movl    $-2147483648, %eax
-;   movd    %eax, %xmm4
+;   vmovd   %eax, %xmm4
 ;   vandnps %xmm4, const(0), %xmm6
 ;   vandps  %xmm4, 0(%rdi), %xmm8
 ;   vorps   %xmm6, %xmm8, %xmm0
@@ -55,7 +55,7 @@ block0(v0: i64):
 ;   movq %rsp, %rbp
 ; block1: ; offset 0x4
 ;   movl $0x80000000, %eax
-;   movd %eax, %xmm4
+;   vmovd %eax, %xmm4
 ;   vandnps 0x1b(%rip), %xmm4, %xmm6
 ;   vandps (%rdi), %xmm4, %xmm8
 ;   vorps %xmm8, %xmm6, %xmm0
diff --git a/cranelift/filetests/filetests/isa/x64/simd-splat-avx.clif b/cranelift/filetests/filetests/isa/x64/simd-splat-avx.clif
index 8848b6694..34ce5c50c 100644
--- a/cranelift/filetests/filetests/isa/x64/simd-splat-avx.clif
+++ b/cranelift/filetests/filetests/isa/x64/simd-splat-avx.clif
@@ -12,7 +12,7 @@ block0(v0: i8):
 ;   pushq   %rbp
 ;   movq    %rsp, %rbp
 ; block0:
-;   movd    %edi, %xmm2
+;   vmovd   %edi, %xmm2
 ;   uninit  %xmm4
 ;   vpxor   %xmm4, %xmm4, %xmm6
 ;   vpshufb %xmm2, %xmm6, %xmm0
@@ -25,7 +25,7 @@ block0(v0: i8):
 ;   pushq %rbp
 ;   movq %rsp, %rbp
 ; block1: ; offset 0x4
-;   movd %edi, %xmm2
+;   vmovd %edi, %xmm2
 ;   vpxor %xmm4, %xmm4, %xmm6
 ;   vpshufb %xmm6, %xmm2, %xmm0
 ;   movq %rbp, %rsp
@@ -42,7 +42,7 @@ block0(v0: i16):
 ;   pushq   %rbp
 ;   movq    %rsp, %rbp
 ; block0:
-;   movd    %edi, %xmm2
+;   vmovd   %edi, %xmm2
 ;   vpshuflw $0, %xmm2, %xmm4
 ;   vpshufd $0, %xmm4, %xmm0
 ;   movq    %rbp, %rsp
@@ -54,7 +54,7 @@ block0(v0: i16):
 ;   pushq %rbp
 ;   movq %rsp, %rbp
 ; block1: ; offset 0x4
-;   movd %edi, %xmm2
+;   vmovd %edi, %xmm2
 ;   vpshuflw $0, %xmm2, %xmm4
 ;   vpshufd $0, %xmm4, %xmm0
 ;   movq %rbp, %rsp
@@ -71,7 +71,7 @@ block0(v0: i32):
 ;   pushq   %rbp
 ;   movq    %rsp, %rbp
 ; block0:
-;   movd    %edi, %xmm2
+;   vmovd   %edi, %xmm2
 ;   vpshufd $0, %xmm2, %xmm0
 ;   movq    %rbp, %rsp
 ;   popq    %rbp
@@ -82,7 +82,7 @@ block0(v0: i32):
 ;   pushq %rbp
 ;   movq %rsp, %rbp
 ; block1: ; offset 0x4
-;   movd %edi, %xmm2
+;   vmovd %edi, %xmm2
 ;   vpshufd $0, %xmm2, %xmm0
 ;   movq %rbp, %rsp
 ;   popq %rbp
@@ -98,7 +98,7 @@ block0(v0: i64):
 ;   pushq   %rbp
 ;   movq    %rsp, %rbp
 ; block0:
-;   movq    %rdi, %xmm2
+;   vmovq   %rdi, %xmm2
 ;   vmovddup %xmm2, %xmm0
 ;   movq    %rbp, %rsp
 ;   popq    %rbp
@@ -109,7 +109,7 @@ block0(v0: i64):
 ;   pushq %rbp
 ;   movq %rsp, %rbp
 ; block1: ; offset 0x4
-;   movq %rdi, %xmm2
+;   vmovq %rdi, %xmm2
 ;   vmovddup %xmm2, %xmm0
 ;   movq %rbp, %rsp
 ;   popq %rbp
diff --git a/cranelift/filetests/filetests/isa/x64/simd-splat-avx2.clif b/cranelift/filetests/filetests/isa/x64/simd-splat-avx2.clif
index 84cdfd373..a7829d945 100644
--- a/cranelift/filetests/filetests/isa/x64/simd-splat-avx2.clif
+++ b/cranelift/filetests/filetests/isa/x64/simd-splat-avx2.clif
@@ -12,7 +12,7 @@ block0(v0: i8):
 ;   pushq   %rbp
 ;   movq    %rsp, %rbp
 ; block0:
-;   movd    %edi, %xmm2
+;   vmovd   %edi, %xmm2
 ;   vpbroadcastb %xmm2, %xmm0
 ;   movq    %rbp, %rsp
 ;   popq    %rbp
@@ -23,7 +23,7 @@ block0(v0: i8):
 ;   pushq %rbp
 ;   movq %rsp, %rbp
 ; block1: ; offset 0x4
-;   movd %edi, %xmm2
+;   vmovd %edi, %xmm2
 ;   vpbroadcastb %xmm2, %xmm0
 ;   movq %rbp, %rsp
 ;   popq %rbp
@@ -39,7 +39,7 @@ block0(v0: i16):
 ;   pushq   %rbp
 ;   movq    %rsp, %rbp
 ; block0:
-;   movd    %edi, %xmm2
+;   vmovd   %edi, %xmm2
 ;   vpbroadcastw %xmm2, %xmm0
 ;   movq    %rbp, %rsp
 ;   popq    %rbp
@@ -50,7 +50,7 @@ block0(v0: i16):
 ;   pushq %rbp
 ;   movq %rsp, %rbp
 ; block1: ; offset 0x4
-;   movd %edi, %xmm2
+;   vmovd %edi, %xmm2
 ;   vpbroadcastw %xmm2, %xmm0
 ;   movq %rbp, %rsp
 ;   popq %rbp
@@ -66,7 +66,7 @@ block0(v0: i32):
 ;   pushq   %rbp
 ;   movq    %rsp, %rbp
 ; block0:
-;   movd    %edi, %xmm2
+;   vmovd   %edi, %xmm2
 ;   vpbroadcastd %xmm2, %xmm0
 ;   movq    %rbp, %rsp
 ;   popq    %rbp
@@ -77,7 +77,7 @@ block0(v0: i32):
 ;   pushq %rbp
 ;   movq %rsp, %rbp
 ; block1: ; offset 0x4
-;   movd %edi, %xmm2
+;   vmovd %edi, %xmm2
 ;   vpbroadcastd %xmm2, %xmm0
 ;   movq %rbp, %rsp
 ;   popq %rbp
@@ -93,7 +93,7 @@ block0(v0: i64):
 ;   pushq   %rbp
 ;   movq    %rsp, %rbp
 ; block0:
-;   movq    %rdi, %xmm2
+;   vmovq   %rdi, %xmm2
 ;   vmovddup %xmm2, %xmm0
 ;   movq    %rbp, %rsp
 ;   popq    %rbp
@@ -104,7 +104,7 @@ block0(v0: i64):
 ;   pushq %rbp
 ;   movq %rsp, %rbp
 ; block1: ; offset 0x4
-;   movq %rdi, %xmm2
+;   vmovq %rdi, %xmm2
 ;   vmovddup %xmm2, %xmm0
 ;   movq %rbp, %rsp
 ;   popq %rbp
diff --git a/cranelift/filetests/filetests/isa/x64/vhigh_bits-avx.clif b/cranelift/filetests/filetests/isa/x64/vhigh_bits-avx.clif
new file mode 100644
index 000000000..7579839f8
--- /dev/null
+++ b/cranelift/filetests/filetests/isa/x64/vhigh_bits-avx.clif
@@ -0,0 +1,108 @@
+test compile precise-output
+set enable_simd
+target x86_64 has_avx
+
+function %f1(i8x16) -> i8 {
+block0(v0: i8x16):
+  v1 = vhigh_bits.i8 v0
+  return v1
+}
+
+; VCode:
+;   pushq   %rbp
+;   movq    %rsp, %rbp
+; block0:
+;   vpmovmskb %xmm0, %eax
+;   movq    %rbp, %rsp
+;   popq    %rbp
+;   ret
+; 
+; Disassembled:
+; block0: ; offset 0x0
+;   pushq %rbp
+;   movq %rsp, %rbp
+; block1: ; offset 0x4
+;   vpmovmskb %xmm0, %eax
+;   movq %rbp, %rsp
+;   popq %rbp
+;   retq
+
+function %f3(i16x8) -> i8 {
+block0(v0: i16x8):
+  v1 = vhigh_bits.i8 v0
+  return v1
+}
+
+; VCode:
+;   pushq   %rbp
+;   movq    %rsp, %rbp
+; block0:
+;   vpacksswb %xmm0, %xmm0, %xmm2
+;   vpmovmskb %xmm2, %eax
+;   shrq    $8, %rax, %rax
+;   movq    %rbp, %rsp
+;   popq    %rbp
+;   ret
+; 
+; Disassembled:
+; block0: ; offset 0x0
+;   pushq %rbp
+;   movq %rsp, %rbp
+; block1: ; offset 0x4
+;   vpacksswb %xmm0, %xmm0, %xmm2
+;   vpmovmskb %xmm2, %eax
+;   shrq $8, %rax
+;   movq %rbp, %rsp
+;   popq %rbp
+;   retq
+
+function %f4(i32x4) -> i8 {
+block0(v0: i32x4):
+  v1 = vhigh_bits.i8 v0
+  return v1
+}
+
+; VCode:
+;   pushq   %rbp
+;   movq    %rsp, %rbp
+; block0:
+;   vmovmskps %xmm0, %eax
+;   movq    %rbp, %rsp
+;   popq    %rbp
+;   ret
+; 
+; Disassembled:
+; block0: ; offset 0x0
+;   pushq %rbp
+;   movq %rsp, %rbp
+; block1: ; offset 0x4
+;   vmovmskps %xmm0, %eax
+;   movq %rbp, %rsp
+;   popq %rbp
+;   retq
+
+function %f5(i64x2) -> i8 {
+block0(v0: i64x2):
+  v1 = vhigh_bits.i8 v0
+  return v1
+}
+
+; VCode:
+;   pushq   %rbp
+;   movq    %rsp, %rbp
+; block0:
+;   vmovmskpd %xmm0, %eax
+;   movq    %rbp, %rsp
+;   popq    %rbp
+;   ret
+; 
+; Disassembled:
+; block0: ; offset 0x0
+;   pushq %rbp
+;   movq %rsp, %rbp
+; block1: ; offset 0x4
+;   vmovmskpd %xmm0, %eax
+;   movq %rbp, %rsp
+;   popq %rbp
+;   retq
+
diff --git a/cranelift/filetests/filetests/runtests/cls.clif b/cranelift/filetests/filetests/runtests/cls.clif
index d87c26193..81e3f54ff 100644
--- a/cranelift/filetests/filetests/runtests/cls.clif
+++ b/cranelift/filetests/filetests/runtests/cls.clif
@@ -2,6 +2,7 @@ test interpret
 test run
 target aarch64
 target riscv64
+target riscv64 has_zbb
 target s390x
 ; not implemented on `x86_64`
 
diff --git a/cranelift/filetests/filetests/runtests/clz.clif b/cranelift/filetests/filetests/runtests/clz.clif
index 98355af69..22080462b 100644
--- a/cranelift/filetests/filetests/runtests/clz.clif
+++ b/cranelift/filetests/filetests/runtests/clz.clif
@@ -5,12 +5,14 @@ target s390x
 target x86_64
 target x86_64 has_lzcnt
 target riscv64
+target riscv64 has_zbb
 
 function %clz_i8(i8) -> i8 {
 block0(v0: i8):
     v1 = clz v0
     return v1
 }
+; run: %clz_i8(0) == 8
 ; run: %clz_i8(1) == 7
 ; run: %clz_i8(0x40) == 1
 ; run: %clz_i8(-1) == 0
@@ -20,6 +22,7 @@ block0(v0: i16):
     v1 = clz v0
     return v1
 }
+; run: %clz_i16(0) == 16
 ; run: %clz_i16(1) == 15
 ; run: %clz_i16(0x4000) == 1
 ; run: %clz_i16(-1) == 0
@@ -29,6 +32,7 @@ block0(v0: i32):
     v1 = clz v0
     return v1
 }
+; run: %clz_i32(0) == 32
 ; run: %clz_i32(1) == 31
 ; run: %clz_i32(0x40000000) == 1
 ; run: %clz_i32(-1) == 0
@@ -38,6 +42,7 @@ block0(v0: i64):
     v1 = clz v0
     return v1
 }
+; run: %clz_i64(0) == 64
 ; run: %clz_i64(1) == 63
 ; run: %clz_i64(0x4000000000000000) == 1
 ; run: %clz_i64(-1) == 0
diff --git a/cranelift/filetests/filetests/runtests/ctz.clif b/cranelift/filetests/filetests/runtests/ctz.clif
index 305163867..adef585fa 100644
--- a/cranelift/filetests/filetests/runtests/ctz.clif
+++ b/cranelift/filetests/filetests/runtests/ctz.clif
@@ -3,14 +3,17 @@ test run
 target aarch64
 target s390x
 target x86_64
-target riscv64
 target x86_64 has_bmi1
+target riscv64
+target riscv64 has_zbb
+target riscv64 has_zbb has_zbs
 
 function %ctz_i8(i8) -> i8 {
 block0(v0: i8):
     v1 = ctz v0
     return v1
 }
+; run: %ctz_i8(0) == 8
 ; run: %ctz_i8(1) == 0
 ; run: %ctz_i8(0x40) == 6
 ; run: %ctz_i8(-1) == 0
@@ -20,6 +23,7 @@ block0(v0: i16):
     v1 = ctz v0
     return v1
 }
+; run: %ctz_i16(0) == 16
 ; run: %ctz_i16(1) == 0
 ; run: %ctz_i16(0x4000) == 14
 ; run: %ctz_i16(-1) == 0
@@ -29,6 +33,7 @@ block0(v0: i32):
     v1 = ctz v0
     return v1
 }
+; run: %ctz_i32(0) == 32
 ; run: %ctz_i32(1) == 0
 ; run: %ctz_i32(0x40000000) == 30
 ; run: %ctz_i32(-1) == 0
@@ -38,6 +43,7 @@ block0(v0: i64):
     v1 = ctz v0
     return v1
 }
+; run: %ctz_i64(0) == 64
 ; run: %ctz_i64(1) == 0
 ; run: %ctz_i64(0x4000000000000000) == 62
 ; run: %ctz_i64(-1) == 0
diff --git a/cranelift/filetests/filetests/runtests/i128-bitops-count.clif b/cranelift/filetests/filetests/runtests/i128-bitops-count.clif
index 533fdce31..a57cc4308 100644
--- a/cranelift/filetests/filetests/runtests/i128-bitops-count.clif
+++ b/cranelift/filetests/filetests/runtests/i128-bitops-count.clif
@@ -4,6 +4,8 @@ target aarch64
 target s390x
 target x86_64
 target riscv64
+target riscv64 has_zbb
+target riscv64 has_zbb has_zbs
 
 function %ctz_i128(i128) -> i128 {
 block0(v0: i128):
diff --git a/cranelift/filetests/filetests/runtests/i128-cls.clif b/cranelift/filetests/filetests/runtests/i128-cls.clif
index cd9deac10..24fe9a172 100644
--- a/cranelift/filetests/filetests/runtests/i128-cls.clif
+++ b/cranelift/filetests/filetests/runtests/i128-cls.clif
@@ -1,6 +1,7 @@
 test run
 target aarch64
-target riscv64 
+target riscv64
+target riscv64 has_zbb
 target s390x
 
 function %cls_i128(i128) -> i128 {
diff --git a/tests/all/epoch_interruption.rs b/tests/all/epoch_interruption.rs
index c34a8b7f7..a340ef658 100644
--- a/tests/all/epoch_interruption.rs
+++ b/tests/all/epoch_interruption.rs
@@ -32,7 +32,7 @@ fn make_env<T>(engine: &Engine) -> Linker<T> {
 
 enum InterruptMode {
     Trap,
-    Callback(fn(&mut usize) -> Result<u64>),
+    Callback(fn(StoreContextMut<usize>) -> Result<u64>),
     Yield(u64),
 }
 
@@ -334,7 +334,8 @@ async fn epoch_callback_continue() {
                 (func $subfunc))
             ",
             1,
-            InterruptMode::Callback(|s| {
+            InterruptMode::Callback(|mut cx| {
+                let s = cx.data_mut();
                 *s += 1;
                 Ok(1)
             }),