Bug 1546439: Bump Cranelift to 538a0662bf90a1daa9921c10f34827ace134abf1; r=lth
authorBenjamin Bouvier <benj@benj.me>
Tue, 23 Apr 2019 17:37:34 +0200
changeset 529990 df4c4083aff8d84ff17010249d08e7b6dc6f9beb
parent 529989 cfafd091d30107f974a22c06ef790bee7950c1cd
child 529991 5fd6e9df0a2c8a76139f5994b8d80afe8af68ac2
push id11265
push userffxbld-merge
push dateMon, 13 May 2019 10:53:39 +0000
treeherdermozilla-beta@77e0fe8dbdd3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerslth
bugs1546439
milestone68.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1546439: Bump Cranelift to 538a0662bf90a1daa9921c10f34827ace134abf1; r=lth The one optimization introduced by this is the rearrangement of branches to prefer fallthrough whenever possible, as well as folding branches when comparing against 0. See also https://github.com/CraneStation/cranelift/pull/629 for details. Differential Revision: https://phabricator.services.mozilla.com/D28512
.cargo/config.in
Cargo.lock
Cargo.toml
js/src/wasm/cranelift/src/compile.rs
third_party/rust/cranelift-codegen-meta/.cargo-checksum.json
third_party/rust/cranelift-codegen-meta/src/gen_inst.rs
third_party/rust/cranelift-codegen-meta/src/lib.rs
third_party/rust/cranelift-codegen/.cargo-checksum.json
third_party/rust/cranelift-codegen/meta-python/build.py
third_party/rust/cranelift-codegen/meta-python/gen_instr.py
third_party/rust/cranelift-codegen/meta-python/gen_legalizer.py
third_party/rust/cranelift-codegen/src/context.rs
third_party/rust/cranelift-codegen/src/simple_preopt.rs
third_party/rust/cranelift-codegen/src/verifier/mod.rs
--- a/.cargo/config.in
+++ b/.cargo/config.in
@@ -19,13 +19,13 @@ replace-with = "vendored-sources"
 
 [source."https://github.com/rust-lang-nursery/packed_simd"]
 git = "https://github.com/hsivonen/packed_simd"
 branch = "rust_1_32"
 replace-with = "vendored-sources"
 
 [source."https://github.com/CraneStation/Cranelift"]
 git = "https://github.com/CraneStation/Cranelift"
