Repository: bytecodealliance/wasmtime
Pull request #6019 (2023-03-14 18:47:12)

craelift: Compact cases in valid_for_target with or-patterns
Compact down the cases in `valid_for_target` a bit by using or-patterns. In many cases, this means that we can express the exemptions of a single issue with one entry, rather than spreading them across many entries.

<!--

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 f61028eb3..015c7f822 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -4031,6 +4031,15 @@ dependencies = [
  "wasmparser",
 ]
 
+[[package]]
+name = "winch-environ"
+version = "0.6.0"
+dependencies = [
+ "wasmparser",
+ "wasmtime-environ",
+ "winch-codegen",
+]
+
 [[package]]
 name = "winch-filetests"
 version = "0.0.0"
@@ -4045,6 +4054,7 @@ dependencies = [
  "wasmtime-environ",
  "wat",
  "winch-codegen",
+ "winch-environ",
  "winch-test-macros",
 ]
 
@@ -4075,6 +4085,7 @@ dependencies = [
  "wasmtime-environ",
  "wat",
  "winch-codegen",
+ "winch-environ",
  "winch-filetests",
  "winch-test-macros",
 ]
diff --git a/Cargo.toml b/Cargo.toml
index f2634cffc..6f081ca40 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -101,7 +101,8 @@ members = [
   "examples/tokio/wasm",
   "fuzz",
   "winch",
-  "winch/codegen"
+  "winch/codegen",
+  "winch/environ"
 ]
 exclude = [
   'crates/wasi-common/WASI/tools/witx-cli',
@@ -163,6 +164,7 @@ cranelift-bforest = { path = "cranelift/bforest", version = "0.95.0" }
 cranelift = { path = "cranelift/umbrella", version = "0.95.0" }
 
 winch-codegen = { path = "winch/codegen", version = "=0.6.0" }
+winch-environ = { path = "winch/environ", version = "=0.6.0" }
 winch-filetests = { path = "winch/filetests" }
 winch-test-macros = { path = "winch/test-macros" }
 
diff --git a/cranelift/fuzzgen/src/function_generator.rs b/cranelift/fuzzgen/src/function_generator.rs
index ff7ae0b88..e48301b27 100644
--- a/cranelift/fuzzgen/src/function_generator.rs
+++ b/cranelift/fuzzgen/src/function_generator.rs
@@ -414,70 +414,36 @@ fn valid_for_target(triple: &Triple, op: Opcode, args: &[Type], rets: &[Type]) -
     match triple.architecture {
         Architecture::X86_64 => {
             exceptions!(
-                (Opcode::IaddCout, &[I8, I8]),
-                (Opcode::IaddCout, &[I16, I16]),
-                (Opcode::IaddCout, &[I128, I128]),
-                // https://github.com/bytecodealliance/wasmtime/issues/5468
-                (Opcode::Smulhi, &[I8, I8]),
+                (Opcode::IaddCout, &([I8, I8] | [I16, I16] | [I128, I128])),
                 // https://github.com/bytecodealliance/wasmtime/issues/5468
-                (Opcode::Umulhi, &[I8, I8]),
+                (Opcode::Smulhi | Opcode::Umulhi, &[I8, I8]),
                 // https://github.com/bytecodealliance/wasmtime/issues/4756
-                (Opcode::Udiv, &[I128, I128]),
-                // https://github.com/bytecodealliance/wasmtime/issues/4770
-                (Opcode::Sdiv, &[I128, I128]),
+                (Opcode::Udiv | Opcode::Sdiv, &[I128, I128]),
                 // https://github.com/bytecodealliance/wasmtime/issues/5474
-                (Opcode::Urem, &[I128, I128]),
-                // https://github.com/bytecodealliance/wasmtime/issues/5474
-                (Opcode::Srem, &[I128, I128]),
+                (Opcode::Urem | Opcode::Srem, &[I128, I128]),
                 // https://github.com/bytecodealliance/wasmtime/issues/5466
                 (Opcode::Iabs, &[I128]),
                 // https://github.com/bytecodealliance/wasmtime/issues/3370
-                (Opcode::Smin, &[I128, I128]),
-                // https://github.com/bytecodealliance/wasmtime/issues/3370
-                (Opcode::Umin, &[I128, I128]),
-                // https://github.com/bytecodealliance/wasmtime/issues/3370
-                (Opcode::Smax, &[I128, I128]),
-                // https://github.com/bytecodealliance/wasmtime/issues/3370
-                (Opcode::Umax, &[I128, I128]),
-                // https://github.com/bytecodealliance/wasmtime/issues/4870
-                (Opcode::Band, &[F32, F32]),
-                (Opcode::Band, &[F64, F64]),
-                // https://github.com/bytecodealliance/wasmtime/issues/4870
-                (Opcode::Bor, &[F32, F32]),
-                (Opcode::Bor, &[F64, F64]),
+                (
+                    Opcode::Smin | Opcode::Umin | Opcode::Smax | Opcode::Umax,
+                    &[I128, I128]
+                ),
                 // https://github.com/bytecodealliance/wasmtime/issues/4870
-                (Opcode::Bxor, &[F32, F32]),
-                (Opcode::Bxor, &[F64, F64]),
-                // https://github.com/bytecodealliance/wasmtime/issues/4870
-                (Opcode::Bnot, &[F32, F32]),
-                (Opcode::Bnot, &[F64, F64]),
-                // https://github.com/bytecodealliance/wasmtime/issues/5041
-                (Opcode::BandNot, &[I8, I8]),
-                (Opcode::BandNot, &[I16, I16]),
-                (Opcode::BandNot, &[I32, I32]),
-                (Opcode::BandNot, &[I64, I64]),
-                (Opcode::BandNot, &[I128, I128]),
-                // https://github.com/bytecodealliance/wasmtime/issues/4870
-                (Opcode::BandNot, &[F32, F32]),
-                (Opcode::BandNot, &[F64, F64]),
+                (
+                    Opcode::Band
+                        | Opcode::Bor
+                        | Opcode::Bxor
+                        | Opcode::Bnot
+                        | Opcode::BandNot
+                        | Opcode::BorNot
+                        | Opcode::BxorNot,
+                    &([F32, F32] | [F64, F64])
+                ),
                 // https://github.com/bytecodealliance/wasmtime/issues/5041
-                (Opcode::BorNot, &[I8, I8]),
-                (Opcode::BorNot, &[I16, I16]),
-                (Opcode::BorNot, &[I32, I32]),
-                (Opcode::BorNot, &[I64, I64]),
-                (Opcode::BorNot, &[I128, I128]),
-                // https://github.com/bytecodealliance/wasmtime/issues/4870
-                (Opcode::BorNot, &[F32, F32]),
-                (Opcode::BorNot, &[F64, F64]),
-                // https://github.com/bytecodealliance/wasmtime/issues/5041
-                (Opcode::BxorNot, &[I8, I8]),
-                (Opcode::BxorNot, &[I16, I16]),
-                (Opcode::BxorNot, &[I32, I32]),
-                (Opcode::BxorNot, &[I64, I64]),
-                (Opcode::BxorNot, &[I128, I128]),
-                // https://github.com/bytecodealliance/wasmtime/issues/4870
-                (Opcode::BxorNot, &[F32, F32]),
-                (Opcode::BxorNot, &[F64, F64]),
+                (
+                    Opcode::BandNot | Opcode::BorNot | Opcode::BxorNot,
+                    &([I8, I8] | [I16, I16] | [I32, I32] | [I64, I64] | [I128, I128])
+                ),
                 // https://github.com/bytecodealliance/wasmtime/issues/5107
                 (Opcode::Cls, &[I8], &[I8]),
                 (Opcode::Cls, &[I16], &[I16]),
@@ -485,93 +451,59 @@ fn valid_for_target(triple: &Triple, op: Opcode, args: &[Type], rets: &[Type]) -
                 (Opcode::Cls, &[I64], &[I64]),
                 (Opcode::Cls, &[I128], &[I128]),
                 // https://github.com/bytecodealliance/wasmtime/issues/5197
-                (Opcode::Bitselect, &[I8, I8, I8]),
-                (Opcode::Bitselect, &[I16, I16, I16]),
-                (Opcode::Bitselect, &[I32, I32, I32]),
-                (Opcode::Bitselect, &[I64, I64, I64]),
-                (Opcode::Bitselect, &[I128, I128, I128]),
+                (
+                    Opcode::Bitselect,
+                    &([I8, I8, I8]
+                        | [I16, I16, I16]
+                        | [I32, I32, I32]
+                        | [I64, I64, I64]
+                        | [I128, I128, I128])
+                ),
                 // https://github.com/bytecodealliance/wasmtime/issues/4897
                 // https://github.com/bytecodealliance/wasmtime/issues/4899
-                (Opcode::FcvtToUint, &[F32], &[I8]),
-                (Opcode::FcvtToUint, &[F32], &[I16]),
-                (Opcode::FcvtToUint, &[F32], &[I128]),
-                (Opcode::FcvtToUint, &[F64], &[I8]),
-                (Opcode::FcvtToUint, &[F64], &[I16]),
-                (Opcode::FcvtToUint, &[F64], &[I128]),
-                (Opcode::FcvtToUint, &[F32X4], &[I32X4]),
-                (Opcode::FcvtToUint, &[F64X2], &[I64X2]),
-                // https://github.com/bytecodealliance/wasmtime/issues/4897
-                // https://github.com/bytecodealliance/wasmtime/issues/4899
-                (Opcode::FcvtToUintSat, &[F32], &[I8]),
-                (Opcode::FcvtToUintSat, &[F32], &[I16]),
-                (Opcode::FcvtToUintSat, &[F32], &[I128]),
-                (Opcode::FcvtToUintSat, &[F64], &[I8]),
-                (Opcode::FcvtToUintSat, &[F64], &[I16]),
-                (Opcode::FcvtToUintSat, &[F64], &[I128]),
-                (Opcode::FcvtToUintSat, &[F64X2], &[I64X2]),
-                // https://github.com/bytecodealliance/wasmtime/issues/4897
-                // https://github.com/bytecodealliance/wasmtime/issues/4899
-                (Opcode::FcvtToSint, &[F32], &[I8]),
-                (Opcode::FcvtToSint, &[F32], &[I16]),
-                (Opcode::FcvtToSint, &[F32], &[I128]),
-                (Opcode::FcvtToSint, &[F64], &[I8]),
-                (Opcode::FcvtToSint, &[F64], &[I16]),
-                (Opcode::FcvtToSint, &[F64], &[I128]),
-                (Opcode::FcvtToSint, &[F32X4], &[I32X4]),
-                (Opcode::FcvtToSint, &[F64X2], &[I64X2]),
-                // https://github.com/bytecodealliance/wasmtime/issues/4897
-                // https://github.com/bytecodealliance/wasmtime/issues/4899
-                (Opcode::FcvtToSintSat, &[F32], &[I8]),
-                (Opcode::FcvtToSintSat, &[F32], &[I16]),
-                (Opcode::FcvtToSintSat, &[F32], &[I128]),
-                (Opcode::FcvtToSintSat, &[F64], &[I8]),
-                (Opcode::FcvtToSintSat, &[F64], &[I16]),
-                (Opcode::FcvtToSintSat, &[F64], &[I128]),
-                (Opcode::FcvtToSintSat, &[F64X2], &[I64X2]),
+                (
+                    Opcode::FcvtToUint
+                        | Opcode::FcvtToUintSat
+                        | Opcode::FcvtToSint
+                        | Opcode::FcvtToSintSat,
+                    &[F32 | F64],
+                    &[I8 | I16 | I128]
+                ),
+                (Opcode::FcvtToUint | Opcode::FcvtToSint, &[F32X4], &[I32X4]),
+                (
+                    Opcode::FcvtToUint
+                        | Opcode::FcvtToUintSat
+                        | Opcode::FcvtToSint
+                        | Opcode::FcvtToSintSat,
+                    &[F64X2],
+                    &[I64X2]
+                ),
                 // https://github.com/bytecodealliance/wasmtime/issues/4900
-                (Opcode::FcvtFromUint, &[I128], &[F32]),
-                (Opcode::FcvtFromUint, &[I128], &[F64]),
+                (Opcode::FcvtFromUint, &[I128], &[F32 | F64]),
                 // This has a lowering, but only when preceded by `uwiden_low`.
                 (Opcode::FcvtFromUint, &[I64X2], &[F64X2]),
                 // https://github.com/bytecodealliance/wasmtime/issues/4900
-                (Opcode::FcvtFromSint, &[I128], &[F32]),
-                (Opcode::FcvtFromSint, &[I128], &[F64]),
+                (Opcode::FcvtFromSint, &[I128], &[F32 | F64]),
                 (Opcode::FcvtFromSint, &[I64X2], &[F64X2]),
-                (Opcode::Bmask, &[I8X16]),
-                (Opcode::Bmask, &[I16X8]),
-                (Opcode::Bmask, &[I32X4]),
-                (Opcode::Bmask, &[I64X2]),
-                (Opcode::Umulhi, &[I8X16, I8X16]),
-                (Opcode::Umulhi, &[I16X8, I16X8]),
-                (Opcode::Umulhi, &[I32X4, I32X4]),
-                (Opcode::Umulhi, &[I64X2, I64X2]),
-                (Opcode::Smulhi, &[I8X16, I8X16]),
-                (Opcode::Smulhi, &[I16X8, I16X8]),
-                (Opcode::Smulhi, &[I32X4, I32X4]),
-                (Opcode::Smulhi, &[I64X2, I64X2]),
-                (Opcode::UaddSat, &[I32X4, I32X4]),
-                (Opcode::UaddSat, &[I64X2, I64X2]),
-                (Opcode::SaddSat, &[I32X4, I32X4]),
-                (Opcode::SaddSat, &[I64X2, I64X2]),
-                (Opcode::UsubSat, &[I32X4, I32X4]),
-                (Opcode::UsubSat, &[I64X2, I64X2]),
-                (Opcode::SsubSat, &[I32X4, I32X4]),
-                (Opcode::SsubSat, &[I64X2, I64X2]),
-                (Opcode::Fcopysign, &[F32X4, F32X4]),
-                (Opcode::Fcopysign, &[F64X2, F64X2]),
-                (Opcode::Popcnt, &[I8X16]),
-                (Opcode::Popcnt, &[I16X8]),
-                (Opcode::Popcnt, &[I32X4]),
-                (Opcode::Popcnt, &[I64X2]),
-                (Opcode::Umax, &[I64X2, I64X2]),
-                (Opcode::Smax, &[I64X2, I64X2]),
-                (Opcode::Umin, &[I64X2, I64X2]),
-                (Opcode::Smin, &[I64X2, I64X2]),
+                (Opcode::Bmask, &[I8X16 | I16X8 | I32X4 | I64X2]),
+                (
+                    Opcode::Umulhi | Opcode::Smulhi,
+                    &([I8X16, I8X16] | [I16X8, I16X8] | [I32X4, I32X4] | [I64X2, I64X2])
+                ),
+                (
+                    Opcode::UaddSat | Opcode::SaddSat | Opcode::UsubSat | Opcode::SsubSat,
+                    &([I32X4, I32X4] | [I64X2, I64X2])
+                ),
+                (Opcode::Fcopysign, &([F32X4, F32X4] | [F64X2, F64X2])),
+                (Opcode::Popcnt, &([I8X16] | [I16X8] | [I32X4] | [I64X2])),
+                (
+                    Opcode::Umax | Opcode::Smax | Opcode::Umin | Opcode::Smin,
+                    &[I64X2, I64X2]
+                ),
                 (Opcode::Bitcast, &[I128], &[_]),
                 (Opcode::Bitcast, &[_], &[I128]),
                 (Opcode::Uunarrow),
-                (Opcode::Snarrow, &[I64X2, I64X2]),
-                (Opcode::Unarrow, &[I64X2, I64X2]),
+                (Opcode::Snarrow | Opcode::Unarrow, &[I64X2, I64X2]),
                 (Opcode::SqmulRoundSat, &[I32X4, I32X4]),
                 // This Icmp is not implemented: #5529
                 (Opcode::Icmp, &[I64X2, I64X2]),
@@ -582,18 +514,15 @@ fn valid_for_target(triple: &Triple, op: Opcode, args: &[Type], rets: &[Type]) -
                 (Opcode::Select, &[_, I128, I128]),
                 // These stack accesses can cause segfaults if they are merged into an SSE instruction.
                 // See: #5922
-                (Opcode::StackStore, &[I8X16], &[]),
-                (Opcode::StackStore, &[I16X8], &[]),
-                (Opcode::StackStore, &[I32X4], &[]),
-                (Opcode::StackStore, &[I64X2], &[]),
-                (Opcode::StackStore, &[F32X4], &[]),
-                (Opcode::StackStore, &[F64X2], &[]),
-                (Opcode::StackLoad, &[], &[I8X16]),
-                (Opcode::StackLoad, &[], &[I16X8]),
-                (Opcode::StackLoad, &[], &[I32X4]),
-                (Opcode::StackLoad, &[], &[I64X2]),
-                (Opcode::StackLoad, &[], &[F32X4]),
-                (Opcode::StackLoad, &[], &[F64X2]),
+                (
+                    Opcode::StackStore,
+                    &[I8X16 | I16X8 | I32X4 | I64X2 | F32X4 | F64X2]
+                ),
+                (
+                    Opcode::StackLoad,
+                    &[],
+                    &[I8X16 | I16X8 | I32X4 | I64X2 | F32X4 | F64X2]
+                ),
             )
         }
 
@@ -601,79 +530,49 @@ fn valid_for_target(triple: &Triple, op: Opcode, args: &[Type], rets: &[Type]) -
             exceptions!(
                 (Opcode::IaddCout, &[I128, I128]),
                 // https://github.com/bytecodealliance/wasmtime/issues/4864
-                (Opcode::Udiv, &[I128, I128]),
-                // https://github.com/bytecodealliance/wasmtime/issues/4864
-                (Opcode::Sdiv, &[I128, I128]),
-                // https://github.com/bytecodealliance/wasmtime/issues/5472
-                (Opcode::Urem, &[I128, I128]),
+                (Opcode::Udiv | Opcode::Sdiv, &[I128, I128]),
                 // https://github.com/bytecodealliance/wasmtime/issues/5472
-                (Opcode::Srem, &[I128, I128]),
+                (Opcode::Urem | Opcode::Srem, &[I128, I128]),
                 // https://github.com/bytecodealliance/wasmtime/issues/5467
                 (Opcode::Iabs, &[I128]),
                 // https://github.com/bytecodealliance/wasmtime/issues/4313
-                (Opcode::Smin, &[I128, I128]),
-                // https://github.com/bytecodealliance/wasmtime/issues/4313
-                (Opcode::Umin, &[I128, I128]),
-                // https://github.com/bytecodealliance/wasmtime/issues/4313
-                (Opcode::Smax, &[I128, I128]),
-                // https://github.com/bytecodealliance/wasmtime/issues/4313
-                (Opcode::Umax, &[I128, I128]),
-                // https://github.com/bytecodealliance/wasmtime/issues/4870
-                (Opcode::Band, &[F32, F32]),
-                (Opcode::Band, &[F64, F64]),
-                // https://github.com/bytecodealliance/wasmtime/issues/4870
-                (Opcode::Bor, &[F32, F32]),
-                (Opcode::Bor, &[F64, F64]),
-                // https://github.com/bytecodealliance/wasmtime/issues/4870
-                (Opcode::Bxor, &[F32, F32]),
-                (Opcode::Bxor, &[F64, F64]),
-                // https://github.com/bytecodealliance/wasmtime/issues/4870
-                (Opcode::Bnot, &[F32, F32]),
-                (Opcode::Bnot, &[F64, F64]),
+                (
+                    Opcode::Smin | Opcode::Umin | Opcode::Smax | Opcode::Umax,
+                    &[I128, I128]
+                ),
                 // https://github.com/bytecodealliance/wasmtime/issues/4870
-                (Opcode::BandNot, &[F32, F32]),
-                (Opcode::BandNot, &[F64, F64]),
-                // https://github.com/bytecodealliance/wasmtime/issues/4870
-                (Opcode::BorNot, &[F32, F32]),
-                (Opcode::BorNot, &[F64, F64]),
-                // https://github.com/bytecodealliance/wasmtime/issues/4870
-                (Opcode::BxorNot, &[F32, F32]),
-                (Opcode::BxorNot, &[F64, F64]),
+                (
+                    Opcode::Band
+                        | Opcode::Bor
+                        | Opcode::Bxor
+                        | Opcode::Bnot
+                        | Opcode::BandNot
+                        | Opcode::BorNot
+                        | Opcode::BxorNot,
+                    &([F32, F32] | [F64, F64])
+                ),
                 // https://github.com/bytecodealliance/wasmtime/issues/5198
                 (Opcode::Bitselect, &[I128, I128, I128]),
                 // https://github.com/bytecodealliance/wasmtime/issues/4934
-                (Opcode::FcvtToUint, &[F32]),
-                (Opcode::FcvtToUint, &[F64]),
-                // https://github.com/bytecodealliance/wasmtime/issues/4934
-                (Opcode::FcvtToUintSat, &[F32]),
-                (Opcode::FcvtToUintSat, &[F64]),
-                // https://github.com/bytecodealliance/wasmtime/issues/4934
-                (Opcode::FcvtToSint, &[F32]),
-                (Opcode::FcvtToSint, &[F64]),
-                // https://github.com/bytecodealliance/wasmtime/issues/4934
-                (Opcode::FcvtToSintSat, &[F32]),
-                (Opcode::FcvtToSintSat, &[F64]),
-                // https://github.com/bytecodealliance/wasmtime/issues/4933
-                (Opcode::FcvtFromUint, &[I128], &[F32]),
-                (Opcode::FcvtFromUint, &[I128], &[F64]),
+                (
+                    Opcode::FcvtToUint
+                        | Opcode::FcvtToUintSat
+                        | Opcode::FcvtToSint
+                        | Opcode::FcvtToSintSat,
+                    &[F32 | F64]
+                ),
                 // https://github.com/bytecodealliance/wasmtime/issues/4933
-                (Opcode::FcvtFromSint, &[I128], &[F32]),
-                (Opcode::FcvtFromSint, &[I128], &[F64]),
-                (Opcode::Bmask, &[I8X16]),
-                (Opcode::Bmask, &[I16X8]),
-                (Opcode::Bmask, &[I32X4]),
-                (Opcode::Bmask, &[I64X2]),
-                (Opcode::Umulhi, &[I8X16, I8X16]),
-                (Opcode::Umulhi, &[I16X8, I16X8]),
-                (Opcode::Umulhi, &[I32X4, I32X4]),
-                (Opcode::Umulhi, &[I64X2, I64X2]),
-                (Opcode::Smulhi, &[I8X16, I8X16]),
-                (Opcode::Smulhi, &[I16X8, I16X8]),
-                (Opcode::Smulhi, &[I32X4, I32X4]),
-                (Opcode::Smulhi, &[I64X2, I64X2]),
-                (Opcode::Popcnt, &[I16X8]),
-                (Opcode::Popcnt, &[I32X4]),
-                (Opcode::Popcnt, &[I64X2]),
+                (
+                    Opcode::FcvtFromUint | Opcode::FcvtFromSint,
+                    &[I128],
+                    &[F32 | F64]
+                ),
+                (Opcode::Bmask, &[I8X16 | I16X8 | I32X4 | I64X2]),
+                (
+                    Opcode::Umulhi | Opcode::Smulhi,
+                    &([I8X16, I8X16] | [I16X8, I16X8] | [I32X4, I32X4] | [I64X2, I64X2])
+                ),
+                (Opcode::Popcnt, &[I16X8 | I32X4 | I64X2]),
                 // Nothing wrong with this select. But we have an isle rule that can optimize it
                 // into a `min`/`max` instructions, which we don't have implemented yet.
                 (Opcode::Select, &[I8, I128, I128]),
@@ -683,42 +582,35 @@ fn valid_for_target(triple: &Triple, op: Opcode, args: &[Type], rets: &[Type]) -
         Architecture::S390x => {
             exceptions!(
                 (Opcode::IaddCout),
-                (Opcode::Udiv, &[I128, I128]),
-                (Opcode::Sdiv, &[I128, I128]),
-                (Opcode::Urem, &[I128, I128]),
-                (Opcode::Srem, &[I128, I128]),
-                (Opcode::Band, &[F32, F32]),
-                (Opcode::Band, &[F64, F64]),
-                (Opcode::Bor, &[F32, F32]),
-                (Opcode::Bor, &[F64, F64]),
-                (Opcode::Bxor, &[F32, F32]),
-                (Opcode::Bxor, &[F64, F64]),
-                (Opcode::Bnot, &[F32, F32]),
-                (Opcode::Bnot, &[F64, F64]),
-                (Opcode::BandNot, &[F32, F32]),
-                (Opcode::BandNot, &[F64, F64]),
-                (Opcode::BorNot, &[F32, F32]),
-                (Opcode::BorNot, &[F64, F64]),
-                (Opcode::BxorNot, &[F32, F32]),
-                (Opcode::BxorNot, &[F64, F64]),
-                (Opcode::FcvtToUint, &[F32], &[I128]),
-                (Opcode::FcvtToUint, &[F64], &[I128]),
-                (Opcode::FcvtToUintSat, &[F32], &[I128]),
-                (Opcode::FcvtToUintSat, &[F64], &[I128]),
-                (Opcode::FcvtToSint, &[F32], &[I128]),
-                (Opcode::FcvtToSint, &[F64], &[I128]),
-                (Opcode::FcvtToSintSat, &[F32], &[I128]),
-                (Opcode::FcvtToSintSat, &[F64], &[I128]),
-                (Opcode::FcvtFromUint, &[I128], &[F32]),
-                (Opcode::FcvtFromUint, &[I128], &[F64]),
-                (Opcode::FcvtFromSint, &[I128], &[F32]),
-                (Opcode::FcvtFromSint, &[I128], &[F64]),
-                (Opcode::Bmask, &[I8X16]),
-                (Opcode::Bmask, &[I16X8]),
-                (Opcode::Bmask, &[I32X4]),
-                (Opcode::Bmask, &[I64X2]),
-                (Opcode::SsubSat, &[I64X2, I64X2]),
-                (Opcode::SaddSat, &[I64X2, I64X2]),
+                (
+                    Opcode::Udiv | Opcode::Sdiv | Opcode::Urem | Opcode::Srem,
+                    &[I128, I128]
+                ),
+                (
+                    Opcode::Band
+                        | Opcode::Bor
+                        | Opcode::Bxor
+                        | Opcode::Bnot
+                        | Opcode::BandNot
+                        | Opcode::BorNot
+                        | Opcode::BxorNot,
+                    &([F32, F32] | [F64, F64])
+                ),
+                (
+                    Opcode::FcvtToUint
+                        | Opcode::FcvtToUintSat
+                        | Opcode::FcvtToSint
+                        | Opcode::FcvtToSintSat,
+                    &[F32 | F64],
+                    &[I128]
+                ),
+                (
+                    Opcode::FcvtFromUint | Opcode::FcvtFromSint,
+                    &[I128],
+                    &[F32 | F64]
+                ),
+                (Opcode::Bmask, &[I8X16 | I16X8 | I32X4 | I64X2]),
+                (Opcode::SsubSat | Opcode::SaddSat, &[I64X2, I64X2]),
             )
         }
 
@@ -733,13 +625,10 @@ fn valid_for_target(triple: &Triple, op: Opcode, args: &[Type], rets: &[Type]) -
                 // TODO
                 (Opcode::IaddCout),
                 // TODO
-                (Opcode::Udiv, &[I128, I128]),
-                // TODO
-                (Opcode::Sdiv, &[I128, I128]),
-                // TODO
-                (Opcode::Urem, &[I128, I128]),
-                // TODO
-                (Opcode::Srem, &[I128, I128]),
+                (
+                    Opcode::Udiv | Opcode::Sdiv | Opcode::Urem | Opcode::Srem,
+                    &[I128, I128]
+                ),
                 // TODO
                 (Opcode::Iabs, &[I128]),
                 // TODO
@@ -747,70 +636,25 @@ fn valid_for_target(triple: &Triple, op: Opcode, args: &[Type], rets: &[Type]) -
                 // TODO
                 (Opcode::Bswap),
                 // https://github.com/bytecodealliance/wasmtime/issues/5528
-                (Opcode::FcvtToUint, &[F32], &[I8]),
-                (Opcode::FcvtToUint, &[F32], &[I16]),
-                // TODO
-                (Opcode::FcvtToUint, &[F32], &[I128]),
-                // https://github.com/bytecodealliance/wasmtime/issues/5528
-                (Opcode::FcvtToUint, &[F64], &[I8]),
-                (Opcode::FcvtToUint, &[F64], &[I16]),
-                // TODO
-                (Opcode::FcvtToUint, &[F64], &[I128]),
+                (
+                    Opcode::FcvtToUint
+                        | Opcode::FcvtToUintSat
+                        | Opcode::FcvtToSint
+                        | Opcode::FcvtToSintSat,
+                    &[F32 | F64],
+                    &[I8 | I16 | I128]
+                ),
                 // https://github.com/bytecodealliance/wasmtime/issues/5528
-                (Opcode::FcvtToUintSat, &[F32], &[I8]),
-                (Opcode::FcvtToUintSat, &[F32], &[I16]),
-                // TODO
-                (Opcode::FcvtToUintSat, &[F32], &[I128]),
-                // https://github.com/bytecodealliance/wasmtime/issues/5528
-                (Opcode::FcvtToUintSat, &[F64], &[I8]),
-                (Opcode::FcvtToUintSat, &[F64], &[I16]),
-                // TODO
-                (Opcode::FcvtToUintSat, &[F64], &[I128]),
-                // https://github.com/bytecodealliance/wasmtime/issues/5528
-                (Opcode::FcvtToSint, &[F32], &[I8]),
-                (Opcode::FcvtToSint, &[F32], &[I16]),
-                // TODO
-                (Opcode::FcvtToSint, &[F32], &[I128]),
-                // https://github.com/bytecodealliance/wasmtime/issues/5528
-                (Opcode::FcvtToSint, &[F64], &[I8]),
-                (Opcode::FcvtToSint, &[F64], &[I16]),
-                // TODO
-                (Opcode::FcvtToSint, &[F64], &[I128]),
-                // https://github.com/bytecodealliance/wasmtime/issues/5528
-                (Opcode::FcvtToSintSat, &[F32], &[I8]),
-                (Opcode::FcvtToSintSat, &[F32], &[I16]),
-                // TODO
-                (Opcode::FcvtToSintSat, &[F32], &[I128]),
-                // https://github.com/bytecodealliance/wasmtime/issues/5528
-                (Opcode::FcvtToSintSat, &[F64], &[I8]),
-                (Opcode::FcvtToSintSat, &[F64], &[I16]),
-                // TODO
-                (Opcode::FcvtToSintSat, &[F64], &[I128]),
-                // https://github.com/bytecodealliance/wasmtime/issues/5528
-                (Opcode::FcvtFromUint, &[I8], &[F32]),
-                (Opcode::FcvtFromUint, &[I8], &[F64]),
-                (Opcode::FcvtFromUint, &[I16], &[F32]),
-                (Opcode::FcvtFromUint, &[I16], &[F64]),
-                // TODO
-                (Opcode::FcvtFromUint, &[I128], &[F32]),
-                (Opcode::FcvtFromUint, &[I128], &[F64]),
-                // https://github.com/bytecodealliance/wasmtime/issues/5528
-                (Opcode::FcvtFromSint, &[I8], &[F32]),
-                (Opcode::FcvtFromSint, &[I8], &[F64]),
-                (Opcode::FcvtFromSint, &[I16], &[F32]),
-                (Opcode::FcvtFromSint, &[I16], &[F64]),
-                // TODO
-                (Opcode::FcvtFromSint, &[I128], &[F32]),
-                (Opcode::FcvtFromSint, &[I128], &[F64]),
-                // TODO
-                (Opcode::BandNot, &[F32, F32]),
-                (Opcode::BandNot, &[F64, F64]),
-                // TODO
-                (Opcode::BorNot, &[F32, F32]),
-                (Opcode::BorNot, &[F64, F64]),
+                (
+                    Opcode::FcvtFromUint | Opcode::FcvtFromSint,
+                    &[I8 | I16 | I128],
+                    &[F32 | F64]
+                ),
                 // TODO
-                (Opcode::BxorNot, &[F32, F32]),
-                (Opcode::BxorNot, &[F64, F64]),
+                (
+                    Opcode::BandNot | Opcode::BorNot | Opcode::BxorNot,
+                    &([F32, F32] | [F64, F64])
+                ),
                 // https://github.com/bytecodealliance/wasmtime/issues/5884
                 (Opcode::AtomicRmw),
             )
diff --git a/scripts/publish.rs b/scripts/publish.rs
index 73a229a54..b64b178db 100644
--- a/scripts/publish.rs
+++ b/scripts/publish.rs
@@ -57,6 +57,7 @@ const CRATES_TO_PUBLISH: &[&str] = &[
     "wasmtime-jit",
     "wasmtime-cache",
     "wasmtime-winch",
+    "winch-environ",
     "wasmtime",
     // wasi-common/wiggle
     "wiggle",
diff --git a/winch/Cargo.toml b/winch/Cargo.toml
index d86a0b22a..825913017 100644
--- a/winch/Cargo.toml
+++ b/winch/Cargo.toml
@@ -13,6 +13,7 @@ path = "src/main.rs"
 
 [dependencies]
 winch-codegen = { workspace = true }
+winch-environ = { workspace = true }
 winch-filetests = { workspace = true }
 winch-test-macros = { workspace = true }
 wasmtime-environ = { workspace = true }
diff --git a/winch/codegen/src/codegen/env.rs b/winch/codegen/src/codegen/env.rs
new file mode 100644
index 000000000..f05ac47fc
--- /dev/null
+++ b/winch/codegen/src/codegen/env.rs
@@ -0,0 +1,19 @@
+use wasmparser::FuncType;
+
+/// Function environment used the by the code generation to
+/// resolve module and runtime-specific information.
+pub trait FuncEnv {
+    /// Get the callee information from a given function index.
+    fn callee_from_index(&self, index: u32) -> Callee;
+}
+
+/// Metadata about a function callee.  Use by the code generation
+/// to emit function calls.
+pub struct Callee {
+    /// The function type.
+    pub ty: FuncType,
+    /// A flag to determine if the callee is imported.
+    pub import: bool,
+    /// The callee index in the WebAssembly function index space.
+    pub index: u32,
+}
diff --git a/winch/codegen/src/codegen/mod.rs b/winch/codegen/src/codegen/mod.rs
index aa4ab537f..807912218 100644
--- a/winch/codegen/src/codegen/mod.rs
+++ b/winch/codegen/src/codegen/mod.rs
@@ -7,6 +7,8 @@ use wasmparser::{BinaryReader, FuncValidator, ValType, ValidatorResources, Visit
 
 mod context;
 pub(crate) use context::*;
+mod env;
+pub use env::*;
 
 /// The code generation abstraction.
 pub(crate) struct CodeGen<'a, M>
diff --git a/winch/codegen/src/lib.rs b/winch/codegen/src/lib.rs
index efee4a711..3321998db 100644
--- a/winch/codegen/src/lib.rs
+++ b/winch/codegen/src/lib.rs
@@ -8,6 +8,7 @@
 
 mod abi;
 mod codegen;
+pub use codegen::{Callee, FuncEnv};
 mod frame;
 pub mod isa;
 pub use isa::*;
diff --git a/winch/environ/Cargo.toml b/winch/environ/Cargo.toml
new file mode 100644
index 000000000..df49636df
--- /dev/null
+++ b/winch/environ/Cargo.toml
@@ -0,0 +1,14 @@
+[package]
+authors = ["The Winch Project Developers"]
+name = "winch-environ"
+description = "Implementation of Winch's function compilation environment"
+license = "Apache-2.0 WITH LLVM-exception"
+repository = "https://github.com/bytecodealliance/wasmtime"
+version = "0.6.0"
+edition.workspace = true
+
+
+[dependencies]
+winch-codegen = { workspace = true }
+wasmtime-environ = { workspace = true }
+wasmparser = { workspace = true }
diff --git a/winch/environ/src/lib.rs b/winch/environ/src/lib.rs
new file mode 100644
index 000000000..1e46ea6ac
--- /dev/null
+++ b/winch/environ/src/lib.rs
@@ -0,0 +1,41 @@
+//! This crate implements Winch's function compilation environment,
+//! which allows Winch's code generation to resolve module and runtime
+//! specific information.  This crate mainly implements the
+//! `winch_codegen::FuncEnv` trait.
+
+use wasmparser::types::Types;
+use wasmtime_environ::{FuncIndex, Module};
+use winch_codegen::{self, Callee, TargetIsa};
+
+/// Function environment containing module and runtime specific
+/// information.
+pub struct FuncEnv<'a> {
+    /// The translated WebAssembly module.
+    pub module: &'a Module,
+    /// Type information about a module, once it has been validated.
+    pub types: &'a Types,
+    /// The current ISA.
+    pub isa: &'a dyn TargetIsa,
+}
+
+impl<'a> winch_codegen::FuncEnv for FuncEnv<'a> {
+    fn callee_from_index(&self, index: u32) -> Callee {
+        let func = self
+            .types
+            .function_at(index)
+            .unwrap_or_else(|| panic!("function type at index: {}", index));
+
+        Callee {
+            ty: func.clone(),
+            import: self.module.is_imported_function(FuncIndex::from_u32(index)),
+            index,
+        }
+    }
+}
+
+impl<'a> FuncEnv<'a> {
+    /// Create a new function environment.
+    pub fn new(module: &'a Module, types: &'a Types, isa: &'a dyn TargetIsa) -> Self {
+        Self { module, types, isa }
+    }
+}
diff --git a/winch/src/compile.rs b/winch/src/compile.rs
index 508fa56c7..1e05a6aaf 100644
--- a/winch/src/compile.rs
+++ b/winch/src/compile.rs
@@ -4,10 +4,11 @@ use cranelift_codegen::settings;
 use std::{fs, path::PathBuf, str::FromStr};
 use target_lexicon::Triple;
 use wasmtime_environ::{
-    wasmparser::{types::Types, Parser as WasmParser, Validator},
-    DefinedFuncIndex, FunctionBodyData, Module, ModuleEnvironment, Tunables,
+    wasmparser::{Parser as WasmParser, Validator},
+    DefinedFuncIndex, FunctionBodyData, ModuleEnvironment, Tunables,
 };
-use winch_codegen::{lookup, TargetIsa};
+use winch_codegen::lookup;
+use winch_environ::FuncEnv;
 use winch_filetests::disasm::disasm;
 
 #[derive(Parser, Debug)]
@@ -40,32 +41,30 @@ pub fn run(opt: &Options) -> Result<()> {
     let body_inputs = std::mem::take(&mut translation.function_body_inputs);
     let module = &translation.module;
     let types = translation.get_types();
+    let env = FuncEnv::new(module, &types, &*isa);
 
     body_inputs
         .into_iter()
-        .try_for_each(|func| compile(&*isa, module, types, func))?;
+        .try_for_each(|func| compile(&env, func))?;
 
     Ok(())
 }
 
-fn compile(
-    isa: &dyn TargetIsa,
-    module: &Module,
-    types: &Types,
-    f: (DefinedFuncIndex, FunctionBodyData<'_>),
-) -> Result<()> {
-    let index = module.func_index(f.0);
-    let sig = types
+fn compile(env: &FuncEnv, f: (DefinedFuncIndex, FunctionBodyData<'_>)) -> Result<()> {
+    let index = env.module.func_index(f.0);
+    let sig = env
+        .types
         .function_at(index.as_u32())
         .expect(&format!("function type at index {:?}", index.as_u32()));
     let FunctionBodyData { body, validator } = f.1;
     let validator = validator.into_validator(Default::default());
-    let buffer = isa
+    let buffer = env
+        .isa
         .compile_function(&sig, &body, validator)
         .expect("Couldn't compile function");
 
     println!("Disassembly for function: {}", index.as_u32());
-    disasm(buffer.data(), isa)?
+    disasm(buffer.data(), env.isa)?
         .iter()
         .for_each(|s| println!("{}", s));
 


Test patch:
diff --git a/winch/filetests/Cargo.toml b/winch/filetests/Cargo.toml
index 9250078b4..a629e3f68 100644
--- a/winch/filetests/Cargo.toml
+++ b/winch/filetests/Cargo.toml
@@ -12,6 +12,7 @@ edition.workspace = true
 winch-test-macros = {workspace = true}
 target-lexicon = { workspace = true }
 winch-codegen = { workspace = true, features = ['all-arch'] }
+winch-environ = { workspace = true }
 wasmtime-environ = { workspace = true }
 anyhow = { workspace = true }
 wat = { workspace = true }
diff --git a/winch/filetests/src/lib.rs b/winch/filetests/src/lib.rs
index 3f49abddc..0d4f8832d 100644
--- a/winch/filetests/src/lib.rs
+++ b/winch/filetests/src/lib.rs
@@ -10,11 +10,11 @@ mod test {
     use std::str::FromStr;
     use target_lexicon::Triple;
     use wasmtime_environ::{
-        wasmparser::{types::Types, Parser as WasmParser, Validator},
-        DefinedFuncIndex, FunctionBodyData, Module, ModuleEnvironment, Tunables,
+        wasmparser::{Parser as WasmParser, Validator},
+        DefinedFuncIndex, FunctionBodyData, ModuleEnvironment, Tunables,
     };
-    use winch_codegen::isa::TargetIsa;
     use winch_codegen::lookup;
+    use winch_environ::FuncEnv;
     use winch_test_macros::generate_file_tests;
 
     #[derive(Clone, Debug, Serialize, Deserialize)]
@@ -109,10 +109,11 @@ mod test {
         let body_inputs = std::mem::take(&mut translation.function_body_inputs);
         let module = &translation.module;
         let types = translation.get_types();
+        let env = FuncEnv::new(module, &types, &*isa);
 
         let binding = body_inputs
             .into_iter()
-            .map(|func| compile(&*isa, module, types, func).join("\n"))
+            .map(|func| compile(&env, func).join("\n"))
             .collect::<Vec<String>>()
             .join("\n\n");
         let actual = binding.as_str();
@@ -143,23 +144,20 @@ mod test {
         }
     }
 
-    fn compile(
-        isa: &dyn TargetIsa,
-        module: &Module,
-        types: &Types,
-        f: (DefinedFuncIndex, FunctionBodyData<'_>),
-    ) -> Vec<String> {
-        let index = module.func_index(f.0);
-        let sig = types
+    fn compile(env: &FuncEnv, f: (DefinedFuncIndex, FunctionBodyData<'_>)) -> Vec<String> {
+        let index = env.module.func_index(f.0);
+        let sig = env
+            .types
             .function_at(index.as_u32())
             .expect(&format!("function type at index {:?}", index.as_u32()));
         let FunctionBodyData { body, validator } = f.1;
         let validator = validator.into_validator(Default::default());
 
-        let buffer = isa
+        let buffer = env
+            .isa
             .compile_function(&sig, &body, validator)
             .expect("Couldn't compile function");
 
-        disasm(buffer.data(), isa).unwrap()
+        disasm(buffer.data(), env.isa).unwrap()
     }
 }