-rev = "542d799dd7a3b2cc15b91eefdcd85cace8fe5cee"
+rev = "538a0662bf90a1daa9921c10f34827ace134abf1"
 replace-with = "vendored-sources"
 
 [source.vendored-sources]
 directory = '@top_srcdir@/third_party/rust'
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -161,18 +161,18 @@ dependencies = [
  "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "baldrdash"
 version = "0.1.0"
 dependencies = [
  "bindgen 0.49.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "cranelift-codegen 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=542d799dd7a3b2cc15b91eefdcd85cace8fe5cee)",
- "cranelift-wasm 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=542d799dd7a3b2cc15b91eefdcd85cace8fe5cee)",
+ "cranelift-codegen 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=538a0662bf90a1daa9921c10f34827ace134abf1)",
+ "cranelift-wasm 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=538a0662bf90a1daa9921c10f34827ace134abf1)",
  "env_logger 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "target-lexicon 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "base64"
 version = "0.9.3"
@@ -573,67 +573,67 @@ version = "0.1.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cose 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "cranelift-bforest"
 version = "0.30.0"
-source = "git+https://github.com/CraneStation/Cranelift?rev=542d799dd7a3b2cc15b91eefdcd85cace8fe5cee#542d799dd7a3b2cc15b91eefdcd85cace8fe5cee"
-dependencies = [
- "cranelift-entity 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=542d799dd7a3b2cc15b91eefdcd85cace8fe5cee)",
+source = "git+https://github.com/CraneStation/Cranelift?rev=538a0662bf90a1daa9921c10f34827ace134abf1#538a0662bf90a1daa9921c10f34827ace134abf1"
+dependencies = [
+ "cranelift-entity 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=538a0662bf90a1daa9921c10f34827ace134abf1)",
 ]
 
 [[package]]
 name = "cranelift-codegen"
 version = "0.30.0"
-source = "git+https://github.com/CraneStation/Cranelift?rev=542d799dd7a3b2cc15b91eefdcd85cace8fe5cee#542d799dd7a3b2cc15b91eefdcd85cace8fe5cee"
-dependencies = [
- "cranelift-bforest 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=542d799dd7a3b2cc15b91eefdcd85cace8fe5cee)",
- "cranelift-codegen-meta 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=542d799dd7a3b2cc15b91eefdcd85cace8fe5cee)",
- "cranelift-entity 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=542d799dd7a3b2cc15b91eefdcd85cace8fe5cee)",
+source = "git+https://github.com/CraneStation/Cranelift?rev=538a0662bf90a1daa9921c10f34827ace134abf1#538a0662bf90a1daa9921c10f34827ace134abf1"
+dependencies = [
+ "cranelift-bforest 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=538a0662bf90a1daa9921c10f34827ace134abf1)",
+ "cranelift-codegen-meta 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=538a0662bf90a1daa9921c10f34827ace134abf1)",
+ "cranelift-entity 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=538a0662bf90a1daa9921c10f34827ace134abf1)",
  "failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "failure_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "target-lexicon 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "cranelift-codegen-meta"
 version = "0.30.0"
-source = "git+https://github.com/CraneStation/Cranelift?rev=542d799dd7a3b2cc15b91eefdcd85cace8fe5cee#542d799dd7a3b2cc15b91eefdcd85cace8fe5cee"
-dependencies = [
- "cranelift-entity 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=542d799dd7a3b2cc15b91eefdcd85cace8fe5cee)",
+source = "git+https://github.com/CraneStation/Cranelift?rev=538a0662bf90a1daa9921c10f34827ace134abf1#538a0662bf90a1daa9921c10f34827ace134abf1"
+dependencies = [
+ "cranelift-entity 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=538a0662bf90a1daa9921c10f34827ace134abf1)",
 ]
 
 [[package]]
 name = "cranelift-entity"
 version = "0.30.0"
-source = "git+https://github.com/CraneStation/Cranelift?rev=542d799dd7a3b2cc15b91eefdcd85cace8fe5cee#542d799dd7a3b2cc15b91eefdcd85cace8fe5cee"
+source = "git+https://github.com/CraneStation/Cranelift?rev=538a0662bf90a1daa9921c10f34827ace134abf1#538a0662bf90a1daa9921c10f34827ace134abf1"
 
 [[package]]
 name = "cranelift-frontend"
 version = "0.30.0"
-source = "git+https://github.com/CraneStation/Cranelift?rev=542d799dd7a3b2cc15b91eefdcd85cace8fe5cee#542d799dd7a3b2cc15b91eefdcd85cace8fe5cee"
-dependencies = [
- "cranelift-codegen 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=542d799dd7a3b2cc15b91eefdcd85cace8fe5cee)",
+source = "git+https://github.com/CraneStation/Cranelift?rev=538a0662bf90a1daa9921c10f34827ace134abf1#538a0662bf90a1daa9921c10f34827ace134abf1"
+dependencies = [
+ "cranelift-codegen 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=538a0662bf90a1daa9921c10f34827ace134abf1)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "target-lexicon 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "cranelift-wasm"
 version = "0.30.0"
-source = "git+https://github.com/CraneStation/Cranelift?rev=542d799dd7a3b2cc15b91eefdcd85cace8fe5cee#542d799dd7a3b2cc15b91eefdcd85cace8fe5cee"
+source = "git+https://github.com/CraneStation/Cranelift?rev=538a0662bf90a1daa9921c10f34827ace134abf1#538a0662bf90a1daa9921c10f34827ace134abf1"
 dependencies = [
  "cast 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "cranelift-codegen 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=542d799dd7a3b2cc15b91eefdcd85cace8fe5cee)",
- "cranelift-entity 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=542d799dd7a3b2cc15b91eefdcd85cace8fe5cee)",
- "cranelift-frontend 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=542d799dd7a3b2cc15b91eefdcd85cace8fe5cee)",
+ "cranelift-codegen 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=538a0662bf90a1daa9921c10f34827ace134abf1)",
+ "cranelift-entity 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=538a0662bf90a1daa9921c10f34827ace134abf1)",
+ "cranelift-frontend 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=538a0662bf90a1daa9921c10f34827ace134abf1)",
  "failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "failure_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "wasmparser 0.29.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "crc"
@@ -3517,22 +3517,22 @@ dependencies = [
 "checksum constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8ff012e225ce166d4422e0e78419d901719760f62ae2b7969ca6b564d1b54a9e"
 "checksum cookie 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1465f8134efa296b4c19db34d909637cb2bf0f7aaf21299e23e18fa29ac557cf"
 "checksum core-foundation 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4e2640d6d0bf22e82bed1b73c6aef8d5dd31e5abe6666c57e6d45e2649f4f887"
 "checksum core-foundation-sys 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e7ca8a5221364ef15ce201e8ed2f609fc312682a8f4e0e3d4aa5879764e0fa3b"
 "checksum core-graphics 0.17.1 (registry+https://github.com/rust-lang/crates.io-index)" = "62ceafe1622ffc9a332199096841d0ff9912ec8cf8f9cde01e254a7d5217cd10"
 "checksum core-text 13.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f3f46450d6f2397261af420b4ccce23807add2e45fa206410a03d66fb7f050ae"
 "checksum cose 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "72fa26cb151d3ae4b70f63d67d0fed57ce04220feafafbae7f503bef7aae590d"
 "checksum cose-c 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "49726015ab0ca765144fcca61e4a7a543a16b795a777fa53f554da2fffff9a94"
-"checksum cranelift-bforest 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=542d799dd7a3b2cc15b91eefdcd85cace8fe5cee)" = "<none>"
-"checksum cranelift-codegen 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=542d799dd7a3b2cc15b91eefdcd85cace8fe5cee)" = "<none>"
-"checksum cranelift-codegen-meta 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=542d799dd7a3b2cc15b91eefdcd85cace8fe5cee)" = "<none>"
-"checksum cranelift-entity 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=542d799dd7a3b2cc15b91eefdcd85cace8fe5cee)" = "<none>"
-"checksum cranelift-frontend 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=542d799dd7a3b2cc15b91eefdcd85cace8fe5cee)" = "<none>"
-"checksum cranelift-wasm 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=542d799dd7a3b2cc15b91eefdcd85cace8fe5cee)" = "<none>"
+"checksum cranelift-bforest 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=538a0662bf90a1daa9921c10f34827ace134abf1)" = "<none>"
+"checksum cranelift-codegen 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=538a0662bf90a1daa9921c10f34827ace134abf1)" = "<none>"
+"checksum cranelift-codegen-meta 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=538a0662bf90a1daa9921c10f34827ace134abf1)" = "<none>"
+"checksum cranelift-entity 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=538a0662bf90a1daa9921c10f34827ace134abf1)" = "<none>"
+"checksum cranelift-frontend 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=538a0662bf90a1daa9921c10f34827ace134abf1)" = "<none>"
+"checksum cranelift-wasm 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=538a0662bf90a1daa9921c10f34827ace134abf1)" = "<none>"
 "checksum crc 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bd5d02c0aac6bd68393ed69e00bbc2457f3e89075c6349db7189618dc4ddc1d7"
 "checksum crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f739f8c5363aca78cfb059edf753d8f0d36908c348f3d8d1503f03d8b75d9cf3"
 "checksum crossbeam-deque 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fe8153ef04a7594ded05b427ffad46ddeaf22e63fd48d42b3e1e3bb4db07cae7"
 "checksum crossbeam-epoch 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "927121f5407de9956180ff5e936fe3cf4324279280001cd56b669d28ee7e9150"
 "checksum crossbeam-epoch 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2af0e75710d6181e234c8ecc79f14a97907850a541b13b0be1dd10992f2e4620"
 "checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9"
 "checksum crossbeam-utils 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d636a8b3bcc1b409d7ffd3facef8f21dcb4009626adbd0c5e6c4305c07253c7b"
 "checksum crossbeam-utils 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "41ee4864f4797060e52044376f7d107429ce1fb43460021b126424b7180ee21a"
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -56,10 +56,16 @@ debug-assertions = false
 panic = "abort"
 codegen-units = 1
 
 [patch.crates-io]
 libudev-sys = { path = "dom/webauthn/libudev-sys" }
 serde_derive = { git = "https://github.com/servo/serde", branch = "deserialize_from_enums10" }
 winapi = { git = "https://github.com/froydnj/winapi-rs", branch = "aarch64" }
 packed_simd = { git = "https://github.com/hsivonen/packed_simd", branch = "rust_1_32" }
-cranelift-codegen = { git = "https://github.com/CraneStation/Cranelift", rev = "542d799dd7a3b2cc15b91eefdcd85cace8fe5cee" }
-cranelift-wasm = { git = "https://github.com/CraneStation/Cranelift", rev = "542d799dd7a3b2cc15b91eefdcd85cace8fe5cee" }
+
+[patch.crates-io.cranelift-codegen]
+git = "https://github.com/CraneStation/Cranelift"
+rev = "538a0662bf90a1daa9921c10f34827ace134abf1"
+
+[patch.crates-io.cranelift-wasm]
+git = "https://github.com/CraneStation/Cranelift"
+rev = "538a0662bf90a1daa9921c10f34827ace134abf1"
--- a/js/src/wasm/cranelift/src/compile.rs
+++ b/js/src/wasm/cranelift/src/compile.rs
@@ -184,16 +184,29 @@ impl<'a, 'b> BatchCompiler<'a, 'b> {
 
     /// Determine whether the current function may contain calls.
     fn contains_calls(&self) -> bool {
         // Conservatively, just check to see if it contains any function
         // signatures which could be called.
         !self.context.func.dfg.signatures.is_empty()
     }
 
+    #[cfg(feature = "cranelift_x86")]
+    fn platform_specific_ignores_metadata(opcode: ir::Opcode) -> bool {
+        match opcode {
+            ir::Opcode::X86Sdivmodx | ir::Opcode::X86Udivmodx => true,
+            _ => false,
+        }
+    }
+
+    #[cfg(not(feature = "cranelift_x86"))]
+    fn platform_specific_ignores_metadata(_opcode: ir::Opcode) -> bool {
+        false
+    }
+
     /// Emit metadata by scanning the compiled function before `emit_to_memory`.
     ///
     /// - All call sites need metadata: direct, indirect, symbolic.
     /// - All explicit traps must be registered.
     ///
     /// We don't get enough callbacks through the `RelocSink` trait to generate all the metadata we
     /// need.
     fn emit_metadata(&self, metadata: &mut Vec<bd::MetadataEntry>) {
@@ -230,34 +243,33 @@ impl<'a, 'b> BatchCompiler<'a, 'b> {
                     | ir::Opcode::Istore8Complex
                     | ir::Opcode::Istore16
                     | ir::Opcode::Istore16Complex
                     | ir::Opcode::Istore32
                     | ir::Opcode::Istore32Complex => self.memory_metadata(metadata, inst, offset),
 
                     // Instructions that are not going to trap in our use, even though their opcode
                     // says they can.
-                    ir::Opcode::Spill
-                    | ir::Opcode::Fill
-                    | ir::Opcode::X86Sdivmodx
-                    | ir::Opcode::X86Udivmodx => {}
+                    ir::Opcode::Spill | ir::Opcode::Fill => {}
+
+                    _ if BatchCompiler::platform_specific_ignores_metadata(opcode) => {}
 
                     _ => {
-                        assert!(!opcode.is_call(), "Missed call opcode");
-                        assert!(
+                        debug_assert!(!opcode.is_call(), "Missed call opcode");
+                        debug_assert!(
                             !opcode.can_trap(),
                             "Missed trap: {}",
                             func.dfg.display_inst(inst, Some(self.isa.as_ref()))
                         );
-                        assert!(
+                        debug_assert!(
                             !opcode.can_load(),
                             "Missed load: {}",
                             func.dfg.display_inst(inst, Some(self.isa.as_ref()))
                         );
-                        assert!(
+                        debug_assert!(
                             !opcode.can_store(),
                             "Missed store: {}",
                             func.dfg.display_inst(inst, Some(self.isa.as_ref()))
                         );
                     }
                 }
             }
         }
--- a/third_party/rust/cranelift-codegen-meta/.cargo-checksum.json
+++ b/third_party/rust/cranelift-codegen-meta/.cargo-checksum.json
@@ -1,1 +1,1 @@
-{"files":{"Cargo.toml":"253c80832ab598570d604ae8a8108ea9835b8eef8d9b9645408ed025ce3b574a","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"b123f056d0d458396679c5f7f2a16d2762af0258fcda4ac14b6655a95e5a0022","src/cdsl/formats.rs":"98ab61698ad4c1fb81541b1820bd1c1561810bdcff2796dec541c98b4b1901d7","src/cdsl/inst.rs":"d5130c1a36a4e33d1374f9867119c3f2d79c384f12afc12e7b7b4518cf1f74b3","src/cdsl/isa.rs":"dd52d35fa963494b7da892a4a04a4f9978079bb2d86c6af4273a8dfdb82bdf51","src/cdsl/mod.rs":"2d2e216f8c3a81978a5113213559a5ab659bc112b6194cbe08a752313aad7f46","src/cdsl/operands.rs":"cc579fd543e36cf8e82938db331c145b77e29855ee2aa8c5dd949678f980796d","src/cdsl/regs.rs":"b99f24c3ecb46691625dc177b4e18d53e02265bc85a2f827a8d18381fe8f39bb","src/cdsl/settings.rs":"4ddeadf1542cc2ddec0f9e6c22d1637050da519586cd9fec0243c3eab9619f82","src/cdsl/type_inference.rs":"8aedb2e99dee299abbc327ce3a604d48f161580776225d2438a54bbec5b725fe","src/cdsl/types.rs":"4cc1f20eb8383fdee6a9e7ca0f7758e563a4fb715056b5edbd4db72f8dfd471b","src/cdsl/typevar.rs":"605786e2bf367879da500327fc003a4d2a663259c2dee76c87e5b99b6f6331ee","src/constant_hash.rs":"b8acd3f8712a4999819d9d9beced2938d9940a5748ba016c182f1132d97eefab","src/error.rs":"5110a4e3c1e97396ba02d9f5abbb8af4b586f0cc4d33a5c2473f1718cc4bef05","src/gen_registers.rs":"a544a2b91fafe08639e39e50bea0892fda89fe2f6eaf111b2d5f3e98e4d07b86","src/gen_settings.rs":"77ee330b85a255c49247222f4d071da839b0520eddd3dc561867f7ae84e199ac","src/gen_types.rs":"3935da6c6a53f9332e06f74bc3a46270656b4d4231ad28ed2648d7b1d2774e90","src/isa/arm32/mod.rs":"6ed3be790b28d3115421be282a06b8c376295e1776c4b77243443799015ab70d","src/isa/arm64/mod.rs":"5c46082f68c958e83ffc636de893e2ff49fd8ce21ef357f359837ca48a60eaa5","src/isa/mod.rs":"fce60d19dd3c099ebee3ac5ae64a2bee363f13da9ff5a4960d3c1a0bee71d29a","src/isa/riscv/mod.rs":"785f0da2b04458793cb2d493c5e1eeb7ea339bc721df76dda69db3b49bcdfd27","src/isa/x86/instructions.rs":"bd6b02ccc79984ed4a5615ae3b20a60a4da3777495b72f771762a886f87d2335","src/isa/x86/mod.rs":"ba7c11aedb190f58432226a6dec8a125b385cc18fd2f70c46703d077904a3112","src/lib.rs":"7ddb2d1f1a80d3dc3a7434309a6e0890dd054e88c549c20d2959236ffe986bd9","src/shared/entities.rs":"e7a44d5f621d726479c3812384e78dd25e8c063d074c64d0908b3667e7d28af1","src/shared/formats.rs":"20908b1048c5e71a185de6b6ded79cdff2c26ddb38ba7b134b7a27f37e8324f3","src/shared/immediates.rs":"1e64836f82045d05da7c151e60cf1e66666af3e0c19179de3f37e72dc81e1bbd","src/shared/instructions.rs":"2a0993279b3529b2c31aa8e83589636104a005351463ec2d3b81b5ffe569d276","src/shared/mod.rs":"696c166d3c19bd84604583a7b8d7ec4f6671622ed581bfce8bee375d02067cbe","src/shared/settings.rs":"bad2dc0e1d71ee6fec6418aa79234296aa918e499a1671c3e5c1d4b0d84b6f49","src/shared/types.rs":"158d73840185e6aa8385463bbf6568efdda0c8de8284cf6b4e565f425ec5d921","src/srcgen.rs":"ad39143ae50f3b19f18a43131bdd3308852c70a9e532cc99f97624e7380b00d8","src/unique_table.rs":"bec9d48ee040216a7c9deab6d2c5050d7ce70e38482cc8957105fd7cbca3c33a"},"package":null}
\ No newline at end of file
+{"files":{"Cargo.toml":"253c80832ab598570d604ae8a8108ea9835b8eef8d9b9645408ed025ce3b574a","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"b123f056d0d458396679c5f7f2a16d2762af0258fcda4ac14b6655a95e5a0022","src/cdsl/formats.rs":"98ab61698ad4c1fb81541b1820bd1c1561810bdcff2796dec541c98b4b1901d7","src/cdsl/inst.rs":"d5130c1a36a4e33d1374f9867119c3f2d79c384f12afc12e7b7b4518cf1f74b3","src/cdsl/isa.rs":"dd52d35fa963494b7da892a4a04a4f9978079bb2d86c6af4273a8dfdb82bdf51","src/cdsl/mod.rs":"2d2e216f8c3a81978a5113213559a5ab659bc112b6194cbe08a752313aad7f46","src/cdsl/operands.rs":"cc579fd543e36cf8e82938db331c145b77e29855ee2aa8c5dd949678f980796d","src/cdsl/regs.rs":"b99f24c3ecb46691625dc177b4e18d53e02265bc85a2f827a8d18381fe8f39bb","src/cdsl/settings.rs":"4ddeadf1542cc2ddec0f9e6c22d1637050da519586cd9fec0243c3eab9619f82","src/cdsl/type_inference.rs":"8aedb2e99dee299abbc327ce3a604d48f161580776225d2438a54bbec5b725fe","src/cdsl/types.rs":"4cc1f20eb8383fdee6a9e7ca0f7758e563a4fb715056b5edbd4db72f8dfd471b","src/cdsl/typevar.rs":"605786e2bf367879da500327fc003a4d2a663259c2dee76c87e5b99b6f6331ee","src/constant_hash.rs":"b8acd3f8712a4999819d9d9beced2938d9940a5748ba016c182f1132d97eefab","src/error.rs":"5110a4e3c1e97396ba02d9f5abbb8af4b586f0cc4d33a5c2473f1718cc4bef05","src/gen_inst.rs":"795d30588a5e87e69f3510606c9aee1b8670d5aee5f3d54067f6c7508a67e565","src/gen_registers.rs":"a544a2b91fafe08639e39e50bea0892fda89fe2f6eaf111b2d5f3e98e4d07b86","src/gen_settings.rs":"77ee330b85a255c49247222f4d071da839b0520eddd3dc561867f7ae84e199ac","src/gen_types.rs":"3935da6c6a53f9332e06f74bc3a46270656b4d4231ad28ed2648d7b1d2774e90","src/isa/arm32/mod.rs":"6ed3be790b28d3115421be282a06b8c376295e1776c4b77243443799015ab70d","src/isa/arm64/mod.rs":"5c46082f68c958e83ffc636de893e2ff49fd8ce21ef357f359837ca48a60eaa5","src/isa/mod.rs":"fce60d19dd3c099ebee3ac5ae64a2bee363f13da9ff5a4960d3c1a0bee71d29a","src/isa/riscv/mod.rs":"785f0da2b04458793cb2d493c5e1eeb7ea339bc721df76dda69db3b49bcdfd27","src/isa/x86/instructions.rs":"bd6b02ccc79984ed4a5615ae3b20a60a4da3777495b72f771762a886f87d2335","src/isa/x86/mod.rs":"ba7c11aedb190f58432226a6dec8a125b385cc18fd2f70c46703d077904a3112","src/lib.rs":"99aec646c7b756c01544a181e9b56ba14fccfb2bce205a8c1f63fb31905630ca","src/shared/entities.rs":"e7a44d5f621d726479c3812384e78dd25e8c063d074c64d0908b3667e7d28af1","src/shared/formats.rs":"20908b1048c5e71a185de6b6ded79cdff2c26ddb38ba7b134b7a27f37e8324f3","src/shared/immediates.rs":"1e64836f82045d05da7c151e60cf1e66666af3e0c19179de3f37e72dc81e1bbd","src/shared/instructions.rs":"2a0993279b3529b2c31aa8e83589636104a005351463ec2d3b81b5ffe569d276","src/shared/mod.rs":"696c166d3c19bd84604583a7b8d7ec4f6671622ed581bfce8bee375d02067cbe","src/shared/settings.rs":"bad2dc0e1d71ee6fec6418aa79234296aa918e499a1671c3e5c1d4b0d84b6f49","src/shared/types.rs":"158d73840185e6aa8385463bbf6568efdda0c8de8284cf6b4e565f425ec5d921","src/srcgen.rs":"ad39143ae50f3b19f18a43131bdd3308852c70a9e532cc99f97624e7380b00d8","src/unique_table.rs":"bec9d48ee040216a7c9deab6d2c5050d7ce70e38482cc8957105fd7cbca3c33a"},"package":null}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/third_party/rust/cranelift-codegen-meta/src/gen_inst.rs
@@ -0,0 +1,1092 @@
+use crate::cdsl::camel_case;
+use crate::cdsl::formats::{FormatRegistry, InstructionFormat};
+use crate::cdsl::inst::{Instruction, InstructionGroup};
+use crate::cdsl::operands::Operand;
+use crate::cdsl::typevar::{TypeSet, TypeVar};
+use crate::constant_hash;
+use crate::error;
+use crate::srcgen::{Formatter, Match};
+use crate::unique_table::{UniqueSeqTable, UniqueTable};
+
+use std::fmt;
+
+// TypeSet indexes are encoded in 8 bits, with `0xff` reserved.
+const TYPESET_LIMIT: usize = 0xff;
+
+/// Generate an instruction format enumeration.
+fn gen_formats(registry: &FormatRegistry, fmt: &mut Formatter) {
+    fmt.doc_comment(
+        r#"
+        An instruction format
+
+        Every opcode has a corresponding instruction format
+        which is represented by both the `InstructionFormat`
+        and the `InstructionData` enums.
+    "#,
+    );
+    fmt.line("#[derive(Copy, Clone, PartialEq, Eq, Debug)]");
+    fmt.line("pub enum InstructionFormat {");
+    fmt.indent(|fmt| {
+        for format in registry.iter() {
+            fmt.doc_comment(format.to_string());
+            fmtln!(fmt, "{},", format.name);
+        }
+    });
+    fmt.line("}");
+    fmt.empty_line();
+
+    // Emit a From<InstructionData> which also serves to verify that
+    // InstructionFormat and InstructionData are in sync.
+    fmt.line("impl<'a> From<&'a InstructionData> for InstructionFormat {");
+    fmt.indent(|fmt| {
+        fmt.line("fn from(inst: &'a InstructionData) -> Self {");
+        fmt.indent(|fmt| {
+            let mut m = Match::new("*inst");
+            for format in registry.iter() {
+                m.arm(
+                    format!("InstructionData::{}", format.name),
+                    vec![".."],
+                    format!("InstructionFormat::{}", format.name),
+                );
+            }
+            fmt.add_match(m);
+        });
+        fmt.line("}");
+    });
+    fmt.line("}");
+    fmt.empty_line();
+}
+
+/// Generate the InstructionData enum.
+///
+/// Every variant must contain an `opcode` field. The size of `InstructionData` should be kept at
+/// 16 bytes on 64-bit architectures. If more space is needed to represent an instruction, use a
+/// `ValueList` to store the additional information out of line.
+fn gen_instruction_data(registry: &FormatRegistry, fmt: &mut Formatter) {
+    fmt.line("#[derive(Clone, Debug)]");
+    fmt.line("#[allow(missing_docs)]");
+    fmt.line("pub enum InstructionData {");
+    fmt.indent(|fmt| {
+        for format in registry.iter() {
+            fmtln!(fmt, "{} {{", format.name);
+            fmt.indent(|fmt| {
+                fmt.line("opcode: Opcode,");
+                if format.typevar_operand.is_some() {
+                    if format.has_value_list {
+                        fmt.line("args: ValueList,");
+                    } else if format.num_value_operands == 1 {
+                        fmt.line("arg: Value,");
+                    } else {
+                        fmtln!(fmt, "args: [Value; {}],", format.num_value_operands);
+                    }
+                }
+                for field in &format.imm_fields {
+                    fmtln!(fmt, "{}: {},", field.member, field.kind.rust_type);
+                }
+            });
+            fmtln!(fmt, "},");
+        }
+    });
+    fmt.line("}");
+}
+
+fn gen_arguments_method(registry: &FormatRegistry, fmt: &mut Formatter, is_mut: bool) {
+    let (method, mut_, rslice, as_slice) = if is_mut {
+        ("arguments_mut", "mut ", "ref_slice_mut", "as_mut_slice")
+    } else {
+        ("arguments", "", "ref_slice", "as_slice")
+    };
+
+    fmtln!(
+        fmt,
+        "pub fn {}<'a>(&'a {}self, pool: &'a {}ir::ValueListPool) -> &{}[Value] {{",
+        method,
+        mut_,
+        mut_,
+        mut_
+    );
+    fmt.indent(|fmt| {
+        let mut m = Match::new("*self");
+        for format in registry.iter() {
+            let name = format!("InstructionData::{}", format.name);
+
+            // Formats with a value list put all of their arguments in the list. We don't split
+            // them up, just return it all as variable arguments. (I expect the distinction to go
+            // away).
+            if format.has_value_list {
+                m.arm(
+                    name,
+                    vec![format!("ref {}args", mut_), "..".to_string()],
+                    format!("args.{}(pool)", as_slice),
+                );
+                continue;
+            }
+
+            // Fixed args.
+            let mut fields = Vec::new();
+            let arg = if format.num_value_operands == 0 {
+                format!("&{}[]", mut_)
+            } else if format.num_value_operands == 1 {
+                fields.push(format!("ref {}arg", mut_));
+                format!("{}(arg)", rslice)
+            } else {
+                let arg = format!("args_arity{}", format.num_value_operands);
+                fields.push(format!("args: ref {}{}", mut_, arg));
+                arg
+            };
+            fields.push("..".into());
+
+            m.arm(name, fields, arg);
+        }
+        fmt.add_match(m);
+    });
+    fmtln!(fmt, "}");
+}
+
+/// Generate the boring parts of the InstructionData implementation.
+///
+/// These methods in `impl InstructionData` can be generated automatically from the instruction
+/// formats:
+///
+/// - `pub fn opcode(&self) -> Opcode`
+/// - `pub fn arguments(&self, &pool) -> &[Value]`
+/// - `pub fn arguments_mut(&mut self, &pool) -> &mut [Value]`
+/// - `pub fn take_value_list(&mut self) -> Option<ir::ValueList>`
+/// - `pub fn put_value_list(&mut self, args: ir::ValueList>`
+/// - `pub fn eq(&self, &other: Self, &pool) -> bool`
+/// - `pub fn hash<H: Hasher>(&self, state: &mut H, &pool)`
+fn gen_instruction_data_impl(registry: &FormatRegistry, fmt: &mut Formatter) {
+    fmt.line("impl InstructionData {");
+    fmt.indent(|fmt| {
+        fmt.doc_comment("Get the opcode of this instruction.");
+        fmt.line("pub fn opcode(&self) -> Opcode {");
+        fmt.indent(|fmt| {
+            let mut m = Match::new("*self");
+            for format in registry.iter() {
+                m.arm(format!("InstructionData::{}", format.name), vec!["opcode", ".."],
+                      "opcode".to_string());
+            }
+            fmt.add_match(m);
+        });
+        fmt.line("}");
+        fmt.empty_line();
+
+        fmt.doc_comment("Get the controlling type variable operand.");
+        fmt.line("pub fn typevar_operand(&self, pool: &ir::ValueListPool) -> Option<Value> {");
+        fmt.indent(|fmt| {
+            let mut m = Match::new("*self");
+            for format in registry.iter() {
+                let name = format!("InstructionData::{}", format.name);
+                if format.typevar_operand.is_none() {
+                    m.arm(name, vec![".."], "None".to_string());
+                } else if format.has_value_list {
+                    // We keep all arguments in a value list.
+                    m.arm(name, vec!["ref args", ".."], format!("args.get({}, pool)", format.typevar_operand.unwrap()));
+                } else if format.num_value_operands == 1 {
+                    m.arm(name, vec!["arg", ".."], "Some(arg)".to_string());
+                } else {
+                    // We have multiple value operands and an array `args`.
+                    // Which `args` index to use?
+                    let args = format!("args_arity{}", format.num_value_operands);
+                    m.arm(name, vec![format!("args: ref {}", args), "..".to_string()],
+                        format!("Some({}[{}])", args, format.typevar_operand.unwrap()));
+                }
+            }
+            fmt.add_match(m);
+        });
+        fmt.line("}");
+        fmt.empty_line();
+
+        fmt.doc_comment("Get the value arguments to this instruction.");
+        gen_arguments_method(registry, fmt, false);
+        fmt.empty_line();
+
+        fmt.doc_comment(r#"Get mutable references to the value arguments to this
+                        instruction."#);
+        gen_arguments_method(registry, fmt, true);
+        fmt.empty_line();
+
+        fmt.doc_comment(r#"
+            Take out the value list with all the value arguments and return
+            it.
+
+            This leaves the value list in the instruction empty. Use
+            `put_value_list` to put the value list back.
+        "#);
+        fmt.line("pub fn take_value_list(&mut self) -> Option<ir::ValueList> {");
+        fmt.indent(|fmt| {
+            let mut m = Match::new("*self");
+
+            for format in registry.iter() {
+                if format.has_value_list {
+                    m.arm(format!("InstructionData::{}", format.name),
+                    vec!["ref mut args", ".."],
+                    "Some(args.take())".to_string());
+                }
+            }
+
+            m.arm_no_fields("_", "None");
+
+            fmt.add_match(m);
+        });
+        fmt.line("}");
+        fmt.empty_line();
+
+        fmt.doc_comment(r#"
+            Put back a value list.
+
+            After removing a value list with `take_value_list()`, use this
+            method to put it back. It is required that this instruction has
+            a format that accepts a value list, and that the existing value
+            list is empty. This avoids leaking list pool memory.
+        "#);
+        fmt.line("pub fn put_value_list(&mut self, vlist: ir::ValueList) {");
+        fmt.indent(|fmt| {
+            fmt.line("let args = match *self {");
+            fmt.indent(|fmt| {
+                for format in registry.iter() {
+                    if format.has_value_list {
+                        fmtln!(fmt, "InstructionData::{} {{ ref mut args, .. }} => args,", format.name);
+                    }
+                }
+                fmt.line("_ => panic!(\"No value list: {:?}\", self),");
+            });
+            fmt.line("};");
+            fmt.line("debug_assert!(args.is_empty(), \"Value list already in use\");");
+            fmt.line("*args = vlist;");
+        });
+        fmt.line("}");
+        fmt.empty_line();
+
+        fmt.doc_comment(r#"
+            Compare two `InstructionData` for equality.
+
+            This operation requires a reference to a `ValueListPool` to
+            determine if the contents of any `ValueLists` are equal.
+        "#);
+        fmt.line("pub fn eq(&self, other: &Self, pool: &ir::ValueListPool) -> bool {");
+        fmt.indent(|fmt| {
+            fmt.line("if ::core::mem::discriminant(self) != ::core::mem::discriminant(other) {");
+            fmt.indent(|fmt| {
+                fmt.line("return false;");
+            });
+            fmt.line("}");
+
+            fmt.line("match (self, other) {");
+            fmt.indent(|fmt| {
+                for format in registry.iter() {
+                    let name = format!("&InstructionData::{}", format.name);
+                    let mut members = vec!["opcode"];
+
+                    let args_eq = if format.typevar_operand.is_none() {
+                        None
+                    } else if format.has_value_list {
+                        members.push("args");
+                        Some("args1.as_slice(pool) == args2.as_slice(pool)")
+                    } else if format.num_value_operands == 1 {
+                        members.push("arg");
+                        Some("arg1 == arg2")
+                    } else {
+                        members.push("args");
+                        Some("args1 == args2")
+                    };
+
+                    for field in &format.imm_fields {
+                        members.push(field.member);
+                    }
+
+                    let pat1 = members.iter().map(|x| format!("{}: ref {}1", x, x)).collect::<Vec<_>>().join(", ");
+                    let pat2 = members.iter().map(|x| format!("{}: ref {}2", x, x)).collect::<Vec<_>>().join(", ");
+                    fmtln!(fmt, "({} {{ {} }}, {} {{ {} }}) => {{", name, pat1, name, pat2);
+                    fmt.indent(|fmt| {
+                        fmt.line("opcode1 == opcode2");
+                        for field in &format.imm_fields {
+                            fmtln!(fmt, "&& {}1 == {}2", field.member, field.member);
+                        }
+                        if let Some(args_eq) = args_eq {
+                            fmtln!(fmt, "&& {}", args_eq);
+                        }
+                    });
+                    fmtln!(fmt, "}");
+                }
+                fmt.line("_ => unreachable!()");
+            });
+            fmt.line("}");
+        });
+        fmt.line("}");
+        fmt.empty_line();
+
+        fmt.doc_comment(r#"
+            Hash an `InstructionData`.
+
+            This operation requires a reference to a `ValueListPool` to
+            hash the contents of any `ValueLists`.
+        "#);
+        fmt.line("pub fn hash<H: ::core::hash::Hasher>(&self, state: &mut H, pool: &ir::ValueListPool) {");
+        fmt.indent(|fmt| {
+            fmt.line("match *self {");
+            fmt.indent(|fmt| {
+                for format in registry.iter() {
+                    let name = format!("InstructionData::{}", format.name);
+                    let mut members = vec!["opcode"];
+
+                    let args = if format.typevar_operand.is_none() {
+                        "&()"
+                    } else if format.has_value_list {
+                        members.push("ref args");
+                        "args.as_slice(pool)"
+                    } else if format.num_value_operands == 1 {
+                        members.push("ref arg");
+                        "arg"
+                    } else {
+                        members.push("ref args");
+                        "args"
+                    };
+
+                    for field in &format.imm_fields {
+                        members.push(field.member);
+                    }
+                    let members = members.join(", ");
+
+                    fmtln!(fmt, "{}{{{}}} => {{", name, members ); // beware the moustaches
+                    fmt.indent(|fmt| {
+                        fmt.line("::core::hash::Hash::hash( &::core::mem::discriminant(self), state);");
+                        fmt.line("::core::hash::Hash::hash(&opcode, state);");
+                        for field in &format.imm_fields {
+                            fmtln!(fmt, "::core::hash::Hash::hash(&{}, state);", field.member);
+                        }
+                        fmtln!(fmt, "::core::hash::Hash::hash({}, state);", args);
+                    });
+                    fmtln!(fmt, "}");
+                }
+            });
+            fmt.line("}");
+        });
+        fmt.line("}");
+    });
+    fmt.line("}");
+}
+
+fn gen_bool_accessor<T: Fn(&Instruction) -> bool>(
+    instruction_groups: &Vec<&InstructionGroup>,
+    get_attr: T,
+    name: &'static str,
+    doc: &'static str,
+    fmt: &mut Formatter,
+) {
+    fmt.doc_comment(doc);
+    fmtln!(fmt, "pub fn {}(self) -> bool {{", name);
+    fmt.indent(|fmt| {
+        let mut m = Match::new("self");
+        for group in instruction_groups.iter() {
+            for inst in group.iter() {
+                if get_attr(inst) {
+                    m.arm_no_fields(format!("Opcode::{}", inst.camel_name), "true");
+                }
+            }
+        }
+        m.arm_no_fields("_", "false");
+        fmt.add_match(m);
+    });
+    fmtln!(fmt, "}");
+    fmt.empty_line();
+}
+
+fn gen_opcodes<'a>(
+    formats: &FormatRegistry,
+    igroups: &Vec<&'a InstructionGroup>,
+    fmt: &mut Formatter,
+) -> Vec<&'a Instruction> {
+    let mut all_inst = Vec::new();
+    for group in igroups {
+        for inst in group.iter() {
+            all_inst.push(inst);
+        }
+    }
+
+    fmt.doc_comment(
+        r#"
+        An instruction opcode.
+
+        All instructions from all supported ISAs are present.
+    "#,
+    );
+    fmt.line("#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]");
+
+    // We explicitly set the discriminant of the first variant to 1, which allows us to take
+    // advantage of the NonZero optimization, meaning that wrapping enums can use the 0
+    // discriminant instead of increasing the size of the whole type, and so the size of
+    // Option<Opcode> is the same as Opcode's.
+    fmt.line("pub enum Opcode {");
+    fmt.indent(|fmt| {
+        let mut is_first_opcode = true;
+        for inst in &all_inst {
+            // TODO we might need to set an instruction number here. Probably can do in the
+            // InstructionGroup itself when adding instruction (would need to remember last
+            // instruction number in the SharedDefinitions or somewhere else).
+            let format = formats.get(inst.format);
+            fmt.doc_comment(format!("`{}`. ({})", inst, format.name));
+
+            // Document polymorphism.
+            if let Some(poly) = &inst.polymorphic_info {
+                if poly.use_typevar_operand {
+                    let op_num = inst.value_opnums[format.typevar_operand.unwrap()];
+                    fmt.doc_comment(format!(
+                        "Type inferred from `{}`.",
+                        inst.operands_in[op_num].name
+                    ));
+                }
+            }
+
+            // Enum variant itself.
+            if is_first_opcode {
+                fmtln!(fmt, "{} = 1,", inst.camel_name);
+                is_first_opcode = false;
+            } else {
+                fmtln!(fmt, "{},", inst.camel_name)
+            }
+        }
+    });
+    fmt.line("}");
+    fmt.empty_line();
+
+    fmt.line("impl Opcode {");
+    fmt.indent(|fmt| {
+        gen_bool_accessor(
+            igroups,
+            |inst| inst.is_terminator,
+            "is_terminator",
+            "True for instructions that terminate the EBB",
+            fmt,
+        );
+        gen_bool_accessor(
+            igroups,
+            |inst| inst.is_branch,
+            "is_branch",
+            "True for all branch or jump instructions.",
+            fmt,
+        );
+        gen_bool_accessor(
+            igroups,
+            |inst| inst.is_indirect_branch,
+            "is_indirect_branch",
+            "True for all indirect branch or jump instructions.",
+            fmt,
+        );
+        gen_bool_accessor(
+            igroups,
+            |inst| inst.is_call,
+            "is_call",
+            "Is this a call instruction?",
+            fmt,
+        );
+        gen_bool_accessor(
+            igroups,
+            |inst| inst.is_return,
+            "is_return",
+            "Is this a return instruction?",
+            fmt,
+        );
+        gen_bool_accessor(
+            igroups,
+            |inst| inst.is_ghost,
+            "is_ghost",
+            "Is this a ghost instruction?",
+            fmt,
+        );
+        gen_bool_accessor(
+            igroups,
+            |inst| inst.can_load,
+            "can_load",
+            "Can this instruction read from memory?",
+            fmt,
+        );
+        gen_bool_accessor(
+            igroups,
+            |inst| inst.can_store,
+            "can_store",
+            "Can this instruction write to memory?",
+            fmt,
+        );
+        gen_bool_accessor(
+            igroups,
+            |inst| inst.can_trap,
+            "can_trap",
+            "Can this instruction cause a trap?",
+            fmt,
+        );
+        gen_bool_accessor(
+            igroups,
+            |inst| inst.other_side_effects,
+            "other_side_effects",
+            "Does this instruction have other side effects besides can_* flags?",
+            fmt,
+        );
+        gen_bool_accessor(
+            igroups,
+            |inst| inst.writes_cpu_flags,
+            "writes_cpu_flags",
+            "Does this instruction write to CPU flags?",
+            fmt,
+        );
+    });
+    fmt.line("}");
+    fmt.empty_line();
+
+    // Generate a private opcode_format table.
+    fmtln!(
+        fmt,
+        "const OPCODE_FORMAT: [InstructionFormat; {}] = [",
+        all_inst.len()
+    );
+    fmt.indent(|fmt| {
+        for inst in &all_inst {
+            let format = formats.get(inst.format);
+            fmtln!(fmt, "InstructionFormat::{}, // {}", format.name, inst.name);
+        }
+    });
+    fmtln!(fmt, "];");
+    fmt.empty_line();
+
+    // Generate a private opcode_name function.
+    fmt.line("fn opcode_name(opc: Opcode) -> &\'static str {");
+    fmt.indent(|fmt| {
+        let mut m = Match::new("opc");
+        for inst in &all_inst {
+            m.arm_no_fields(
+                format!("Opcode::{}", inst.camel_name),
+                format!("\"{}\"", inst.name),
+            );
+        }
+        fmt.add_match(m);
+    });
+    fmt.line("}");
+    fmt.empty_line();
+
+    // Generate an opcode hash table for looking up opcodes by name.
+    let hash_table =
+        constant_hash::generate_table(&all_inst, |inst| constant_hash::simple_hash(inst.name));
+    fmtln!(
+        fmt,
+        "const OPCODE_HASH_TABLE: [Option<Opcode>; {}] = [",
+        hash_table.len()
+    );
+    fmt.indent(|fmt| {
+        for i in hash_table {
+            match i {
+                Some(i) => fmtln!(fmt, "Some(Opcode::{}),", i.camel_name),
+                None => fmtln!(fmt, "None,"),
+            }
+        }
+    });
+    fmtln!(fmt, "];");
+    fmt.empty_line();
+
+    all_inst
+}
+
+/// Get the value type constraint for an SSA value operand, where
+/// `ctrl_typevar` is the controlling type variable.
+///
+/// Each operand constraint is represented as a string, one of:
+/// - `Concrete(vt)`, where `vt` is a value type name.
+/// - `Free(idx)` where `idx` is an index into `type_sets`.
+/// - `Same`, `Lane`, `AsBool` for controlling typevar-derived constraints.
+fn get_constraint<'entries, 'table>(
+    operand: &'entries Operand,
+    ctrl_typevar: Option<&TypeVar>,
+    type_sets: &'table mut UniqueTable<'entries, TypeSet>,
+) -> String {
+    assert!(operand.is_value());
+    let type_var = operand.type_var().unwrap();
+
+    if let Some(typ) = type_var.singleton_type() {
+        return format!("Concrete({})", typ.rust_name());
+    }
+
+    if let Some(free_typevar) = type_var.free_typevar() {
+        if ctrl_typevar.is_some() && free_typevar != *ctrl_typevar.unwrap() {
+            assert!(type_var.base.is_none());
+            return format!("Free({})", type_sets.add(&type_var.get_raw_typeset()));
+        }
+    }
+
+    if let Some(base) = &type_var.base {
+        assert!(base.type_var == *ctrl_typevar.unwrap());
+        return camel_case(base.derived_func.name());
+    }
+
+    assert!(type_var == ctrl_typevar.unwrap());
+    return "Same".into();
+}
+
+fn gen_bitset<'a, T: IntoIterator<Item = &'a u16>>(
+    iterable: T,
+    name: &'static str,
+    field_size: u8,
+    fmt: &mut Formatter,
+) {
+    let bits = iterable.into_iter().fold(0, |acc, x| {
+        assert!(x.is_power_of_two());
+        assert!(u32::from(*x) < (1 << u32::from(field_size)));
+        acc | x
+    });
+    fmtln!(fmt, "{}: BitSet::<u{}>({}),", name, field_size, bits);
+}
+
+fn iterable_to_string<I: fmt::Display, T: IntoIterator<Item = I>>(iterable: T) -> String {
+    let elems = iterable
+        .into_iter()
+        .map(|x| x.to_string())
+        .collect::<Vec<_>>()
+        .join(", ");
+    format!("{{{}}}", elems)
+}
+
+fn typeset_to_string(ts: &TypeSet) -> String {
+    let mut result = format!("TypeSet(lanes={}", iterable_to_string(&ts.lanes));
+    if ts.ints.len() > 0 {
+        result += &format!(", ints={}", iterable_to_string(&ts.ints));
+    }
+    if ts.floats.len() > 0 {
+        result += &format!(", floats={}", iterable_to_string(&ts.floats));
+    }
+    if ts.bools.len() > 0 {
+        result += &format!(", bools={}", iterable_to_string(&ts.bools));
+    }
+    if ts.bitvecs.len() > 0 {
+        result += &format!(", bitvecs={}", iterable_to_string(&ts.bitvecs));
+    }
+    if ts.specials.len() > 0 {
+        result += &format!(", specials=[{}]", iterable_to_string(&ts.specials));
+    }
+    result += ")";
+    result
+}
+
+/// Generate the table of ValueTypeSets described by type_sets.
+fn gen_typesets_table(type_sets: &UniqueTable<TypeSet>, fmt: &mut Formatter) {
+    if type_sets.len() == 0 {
+        return;
+    }
+
+    fmt.comment("Table of value type sets.");
+    assert!(type_sets.len() <= TYPESET_LIMIT, "Too many type sets!");
+    fmtln!(
+        fmt,
+        "const TYPE_SETS: [ir::instructions::ValueTypeSet; {}] = [",
+        type_sets.len()
+    );
+    fmt.indent(|fmt| {
+        for ts in type_sets.iter() {
+            fmt.line("ir::instructions::ValueTypeSet {");
+            fmt.indent(|fmt| {
+                assert!(ts.bitvecs.len() == 0, "Bitvector types are not emittable.");
+                fmt.comment(typeset_to_string(ts));
+                gen_bitset(&ts.lanes, "lanes", 16, fmt);
+                gen_bitset(&ts.ints, "ints", 8, fmt);
+                gen_bitset(&ts.floats, "floats", 8, fmt);
+                gen_bitset(&ts.bools, "bools", 8, fmt);
+            });
+            fmt.line("},");
+        }
+    });
+    fmtln!(fmt, "];");
+}
+
+/// Generate value type constraints for all instructions.
+/// - Emit a compact constant table of ValueTypeSet objects.
+/// - Emit a compact constant table of OperandConstraint objects.
+/// - Emit an opcode-indexed table of instruction constraints.
+fn gen_type_constraints(all_inst: &Vec<&Instruction>, fmt: &mut Formatter) {
+    // Table of TypeSet instances.
+    let mut type_sets = UniqueTable::new();
+
+    // Table of operand constraint sequences (as tuples). Each operand
+    // constraint is represented as a string, one of:
+    // - `Concrete(vt)`, where `vt` is a value type name.
+    // - `Free(idx)` where `idx` is an index into `type_sets`.
+    // - `Same`, `Lane`, `AsBool` for controlling typevar-derived constraints.
+    let mut operand_seqs = UniqueSeqTable::new();
+
+    // Preload table with constraints for typical binops.
+    operand_seqs.add(&vec!["Same".to_string(); 3]);
+
+    fmt.comment("Table of opcode constraints.");
+    fmtln!(
+        fmt,
+        "const OPCODE_CONSTRAINTS: [OpcodeConstraints; {}] = [",
+        all_inst.len()
+    );
+    fmt.indent(|fmt| {
+        for inst in all_inst {
+            let (ctrl_typevar, ctrl_typeset) = if let Some(poly) = &inst.polymorphic_info {
+                let index = type_sets.add(&*poly.ctrl_typevar.get_raw_typeset());
+                (Some(&poly.ctrl_typevar), index)
+            } else {
+                (None, TYPESET_LIMIT)
+            };
+
+            // Collect constraints for the value results, not including `variable_args` results
+            // which are always special cased.
+            let mut constraints = Vec::new();
+            for &index in &inst.value_results {
+                constraints.push(get_constraint(&inst.operands_out[index], ctrl_typevar, &mut type_sets));
+            }
+            for &index in &inst.value_opnums {
+                constraints.push(get_constraint(&inst.operands_in[index], ctrl_typevar, &mut type_sets));
+            }
+
+            let constraint_offset = operand_seqs.add(&constraints);
+
+            let fixed_results = inst.value_results.len();
+            let fixed_values = inst.value_opnums.len();
+
+            // Can the controlling type variable be inferred from the designated operand?
+            let use_typevar_operand = if let Some(poly) = &inst.polymorphic_info {
+                poly.use_typevar_operand
+            } else {
+                false
+            };
+
+            // Can the controlling type variable be inferred from the result?
+            let use_result = fixed_results > 0 && inst.operands_out[inst.value_results[0]].type_var() == ctrl_typevar;
+
+            // Are we required to use the designated operand instead of the result?
+            let requires_typevar_operand = use_typevar_operand && !use_result;
+
+            fmt.comment(
+                format!("{}: fixed_results={}, use_typevar_operand={}, requires_typevar_operand={}, fixed_values={}",
+                inst.camel_name,
+                fixed_results,
+                use_typevar_operand,
+                requires_typevar_operand,
+                fixed_values)
+            );
+            fmt.comment(format!("Constraints=[{}]", constraints
+                .iter()
+                .map(|x| format!("'{}'", x))
+                .collect::<Vec<_>>()
+                .join(", ")));
+            if let Some(poly) = &inst.polymorphic_info {
+                fmt.comment(format!("Polymorphic over {}", typeset_to_string(&poly.ctrl_typevar.get_raw_typeset())));
+            }
+
+            // Compute the bit field encoding, c.f. instructions.rs.
+            assert!(fixed_results < 8 && fixed_values < 8, "Bit field encoding too tight");
+            let mut flags = fixed_results; // 3 bits
+            if use_typevar_operand {
+                flags |= 1<<3; // 4th bit
+            }
+            if requires_typevar_operand {
+                flags |= 1<<4; // 5th bit
+            }
+            flags |= fixed_values << 5; // 6th bit and more
+
+            fmt.line("OpcodeConstraints {");
+            fmt.indent(|fmt| {
+                fmtln!(fmt, "flags: {:#04x},", flags);
+                fmtln!(fmt, "typeset_offset: {},", ctrl_typeset);
+                fmtln!(fmt, "constraint_offset: {},", constraint_offset);
+            });
+            fmt.line("},");
+        }
+    });
+    fmtln!(fmt, "];");
+    fmt.empty_line();
+
+    gen_typesets_table(&type_sets, fmt);
+    fmt.empty_line();
+
+    fmt.comment("Table of operand constraint sequences.");
+    fmtln!(
+        fmt,
+        "const OPERAND_CONSTRAINTS: [OperandConstraint; {}] = [",
+        operand_seqs.len()
+    );
+    fmt.indent(|fmt| {
+        for constraint in operand_seqs.iter() {
+            fmtln!(fmt, "OperandConstraint::{},", constraint);
+        }
+    });
+    fmtln!(fmt, "];");
+}
+
+/// Emit member initializers for an instruction format.
+fn gen_member_inits(format: &InstructionFormat, fmt: &mut Formatter) {
+    // Immediate operands.
+    // We have local variables with the same names as the members.
+    for f in &format.imm_fields {
+        fmtln!(fmt, "{},", f.member);
+    }
+
+    // Value operands.
+    if format.has_value_list {
+        fmt.line("args,");
+    } else if format.num_value_operands == 1 {
+        fmt.line("arg: arg0,");
+    } else if format.num_value_operands > 1 {
+        let mut args = Vec::new();
+        for i in 0..format.num_value_operands {
+            args.push(format!("arg{}", i));
+        }
+        fmtln!(fmt, "args: [{}],", args.join(", "));
+    }
+}
+
+/// Emit a method for creating and inserting an instruction format.
+///
+/// All instruction formats take an `opcode` argument and a `ctrl_typevar` argument for deducing
+/// the result types.
+fn gen_format_constructor(format: &InstructionFormat, fmt: &mut Formatter) {
+    // Construct method arguments.
+    let mut args = vec![
+        "self".to_string(),
+        "opcode: Opcode".into(),
+        "ctrl_typevar: Type".into(),
+    ];
+
+    // Normal operand arguments. Start with the immediate operands.
+    for f in &format.imm_fields {
+        args.push(format!("{}: {}", f.member, f.kind.rust_type));
+    }
+
+    // Then the value operands.
+    if format.has_value_list {
+        // Take all value arguments as a finished value list. The value lists
+        // are created by the individual instruction constructors.
+        args.push("args: ir::ValueList".into());
+    } else {
+        // Take a fixed number of value operands.
+        for i in 0..format.num_value_operands {
+            args.push(format!("arg{}: Value", i));
+        }
+    }
+
+    let proto = format!(
+        "{}({}) -> (Inst, &'f mut ir::DataFlowGraph)",
+        format.name,
+        args.join(", ")
+    );
+
+    fmt.doc_comment(format.to_string());
+    fmt.line("#[allow(non_snake_case)]");
+    fmtln!(fmt, "fn {} {{", proto);
+    fmt.indent(|fmt| {
+        // Generate the instruction data.
+        fmtln!(fmt, "let data = ir::InstructionData::{} {{", format.name);
+        fmt.indent(|fmt| {
+            fmt.line("opcode,");
+            gen_member_inits(format, fmt);
+        });
+        fmtln!(fmt, "};");
+        fmt.line("self.build(data, ctrl_typevar)");
+    });
+    fmtln!(fmt, "}");
+}
+
+/// Emit a method for generating the instruction `inst`.
+///
+/// The method will create and insert an instruction, then return the result values, or the
+/// instruction reference itself for instructions that don't have results.
+fn gen_inst_builder(inst: &Instruction, format: &InstructionFormat, fmt: &mut Formatter) {
+    // Construct method arguments.
+    let mut args = vec![if format.has_value_list {
+        "mut self"
+    } else {
+        "self"
+    }
+    .to_string()];
+
+    // The controlling type variable will be inferred from the input values if
+    // possible. Otherwise, it is the first method argument.
+    if let Some(poly) = &inst.polymorphic_info {
+        if !poly.use_typevar_operand {
+            args.push(format!("{}: crate::ir::Type", poly.ctrl_typevar.name));
+        }
+    }
+
+    let mut tmpl_types = Vec::new();
+    let mut into_args = Vec::new();
+    for op in &inst.operands_in {
+        let t = if op.is_pure_immediate() {
+            let t = format!("T{}{}", tmpl_types.len() + 1, op.kind.name);
+            tmpl_types.push(format!("{}: Into<{}>", t, op.kind.rust_type));
+            into_args.push(op.name);
+            t
+        } else {
+            op.kind.rust_type.clone()
+        };
+        args.push(format!("{}: {}", op.name, t));
+    }
+
+    let rtype = match inst.value_results.len() {
+        0 => "Inst".into(),
+        1 => "Value".into(),
+        _ => format!("({})", vec!["Value"; inst.value_results.len()].join(", ")),
+    };
+
+    let tmpl = if tmpl_types.len() > 0 {
+        format!("<{}>", tmpl_types.join(", "))
+    } else {
+        "".into()
+    };
+
+    let proto = format!(
+        "{}{}({}) -> {}",
+        inst.snake_name(),
+        tmpl,
+        args.join(", "),
+        rtype
+    );
+
+    fmt.doc_comment(format!("`{}`\n\n{}", inst, inst.doc_comment_first_line()));
+    fmt.line("#[allow(non_snake_case)]");
+    fmtln!(fmt, "fn {} {{", proto);
+    fmt.indent(|fmt| {
+        // Convert all of the `Into<>` arguments.
+        for arg in &into_args {
+            fmtln!(fmt, "let {} = {}.into();", arg, arg);
+        }
+
+        // Arguments for instruction constructor.
+        let first_arg = format!("Opcode::{}", inst.camel_name);
+        let mut args = vec![first_arg.as_str()];
+        if let Some(poly) = &inst.polymorphic_info {
+            if poly.use_typevar_operand {
+                // Infer the controlling type variable from the input operands.
+                let op_num = inst.value_opnums[format.typevar_operand.unwrap()];
+                fmtln!(
+                    fmt,
+                    "let ctrl_typevar = self.data_flow_graph().value_type({});",
+                    inst.operands_in[op_num].name
+                );
+
+                // The format constructor will resolve the result types from the type var.
+                args.push("ctrl_typevar");
+            } else {
+                // This was an explicit method argument.
+                args.push(&poly.ctrl_typevar.name);
+            }
+        } else {
+            // No controlling type variable needed.
+            args.push("types::INVALID");
+        }
+
+        // Now add all of the immediate operands to the constructor arguments.
+        for &op_num in &inst.imm_opnums {
+            args.push(inst.operands_in[op_num].name);
+        }
+
+        // Finally, the value operands.
+        if format.has_value_list {
+            // We need to build a value list with all the arguments.
+            fmt.line("let mut vlist = ir::ValueList::default();");
+            args.push("vlist");
+            fmt.line("{");
+            fmt.indent(|fmt| {
+                fmt.line("let pool = &mut self.data_flow_graph_mut().value_lists;");
+                for op in &inst.operands_in {
+                    if op.is_value() {
+                        fmtln!(fmt, "vlist.push({}, pool);", op.name);
+                    } else if op.is_varargs() {
+                        fmtln!(fmt, "vlist.extend({}.iter().cloned(), pool);", op.name);
+                    }
+                }
+            });
+            fmt.line("}");
+        } else {
+            // With no value list, we're guaranteed to just have a set of fixed value operands.
+            for &op_num in &inst.value_opnums {
+                args.push(inst.operands_in[op_num].name);
+            }
+        }
+
+        // Call to the format constructor,
+        let fcall = format!("self.{}({})", format.name, args.join(", "));
+
+        if inst.value_results.len() == 0 {
+            fmtln!(fmt, "{}.0", fcall);
+            return;
+        }
+
+        fmtln!(fmt, "let (inst, dfg) = {};", fcall);
+        if inst.value_results.len() == 1 {
+            fmt.line("dfg.first_result(inst)");
+        } else {
+            fmtln!(
+                fmt,
+                "let results = &dfg.inst_results(inst)[0..{}];",
+                inst.value_results.len()
+            );
+            fmtln!(
+                fmt,
+                "({})",
+                inst.value_results
+                    .iter()
+                    .enumerate()
+                    .map(|(i, _)| format!("results[{}]", i))
+                    .collect::<Vec<_>>()
+                    .join(", ")
+            );
+        }
+    });
+    fmtln!(fmt, "}")
+}
+
+/// Generate a Builder trait with methods for all instructions.
+fn gen_builder(instructions: &Vec<&Instruction>, formats: &FormatRegistry, fmt: &mut Formatter) {
+    fmt.doc_comment(
+        r#"
+        Convenience methods for building instructions.
+
+        The `InstBuilder` trait has one method per instruction opcode for
+        conveniently constructing the instruction with minimum arguments.
+        Polymorphic instructions infer their result types from the input
+        arguments when possible. In some cases, an explicit `ctrl_typevar`
+        argument is required.
+
+        The opcode methods return the new instruction's result values, or
+        the `Inst` itself for instructions that don't have any results.
+
+        There is also a method per instruction format. These methods all
+        return an `Inst`.
+    "#,
+    );
+    fmt.line("pub trait InstBuilder<'f>: InstBuilderBase<'f> {");
+    fmt.indent(|fmt| {
+        for inst in instructions {
+            gen_inst_builder(inst, formats.get(inst.format), fmt);
+        }
+        for format in formats.iter() {
+            gen_format_constructor(format, fmt);
+        }
+    });
+    fmt.line("}");
+}
+
+pub fn generate(
+    all_inst_groups: Vec<&InstructionGroup>,
+    format_registry: &FormatRegistry,
+    opcode_filename: &str,
+    inst_builder_filename: &str,
+    out_dir: &str,
+) -> Result<(), error::Error> {
+    // Opcodes.
+    let mut fmt = Formatter::new();
+    gen_formats(format_registry, &mut fmt);
+    gen_instruction_data(format_registry, &mut fmt);
+    fmt.empty_line();
+    gen_instruction_data_impl(format_registry, &mut fmt);
+    fmt.empty_line();
+    let all_inst = gen_opcodes(format_registry, &all_inst_groups, &mut fmt);
+    gen_type_constraints(&all_inst, &mut fmt);
+    fmt.update_file(opcode_filename, out_dir)?;
+
+    // Instruction builder.
+    let mut fmt = Formatter::new();
+    gen_builder(&all_inst, format_registry, &mut fmt);
+    fmt.update_file(inst_builder_filename, out_dir)?;
+
+    Ok(())
+}
--- a/third_party/rust/cranelift-codegen-meta/src/lib.rs
+++ b/third_party/rust/cranelift-codegen-meta/src/lib.rs
@@ -1,15 +1,16 @@
 #[macro_use]
 mod cdsl;
 mod srcgen;
 
 pub mod error;
 pub mod isa;
 
+mod gen_inst;
 mod gen_registers;
 mod gen_settings;
 mod gen_types;
 
 mod constant_hash;
 mod shared;
 mod unique_table;
 
@@ -28,16 +29,27 @@ pub fn generate(isas: &Vec<isa::Isa>, ou
         "new_settings.rs",
         &out_dir,
     )?;
     gen_types::generate("types.rs", &out_dir)?;
 
     // Per ISA definitions.
     let isas = isa::define(isas, &mut shared_defs);
 
+    let mut all_inst_groups = vec![&shared_defs.instructions];
+    all_inst_groups.extend(isas.iter().map(|isa| &isa.instructions));
+
+    gen_inst::generate(
+        all_inst_groups,
+        &shared_defs.format_registry,
+        "opcodes.rs",
+        "inst_builder.rs",
+        &out_dir,
+    )?;
+
     for isa in isas {
         gen_registers::generate(&isa, &format!("registers-{}.rs", isa.name), &out_dir)?;
         gen_settings::generate(
             &isa.settings,
             gen_settings::ParentGroup::Shared,
             &format!("new_settings-{}", isa.name),
             &out_dir,
         )?;
--- a/third_party/rust/cranelift-codegen/.cargo-checksum.json
+++ b/third_party/rust/cranelift-codegen/.cargo-checksum.json
@@ -1,1 +1,1 @@
-{"files":{"Cargo.toml":"9e1e9d197a2fcdb9bfd3c32a7608ab772ed4301aa0b9f2e60b73c98f542ac760","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"e5127227a7db4a8aa92fa6613ed71801025790e696bb41b0323fb7f3c6f7495a","build.rs":"7c0919d12ff966e0c400e7cfa0a555b2e50ede20c0dfb4f4401e35a828134ea9","meta-python/base/__init__.py":"4fac8bb055541dc964383bb04223bae6dfbfe348abf5e23f83655966cbb4aa8f","meta-python/base/entities.py":"f956b8ba863cd26f6867e13c1b2db3c202e9b07c48c1e43a9c2b41ad0deb8922","meta-python/base/formats.py":"f9fb41210bc1f99a78cb7a60ee9f01c603412c6b1db7e69abbcc0f573cf9fb40","meta-python/base/immediates.py":"f42682d86bda7b569ec2fc2debd9036355999e61caaa9fbf8307e0be8a164814","meta-python/base/instructions.py":"4f92066dc9cfa651e395afc8956b1a082b4e8591c6f7310db89593ff55322e2b","meta-python/base/legalize.py":"8455a5c7428e98d23e432d7be28cc863804781013ac614ba57f6d231cd810d28","meta-python/base/predicates.py":"53a5a9a37021a9762f0faec9f9e3c5b713411d47dd9192423cfe0f7a61916809","meta-python/base/semantics.py":"b90cbca9a143676ac37496c83634a66a83360248e4505ff7bda12b0d454efd92","meta-python/base/settings.py":"97fca9ddaab347f50f1594c93283f8f474e53a7232eae65949f56a6a702c2bba","meta-python/base/types.py":"9616d6fe4cab050827ab02eeb9843eacebbb8f7555521f504b5ee2ddf7214fdb","meta-python/build.py":"5668220ffa5106c0890157ee2839870264ec8eaf60c99ddf5d5bd2d2cf57b100","meta-python/cdsl/__init__.py":"b534ec129a0e517f0d13313c2b4bb3a345d3e5b62693a31d8d42c80a219e39fa","meta-python/cdsl/ast.py":"832ac98dddea88f4f8a608ac6ac3fda009a15b52abacca30cf39e3787154521c","meta-python/cdsl/formats.py":"fedfeaec754b40d6a9cc92b827976782c615d8eab1c7f47f6b47510cbef585f4","meta-python/cdsl/instructions.py":"50fe9329a56e6294a27306aad7be22c88a5b5ef42c3b030ec59218167157f62f","meta-python/cdsl/isa.py":"dc530a4dd5642e3379398dfc8a90ad6ae1692302de63851370bdfa8abf4cdce0","meta-python/cdsl/operands.py":"e24914eae4059b88781bf5a5d7a14ecf98b10a701ed6cf6e88d15981b2ccbfdf","meta-python/cdsl/predicates.py":"fe2dc6e78ff6d4bcb6b1d5448ded343ede0f03b96a965a11aef0f5bbe7bb8f56","meta-python/cdsl/registers.py":"939dafd1b8976a6cd456c9a5e4b374af81fafb9da979ea3a1f6d14e4645914a6","meta-python/cdsl/settings.py":"a859bd006e13b245ff906977512cd4822c3b22601ed17e87ce0618503172809f","meta-python/cdsl/test_ast.py":"947e934e2862445a158bf266dff58a8c88aae31fb34a7f823309ee58a15c5393","meta-python/cdsl/test_package.py":"ffa53d20e023ecb89137294bb13614f4de9b09e1bf05d9772131570bf78f7987","meta-python/cdsl/test_ti.py":"04656e2da99ec37875f91172bb2fa423da1ee27bf523a4d41af311ea22492d1b","meta-python/cdsl/test_typevar.py":"768bf3c35481950264ad6fd7059a532ac62b121ac439983bb4fe1ae76a1d1248","meta-python/cdsl/test_xform.py":"ddb6633c7941bbf68570701cb887a81d6b4b27f4bc45eabccf2ce287ad9b77e9","meta-python/cdsl/ti.py":"566e91f0bb3ebacd5abf9f5a663caee69706c2e829dee1ed735d229198689f76","meta-python/cdsl/types.py":"adee4bbc1a9478288fa4b53ee1edeb5ee3296dba2c70bfbe01e923895064999e","meta-python/cdsl/typevar.py":"b5669934eddaf5b9cc0c27b966e2566b5f669f1c5a345f005960930fb499097e","meta-python/cdsl/xform.py":"bf200b711570b905f0fb30611ba64f131f98593060eedbe5575054cca4928593","meta-python/check.sh":"707cda14534882e8d4593f93c056390560394c9bc8a687e99f10a56d7b09cb92","meta-python/constant_hash.py":"c752e6dadf3a9a5bd00c978e85ab27a20c49138a1ccdc6fc9a1904797a4bfe48","meta-python/gen_binemit.py":"76472fb199a330b934ba9ad0a1bbacfb52f0eae7c9a66d83f0d7890970323a2d","meta-python/gen_build_deps.py":"53bbdd591c91f8e28da95e4da02c9299a01a32d8be6a0c7490b6b7c60a4fbebe","meta-python/gen_encoding.py":"471c5f4ecf24a2a173864c62a48920e5fbe1aacd2229b3eb4483637570bb26b2","meta-python/gen_instr.py":"c57caccd6329ca6ab33db1a47e1dafa37e669e4b518808b9b78b28cdf9e221e1","meta-python/gen_legalizer.py":"4108393f261e8e0f0757709072eefcafc2f68aad290aff3e5bbf30e283e87968","meta-python/gen_settings.py":"f13e47335ae87b6381134b3d334f2fcbdfc03da92a8864dd1ff1c026408062a7","meta-python/isa/__init__.py":"e499c1206cd095a926fa0ca7eb9d0a50a802ed71c8eb7598e5d3a0f939c8ada5","meta-python/isa/arm32/__init__.py":"eecba73231aa398ded7304690bdba3450dc163afd4360f1b0ad02a28e2380363","meta-python/isa/arm32/defs.py":"01c41dbd7406c624e26229df6befa0992194bddcc7d11e8f6174abfe2b33bf61","meta-python/isa/arm32/registers.py":"c03ca6435828ad5f262049e42f1f71bcf74903831f85daa92c3f322a6c1050ea","meta-python/isa/arm32/settings.py":"afd5a04a9d029f578d6f62dc7c539191886cc9f9dea15d65fc66bf37a63b8814","meta-python/isa/arm64/__init__.py":"f6877253cf786d7ee972881e7d9b3c78c11e6b024e4e227487340dd01d0c44e4","meta-python/isa/arm64/defs.py":"797c5bb6d11fc7a44afe67476136dbd11c40f5e13a1c8f52f9f96be4441677b2","meta-python/isa/arm64/registers.py":"9bdd06edaa382be96042e1ac36d63137e73292292b61dcf4becb7d1428130317","meta-python/isa/arm64/settings.py":"f7b1f8733e775ea8005372ee35f1c2a627b3a69d722e837295599e4cf1f5eb43","meta-python/isa/riscv/__init__.py":"c11607c9eef0bc2707daa3edd4174e934c7a0dcc8ce90cee2c9292a85b1ac596","meta-python/isa/riscv/defs.py":"e73740055c4fb123c45453fc149a807e9720466de848022d5375049bdcfc311c","meta-python/isa/riscv/encodings.py":"ecaad5ea98273ade1cb10606354e893342c495bb48771df50121f789566d7be6","meta-python/isa/riscv/recipes.py":"3852e5b7aa6995fa721ba91744a0470343ce1834651e7b9cc97b5d69af7dfdc5","meta-python/isa/riscv/registers.py":"ef9aca3a6ec2b08ee8f5952186d232861b64a919b671b41911a365e7672b01bd","meta-python/isa/riscv/settings.py":"dfe29722d67be0620a70e08cfb802829a26f5fd339a9342a8ac2dd419daf8a85","meta-python/isa/x86/__init__.py":"ad579de68ea7bf5dc2bce0e3a6f09e7978b1697f1afec8a5ce5dc591136e590d","meta-python/isa/x86/defs.py":"b5eb7889b6f5e5b221ed3923d0137bbb1566c55b5961448cc39e4ea2f13cf4b7","meta-python/isa/x86/encodings.py":"028acd4ba348ba2dfa601217b8d4597748f87cdbfbaeece477150fc09bab50a6","meta-python/isa/x86/instructions.py":"530cde78e6b9f6e4ea2192985f4c5c77a987cdc19001d50fb47fa8e36a62f52e","meta-python/isa/x86/legalize.py":"1375ded072c29459e7c0e40ecb02f28d5395d9d8c603eb70e338b2bf2991c9cd","meta-python/isa/x86/recipes.py":"c9d7910cd4311ee4307460ca55070404e212727814664f2a2096b9b702ff7178","meta-python/isa/x86/registers.py":"ff934491d07ec6b51fbfd454b865a7c7c191ffbd31b1804615735266b120f4b2","meta-python/isa/x86/settings.py":"d779a768475cf00c2a8d3ddb5cd0a70ce34662e0ebb52ee26a7e1a495ec41aa2","meta-python/mypy.ini":"5ec2f7cc0bbc4fd0435643d6b72e715bd9568a3a0fe14c043f9e559c405b66fb","meta-python/semantics/__init__.py":"c9dd72fde0ab020d3328dde532d92b39e438e4147930e41df7613c27727e11eb","meta-python/semantics/elaborate.py":"3a3fbba83a6818c2d1ce236fd0413111380875a0307f7a5f4b5dd66d8ef714b1","meta-python/semantics/macros.py":"b218c52e1bd4f019dc14a27d315b4f3405a10e5bdc6f2523fe709c8faf91b418","meta-python/semantics/primitives.py":"4e5eb0c90fcc295686732c8c66ad7a793997645c9a676c97babf06823fd2b60d","meta-python/semantics/smtlib.py":"48ef80320f21682860bbf5f79f18739f1d10f0b1fe581ebb05541e90dc2f2f4f","meta-python/semantics/test_elaborate.py":"3a4c850a7385007422c7549661b211903cd1dd1606dad7a86262ae27e697bca6","meta-python/srcgen.py":"999557d683e808a2ca90688c489ec4aff65798f44ac321ecf7de34d307261913","meta-python/stubs/z3/__init__.pyi":"6aaeb80f783b29c4364dee21da45f6df041c0a4807189a15777ee5447f6515dc","meta-python/stubs/z3/z3core.pyi":"c01a41d468e07cc4f8b405c292ed7f8c82bc1077f8b82dfde1e474577ade3335","meta-python/stubs/z3/z3types.pyi":"30009c951af99b9028d47cd4cabae95ff9742b77b690bd8dd63f6b7dba580759","meta-python/test_constant_hash.py":"157cf4f8964e0f04c041ffd349e889ce565b144453436690578c5d03c3a60216","meta-python/test_gen_legalizer.py":"d7da85622f142d2d66d0b92660b6f04b1424788bac05e6fbe0e5822b54dec705","meta-python/test_srcgen.py":"d6d7775e19a5b2621360c00eb6d92dfcb4568e49220993e0ceaac9628dbfd661","meta-python/unique_table.py":"5bd500667430c15f6ae586603d8612fb3bda07b072e40d86286e08392bdc3127","src/abi.rs":"76ee030cf0780fe63ccbf855b1161f215e3e2991cb9abe71ca9aff25e5f1dbc2","src/binemit/memorysink.rs":"ad79459de45431b04f28a296074d3613e804538911fbfd451b68058218594574","src/binemit/mod.rs":"bfd83cb1e23e7b2f6926134e1e57548af240036128033f19e557f4d130133e87","src/binemit/relaxation.rs":"95442e08349762b11dce3d8f5d86adea97d3554a0353d7d519bbabfe18a87b01","src/binemit/shrink.rs":"45434d5fb17804f5199f5fa80fd96aedaeac1ca3824766236eb16b6b529155b4","src/bitset.rs":"d57a79058a31b094b4bbe9d34876a5543286df1e08b5ceadfd05a9efc5a3b1ce","src/cfg_printer.rs":"69b4f16132c886ef0b883c8b78b59d041ceec3c8b96dd8015e990ac06733ce91","src/constant_hash.rs":"330e8289789ee351d0abeaf4b5e859b8db8772306e0820d34864fc9905d53b38","src/context.rs":"e5a2d8f608e1af17ee074fe8c791cfed42ec763b4cbb5319d56a8aac7452c69f","src/cursor.rs":"dcce946ad85d8fc2f1c9cc885ae8a0440c37d9e512606fb8a518aaffcc6d6f8f","src/dbg.rs":"1898d94cff0975815eb348651702e95c8f2f63886501d3b7043ee75668480472","src/dce.rs":"d8ab7c0cac0416f9d75afdacc60ba02e532361ec927c3f8bd171b1a53ec8b31a","src/divconst_magic_numbers.rs":"baccf8894bf8113b25fe3c35a16160544557d5a77290e08b27cc50f258973532","src/dominator_tree.rs":"7ee4114026011b11d49e48c5a9202970bafe3b22c2074f7c1390b98ebb2edb7a","src/flowgraph.rs":"bf520026c32c5454554d0b078b64a78bd44f3c0f4f198eddf71bcfd78cc963a3","src/fx.rs":"8a5d07487906d8316a179e826fcd817a92a4860686256a6fd9d78ba47c63f330","src/ir/builder.rs":"1a12c57f4168fa3c2fcf6be2f19d0d377eee40f24ae4390e6ba9d954f85a8a3e","src/ir/condcodes.rs":"5247c8d849e1372d2a22379c33a4a88226ec6187be18ca6f2c4e0f315d812aa8","src/ir/dfg.rs":"50a3a7c44b6a993f033a65682beaeae12d5ed78ff67d7ac5e205e645ef8e122f","src/ir/entities.rs":"8bae1166b59afd38953e7d9154ae141c979ab77153b9512f45db7b82a256fdf4","src/ir/extfunc.rs":"9806734eeb480724481128d8c1de78a3b1f80f1214c20f24131196a0df137872","src/ir/extname.rs":"ed2c0b52cdaecc7f0ba9a894ef9fffe139e09b520e43dcd6f0c887a3d41a31ac","src/ir/function.rs":"907c4658865559c27fe4ee2f4064d0c64add712f2a190185236dba3cb98d4c32","src/ir/globalvalue.rs":"1f6125788a9a5c118716f87fd72e85009d2e0a7f4c13b2a7904be8c7412ee4eb","src/ir/heap.rs":"a59d3e5901412b53c0b53a8cdf10765ff5921de9c410ae9acea226c89827df3c","src/ir/immediates.rs":"029a8aa905e6fd0f3334e17a28e73ac36684df2ca0829dcae0158ea8cf64ca8c","src/ir/instructions.rs":"2180de1d127ab5878c5743d8e096d551edb973e0ff1d373c4239c32e7981364c","src/ir/jumptable.rs":"7764abc9aa027a5a89d22059b360372bd9a19686887c5a7830f7637d6f188e1e","src/ir/layout.rs":"bb45eefde16ac9423f637dfcc2796ae7b955a97f38a55f23a19cc45da5decce1","src/ir/libcall.rs":"55fd77f6e32370812a271f4fd5d9817c03904733be79d49e17e2683fe516e30e","src/ir/memflags.rs":"dbcf3798ab66dc764b73fb7f139a621c54cc6bcc683f1f70a33ed7e8c3486bfd","src/ir/mod.rs":"ec1da8a8bd99a3dbbcea59e2c10aa60511488471930646ab293f47d428013224","src/ir/progpoint.rs":"49433f22bd6ff3a96ad0733ff612f3617b312e4492b6b663187141966f6aa701","src/ir/sourceloc.rs":"37ef5fd8cef1de99620797d7d5aba3630e737171853c8471495c685dafac19b6","src/ir/stackslot.rs":"2f54359339837bb1d0d817d3af21bb4b1b050c31703885dfaced29f6e41153c2","src/ir/table.rs":"dcc3b663a989b2b084402b08dc9a0e928dbd052e194a46a1886cc6f0cf1a5f2c","src/ir/trapcode.rs":"59e223193617b8c1043ddd3a907c6131f2987e8fe0965ebfd9f7c056c064b7c5","src/ir/types.rs":"1f644beba2c797f7bd89378d930c3eca1491ec5f82c4715945ac63a0a5754473","src/ir/valueloc.rs":"4c676c2d21d75611ef922a230ee82846afb565ce0f55bc71e33c70e1a1d92a07","src/isa/arm32/abi.rs":"74775c5f1eb95764e46815fa8b31891416a616fdd212972eb77aead43b3345a9","src/isa/arm32/binemit.rs":"52b2f4b3c6d8683ed6963c1f53907ac57b6aab7cc149464c9a12d6875aa3b5c6","src/isa/arm32/enc_tables.rs":"b5b7f2fdcaf1d1878a357c54ab757e94f0d06e5bd391ac5d876e96f5b30d6b7a","src/isa/arm32/mod.rs":"24492cfe9120a3ebb199b1d0a0b58425c58970bae32349b3cf2dd390ce51e62f","src/isa/arm32/registers.rs":"254b568a02480f46bb4967a24a438390231014258f0c159f0a41dbafe8e66d56","src/isa/arm32/settings.rs":"188f3cc445168b472b488e73b011e83edd31ac17e3841dacda07a55ccf923468","src/isa/arm64/abi.rs":"52353ed2e2133dacddaad70a876ecebb9c179c19b911ffa823b5b89d3ee7a17c","src/isa/arm64/binemit.rs":"4465cceb68d03ae4d0fdf188c9b86870fb57b3617d67f0bb7d476e5afb581e81","src/isa/arm64/enc_tables.rs":"8c829c544daeed9adc8458891614a0be6f149e775bd22651465f2c165d4a9e56","src/isa/arm64/mod.rs":"f9ca60e7407b69595cb4ef42103ed079e7bcb40546f11d944ddcfc6a04a7fd11","src/isa/arm64/registers.rs":"308cfcfd9ff2191d7656e7350bb36e41803664eb86ae490fb4b4d3549b25b6a2","src/isa/arm64/settings.rs":"0dff47e995e5d9740deb0116b59e91fbcb725a7fa1bdbd802bf83c13381b17f7","src/isa/call_conv.rs":"833ac811ff78ab8d3a5052165e76c51c6da7686020d95462c18074750fb790ed","src/isa/constraints.rs":"f2e2dee4308dabaab1071983d2edd9a9972a99c5c99edf919adbb4554b4eb067","src/isa/enc_tables.rs":"3497f3d701f21d6f952424abf31515fde9e67aea1cde26236c9ee8b033c61ae6","src/isa/encoding.rs":"7ea5b4400530172f96e263561682886ea6c67e706398d44a83933ef7f0ac98a5","src/isa/mod.rs":"40ab1c6d86f903a88bc7ef83b7cdcbee0eedbfdf7112fb7a6749c0c8cc9ee42c","src/isa/registers.rs":"4a91d4888df5eeed1802f34c43a42b82aaf1f9928a58329b0cbc9c3c57c75485","src/isa/riscv/abi.rs":"36557b91ad16a1344c80fbb16a62b46eac88500d76cb9ebcd4eae224dd67b2de","src/isa/riscv/binemit.rs":"0bd76b005b53b71bdb59057a20671fbcd8ab1c37d767bfd4ab0a92d05e192d9a","src/isa/riscv/enc_tables.rs":"ab73c80fef6b1256fbd3c0e1bdd8e43a20f7d132a32236f6bfc028e9003adfe0","src/isa/riscv/mod.rs":"377dfc7dc9940d284b21bf3d2433916dd9c3df79cce172a2a75ef572dcafe98f","src/isa/riscv/registers.rs":"666c2abe1a93db5f1573d1603db6c13c37f3fc877c0c93b64d1b971921bfa950","src/isa/riscv/settings.rs":"d018d23418ff3fb98571bcdeeddde3277bf213b4b8ac1e55b6573e128b3931ce","src/isa/stack.rs":"d023c57feb944c94c4dc8b7138dcbc9d37ff18ca23c23d83e9bab3c88299ffa0","src/isa/x86/abi.rs":"98092944de6b8a8171f1c7d24a63d23ee6dc77a5b4048be113582c5362ac0158","src/isa/x86/binemit.rs":"328f5803717e095abbda0d0a49a79b8f5250a6d16a739a5912ee0a71f276d9de","src/isa/x86/enc_tables.rs":"250ab677b2a316f9826495a0719f71f4b54b3c3c26d0bb42a76dd85b55a2f8e3","src/isa/x86/mod.rs":"15488d60a950aa4cb75afb63d42d4524e1fcea3b77c7c160e2cb862ec2236a92","src/isa/x86/registers.rs":"bed70bbe1f56f3ef03ea7cd1bea68eb911913cb4c8b93167e044dfc639f7f461","src/isa/x86/settings.rs":"cd8f8c5255663f6e247f0634088b16b53d785ee8c62cb5c0926b3d27597c12ff","src/iterators.rs":"f85f52d3fa707a0eb974c92215b3e976923ce8f9481219f7812e0f2869c2bd37","src/legalizer/boundary.rs":"435707e84b5e406843238d27f5cc4886f4ae37e2c4d25a749e189a378b3af632","src/legalizer/call.rs":"6a82a9daeba5f452a7db0c47dcc43829b119b0652961bc2aa336b809c3f34ef1","src/legalizer/globalvalue.rs":"896f59dc5b8c4a5aee45e3f59211066f214d3ab9142865d80ad6610633363ac9","src/legalizer/heap.rs":"4caf9b5f98556364f16164613872c29a457dcbf44b07cc49fc415abbcd61ec6c","src/legalizer/libcall.rs":"6e58da5e1c2419192a3393debc6e9714df9728e59e1740ff569e8a9c0daa40d5","src/legalizer/mod.rs":"7df6ed89a80c9dab7f6e3ddbedcb1c4bcc86c3c6e5bdc3e71e51d5322cb1ce52","src/legalizer/split.rs":"13fe4d2cecea166ecdc1ebb11f5254374ee170518f1a61de7ac0a921bc8fb25d","src/legalizer/table.rs":"d6e09f8340ca597fdb13f86021e5c53bd3161dc4258effc56c1f6d9be7b819ec","src/lib.rs":"12855b9aedb583859a89dd8f8a7e1ff6d6c9f68e938f60ff4d123aa3d98c2da5","src/licm.rs":"a4b482c995daf0ecf928a525747316760986a42234331554ae68fe9ef8c7145e","src/loop_analysis.rs":"58fc3cc0e700f05e3131ff1b16ff975d4f32a68c790f095d8445bd300356d3c0","src/nan_canonicalization.rs":"9619bb5554791bd1be75ecd98564d6c9f5b65132bc07c5c4d8c210cd79b66f82","src/partition_slice.rs":"bc13504e7658aab565918d965a0b67e941eb572e583870571bc6dbb2b9aad272","src/postopt.rs":"f3af3f27496de14e4e65b7efb0748ca11edff8fedd7b57d680b310de5156aa62","src/predicates.rs":"44bbc09ae0c7d5b54c05eb6061b062e92d1893edc7dda43ae2bccfedc6bb25e3","src/print_errors.rs":"0955151433563b4c305c78b9a8f192c5fe0556ac2528a5ede3b2fd4d143eb743","src/ref_slice.rs":"421a61323c11858a596d50220487f399e1bcedeff0e8d1b716dd4b3531eb01a5","src/regalloc/affinity.rs":"66ee6b9789ec207393c318b14177e1439a54f197b13ebefdb0c4ab77acf38c00","src/regalloc/coalescing.rs":"881c8be32eb4d4b34cf208d0dba3e18b8469bc19f19aa7120514c801562392d3","src/regalloc/coloring.rs":"72bef8b5e3425c805d62cf2329acd29510f1be0886ee73308b69938cf2de203f","src/regalloc/context.rs":"a7da41171ad73cd541977657f0af0d5308567fff140fa7eb7ee44e03c62d8c96","src/regalloc/diversion.rs":"d46d733f6d00a8f536d5c7c8b8fc6f348c3d0605dd0ee77e1d8359367ba53347","src/regalloc/live_value_tracker.rs":"28823003dc72e8a4702776a8ab5ffd878712700a272b64376b0de2022e0ee31a","src/regalloc/liveness.rs":"cc904b813a8a2fc819f0cd5ffacb5a4b82f29ae3ae6a34cccc01fc47c20d150f","src/regalloc/liverange.rs":"7a28454e5f70d570db439b966a01ead759b65eb65c5845f9c58bf2f230a5f2ab","src/regalloc/mod.rs":"6254df639f9289fd578e01b7dca99bc9c9e3c6680c6d031405e8df8d0cff31ad","src/regalloc/pressure.rs":"c9d1098266c5b8b89eff84a55be3bc4838b70416c2446edf57f5257a6232d059","src/regalloc/register_set.rs":"bc58f93f22f0adbe43260fe20c6089be1fca64f5bcc4acff85dc0a5ec5b61937","src/regalloc/reload.rs":"4dd64aacc97fda5e950222df37df20bf2281cfbca93d1945f3a4f25e4b867aac","src/regalloc/solver.rs":"e2a6d2782d213676dec9781aeb5a37806e092d6daac3249a6cd4d4c92a9d117f","src/regalloc/spilling.rs":"f21ae054e6546b0cd774a94bb301517ba341b985223b6db36e6c9ba995eecfd8","src/regalloc/virtregs.rs":"e5c8da6860ba9495f9396621530347e1dd6fc5b2fae2eb23c171ea77429356f1","src/result.rs":"c10354d615f93caa446c3c8c49d6ba3af762816af470f9c4accf04315cce9753","src/scoped_hash_map.rs":"5afafb3a4039094c3a2aad1582354220d21f399aa50046e7f4a1259e1976597e","src/settings.rs":"23eb1461f7f02f4e26cca71ddc72ead7887bb1aec64b04eb6eb0397c402bf3c8","src/simple_gvn.rs":"c8feb380d4831badc59aa1e65efeafa6702711585817fe5f6b31de6b265fac24","src/simple_preopt.rs":"3a576a993312be6a9119fb3180f609988f606f837c4430878e8becca078935ce","src/stack_layout.rs":"c5de271e296fc424f1a30017620bc88500369c8e553fef6e95beccb9c6640e7c","src/timing.rs":"a6808943eec68f5d3ff32132d40c07c142e6aa8073473561573a013978883e4f","src/topo_order.rs":"b01ed68a7300691f41ac434e58a5267b10a8b4a7056d65035e24aa8a6722122a","src/unreachable_code.rs":"40cc71a02887ee4065c76ce96dda0a363a8cc134ec784fe5ed1f276db76596ce","src/verifier/cssa.rs":"e3e1d77b763c0ba82d3b59ab5b4667fd3152d5a08be50b58b0c82f86376bb062","src/verifier/flags.rs":"f4ba0e0c13fd643bdbec6466219a25a33993a6e170debb48497a859d9f79d914","src/verifier/liveness.rs":"2631037bafa88659bc47d2174e261f5acb1702ca522722a597fa28e474994d79","src/verifier/locations.rs":"9623bbc2d2f86f36893eebe60330fd51b99c9f9c8e5162c61cc89ab221e75b5a","src/verifier/mod.rs":"21e92c6b84d885882360794528afb33c828b7a232abab43d0a49a0f0bb3e0043","src/write.rs":"24b5caa5fa9145f8da78b9ef2342f52a05d04318b3b03f5b8bb1d486a3d46041"},"package":null}
\ No newline at end of file
+{"files":{"Cargo.toml":"9e1e9d197a2fcdb9bfd3c32a7608ab772ed4301aa0b9f2e60b73c98f542ac760","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"e5127227a7db4a8aa92fa6613ed71801025790e696bb41b0323fb7f3c6f7495a","build.rs":"7c0919d12ff966e0c400e7cfa0a555b2e50ede20c0dfb4f4401e35a828134ea9","meta-python/base/__init__.py":"4fac8bb055541dc964383bb04223bae6dfbfe348abf5e23f83655966cbb4aa8f","meta-python/base/entities.py":"f956b8ba863cd26f6867e13c1b2db3c202e9b07c48c1e43a9c2b41ad0deb8922","meta-python/base/formats.py":"f9fb41210bc1f99a78cb7a60ee9f01c603412c6b1db7e69abbcc0f573cf9fb40","meta-python/base/immediates.py":"f42682d86bda7b569ec2fc2debd9036355999e61caaa9fbf8307e0be8a164814","meta-python/base/instructions.py":"4f92066dc9cfa651e395afc8956b1a082b4e8591c6f7310db89593ff55322e2b","meta-python/base/legalize.py":"8455a5c7428e98d23e432d7be28cc863804781013ac614ba57f6d231cd810d28","meta-python/base/predicates.py":"53a5a9a37021a9762f0faec9f9e3c5b713411d47dd9192423cfe0f7a61916809","meta-python/base/semantics.py":"b90cbca9a143676ac37496c83634a66a83360248e4505ff7bda12b0d454efd92","meta-python/base/settings.py":"97fca9ddaab347f50f1594c93283f8f474e53a7232eae65949f56a6a702c2bba","meta-python/base/types.py":"9616d6fe4cab050827ab02eeb9843eacebbb8f7555521f504b5ee2ddf7214fdb","meta-python/build.py":"a6617c8a4d20b76e0c8ea8c6cb2e95ada9ffd0c6cf0f93d841a5204e4678f218","meta-python/cdsl/__init__.py":"b534ec129a0e517f0d13313c2b4bb3a345d3e5b62693a31d8d42c80a219e39fa","meta-python/cdsl/ast.py":"832ac98dddea88f4f8a608ac6ac3fda009a15b52abacca30cf39e3787154521c","meta-python/cdsl/formats.py":"fedfeaec754b40d6a9cc92b827976782c615d8eab1c7f47f6b47510cbef585f4","meta-python/cdsl/instructions.py":"50fe9329a56e6294a27306aad7be22c88a5b5ef42c3b030ec59218167157f62f","meta-python/cdsl/isa.py":"dc530a4dd5642e3379398dfc8a90ad6ae1692302de63851370bdfa8abf4cdce0","meta-python/cdsl/operands.py":"e24914eae4059b88781bf5a5d7a14ecf98b10a701ed6cf6e88d15981b2ccbfdf","meta-python/cdsl/predicates.py":"fe2dc6e78ff6d4bcb6b1d5448ded343ede0f03b96a965a11aef0f5bbe7bb8f56","meta-python/cdsl/registers.py":"939dafd1b8976a6cd456c9a5e4b374af81fafb9da979ea3a1f6d14e4645914a6","meta-python/cdsl/settings.py":"a859bd006e13b245ff906977512cd4822c3b22601ed17e87ce0618503172809f","meta-python/cdsl/test_ast.py":"947e934e2862445a158bf266dff58a8c88aae31fb34a7f823309ee58a15c5393","meta-python/cdsl/test_package.py":"ffa53d20e023ecb89137294bb13614f4de9b09e1bf05d9772131570bf78f7987","meta-python/cdsl/test_ti.py":"04656e2da99ec37875f91172bb2fa423da1ee27bf523a4d41af311ea22492d1b","meta-python/cdsl/test_typevar.py":"768bf3c35481950264ad6fd7059a532ac62b121ac439983bb4fe1ae76a1d1248","meta-python/cdsl/test_xform.py":"ddb6633c7941bbf68570701cb887a81d6b4b27f4bc45eabccf2ce287ad9b77e9","meta-python/cdsl/ti.py":"566e91f0bb3ebacd5abf9f5a663caee69706c2e829dee1ed735d229198689f76","meta-python/cdsl/types.py":"adee4bbc1a9478288fa4b53ee1edeb5ee3296dba2c70bfbe01e923895064999e","meta-python/cdsl/typevar.py":"b5669934eddaf5b9cc0c27b966e2566b5f669f1c5a345f005960930fb499097e","meta-python/cdsl/xform.py":"bf200b711570b905f0fb30611ba64f131f98593060eedbe5575054cca4928593","meta-python/check.sh":"707cda14534882e8d4593f93c056390560394c9bc8a687e99f10a56d7b09cb92","meta-python/constant_hash.py":"c752e6dadf3a9a5bd00c978e85ab27a20c49138a1ccdc6fc9a1904797a4bfe48","meta-python/gen_binemit.py":"76472fb199a330b934ba9ad0a1bbacfb52f0eae7c9a66d83f0d7890970323a2d","meta-python/gen_build_deps.py":"53bbdd591c91f8e28da95e4da02c9299a01a32d8be6a0c7490b6b7c60a4fbebe","meta-python/gen_encoding.py":"471c5f4ecf24a2a173864c62a48920e5fbe1aacd2229b3eb4483637570bb26b2","meta-python/gen_legalizer.py":"758f5aa072be71041915b8b662a59fc2dab8b0359dd91533161a8f449051fb3b","meta-python/gen_settings.py":"f13e47335ae87b6381134b3d334f2fcbdfc03da92a8864dd1ff1c026408062a7","meta-python/isa/__init__.py":"e499c1206cd095a926fa0ca7eb9d0a50a802ed71c8eb7598e5d3a0f939c8ada5","meta-python/isa/arm32/__init__.py":"eecba73231aa398ded7304690bdba3450dc163afd4360f1b0ad02a28e2380363","meta-python/isa/arm32/defs.py":"01c41dbd7406c624e26229df6befa0992194bddcc7d11e8f6174abfe2b33bf61","meta-python/isa/arm32/registers.py":"c03ca6435828ad5f262049e42f1f71bcf74903831f85daa92c3f322a6c1050ea","meta-python/isa/arm32/settings.py":"afd5a04a9d029f578d6f62dc7c539191886cc9f9dea15d65fc66bf37a63b8814","meta-python/isa/arm64/__init__.py":"f6877253cf786d7ee972881e7d9b3c78c11e6b024e4e227487340dd01d0c44e4","meta-python/isa/arm64/defs.py":"797c5bb6d11fc7a44afe67476136dbd11c40f5e13a1c8f52f9f96be4441677b2","meta-python/isa/arm64/registers.py":"9bdd06edaa382be96042e1ac36d63137e73292292b61dcf4becb7d1428130317","meta-python/isa/arm64/settings.py":"f7b1f8733e775ea8005372ee35f1c2a627b3a69d722e837295599e4cf1f5eb43","meta-python/isa/riscv/__init__.py":"c11607c9eef0bc2707daa3edd4174e934c7a0dcc8ce90cee2c9292a85b1ac596","meta-python/isa/riscv/defs.py":"e73740055c4fb123c45453fc149a807e9720466de848022d5375049bdcfc311c","meta-python/isa/riscv/encodings.py":"ecaad5ea98273ade1cb10606354e893342c495bb48771df50121f789566d7be6","meta-python/isa/riscv/recipes.py":"3852e5b7aa6995fa721ba91744a0470343ce1834651e7b9cc97b5d69af7dfdc5","meta-python/isa/riscv/registers.py":"ef9aca3a6ec2b08ee8f5952186d232861b64a919b671b41911a365e7672b01bd","meta-python/isa/riscv/settings.py":"dfe29722d67be0620a70e08cfb802829a26f5fd339a9342a8ac2dd419daf8a85","meta-python/isa/x86/__init__.py":"ad579de68ea7bf5dc2bce0e3a6f09e7978b1697f1afec8a5ce5dc591136e590d","meta-python/isa/x86/defs.py":"b5eb7889b6f5e5b221ed3923d0137bbb1566c55b5961448cc39e4ea2f13cf4b7","meta-python/isa/x86/encodings.py":"028acd4ba348ba2dfa601217b8d4597748f87cdbfbaeece477150fc09bab50a6","meta-python/isa/x86/instructions.py":"530cde78e6b9f6e4ea2192985f4c5c77a987cdc19001d50fb47fa8e36a62f52e","meta-python/isa/x86/legalize.py":"1375ded072c29459e7c0e40ecb02f28d5395d9d8c603eb70e338b2bf2991c9cd","meta-python/isa/x86/recipes.py":"c9d7910cd4311ee4307460ca55070404e212727814664f2a2096b9b702ff7178","meta-python/isa/x86/registers.py":"ff934491d07ec6b51fbfd454b865a7c7c191ffbd31b1804615735266b120f4b2","meta-python/isa/x86/settings.py":"d779a768475cf00c2a8d3ddb5cd0a70ce34662e0ebb52ee26a7e1a495ec41aa2","meta-python/mypy.ini":"5ec2f7cc0bbc4fd0435643d6b72e715bd9568a3a0fe14c043f9e559c405b66fb","meta-python/semantics/__init__.py":"c9dd72fde0ab020d3328dde532d92b39e438e4147930e41df7613c27727e11eb","meta-python/semantics/elaborate.py":"3a3fbba83a6818c2d1ce236fd0413111380875a0307f7a5f4b5dd66d8ef714b1","meta-python/semantics/macros.py":"b218c52e1bd4f019dc14a27d315b4f3405a10e5bdc6f2523fe709c8faf91b418","meta-python/semantics/primitives.py":"4e5eb0c90fcc295686732c8c66ad7a793997645c9a676c97babf06823fd2b60d","meta-python/semantics/smtlib.py":"48ef80320f21682860bbf5f79f18739f1d10f0b1fe581ebb05541e90dc2f2f4f","meta-python/semantics/test_elaborate.py":"3a4c850a7385007422c7549661b211903cd1dd1606dad7a86262ae27e697bca6","meta-python/srcgen.py":"999557d683e808a2ca90688c489ec4aff65798f44ac321ecf7de34d307261913","meta-python/stubs/z3/__init__.pyi":"6aaeb80f783b29c4364dee21da45f6df041c0a4807189a15777ee5447f6515dc","meta-python/stubs/z3/z3core.pyi":"c01a41d468e07cc4f8b405c292ed7f8c82bc1077f8b82dfde1e474577ade3335","meta-python/stubs/z3/z3types.pyi":"30009c951af99b9028d47cd4cabae95ff9742b77b690bd8dd63f6b7dba580759","meta-python/test_constant_hash.py":"157cf4f8964e0f04c041ffd349e889ce565b144453436690578c5d03c3a60216","meta-python/test_gen_legalizer.py":"d7da85622f142d2d66d0b92660b6f04b1424788bac05e6fbe0e5822b54dec705","meta-python/test_srcgen.py":"d6d7775e19a5b2621360c00eb6d92dfcb4568e49220993e0ceaac9628dbfd661","meta-python/unique_table.py":"5bd500667430c15f6ae586603d8612fb3bda07b072e40d86286e08392bdc3127","src/abi.rs":"76ee030cf0780fe63ccbf855b1161f215e3e2991cb9abe71ca9aff25e5f1dbc2","src/binemit/memorysink.rs":"ad79459de45431b04f28a296074d3613e804538911fbfd451b68058218594574","src/binemit/mod.rs":"bfd83cb1e23e7b2f6926134e1e57548af240036128033f19e557f4d130133e87","src/binemit/relaxation.rs":"95442e08349762b11dce3d8f5d86adea97d3554a0353d7d519bbabfe18a87b01","src/binemit/shrink.rs":"45434d5fb17804f5199f5fa80fd96aedaeac1ca3824766236eb16b6b529155b4","src/bitset.rs":"d57a79058a31b094b4bbe9d34876a5543286df1e08b5ceadfd05a9efc5a3b1ce","src/cfg_printer.rs":"69b4f16132c886ef0b883c8b78b59d041ceec3c8b96dd8015e990ac06733ce91","src/constant_hash.rs":"330e8289789ee351d0abeaf4b5e859b8db8772306e0820d34864fc9905d53b38","src/context.rs":"5c5eeb2aa36eec4d311efb60f6135fbeb223382e17a6e4126a779dfaf73e9be7","src/cursor.rs":"dcce946ad85d8fc2f1c9cc885ae8a0440c37d9e512606fb8a518aaffcc6d6f8f","src/dbg.rs":"1898d94cff0975815eb348651702e95c8f2f63886501d3b7043ee75668480472","src/dce.rs":"d8ab7c0cac0416f9d75afdacc60ba02e532361ec927c3f8bd171b1a53ec8b31a","src/divconst_magic_numbers.rs":"baccf8894bf8113b25fe3c35a16160544557d5a77290e08b27cc50f258973532","src/dominator_tree.rs":"7ee4114026011b11d49e48c5a9202970bafe3b22c2074f7c1390b98ebb2edb7a","src/flowgraph.rs":"bf520026c32c5454554d0b078b64a78bd44f3c0f4f198eddf71bcfd78cc963a3","src/fx.rs":"8a5d07487906d8316a179e826fcd817a92a4860686256a6fd9d78ba47c63f330","src/ir/builder.rs":"1a12c57f4168fa3c2fcf6be2f19d0d377eee40f24ae4390e6ba9d954f85a8a3e","src/ir/condcodes.rs":"5247c8d849e1372d2a22379c33a4a88226ec6187be18ca6f2c4e0f315d812aa8","src/ir/dfg.rs":"50a3a7c44b6a993f033a65682beaeae12d5ed78ff67d7ac5e205e645ef8e122f","src/ir/entities.rs":"8bae1166b59afd38953e7d9154ae141c979ab77153b9512f45db7b82a256fdf4","src/ir/extfunc.rs":"9806734eeb480724481128d8c1de78a3b1f80f1214c20f24131196a0df137872","src/ir/extname.rs":"ed2c0b52cdaecc7f0ba9a894ef9fffe139e09b520e43dcd6f0c887a3d41a31ac","src/ir/function.rs":"907c4658865559c27fe4ee2f4064d0c64add712f2a190185236dba3cb98d4c32","src/ir/globalvalue.rs":"1f6125788a9a5c118716f87fd72e85009d2e0a7f4c13b2a7904be8c7412ee4eb","src/ir/heap.rs":"a59d3e5901412b53c0b53a8cdf10765ff5921de9c410ae9acea226c89827df3c","src/ir/immediates.rs":"029a8aa905e6fd0f3334e17a28e73ac36684df2ca0829dcae0158ea8cf64ca8c","src/ir/instructions.rs":"2180de1d127ab5878c5743d8e096d551edb973e0ff1d373c4239c32e7981364c","src/ir/jumptable.rs":"7764abc9aa027a5a89d22059b360372bd9a19686887c5a7830f7637d6f188e1e","src/ir/layout.rs":"bb45eefde16ac9423f637dfcc2796ae7b955a97f38a55f23a19cc45da5decce1","src/ir/libcall.rs":"55fd77f6e32370812a271f4fd5d9817c03904733be79d49e17e2683fe516e30e","src/ir/memflags.rs":"dbcf3798ab66dc764b73fb7f139a621c54cc6bcc683f1f70a33ed7e8c3486bfd","src/ir/mod.rs":"ec1da8a8bd99a3dbbcea59e2c10aa60511488471930646ab293f47d428013224","src/ir/progpoint.rs":"49433f22bd6ff3a96ad0733ff612f3617b312e4492b6b663187141966f6aa701","src/ir/sourceloc.rs":"37ef5fd8cef1de99620797d7d5aba3630e737171853c8471495c685dafac19b6","src/ir/stackslot.rs":"2f54359339837bb1d0d817d3af21bb4b1b050c31703885dfaced29f6e41153c2","src/ir/table.rs":"dcc3b663a989b2b084402b08dc9a0e928dbd052e194a46a1886cc6f0cf1a5f2c","src/ir/trapcode.rs":"59e223193617b8c1043ddd3a907c6131f2987e8fe0965ebfd9f7c056c064b7c5","src/ir/types.rs":"1f644beba2c797f7bd89378d930c3eca1491ec5f82c4715945ac63a0a5754473","src/ir/valueloc.rs":"4c676c2d21d75611ef922a230ee82846afb565ce0f55bc71e33c70e1a1d92a07","src/isa/arm32/abi.rs":"74775c5f1eb95764e46815fa8b31891416a616fdd212972eb77aead43b3345a9","src/isa/arm32/binemit.rs":"52b2f4b3c6d8683ed6963c1f53907ac57b6aab7cc149464c9a12d6875aa3b5c6","src/isa/arm32/enc_tables.rs":"b5b7f2fdcaf1d1878a357c54ab757e94f0d06e5bd391ac5d876e96f5b30d6b7a","src/isa/arm32/mod.rs":"24492cfe9120a3ebb199b1d0a0b58425c58970bae32349b3cf2dd390ce51e62f","src/isa/arm32/registers.rs":"254b568a02480f46bb4967a24a438390231014258f0c159f0a41dbafe8e66d56","src/isa/arm32/settings.rs":"188f3cc445168b472b488e73b011e83edd31ac17e3841dacda07a55ccf923468","src/isa/arm64/abi.rs":"52353ed2e2133dacddaad70a876ecebb9c179c19b911ffa823b5b89d3ee7a17c","src/isa/arm64/binemit.rs":"4465cceb68d03ae4d0fdf188c9b86870fb57b3617d67f0bb7d476e5afb581e81","src/isa/arm64/enc_tables.rs":"8c829c544daeed9adc8458891614a0be6f149e775bd22651465f2c165d4a9e56","src/isa/arm64/mod.rs":"f9ca60e7407b69595cb4ef42103ed079e7bcb40546f11d944ddcfc6a04a7fd11","src/isa/arm64/registers.rs":"308cfcfd9ff2191d7656e7350bb36e41803664eb86ae490fb4b4d3549b25b6a2","src/isa/arm64/settings.rs":"0dff47e995e5d9740deb0116b59e91fbcb725a7fa1bdbd802bf83c13381b17f7","src/isa/call_conv.rs":"833ac811ff78ab8d3a5052165e76c51c6da7686020d95462c18074750fb790ed","src/isa/constraints.rs":"f2e2dee4308dabaab1071983d2edd9a9972a99c5c99edf919adbb4554b4eb067","src/isa/enc_tables.rs":"3497f3d701f21d6f952424abf31515fde9e67aea1cde26236c9ee8b033c61ae6","src/isa/encoding.rs":"7ea5b4400530172f96e263561682886ea6c67e706398d44a83933ef7f0ac98a5","src/isa/mod.rs":"40ab1c6d86f903a88bc7ef83b7cdcbee0eedbfdf7112fb7a6749c0c8cc9ee42c","src/isa/registers.rs":"4a91d4888df5eeed1802f34c43a42b82aaf1f9928a58329b0cbc9c3c57c75485","src/isa/riscv/abi.rs":"36557b91ad16a1344c80fbb16a62b46eac88500d76cb9ebcd4eae224dd67b2de","src/isa/riscv/binemit.rs":"0bd76b005b53b71bdb59057a20671fbcd8ab1c37d767bfd4ab0a92d05e192d9a","src/isa/riscv/enc_tables.rs":"ab73c80fef6b1256fbd3c0e1bdd8e43a20f7d132a32236f6bfc028e9003adfe0","src/isa/riscv/mod.rs":"377dfc7dc9940d284b21bf3d2433916dd9c3df79cce172a2a75ef572dcafe98f","src/isa/riscv/registers.rs":"666c2abe1a93db5f1573d1603db6c13c37f3fc877c0c93b64d1b971921bfa950","src/isa/riscv/settings.rs":"d018d23418ff3fb98571bcdeeddde3277bf213b4b8ac1e55b6573e128b3931ce","src/isa/stack.rs":"d023c57feb944c94c4dc8b7138dcbc9d37ff18ca23c23d83e9bab3c88299ffa0","src/isa/x86/abi.rs":"98092944de6b8a8171f1c7d24a63d23ee6dc77a5b4048be113582c5362ac0158","src/isa/x86/binemit.rs":"328f5803717e095abbda0d0a49a79b8f5250a6d16a739a5912ee0a71f276d9de","src/isa/x86/enc_tables.rs":"250ab677b2a316f9826495a0719f71f4b54b3c3c26d0bb42a76dd85b55a2f8e3","src/isa/x86/mod.rs":"15488d60a950aa4cb75afb63d42d4524e1fcea3b77c7c160e2cb862ec2236a92","src/isa/x86/registers.rs":"bed70bbe1f56f3ef03ea7cd1bea68eb911913cb4c8b93167e044dfc639f7f461","src/isa/x86/settings.rs":"cd8f8c5255663f6e247f0634088b16b53d785ee8c62cb5c0926b3d27597c12ff","src/iterators.rs":"f85f52d3fa707a0eb974c92215b3e976923ce8f9481219f7812e0f2869c2bd37","src/legalizer/boundary.rs":"435707e84b5e406843238d27f5cc4886f4ae37e2c4d25a749e189a378b3af632","src/legalizer/call.rs":"6a82a9daeba5f452a7db0c47dcc43829b119b0652961bc2aa336b809c3f34ef1","src/legalizer/globalvalue.rs":"896f59dc5b8c4a5aee45e3f59211066f214d3ab9142865d80ad6610633363ac9","src/legalizer/heap.rs":"4caf9b5f98556364f16164613872c29a457dcbf44b07cc49fc415abbcd61ec6c","src/legalizer/libcall.rs":"6e58da5e1c2419192a3393debc6e9714df9728e59e1740ff569e8a9c0daa40d5","src/legalizer/mod.rs":"7df6ed89a80c9dab7f6e3ddbedcb1c4bcc86c3c6e5bdc3e71e51d5322cb1ce52","src/legalizer/split.rs":"13fe4d2cecea166ecdc1ebb11f5254374ee170518f1a61de7ac0a921bc8fb25d","src/legalizer/table.rs":"d6e09f8340ca597fdb13f86021e5c53bd3161dc4258effc56c1f6d9be7b819ec","src/lib.rs":"12855b9aedb583859a89dd8f8a7e1ff6d6c9f68e938f60ff4d123aa3d98c2da5","src/licm.rs":"a4b482c995daf0ecf928a525747316760986a42234331554ae68fe9ef8c7145e","src/loop_analysis.rs":"58fc3cc0e700f05e3131ff1b16ff975d4f32a68c790f095d8445bd300356d3c0","src/nan_canonicalization.rs":"9619bb5554791bd1be75ecd98564d6c9f5b65132bc07c5c4d8c210cd79b66f82","src/partition_slice.rs":"bc13504e7658aab565918d965a0b67e941eb572e583870571bc6dbb2b9aad272","src/postopt.rs":"f3af3f27496de14e4e65b7efb0748ca11edff8fedd7b57d680b310de5156aa62","src/predicates.rs":"44bbc09ae0c7d5b54c05eb6061b062e92d1893edc7dda43ae2bccfedc6bb25e3","src/print_errors.rs":"0955151433563b4c305c78b9a8f192c5fe0556ac2528a5ede3b2fd4d143eb743","src/ref_slice.rs":"421a61323c11858a596d50220487f399e1bcedeff0e8d1b716dd4b3531eb01a5","src/regalloc/affinity.rs":"66ee6b9789ec207393c318b14177e1439a54f197b13ebefdb0c4ab77acf38c00","src/regalloc/coalescing.rs":"881c8be32eb4d4b34cf208d0dba3e18b8469bc19f19aa7120514c801562392d3","src/regalloc/coloring.rs":"72bef8b5e3425c805d62cf2329acd29510f1be0886ee73308b69938cf2de203f","src/regalloc/context.rs":"a7da41171ad73cd541977657f0af0d5308567fff140fa7eb7ee44e03c62d8c96","src/regalloc/diversion.rs":"d46d733f6d00a8f536d5c7c8b8fc6f348c3d0605dd0ee77e1d8359367ba53347","src/regalloc/live_value_tracker.rs":"28823003dc72e8a4702776a8ab5ffd878712700a272b64376b0de2022e0ee31a","src/regalloc/liveness.rs":"cc904b813a8a2fc819f0cd5ffacb5a4b82f29ae3ae6a34cccc01fc47c20d150f","src/regalloc/liverange.rs":"7a28454e5f70d570db439b966a01ead759b65eb65c5845f9c58bf2f230a5f2ab","src/regalloc/mod.rs":"6254df639f9289fd578e01b7dca99bc9c9e3c6680c6d031405e8df8d0cff31ad","src/regalloc/pressure.rs":"c9d1098266c5b8b89eff84a55be3bc4838b70416c2446edf57f5257a6232d059","src/regalloc/register_set.rs":"bc58f93f22f0adbe43260fe20c6089be1fca64f5bcc4acff85dc0a5ec5b61937","src/regalloc/reload.rs":"4dd64aacc97fda5e950222df37df20bf2281cfbca93d1945f3a4f25e4b867aac","src/regalloc/solver.rs":"e2a6d2782d213676dec9781aeb5a37806e092d6daac3249a6cd4d4c92a9d117f","src/regalloc/spilling.rs":"f21ae054e6546b0cd774a94bb301517ba341b985223b6db36e6c9ba995eecfd8","src/regalloc/virtregs.rs":"e5c8da6860ba9495f9396621530347e1dd6fc5b2fae2eb23c171ea77429356f1","src/result.rs":"c10354d615f93caa446c3c8c49d6ba3af762816af470f9c4accf04315cce9753","src/scoped_hash_map.rs":"5afafb3a4039094c3a2aad1582354220d21f399aa50046e7f4a1259e1976597e","src/settings.rs":"23eb1461f7f02f4e26cca71ddc72ead7887bb1aec64b04eb6eb0397c402bf3c8","src/simple_gvn.rs":"c8feb380d4831badc59aa1e65efeafa6702711585817fe5f6b31de6b265fac24","src/simple_preopt.rs":"3e8958c7eddf0f0e207d1f6a10ce9d9595b554dcabd984fcea1d6a4716365358","src/stack_layout.rs":"c5de271e296fc424f1a30017620bc88500369c8e553fef6e95beccb9c6640e7c","src/timing.rs":"a6808943eec68f5d3ff32132d40c07c142e6aa8073473561573a013978883e4f","src/topo_order.rs":"b01ed68a7300691f41ac434e58a5267b10a8b4a7056d65035e24aa8a6722122a","src/unreachable_code.rs":"40cc71a02887ee4065c76ce96dda0a363a8cc134ec784fe5ed1f276db76596ce","src/verifier/cssa.rs":"e3e1d77b763c0ba82d3b59ab5b4667fd3152d5a08be50b58b0c82f86376bb062","src/verifier/flags.rs":"f4ba0e0c13fd643bdbec6466219a25a33993a6e170debb48497a859d9f79d914","src/verifier/liveness.rs":"2631037bafa88659bc47d2174e261f5acb1702ca522722a597fa28e474994d79","src/verifier/locations.rs":"9623bbc2d2f86f36893eebe60330fd51b99c9f9c8e5162c61cc89ab221e75b5a","src/verifier/mod.rs":"0d4a46879a8c4b110b354ba35c667478a785e69b8a1c3b97c7f1aadc79433637","src/write.rs":"24b5caa5fa9145f8da78b9ef2342f52a05d04318b3b03f5b8bb1d486a3d46041"},"package":null}
\ No newline at end of file
--- a/third_party/rust/cranelift-codegen/meta-python/build.py
+++ b/third_party/rust/cranelift-codegen/meta-python/build.py
@@ -1,35 +1,54 @@
 # Second-level build script.
 #
 # This script is run from cranelift-codegen/build.rs to generate Rust files.
 
 from __future__ import absolute_import
 import argparse
 import isa
-import gen_instr
 import gen_settings
 import gen_build_deps
 import gen_encoding
 import gen_legalizer
 import gen_binemit
 
+try:
+    from typing import List, Set  # noqa
+    from cdsl.isa import TargetISA  # noqa
+    from cdsl.instructions import InstructionGroup  # noqa
+except ImportError:
+    pass
+
+
+def number_all_instructions(isas):
+    # type: (List[TargetISA]) -> None
+    seen = set()  # type: Set[InstructionGroup]
+    num_inst = 1
+    for target_isa in isas:
+        for g in target_isa.instruction_groups:
+            if g not in seen:
+                for i in g.instructions:
+                    i.number = num_inst
+                    num_inst += 1
+                seen.add(g)
+
 
 def main():
     # type: () -> None
     parser = argparse.ArgumentParser(
             description='Generate sources for Cranelift.')
     parser.add_argument('--out-dir', help='set output directory')
 
     args = parser.parse_args()
     out_dir = args.out_dir
 
     isas = isa.all_isas()
+    number_all_instructions(isas)
 
-    gen_instr.generate(isas, out_dir)
     gen_settings.generate(isas, out_dir)
     gen_encoding.generate(isas, out_dir)
     gen_legalizer.generate(isas, out_dir)
     gen_binemit.generate(isas, out_dir)
     gen_build_deps.generate()
 
 
 if __name__ == "__main__":
deleted file mode 100644
--- a/third_party/rust/cranelift-codegen/meta-python/gen_instr.py
+++ /dev/null
@@ -1,812 +0,0 @@
-"""
-Generate sources with instruction info.
-"""
-from __future__ import absolute_import
-import srcgen
-import constant_hash
-from unique_table import UniqueTable, UniqueSeqTable
-from cdsl import camel_case
-from cdsl.operands import ImmediateKind
-from cdsl.formats import InstructionFormat
-from cdsl.instructions import Instruction
-
-# The typing module is only required by mypy, and we don't use these imports
-# outside type comments.
-try:
-    from typing import List, Sequence, Set, TYPE_CHECKING  # noqa
-    if TYPE_CHECKING:
-        from cdsl.isa import TargetISA  # noqa
-        from cdsl.instructions import InstructionGroup  # noqa
-        from cdsl.operands import Operand  # noqa
-        from cdsl.typevar import TypeVar  # noqa
-
-except ImportError:
-    pass
-
-
-def gen_formats(fmt):
-    # type: (srcgen.Formatter) -> None
-    """Generate an instruction format enumeration"""
-
-    fmt.doc_comment('''
-                    An instruction format
-
-                    Every opcode has a corresponding instruction format
-                    which is represented by both the `InstructionFormat`
-                    and the `InstructionData` enums.
-                    ''')
-    fmt.line('#[derive(Copy, Clone, PartialEq, Eq, Debug)]')
-    with fmt.indented('pub enum InstructionFormat {', '}'):
-        for f in InstructionFormat.all_formats:
-            fmt.doc_comment(str(f))
-            fmt.line(f.name + ',')
-    fmt.line()
-
-    # Emit a From<InstructionData> which also serves to verify that
-    # InstructionFormat and InstructionData are in sync.
-    with fmt.indented(
-            "impl<'a> From<&'a InstructionData> for InstructionFormat {", '}'):
-        with fmt.indented(
-                "fn from(inst: &'a InstructionData) -> Self {",
-                '}'):
-            m = srcgen.Match('*inst')
-            for f in InstructionFormat.all_formats:
-                m.arm('InstructionData::' + f.name, ['..'],
-                      'InstructionFormat::' + f.name)
-            fmt.match(m)
-    fmt.line()
-
-
-def gen_arguments_method(fmt, is_mut):
-    # type: (srcgen.Formatter, bool) -> None
-    method = 'arguments'
-    mut = ''
-    rslice = 'ref_slice'
-    as_slice = 'as_slice'
-    if is_mut:
-        method += '_mut'
-        mut = 'mut '
-        rslice += '_mut'
-        as_slice = 'as_mut_slice'
-
-    with fmt.indented(
-            'pub fn {f}<\'a>(&\'a {m}self, '
-            'pool: &\'a {m}ir::ValueListPool) -> '
-            '&{m}[Value] {{'
-            .format(f=method, m=mut), '}'):
-        m = srcgen.Match('*self')
-        for f in InstructionFormat.all_formats:
-            n = 'InstructionData::' + f.name
-
-            # Formats with a value list put all of their arguments in the
-            # list. We don't split them up, just return it all as variable
-            # arguments. (I expect the distinction to go away).
-            if f.has_value_list:
-                m.arm(n, ['ref {}args'.format(mut), '..'],
-                      'args.{}(pool)'.format(as_slice))
-                continue
-
-            # Fixed args.
-            fields = []
-            if f.num_value_operands == 0:
-                arg = '&{}[]'.format(mut)
-            elif f.num_value_operands == 1:
-                fields.append('ref {}arg'.format(mut))
-                arg = '{}(arg)'.format(rslice)
-            else:
-                args = 'args_arity{}'.format(f.num_value_operands)
-                fields.append('args: ref {}{}'.format(mut, args))
-                arg = args
-            fields.append('..')
-            m.arm(n, fields, arg)
-        fmt.match(m)
-
-
-def gen_instruction_data(fmt):
-    # type: (srcgen.Formatter) -> None
-    """
-    Generate the InstructionData enum.
-
-    Every variant must contain an `opcode` field. The size of `InstructionData`
-    should be kept at 16 bytes on 64-bit architectures. If more space is needed
-    to represent an instruction, use a `Box<AuxData>` to store the additional
-    information out of line.
-    """
-
-    fmt.line('#[derive(Clone, Debug)]')
-    fmt.line('#[allow(missing_docs)]')
-    with fmt.indented('pub enum InstructionData {', '}'):
-        for f in InstructionFormat.all_formats:
-            with fmt.indented('{} {{'.format(f.name), '},'):
-                fmt.line('opcode: Opcode,')
-                if f.typevar_operand is None:
-                    pass
-                elif f.has_value_list:
-                    fmt.line('args: ValueList,')
-                elif f.num_value_operands == 1:
-                    fmt.line('arg: Value,')
-                else:
-                    fmt.line('args: [Value; {}],'.format(f.num_value_operands))
-                for field in f.imm_fields:
-                    fmt.line(
-                            '{}: {},'
-                            .format(field.member, field.kind.rust_type))
-
-
-def gen_instruction_data_impl(fmt):
-    # type: (srcgen.Formatter) -> None
-    """
-    Generate the boring parts of the InstructionData implementation.
-
-    These methods in `impl InstructionData` can be generated automatically from
-    the instruction formats:
-
-    - `pub fn opcode(&self) -> Opcode`
-    - `pub fn arguments(&self, &pool) -> &[Value]`
-    - `pub fn arguments_mut(&mut self, &pool) -> &mut [Value]`
-    - `pub fn take_value_list(&mut self) -> Option<ir::ValueList>`
-    - `pub fn put_value_list(&mut self, args: ir::ValueList>`
-    - `pub fn eq(&self, &other: Self, &pool) -> bool`
-    - `pub fn hash<H: Hasher>(&self, state: &mut H, &pool)`
-    """
-
-    # The `opcode` method simply reads the `opcode` members. This is really a
-    # workaround for Rust's enum types missing shared members.
-    with fmt.indented('impl InstructionData {', '}'):
-        fmt.doc_comment('Get the opcode of this instruction.')
-        with fmt.indented('pub fn opcode(&self) -> Opcode {', '}'):
-            m = srcgen.Match('*self')
-            for f in InstructionFormat.all_formats:
-                m.arm('InstructionData::' + f.name, ['opcode', '..'],
-                      'opcode')
-            fmt.match(m)
-        fmt.line()
-
-        fmt.doc_comment('Get the controlling type variable operand.')
-        with fmt.indented(
-                'pub fn typevar_operand(&self, pool: &ir::ValueListPool) -> '
-                'Option<Value> {', '}'):
-            m = srcgen.Match('*self')
-            for f in InstructionFormat.all_formats:
-                n = 'InstructionData::' + f.name
-                if f.typevar_operand is None:
-                    m.arm(n, ['..'], 'None')
-                elif f.has_value_list:
-                    # We keep all arguments in a value list.
-                    i = f.typevar_operand
-                    m.arm(n, ['ref args', '..'],
-                          'args.get({}, pool)'.format(i))
-                elif f.num_value_operands == 1:
-                    # We have a single value operand called 'arg'.
-                    m.arm(n, ['arg', '..'], 'Some(arg)')
-                else:
-                    # We have multiple value operands and an array `args`.
-                    # Which `args` index to use?
-                    args = 'args_arity{}'.format(f.num_value_operands)
-                    m.arm(n, ['args: ref {}'.format(args), '..'],
-                          'Some({}[{}])'.format(args, f.typevar_operand))
-            fmt.match(m)
-        fmt.line()
-
-        fmt.doc_comment(
-                """
-                Get the value arguments to this instruction.
-                """)
-        gen_arguments_method(fmt, False)
-        fmt.line()
-
-        fmt.doc_comment(
-                """
-                Get mutable references to the value arguments to this
-                instruction.
-                """)
-        gen_arguments_method(fmt, True)
-        fmt.line()
-
-        fmt.doc_comment(
-                """
-                Take out the value list with all the value arguments and return
-                it.
-
-                This leaves the value list in the instruction empty. Use
-                `put_value_list` to put the value list back.
-                """)
-        with fmt.indented(
-                'pub fn take_value_list(&mut self) -> Option<ir::ValueList> {',
-                '}'):
-            m = srcgen.Match('*self')
-            for f in InstructionFormat.all_formats:
-                n = 'InstructionData::' + f.name
-                if f.has_value_list:
-                    m.arm(n, ['ref mut args', '..'], 'Some(args.take())')
-            m.arm('_', [], 'None')
-            fmt.match(m)
-        fmt.line()
-
-        fmt.doc_comment(
-                """
-                Put back a value list.
-
-                After removing a value list with `take_value_list()`, use this
-                method to put it back. It is required that this instruction has
-                a format that accepts a value list, and that the existing value
-                list is empty. This avoids leaking list pool memory.
-                """)
-        with fmt.indented(
-                'pub fn put_value_list(&mut self, vlist: ir::ValueList) {',
-                '}'):
-            with fmt.indented('let args = match *self {', '};'):
-                for f in InstructionFormat.all_formats:
-                    n = 'InstructionData::' + f.name
-                    if f.has_value_list:
-                        fmt.line(n + ' { ref mut args, .. } => args,')
-                fmt.line('_ => panic!("No value list: {:?}", self),')
-            fmt.line(
-                'debug_assert!(args.is_empty(), "Value list already in use");')
-            fmt.line('*args = vlist;')
-        fmt.line()
-
-        fmt.doc_comment(
-                """
-                Compare two `InstructionData` for equality.
-
-                This operation requires a reference to a `ValueListPool` to
-                determine if the contents of any `ValueLists` are equal.
-                """)
-        with fmt.indented(
-                'pub fn eq(&self, other: &Self, pool: &ir::ValueListPool)'
-                ' -> bool {',
-                '}'):
-            with fmt.indented('if ::core::mem::discriminant(self) != '
-                              '::core::mem::discriminant(other) {', '}'):
-                fmt.line('return false;')
-            with fmt.indented('match (self, other) {', '}'):
-                for f in InstructionFormat.all_formats:
-                    n = '&InstructionData::' + f.name
-                    members = ['opcode']
-                    if f.typevar_operand is None:
-                        args_eq = None
-                    elif f.has_value_list:
-                        members.append('args')
-                        args_eq = 'args1.as_slice(pool) == ' \
-                                  'args2.as_slice(pool)'
-                    elif f.num_value_operands == 1:
-                        members.append('arg')
-                        args_eq = 'arg1 == arg2'
-                    else:
-                        members.append('args')
-                        args_eq = 'args1 == args2'
-                    for field in f.imm_fields:
-                        members.append(field.member)
-                    pat1 = ', '.join('{}: ref {}1'.format(x, x)
-                                     for x in members)
-                    pat2 = ', '.join('{}: ref {}2'.format(x, x)
-                                     for x in members)
-                    with fmt.indented('({} {{ {} }}, {} {{ {} }}) => {{'
-                                      .format(n, pat1, n, pat2), '}'):
-                        fmt.line('opcode1 == opcode2')
-                        for field in f.imm_fields:
-                            fmt.line('&& {}1 == {}2'
-                                     .format(field.member, field.member))
-                        if args_eq is not None:
-                            fmt.line('&& {}'.format(args_eq))
-                fmt.line('_ => unreachable!()')
-        fmt.line()
-
-        fmt.doc_comment(
-                """
-                Hash an `InstructionData`.
-
-                This operation requires a reference to a `ValueListPool` to
-                hash the contents of any `ValueLists`.
-                """)
-        with fmt.indented(
-                'pub fn hash<H: ::core::hash::Hasher>'
-                '(&self, state: &mut H, pool: &ir::ValueListPool) {',
-                '}'):
-            with fmt.indented('match *self {', '}'):
-                for f in InstructionFormat.all_formats:
-                    n = 'InstructionData::' + f.name
-                    members = ['opcode']
-                    if f.typevar_operand is None:
-                        args = '&()'
-                    elif f.has_value_list:
-                        members.append('ref args')
-                        args = 'args.as_slice(pool)'
-                    elif f.num_value_operands == 1:
-                        members.append('ref arg')
-                        args = 'arg'
-                    else:
-                        members.append('ref args')
-                        args = 'args'
-                    for field in f.imm_fields:
-                        members.append(field.member)
-                    pat = n + ' { ' + ', '.join(members) + ' }'
-                    with fmt.indented(pat + ' => {', '}'):
-                        fmt.line('::core::hash::Hash::hash( '
-                                 '&::core::mem::discriminant(self), state);')
-                        fmt.line('::core::hash::Hash::hash(&opcode, state);')
-                        for field in f.imm_fields:
-                            fmt.line('::core::hash::Hash::hash(&{}, state);'
-                                     .format(field.member))
-                        fmt.line('::core::hash::Hash::hash({}, state);'
-                                 .format(args))
-
-
-def collect_instr_groups(isas):
-    # type: (Sequence[TargetISA]) -> List[InstructionGroup]
-    seen = set()  # type: Set[InstructionGroup]
-    groups = []
-    for isa in isas:
-        for g in isa.instruction_groups:
-            if g not in seen:
-                groups.append(g)
-                seen.add(g)
-    return groups
-
-
-def gen_opcodes(groups, fmt):
-    # type: (Sequence[InstructionGroup], srcgen.Formatter) -> Sequence[Instruction]  # noqa
-    """
-    Generate opcode enumerations.
-
-    Return a list of all instructions.
-    """
-
-    fmt.doc_comment('''
-                    An instruction opcode.
-
-                    All instructions from all supported ISAs are present.
-                    ''')
-    fmt.line('#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]')
-    instrs = []
-
-    # We explicitly set the discriminant of the first variant to 1, which
-    # allows us to take advantage of the NonZero optimization, meaning that
-    # wrapping enums can use the 0 discriminant instead of increasing the size
-    # of the whole type, and so SIZEOF(Option<Opcode>>) == SIZEOF(Opcode)
-    is_first_opcode = True
-    with fmt.indented('pub enum Opcode {', '}'):
-        for g in groups:
-            for i in g.instructions:
-                instrs.append(i)
-                i.number = len(instrs)
-                fmt.doc_comment('`{}`. ({})'.format(i, i.format.name))
-                # Document polymorphism.
-                if i.is_polymorphic:
-                    if i.use_typevar_operand:
-                        opnum = i.value_opnums[i.format.typevar_operand]
-                        fmt.doc_comment(
-                                'Type inferred from {}.'
-                                .format(i.ins[opnum]))
-                # Enum variant itself.
-                if is_first_opcode:
-                    fmt.line(i.camel_name + ' = 1,')
-                    is_first_opcode = False
-                else:
-                    fmt.line(i.camel_name + ',')
-    fmt.line()
-
-    with fmt.indented('impl Opcode {', '}'):
-        for attr in sorted(Instruction.ATTRIBS.keys()):
-            fmt.doc_comment(Instruction.ATTRIBS[attr])
-            with fmt.indented('pub fn {}(self) -> bool {{'
-                              .format(attr), '}'):
-                m = srcgen.Match('self')
-                for i in instrs:
-                    if getattr(i, attr):
-                        m.arm('Opcode::' + i.camel_name, [], 'true')
-                m.arm('_', [], 'false')
-                fmt.match(m)
-            fmt.line()
-    fmt.line()
-
-    # Generate a private opcode_format table.
-    with fmt.indented(
-            'const OPCODE_FORMAT: [InstructionFormat; {}] = ['
-            .format(len(instrs)),
-            '];'):
-        for i in instrs:
-            fmt.format(
-                    'InstructionFormat::{}, // {}',
-                    i.format.name, i.name)
-    fmt.line()
-
-    # Generate a private opcode_name function.
-    with fmt.indented('fn opcode_name(opc: Opcode) -> &\'static str {', '}'):
-        m = srcgen.Match('opc')
-        for i in instrs:
-            m.arm('Opcode::' + i.camel_name, [], '"{}"'.format(i.name))
-        fmt.match(m)
-    fmt.line()
-
-    # Generate an opcode hash table for looking up opcodes by name.
-    hash_table = constant_hash.compute_quadratic(
-            instrs,
-            lambda i: constant_hash.simple_hash(i.name))
-    with fmt.indented(
-            'const OPCODE_HASH_TABLE: [Option<Opcode>; {}] = ['
-            .format(len(hash_table)), '];'):
-        for i in hash_table:
-            if i is None:
-                fmt.line('None,')
-            else:
-                fmt.format('Some(Opcode::{}),', i.camel_name)
-    fmt.line()
-    return instrs
-
-
-def get_constraint(op, ctrl_typevar, type_sets):
-    # type: (Operand, TypeVar, UniqueTable) -> str
-    """
-    Get the value type constraint for an SSA value operand, where
-    `ctrl_typevar` is the controlling type variable.
-
-    Each operand constraint is represented as a string, one of:
-
-    - `Concrete(vt)`, where `vt` is a value type name.
-    - `Free(idx)` where `idx` is an index into `type_sets`.
-    - `Same`, `Lane`, `AsBool` for controlling typevar-derived constraints.
-    """
-    assert op.is_value()
-    tv = op.typevar
-
-    # A concrete value type.
-    if tv.singleton_type():
-        return 'Concrete({})'.format(tv.singleton_type().rust_name())
-
-    if tv.free_typevar() is not ctrl_typevar:
-        assert not tv.is_derived
-        return 'Free({})'.format(type_sets.add(tv.type_set))
-
-    if tv.is_derived:
-        assert tv.base is ctrl_typevar, "Not derived from ctrl_typevar"
-        return camel_case(tv.derived_func)
-
-    assert tv is ctrl_typevar
-    return 'Same'
-
-
-# TypeSet indexes are encoded in 8 bits, with `0xff` reserved.
-typeset_limit = 0xff
-
-
-def gen_typesets_table(fmt, type_sets):
-    # type: (srcgen.Formatter, UniqueTable) -> None
-    """
-    Generate the table of ValueTypeSets described by type_sets.
-    """
-    if len(type_sets.table) == 0:
-        return
-    fmt.comment('Table of value type sets.')
-    assert len(type_sets.table) <= typeset_limit, "Too many type sets"
-    with fmt.indented(
-            'const TYPE_SETS: [ir::instructions::ValueTypeSet; {}] = ['
-            .format(len(type_sets.table)), '];'):
-        for ts in type_sets.table:
-            with fmt.indented('ir::instructions::ValueTypeSet {', '},'):
-                ts.emit_fields(fmt)
-
-
-def gen_type_constraints(fmt, instrs):
-    # type: (srcgen.Formatter, Sequence[Instruction]) -> None
-    """
-    Generate value type constraints for all instructions.
-
-    - Emit a compact constant table of ValueTypeSet objects.
-    - Emit a compact constant table of OperandConstraint objects.
-    - Emit an opcode-indexed table of instruction constraints.
-
-    """
-
-    # Table of TypeSet instances.
-    type_sets = UniqueTable()
-
-    # Table of operand constraint sequences (as tuples). Each operand
-    # constraint is represented as a string, one of:
-    # - `Concrete(vt)`, where `vt` is a value type name.
-    # - `Free(idx)` where `idx` is an index into `type_sets`.
-    # - `Same`, `Lane`, `AsBool` for controlling typevar-derived constraints.
-    operand_seqs = UniqueSeqTable()
-
-    # Preload table with constraints for typical binops.
-    operand_seqs.add(['Same'] * 3)
-
-    fmt.comment('Table of opcode constraints.')
-    with fmt.indented(
-            'const OPCODE_CONSTRAINTS: [OpcodeConstraints; {}] = ['
-            .format(len(instrs)), '];'):
-        for i in instrs:
-            # Collect constraints for the value results, not including
-            # `variable_args` results which are always special cased.
-            constraints = list()
-            ctrl_typevar = None
-            ctrl_typeset = typeset_limit
-            if i.is_polymorphic:
-                ctrl_typevar = i.ctrl_typevar
-                ctrl_typeset = type_sets.add(ctrl_typevar.type_set)
-            for idx in i.value_results:
-                constraints.append(
-                        get_constraint(i.outs[idx], ctrl_typevar, type_sets))
-            for opnum in i.value_opnums:
-                constraints.append(
-                        get_constraint(i.ins[opnum], ctrl_typevar, type_sets))
-            offset = operand_seqs.add(constraints)
-            fixed_results = len(i.value_results)
-            fixed_values = len(i.value_opnums)
-            # Can the controlling type variable be inferred from the designated
-            # operand?
-            use_typevar_operand = i.is_polymorphic and i.use_typevar_operand
-            # Can the controlling type variable be inferred from the result?
-            use_result = (fixed_results > 0 and
-                          i.outs[i.value_results[0]].typevar == ctrl_typevar)
-            # Are we required to use the designated operand instead of the
-            # result?
-            requires_typevar_operand = use_typevar_operand and not use_result
-            fmt.comment(
-                    '{}: fixed_results={}, use_typevar_operand={}, '
-                    'requires_typevar_operand={}, fixed_values={}'
-                    .format(i.camel_name, fixed_results, use_typevar_operand,
-                            requires_typevar_operand, fixed_values))
-            fmt.comment('Constraints={}'.format(constraints))
-            if i.is_polymorphic:
-                fmt.comment(
-                        'Polymorphic over {}'.format(ctrl_typevar.type_set))
-            # Compute the bit field encoding, c.f. instructions.rs.
-            assert fixed_results < 8, "Bit field encoding too tight"
-            flags = fixed_results
-            if use_typevar_operand:
-                flags |= 8
-            if requires_typevar_operand:
-                flags |= 0x10
-            assert fixed_values < 8, "Bit field encoding too tight"
-            flags |= fixed_values << 5
-
-            with fmt.indented('OpcodeConstraints {', '},'):
-                fmt.line('flags: {:#04x},'.format(flags))
-                fmt.line('typeset_offset: {},'.format(ctrl_typeset))
-                fmt.line('constraint_offset: {},'.format(offset))
-    fmt.line()
-
-    gen_typesets_table(fmt, type_sets)
-    fmt.line()
-
-    fmt.comment('Table of operand constraint sequences.')
-    with fmt.indented(
-            'const OPERAND_CONSTRAINTS: [OperandConstraint; {}] = ['
-            .format(len(operand_seqs.table)), '];'):
-        for c in operand_seqs.table:
-            fmt.line('OperandConstraint::{},'.format(c))
-
-
-def gen_format_constructor(iform, fmt):
-    # type: (InstructionFormat, srcgen.Formatter) -> None
-    """
-    Emit a method for creating and inserting an `iform` instruction, where
-    `iform` is an instruction format.
-
-    All instruction formats take an `opcode` argument and a `ctrl_typevar`
-    argument for deducing the result types.
-    """
-
-    # Construct method arguments.
-    args = ['self', 'opcode: Opcode', 'ctrl_typevar: Type']
-
-    # Normal operand arguments. Start with the immediate operands.
-    for f in iform.imm_fields:
-        args.append('{}: {}'.format(f.member, f.kind.rust_type))
-    # Then the value operands.
-    if iform.has_value_list:
-        # Take all value arguments as a finished value list. The value lists
-        # are created by the individual instruction constructors.
-        args.append('args: ir::ValueList')
-    else:
-        # Take a fixed number of value operands.
-        for i in range(iform.num_value_operands):
-            args.append('arg{}: Value'.format(i))
-
-    proto = '{}({})'.format(iform.name, ', '.join(args))
-    proto += " -> (Inst, &'f mut ir::DataFlowGraph)"
-
-    fmt.doc_comment(str(iform))
-    fmt.line('#[allow(non_snake_case)]')
-    with fmt.indented('fn {} {{'.format(proto), '}'):
-        # Generate the instruction data.
-        with fmt.indented(
-                'let data = ir::InstructionData::{} {{'.format(iform.name),
-                '};'):
-            fmt.line('opcode,')
-            gen_member_inits(iform, fmt)
-
-        fmt.line('self.build(data, ctrl_typevar)')
-
-
-def gen_member_inits(iform, fmt):
-    # type: (InstructionFormat, srcgen.Formatter) -> None
-    """
-    Emit member initializers for an `iform` instruction.
-    """
-
-    # Immediate operands.
-    # We have local variables with the same names as the members.
-    for f in iform.imm_fields:
-        fmt.line('{},'.format(f.member))
-
-    # Value operands.
-    if iform.has_value_list:
-        fmt.line('args,')
-    elif iform.num_value_operands == 1:
-        fmt.line('arg: arg0,')
-    elif iform.num_value_operands > 1:
-        args = ('arg{}'.format(i) for i in range(iform.num_value_operands))
-        fmt.line('args: [{}],'.format(', '.join(args)))
-
-
-def gen_inst_builder(inst, fmt):
-    # type: (Instruction, srcgen.Formatter) -> None
-    """
-    Emit a method for generating the instruction `inst`.
-
-    The method will create and insert an instruction, then return the result
-    values, or the instruction reference itself for instructions that don't
-    have results.
-    """
-
-    # Construct method arguments.
-    if inst.format.has_value_list:
-        args = ['mut self']
-    else:
-        args = ['self']
-
-    # The controlling type variable will be inferred from the input values if
-    # possible. Otherwise, it is the first method argument.
-    if inst.is_polymorphic and not inst.use_typevar_operand:
-        args.append('{}: crate::ir::Type'.format(inst.ctrl_typevar.name))
-
-    tmpl_types = list()  # type: List[str]
-    into_args = list()  # type: List[str]
-    for op in inst.ins:
-        if isinstance(op.kind, ImmediateKind):
-            t = 'T{}{}'.format(1 + len(tmpl_types), op.kind.name)
-            tmpl_types.append('{}: Into<{}>'.format(t, op.kind.rust_type))
-            into_args.append(op.name)
-        else:
-            t = op.kind.rust_type
-        args.append('{}: {}'.format(op.name, t))
-
-    # Return the inst reference for result-less instructions.
-    if len(inst.value_results) == 0:
-        rtype = 'Inst'
-    elif len(inst.value_results) == 1:
-        rtype = 'Value'
-    else:
-        rvals = ', '.join(len(inst.value_results) * ['Value'])
-        rtype = '({})'.format(rvals)
-
-    if len(tmpl_types) > 0:
-        tmpl = '<{}>'.format(', '.join(tmpl_types))
-    else:
-        tmpl = ''
-    proto = '{}{}({}) -> {}'.format(
-            inst.snake_name(), tmpl,  ', '.join(args), rtype)
-
-    fmt.doc_comment('`{}`\n\n{}'.format(inst, inst.blurb()))
-    fmt.line('#[allow(non_snake_case)]')
-    with fmt.indented('fn {} {{'.format(proto), '}'):
-        # Convert all of the `Into<>` arguments.
-        for arg in into_args:
-            fmt.line('let {} = {}.into();'.format(arg, arg))
-
-        # Arguments for instruction constructor.
-        args = ['Opcode::' + inst.camel_name]
-
-        if inst.is_polymorphic and not inst.use_typevar_operand:
-            # This was an explicit method argument.
-            args.append(inst.ctrl_typevar.name)
-        elif not inst.is_polymorphic:
-            # No controlling type variable needed.
-            args.append('types::INVALID')
-        else:
-            assert inst.is_polymorphic and inst.use_typevar_operand
-            # Infer the controlling type variable from the input operands.
-            opnum = inst.value_opnums[inst.format.typevar_operand]
-            fmt.line(
-                    'let ctrl_typevar = self.data_flow_graph().value_type({});'
-                    .format(inst.ins[opnum].name))
-            # The format constructor will resolve the result types from the
-            # type var.
-            args.append('ctrl_typevar')
-
-        # Now add all of the immediate operands to the constructor arguments.
-        for opnum in inst.imm_opnums:
-            args.append(inst.ins[opnum].name)
-
-        # Finally, the value operands.
-        if inst.format.has_value_list:
-            # We need to build a value list with all the arguments.
-            fmt.line('let mut vlist = ir::ValueList::default();')
-            args.append('vlist')
-            with fmt.indented('{', '}'):
-                fmt.line(
-                        'let pool = '
-                        '&mut self.data_flow_graph_mut().value_lists;')
-                for op in inst.ins:
-                    if op.is_value():
-                        fmt.line('vlist.push({}, pool);'.format(op.name))
-                    elif op.is_varargs():
-                        fmt.line(
-                            'vlist.extend({}.iter().cloned(), pool);'
-                            .format(op.name))
-        else:
-            # With no value list, we're guaranteed to just have a set of fixed
-            # value operands.
-            for opnum in inst.value_opnums:
-                args.append(inst.ins[opnum].name)
-
-        # Call to the format constructor,
-        fcall = 'self.{}({})'.format(inst.format.name, ', '.join(args))
-
-        if len(inst.value_results) == 0:
-            fmt.line(fcall + '.0')
-            return
-
-        fmt.line('let (inst, dfg) = {};'.format(fcall))
-
-        if len(inst.value_results) == 1:
-            fmt.line('dfg.first_result(inst)')
-            return
-
-        fmt.format(
-            'let results = &dfg.inst_results(inst)[0..{}];',
-            len(inst.value_results))
-        fmt.format('({})', ', '.join(
-            'results[{}]'.format(i) for i in range(len(inst.value_results))))
-
-
-def gen_builder(insts, fmt):
-    # type: (Sequence[Instruction], srcgen.Formatter) -> None
-    """
-    Generate a Builder trait with methods for all instructions.
-    """
-    fmt.doc_comment("""
-            Convenience methods for building instructions.
-
-            The `InstBuilder` trait has one method per instruction opcode for
-            conveniently constructing the instruction with minimum arguments.
-            Polymorphic instructions infer their result types from the input
-            arguments when possible. In some cases, an explicit `ctrl_typevar`
-            argument is required.
-
-            The opcode methods return the new instruction's result values, or
-            the `Inst` itself for instructions that don't have any results.
-
-            There is also a method per instruction format. These methods all
-            return an `Inst`.
-            """)
-    with fmt.indented(
-            "pub trait InstBuilder<'f>: InstBuilderBase<'f> {",  '}'):
-        for inst in insts:
-            gen_inst_builder(inst, fmt)
-        for f in InstructionFormat.all_formats:
-            gen_format_constructor(f, fmt)
-
-
-def generate(isas, out_dir):
-    # type: (Sequence[TargetISA], str) -> None
-    groups = collect_instr_groups(isas)
-
-    # opcodes.rs
-    fmt = srcgen.Formatter()
-    gen_formats(fmt)
-    gen_instruction_data(fmt)
-    fmt.line()
-    gen_instruction_data_impl(fmt)
-    fmt.line()
-    instrs = gen_opcodes(groups, fmt)
-    gen_type_constraints(fmt, instrs)
-    fmt.update_file('opcodes.rs', out_dir)
-
-    # inst_builder.rs
-    fmt = srcgen.Formatter()
-    gen_builder(instrs, fmt)
-    fmt.update_file('inst_builder.rs', out_dir)
--- a/third_party/rust/cranelift-codegen/meta-python/gen_legalizer.py
+++ b/third_party/rust/cranelift-codegen/meta-python/gen_legalizer.py
@@ -10,30 +10,50 @@ the input instruction.
 from __future__ import absolute_import
 from srcgen import Formatter
 from collections import defaultdict
 from base import instructions
 from cdsl.ast import Var
 from cdsl.ti import ti_rtl, TypeEnv, get_type_env, TypesEqual,\
     InTypeset, WiderOrEq
 from unique_table import UniqueTable
-from gen_instr import gen_typesets_table
 from cdsl.typevar import TypeVar
 
 try:
     from typing import Sequence, List, Dict, Set, DefaultDict # noqa
     from cdsl.isa import TargetISA  # noqa
     from cdsl.ast import Def, VarAtomMap  # noqa
     from cdsl.xform import XForm, XFormGroup  # noqa
     from cdsl.typevar import TypeSet # noqa
     from cdsl.ti import TypeConstraint # noqa
 except ImportError:
     pass
 
 
+# TypeSet indexes are encoded in 8 bits, with `0xff` reserved.
+typeset_limit = 0xff
+
+
+def gen_typesets_table(fmt, type_sets):
+    # type: (Formatter, UniqueTable) -> None
+    """
+    Generate the table of ValueTypeSets described by type_sets.
+    """
+    if len(type_sets.table) == 0:
+        return
+    fmt.comment('Table of value type sets.')
+    assert len(type_sets.table) <= typeset_limit, "Too many type sets"
+    with fmt.indented(
+            'const TYPE_SETS: [ir::instructions::ValueTypeSet; {}] = ['
+            .format(len(type_sets.table)), '];'):
+        for ts in type_sets.table:
+            with fmt.indented('ir::instructions::ValueTypeSet {', '},'):
+                ts.emit_fields(fmt)
+
+
 def get_runtime_typechecks(xform):
     # type: (XForm) -> List[TypeConstraint]
     """
     Given a XForm build a list of runtime type checks necessary to determine
     if it applies. We have 2 types of runtime checks:
         1) typevar tv belongs to typeset T - needed for free tvs whose
                typeset is constrained by their use in the dst pattern
 
--- a/third_party/rust/cranelift-codegen/src/context.rs
+++ b/third_party/rust/cranelift-codegen/src/context.rs
@@ -220,17 +220,17 @@ impl Context {
     pub fn dce<'a, FOI: Into<FlagsOrIsa<'a>>>(&mut self, fisa: FOI) -> CodegenResult<()> {
         do_dce(&mut self.func, &mut self.domtree);
         self.verify_if(fisa)?;
         Ok(())
     }
 
     /// Perform pre-legalization rewrites on the function.
     pub fn preopt(&mut self, isa: &TargetIsa) -> CodegenResult<()> {
-        do_preopt(&mut self.func);
+        do_preopt(&mut self.func, &mut self.cfg);
         self.verify_if(isa)?;
         Ok(())
     }
 
     /// Perform NaN canonicalizing rewrites on the function.
     pub fn canonicalize_nans(&mut self, isa: &TargetIsa) -> CodegenResult<()> {
         do_nan_canonicalization(&mut self.func);
         self.verify_if(isa)
--- a/third_party/rust/cranelift-codegen/src/simple_preopt.rs
+++ b/third_party/rust/cranelift-codegen/src/simple_preopt.rs
@@ -1,20 +1,26 @@
 //! A pre-legalization rewriting pass.
+//!
+//! This module provides early-stage optimizations. The optimizations found
+//! should be useful for already well-optimized code. More general purpose
+//! early-stage optimizations can be found in the preopt crate.
 
 #![allow(non_snake_case)]
 
 use crate::cursor::{Cursor, FuncCursor};
 use crate::divconst_magic_numbers::{magic_s32, magic_s64, magic_u32, magic_u64};
 use crate::divconst_magic_numbers::{MS32, MS64, MU32, MU64};
+use crate::flowgraph::ControlFlowGraph;
+use crate::ir::condcodes::{CondCode, IntCC};
 use crate::ir::dfg::ValueDef;
-use crate::ir::instructions::Opcode;
+use crate::ir::instructions::{Opcode, ValueList};
 use crate::ir::types::{I32, I64};
 use crate::ir::Inst;
-use crate::ir::{DataFlowGraph, Function, InstBuilder, InstructionData, Type, Value};
+use crate::ir::{DataFlowGraph, Ebb, Function, InstBuilder, InstructionData, Type, Value};
 use crate::timing;
 
 //----------------------------------------------------------------------
 //
 // Pattern-match helpers and transformation for div and rem by constants.
 
 // Simple math helpers
 
@@ -531,29 +537,251 @@ fn simplify(pos: &mut FuncCursor, inst: 
                     args[0] = bool_val;
                 }
             }
         }
         _ => {}
     }
 }
 
+struct BranchOptInfo {
+    br_inst: Inst,
+    cmp_arg: Value,
+    args: ValueList,
+    new_opcode: Opcode,
+}
+
+/// Fold comparisons into branch operations when possible.
+///
+/// This matches against operations which compare against zero, then use the
+/// result in a `brz` or `brnz` branch. It folds those two operations into a
+/// single `brz` or `brnz`.
+fn branch_opt(pos: &mut FuncCursor, inst: Inst) {
+    let mut info = if let InstructionData::Branch {
+        opcode: br_opcode,
+        args: ref br_args,
+        ..
+    } = pos.func.dfg[inst]
+    {
+        let first_arg = {
+            let args = pos.func.dfg.inst_args(inst);
+            args[0]
+        };
+
+        let icmp_inst = if let ValueDef::Result(icmp_inst, _) = pos.func.dfg.value_def(first_arg) {
+            icmp_inst
+        } else {
+            return;
+        };
+
+        if let InstructionData::IntCompareImm {
+            opcode: Opcode::IcmpImm,
+            arg: cmp_arg,
+            cond: cmp_cond,
+            imm: cmp_imm,
+        } = pos.func.dfg[icmp_inst]
+        {
+            let cmp_imm: i64 = cmp_imm.into();
+            if cmp_imm != 0 {
+                return;
+            }
+
+            // icmp_imm returns non-zero when the comparison is true. So, if
+            // we're branching on zero, we need to invert the condition.
+            let cond = match br_opcode {
+                Opcode::Brz => cmp_cond.inverse(),
+                Opcode::Brnz => cmp_cond,
+                _ => return,
+            };
+
+            let new_opcode = match cond {
+                IntCC::Equal => Opcode::Brz,
+                IntCC::NotEqual => Opcode::Brnz,
+                _ => return,
+            };
+
+            BranchOptInfo {
+                br_inst: inst,
+                cmp_arg: cmp_arg,
+                args: br_args.clone(),
+                new_opcode: new_opcode,
+            }
+        } else {
+            return;
+        }
+    } else {
+        return;
+    };
+
+    info.args.as_mut_slice(&mut pos.func.dfg.value_lists)[0] = info.cmp_arg;
+    if let InstructionData::Branch { ref mut opcode, .. } = pos.func.dfg[info.br_inst] {
+        *opcode = info.new_opcode;
+    } else {
+        panic!();
+    }
+}
+
+enum BranchOrderKind {
+    BrzToBrnz(Value),
+    BrnzToBrz(Value),
+    InvertIcmpCond(IntCC, Value, Value),
+}
+
+/// Reorder branches to encourage fallthroughs.
+///
+/// When an ebb ends with a conditional branch followed by an unconditional
+/// branch, this will reorder them if one of them is branching to the next Ebb
+/// layout-wise. The unconditional jump can then become a fallthrough.
+fn branch_order(pos: &mut FuncCursor, cfg: &mut ControlFlowGraph, ebb: Ebb, inst: Inst) {
+    let (term_inst, term_inst_args, term_dest, cond_inst, cond_inst_args, cond_dest, kind) =
+        match pos.func.dfg[inst] {
+            InstructionData::Jump {
+                opcode: Opcode::Jump,
+                destination,
+                ref args,
+            } => {
+                let next_ebb = if let Some(next_ebb) = pos.func.layout.next_ebb(ebb) {
+                    next_ebb
+                } else {
+                    return;
+                };
+
+                if destination == next_ebb {
+                    return;
+                }
+
+                let prev_inst = if let Some(prev_inst) = pos.func.layout.prev_inst(inst) {
+                    prev_inst
+                } else {
+                    return;
+                };
+
+                let prev_inst_data = &pos.func.dfg[prev_inst];
+
+                if let Some(prev_dest) = prev_inst_data.branch_destination() {
+                    if prev_dest != next_ebb {
+                        return;
+                    }
+                } else {
+                    return;
+                }
+
+                match prev_inst_data {
+                    InstructionData::Branch {
+                        opcode,
+                        args: ref prev_args,
+                        destination: cond_dest,
+                    } => {
+                        let cond_arg = {
+                            let args = pos.func.dfg.inst_args(prev_inst);
+                            args[0]
+                        };
+
+                        let kind = match opcode {
+                            Opcode::Brz => BranchOrderKind::BrzToBrnz(cond_arg),
+                            Opcode::Brnz => BranchOrderKind::BrnzToBrz(cond_arg),
+                            _ => panic!("unexpected opcode"),
+                        };
+
+                        (
+                            inst,
+                            args.clone(),
+                            destination,
+                            prev_inst,
+                            prev_args.clone(),
+                            *cond_dest,
+                            kind,
+                        )
+                    }
+                    InstructionData::BranchIcmp {
+                        opcode: Opcode::BrIcmp,
+                        cond,
+                        destination: cond_dest,
+                        args: ref prev_args,
+                    } => {
+                        let (x_arg, y_arg) = {
+                            let args = pos.func.dfg.inst_args(prev_inst);
+                            (args[0], args[1])
+                        };
+
+                        (
+                            inst,
+                            args.clone(),
+                            destination,
+                            prev_inst,
+                            prev_args.clone(),
+                            *cond_dest,
+                            BranchOrderKind::InvertIcmpCond(*cond, x_arg, y_arg),
+                        )
+                    }
+                    _ => return,
+                }
+            }
+
+            _ => return,
+        };
+
+    let cond_args = { cond_inst_args.as_slice(&pos.func.dfg.value_lists).to_vec() };
+    let term_args = { term_inst_args.as_slice(&pos.func.dfg.value_lists).to_vec() };
+
+    match kind {
+        BranchOrderKind::BrnzToBrz(cond_arg) => {
+            pos.func
+                .dfg
+                .replace(term_inst)
+                .jump(cond_dest, &cond_args[1..]);
+            pos.func
+                .dfg
+                .replace(cond_inst)
+                .brz(cond_arg, term_dest, &term_args);
+        }
+        BranchOrderKind::BrzToBrnz(cond_arg) => {
+            pos.func
+                .dfg
+                .replace(term_inst)
+                .jump(cond_dest, &cond_args[1..]);
+            pos.func
+                .dfg
+                .replace(cond_inst)
+                .brnz(cond_arg, term_dest, &term_args);
+        }
+        BranchOrderKind::InvertIcmpCond(cond, x_arg, y_arg) => {
+            pos.func
+                .dfg
+                .replace(term_inst)
+                .jump(cond_dest, &cond_args[2..]);
+            pos.func.dfg.replace(cond_inst).br_icmp(
+                cond.inverse(),
+                x_arg,
+                y_arg,
+                term_dest,
+                &term_args,
+            );
+        }
+    }
+
+    cfg.recompute_ebb(pos.func, ebb);
+}
+
 /// The main pre-opt pass.
-pub fn do_preopt(func: &mut Function) {
+pub fn do_preopt(func: &mut Function, cfg: &mut ControlFlowGraph) {
     let _tt = timing::preopt();
     let mut pos = FuncCursor::new(func);
-    while let Some(_ebb) = pos.next_ebb() {
+    while let Some(ebb) = pos.next_ebb() {
         while let Some(inst) = pos.next_inst() {
             // Apply basic simplifications.
             simplify(&mut pos, inst);
 
             //-- BEGIN -- division by constants ----------------
 
             let mb_dri = get_div_info(inst, &pos.func.dfg);
             if let Some(divrem_info) = mb_dri {
                 do_divrem_transformation(&divrem_info, &mut pos, inst);
                 continue;
             }
 
             //-- END -- division by constants ------------------
+
+            branch_opt(&mut pos, inst);
+            branch_order(&mut pos, cfg, ebb, inst);
         }
     }
 }
--- a/third_party/rust/cranelift-codegen/src/verifier/mod.rs
+++ b/third_party/rust/cranelift-codegen/src/verifier/mod.rs
@@ -454,16 +454,25 @@ impl<'a> Verifier<'a> {
                     );
                 }
             }
         }
 
         Ok(())
     }
 
+    fn verify_jump_tables(&self, errors: &mut VerifierErrors) -> VerifierStepResult<()> {
+        for (jt, jt_data) in &self.func.jump_tables {
+            for &ebb in jt_data.iter() {
+                self.verify_ebb(jt, ebb, errors)?;
+            }
+        }
+        Ok(())
+    }
+
     fn ebb_integrity(
         &self,
         ebb: Ebb,
         inst: Inst,
         errors: &mut VerifierErrors,
     ) -> VerifierStepResult<()> {
         let is_terminator = self.func.dfg[inst].opcode().is_terminator();
         let is_last_inst = self.func.layout.last_inst(ebb) == Some(inst);
@@ -601,18 +610,23 @@ impl<'a> Verifier<'a> {
             | BranchIcmp {
                 destination,
                 ref args,
                 ..
             } => {
                 self.verify_ebb(inst, destination, errors)?;
                 self.verify_value_list(inst, args, errors)?;
             }
-            BranchTable { table, .. }
-            | BranchTableBase { table, .. }
+            BranchTable {
+                table, destination, ..
+            } => {
+                self.verify_ebb(inst, destination, errors)?;
+                self.verify_jump_table(inst, table, errors)?;
+            }
+            BranchTableBase { table, .. }
             | BranchTableEntry { table, .. }
             | IndirectJump { table, .. } => {
                 self.verify_jump_table(inst, table, errors)?;
             }
             Call {
                 func_ref, ref args, ..
             } => {
                 self.verify_func_ref(inst, func_ref, errors)?;
@@ -680,26 +694,26 @@ impl<'a> Verifier<'a> {
             | NullAry { .. } => {}
         }
 
         Ok(())
     }
 
     fn verify_ebb(
         &self,
-        inst: Inst,
+        loc: impl Into<AnyEntity>,
         e: Ebb,
         errors: &mut VerifierErrors,
     ) -> VerifierStepResult<()> {
         if !self.func.dfg.ebb_is_valid(e) || !self.func.layout.is_ebb_inserted(e) {
-            return fatal!(errors, inst, "invalid ebb reference {}", e);
+            return fatal!(errors, loc, "invalid ebb reference {}", e);
         }
         if let Some(entry_block) = self.func.layout.entry_block() {
             if e == entry_block {
-                return fatal!(errors, inst, "invalid reference to entry ebb {}", e);
+                return fatal!(errors, loc, "invalid reference to entry ebb {}", e);
             }
         }
         Ok(())
     }
 
     fn verify_sig_ref(
         &self,
         inst: Inst,
@@ -1674,16 +1688,17 @@ impl<'a> Verifier<'a> {
             Ok(())
         }
     }
 
     pub fn run(&self, errors: &mut VerifierErrors) -> VerifierStepResult<()> {
         self.verify_global_values(errors)?;
         self.verify_heaps(errors)?;
         self.verify_tables(errors)?;
+        self.verify_jump_tables(errors)?;
         self.typecheck_entry_block_params(errors)?;
 
         for ebb in self.func.layout.ebbs() {
             for inst in self.func.layout.ebb_insts(ebb) {
                 self.ebb_integrity(ebb, inst, errors)?;
                 self.instruction_integrity(inst, errors)?;
                 self.typecheck(inst, errors)?;
                 self.verify_encoding(inst, errors)?;