Bug 1517752: Update to Cranelift 0.26; r=sunfish
authorBenjamin Bouvier <benj@benj.me>
Fri, 04 Jan 2019 16:19:48 +0100
changeset 509714 9a4aab87dc85ec697a804bd0934bb8ae22908dcd
parent 509713 1b508a44e699f02353c230b7021136bfd18a800c
child 509715 df1b7a886a9d92c035cd11eb816c797e97a1dd1d
push id10547
push userffxbld-merge
push dateMon, 21 Jan 2019 13:03:58 +0000
treeherdermozilla-beta@24ec1916bffe [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssunfish
bugs1517752
milestone66.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 1517752: Update to Cranelift 0.26; r=sunfish
Cargo.lock
js/src/wasm/cranelift/Cargo.toml
js/src/wasm/cranelift/build.rs
js/src/wasm/cranelift/src/lib.rs
js/src/wasm/cranelift/src/wasm2clif.rs
third_party/rust/cast/.cargo-checksum.json
third_party/rust/cast/CHANGELOG.md
third_party/rust/cast/Cargo.toml
third_party/rust/cast/LICENSE-APACHE
third_party/rust/cast/LICENSE-MIT
third_party/rust/cast/README.md
third_party/rust/cast/ci/install.sh
third_party/rust/cast/ci/script.sh
third_party/rust/cast/src/lib.rs
third_party/rust/cast/src/test.rs
third_party/rust/cranelift-bforest/.cargo-checksum.json
third_party/rust/cranelift-bforest/Cargo.toml
third_party/rust/cranelift-bforest/src/lib.rs
third_party/rust/cranelift-codegen-meta/.cargo-checksum.json
third_party/rust/cranelift-codegen-meta/Cargo.toml
third_party/rust/cranelift-codegen-meta/src/base/mod.rs
third_party/rust/cranelift-codegen-meta/src/base/settings.rs
third_party/rust/cranelift-codegen-meta/src/cdsl/isa.rs
third_party/rust/cranelift-codegen-meta/src/cdsl/mod.rs
third_party/rust/cranelift-codegen-meta/src/cdsl/settings.rs
third_party/rust/cranelift-codegen-meta/src/cdsl/types.rs
third_party/rust/cranelift-codegen-meta/src/constant_hash.rs
third_party/rust/cranelift-codegen-meta/src/gen_registers.rs
third_party/rust/cranelift-codegen-meta/src/gen_settings.rs
third_party/rust/cranelift-codegen-meta/src/isa/arm32/mod.rs
third_party/rust/cranelift-codegen-meta/src/isa/arm64/mod.rs
third_party/rust/cranelift-codegen-meta/src/isa/mod.rs
third_party/rust/cranelift-codegen-meta/src/isa/riscv/mod.rs
third_party/rust/cranelift-codegen-meta/src/isa/x86/mod.rs
third_party/rust/cranelift-codegen-meta/src/lib.rs
third_party/rust/cranelift-codegen-meta/src/srcgen.rs
third_party/rust/cranelift-codegen-meta/src/unique_table.rs
third_party/rust/cranelift-codegen/.cargo-checksum.json
third_party/rust/cranelift-codegen/Cargo.toml
third_party/rust/cranelift-codegen/build.rs
third_party/rust/cranelift-codegen/meta-python/base/instructions.py
third_party/rust/cranelift-codegen/meta-python/cdsl/settings.py
third_party/rust/cranelift-codegen/meta-python/check.sh
third_party/rust/cranelift-codegen/meta-python/gen_settings.py
third_party/rust/cranelift-codegen/meta-python/isa/x86/encodings.py
third_party/rust/cranelift-codegen/meta-python/isa/x86/recipes.py
third_party/rust/cranelift-codegen/src/binemit/relaxation.rs
third_party/rust/cranelift-codegen/src/constant_hash.rs
third_party/rust/cranelift-codegen/src/ir/dfg.rs
third_party/rust/cranelift-codegen/src/ir/heap.rs
third_party/rust/cranelift-codegen/src/ir/immediates.rs
third_party/rust/cranelift-codegen/src/ir/memflags.rs
third_party/rust/cranelift-codegen/src/ir/progpoint.rs
third_party/rust/cranelift-codegen/src/ir/table.rs
third_party/rust/cranelift-codegen/src/ir/trapcode.rs
third_party/rust/cranelift-codegen/src/ir/types.rs
third_party/rust/cranelift-codegen/src/isa/call_conv.rs
third_party/rust/cranelift-codegen/src/isa/mod.rs
third_party/rust/cranelift-codegen/src/isa/registers.rs
third_party/rust/cranelift-codegen/src/isa/x86/abi.rs
third_party/rust/cranelift-codegen/src/legalizer/boundary.rs
third_party/rust/cranelift-codegen/src/legalizer/globalvalue.rs
third_party/rust/cranelift-codegen/src/legalizer/heap.rs
third_party/rust/cranelift-codegen/src/legalizer/mod.rs
third_party/rust/cranelift-codegen/src/legalizer/split.rs
third_party/rust/cranelift-codegen/src/legalizer/table.rs
third_party/rust/cranelift-codegen/src/lib.rs
third_party/rust/cranelift-codegen/src/print_errors.rs
third_party/rust/cranelift-codegen/src/regalloc/coloring.rs
third_party/rust/cranelift-codegen/src/regalloc/context.rs
third_party/rust/cranelift-codegen/src/regalloc/liveness.rs
third_party/rust/cranelift-codegen/src/regalloc/register_set.rs
third_party/rust/cranelift-codegen/src/regalloc/reload.rs
third_party/rust/cranelift-codegen/src/regalloc/spilling.rs
third_party/rust/cranelift-codegen/src/regalloc/virtregs.rs
third_party/rust/cranelift-codegen/src/timing.rs
third_party/rust/cranelift-codegen/src/verifier/mod.rs
third_party/rust/cranelift-entity/.cargo-checksum.json
third_party/rust/cranelift-entity/Cargo.toml
third_party/rust/cranelift-entity/src/boxed_slice.rs
third_party/rust/cranelift-entity/src/lib.rs
third_party/rust/cranelift-entity/src/map.rs
third_party/rust/cranelift-entity/src/primary.rs
third_party/rust/cranelift-entity/src/set.rs
third_party/rust/cranelift-entity/src/sparse.rs
third_party/rust/cranelift-frontend/.cargo-checksum.json
third_party/rust/cranelift-frontend/Cargo.toml
third_party/rust/cranelift-frontend/src/frontend.rs
third_party/rust/cranelift-frontend/src/lib.rs
third_party/rust/cranelift-frontend/src/ssa.rs
third_party/rust/cranelift-wasm/.cargo-checksum.json
third_party/rust/cranelift-wasm/Cargo.toml
third_party/rust/cranelift-wasm/src/code_translator.rs
third_party/rust/cranelift-wasm/src/environ/dummy.rs
third_party/rust/cranelift-wasm/src/environ/spec.rs
third_party/rust/cranelift-wasm/src/lib.rs
third_party/rust/cranelift-wasm/src/sections_translator.rs
third_party/rust/cranelift-wasm/src/state.rs
third_party/rust/cranelift-wasm/src/translation_utils.rs
third_party/rust/cranelift-wasm/tests/wasm_testsuite.rs
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -156,18 +156,18 @@ dependencies = [
  "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "baldrdash"
 version = "0.1.0"
 dependencies = [
  "bindgen 0.43.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "cranelift-codegen 0.25.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "cranelift-wasm 0.25.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cranelift-codegen 0.26.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cranelift-wasm 0.26.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "env_logger 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "target-lexicon 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "base64"
 version = "0.10.0"
@@ -348,16 +348,21 @@ name = "bzip2-sys"
 version = "0.1.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cc 1.0.23 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
+name = "cast"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
 name = "cc"
 version = "1.0.23"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "cexpr"
 version = "0.3.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -475,67 +480,68 @@ name = "cose-c"
 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.25.0"
+version = "0.26.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cranelift-entity 0.25.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cranelift-entity 0.26.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "cranelift-codegen"
-version = "0.25.0"
+version = "0.26.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cranelift-bforest 0.25.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "cranelift-codegen-meta 0.25.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "cranelift-entity 0.25.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cranelift-bforest 0.26.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cranelift-codegen-meta 0.26.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cranelift-entity 0.26.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "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.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "target-lexicon 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "cranelift-codegen-meta"
-version = "0.25.0"
+version = "0.26.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cranelift-entity 0.25.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cranelift-entity 0.26.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "cranelift-entity"
-version = "0.25.0"
+version = "0.26.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "cranelift-frontend"
-version = "0.25.0"
+version = "0.26.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cranelift-codegen 0.25.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cranelift-codegen 0.26.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "target-lexicon 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "cranelift-wasm"
-version = "0.25.0"
+version = "0.26.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cranelift-codegen 0.25.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "cranelift-entity 0.25.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "cranelift-frontend 0.25.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cast 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cranelift-codegen 0.26.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cranelift-entity 0.26.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cranelift-frontend 0.26.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "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.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "wasmparser 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "crc"
@@ -3194,37 +3200,38 @@ dependencies = [
 "checksum boxfnonce 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8380105befe91099e6f69206164072c05bc92427ff6aa8a5171388317346dd75"
 "checksum build_const 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e90dc84f5e62d2ebe7676b83c22d33b6db8bd27340fb6ffbff0a364efa0cb9c9"
 "checksum byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "560c32574a12a89ecd91f5e742165893f86e3ab98d21f8ea548658eb9eef5f40"
 "checksum byte-tools 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "980479e6fde23246dfb54d47580d66b4e99202e7579c5eaa9fe10ecb5ebd2182"
 "checksum byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "94f88df23a25417badc922ab0f5716cc1330e87f71ddd9203b3a3ccd9cedf75d"
 "checksum bytes 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e178b8e0e239e844b083d5a0d4a156b2654e67f9f80144d48398fcd736a24fb8"
 "checksum bzip2 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c3eafc42c44e0d827de6b1c131175098fe7fb53b8ce8a47e65cb3ea94688be24"
 "checksum bzip2-sys 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2c5162604199bbb17690ede847eaa6120a3f33d5ab4dcc8e7c25b16d849ae79b"
+"checksum cast 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "926013f2860c46252efceabb19f4a6b308197505082c609025aa6706c011d427"
 "checksum cc 1.0.23 (registry+https://github.com/rust-lang/crates.io-index)" = "c37f0efaa4b9b001fa6f02d4b644dee4af97d3414df07c51e3e4f015f3a3e131"
 "checksum cexpr 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8fc0086be9ca82f7fc89fc873435531cb898b86e850005850de1f820e2db6e9b"
 "checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de"
 "checksum chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "45912881121cb26fad7c38c17ba7daa18764771836b34fab7d3fbd93ed633878"
 "checksum clang-sys 0.26.1 (registry+https://github.com/rust-lang/crates.io-index)" = "481e42017c1416b1c0856ece45658ecbb7c93d8a93455f7e5fa77f3b35455557"
 "checksum clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f0f16b89cbb9ee36d87483dc939fe9f1e13c05898d56d7b230a0d4dff033a536"
 "checksum cmake 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)" = "56d741ea7a69e577f6d06b36b7dff4738f680593dc27a701ffa8506b73ce28bb"
 "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.25.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b2d527b241af388ff017d72f2b0b323929a70cf97342c6ec1534e3b0f4dfaa0"
-"checksum cranelift-codegen 0.25.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e92fa0fa287cf00a6739c46aba114957e0a8eeeb4f0d1aa65d6ed0699c34ca6b"
-"checksum cranelift-codegen-meta 0.25.0 (registry+https://github.com/rust-lang/crates.io-index)" = "963262697a05d9aa63ca40f4670a7243e4525f4a098e10d654c3f5143fcef686"
-"checksum cranelift-entity 0.25.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc9a0329208e5e0d7d4d6e64cd50985d4c4cbfdbeeb594ae2157a094b98e8dcc"
-"checksum cranelift-frontend 0.25.0 (registry+https://github.com/rust-lang/crates.io-index)" = "98d9eb4a2343435d520499236c805725c88d6d55eefb9a6ad0819b7970c76bdd"
-"checksum cranelift-wasm 0.25.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5022a3a3d1044fdc8c97909b5e8d701884982dcfb43885034d004cfdd9b7d577"
+"checksum cranelift-bforest 0.26.0 (registry+https://github.com/rust-lang/crates.io-index)" = "40f8ff24e9a6c89b8a846b14df9a34d2cac17cea7bdb5c81ed6b4744ee0e38bf"
+"checksum cranelift-codegen 0.26.0 (registry+https://github.com/rust-lang/crates.io-index)" = "42f5b809bd885c368e01aeec8fe04f21dcb07569834b907d75b4a7bed8d067eb"
+"checksum cranelift-codegen-meta 0.26.0 (registry+https://github.com/rust-lang/crates.io-index)" = "014c23ed3ebdc8377d41540af638245207dd169f421df042dfccc867465734ed"
+"checksum cranelift-entity 0.26.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d4df40e26c0cf7b4d86919cb995bb412ee3001cc18e4f3c83a903f30b7007d8b"
+"checksum cranelift-frontend 0.26.0 (registry+https://github.com/rust-lang/crates.io-index)" = "789907218eeebebcea8122c2053d71affac91c96ce72cea35ebfdbbf547e82af"
+"checksum cranelift-wasm 0.26.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49723365dab9a48b354bdc24cb6d9d5719bc1d3b858ffd2ea179d0d7d885804a"
 "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 cssparser 0.25.0 (registry+https://github.com/rust-lang/crates.io-index)" = "730363a45c4e248d4f21d3e5c1156d1a9cdec0855056c0d9539e814bc59865c3"
--- a/js/src/wasm/cranelift/Cargo.toml
+++ b/js/src/wasm/cranelift/Cargo.toml
@@ -3,20 +3,20 @@ name = "baldrdash"
 version = "0.1.0"
 authors = ["The Spidermonkey and Cranelift developers"]
 
 [lib]
 crate-type = ["rlib"]
 name = "baldrdash"
 
 [dependencies]
-cranelift-codegen = "0.25.0"
-cranelift-wasm = "0.25.0"
+cranelift-codegen = "0.26.0"
+cranelift-wasm = "0.26.0"
 target-lexicon = "0.2.0"
-log = { version = "0.4.4", default-features = false, features = ["release_max_level_info"] }
+log = { version = "0.4.5", default-features = false, features = ["release_max_level_info"] }
 env_logger = "0.5.6"
 
 [build-dependencies]
 bindgen = {version = "0.43", default-features = false} # disable `logging` to reduce code size
 
 # Uncomment this to enable perf support in release mode.
 #[profile.release]
 #debug = true
--- a/js/src/wasm/cranelift/build.rs
+++ b/js/src/wasm/cranelift/build.rs
@@ -43,17 +43,18 @@ fn main() {
         .whitelist_type("BD_.*|Trap|TypeCode|FuncTypeIdDescKind")
         .header("baldrapi.h")
         .clang_args(&[
             "-x",
             "c++",
             "-std=gnu++14",
             "-fno-sized-deallocation",
             "-DRUST_BINDGEN",
-        ]).clang_arg("-I../..");
+        ])
+        .clang_arg("-I../..");
 
     match env::var_os("MOZ_TOPOBJDIR") {
         Some(path) => {
             let path = PathBuf::from(path).join("js/src/rust/extra-bindgen-flags");
 
             let mut extra_flags = String::new();
             File::open(&path)
                 .expect("Failed to open extra-bindgen-flags file")
--- a/js/src/wasm/cranelift/src/lib.rs
+++ b/js/src/wasm/cranelift/src/lib.rs
@@ -16,21 +16,21 @@
 extern crate cranelift_codegen;
 extern crate cranelift_wasm;
 #[macro_use]
 extern crate target_lexicon;
 #[macro_use]
 extern crate log;
 extern crate env_logger;
 
-mod baldrapi;  // Low-level C API, ignore this.
+mod baldrapi; // Low-level C API, ignore this.
 mod baldrdash; // High-level Rust API, use this.
-mod compile;   // Cranelift function compiler.
-mod cpu;       // CPU detection and `TargetISA` configuration.
-mod utils;     // Helpers for other source files.
+mod compile; // Cranelift function compiler.
+mod cpu; // CPU detection and `TargetISA` configuration.
+mod utils; // Helpers for other source files.
 mod wasm2clif; // WebAssembly to Cranelift translation callbacks.
 
 use baldrdash::{CompiledFunc, FuncCompileInput, ModuleEnvironment, StaticEnvironment};
 use compile::BatchCompiler;
 use std::ptr;
 
 #[no_mangle]
 pub extern "C" fn cranelift_initialize() {
--- a/js/src/wasm/cranelift/src/wasm2clif.rs
+++ b/js/src/wasm/cranelift/src/wasm2clif.rs
@@ -57,16 +57,21 @@ fn offset32(offset: usize) -> ir::immedi
     (offset as i32).into()
 }
 
 /// Convert a usize offset into a `Imm64` for an iadd_imm.
 fn imm64(offset: usize) -> ir::immediates::Imm64 {
     (offset as i64).into()
 }
 
+/// Convert a usize offset into a `Uimm64`.
+fn uimm64(offset: usize) -> ir::immediates::Uimm64 {
+    (offset as u64).into()
+}
+
 /// Initialize a `Signature` from a wasm signature.
 fn init_sig_from_wsig(sig: &mut ir::Signature, wsig: bd::FuncTypeWithId) {
     sig.clear(CallConv::Baldrdash);
     for &arg in wsig.args() {
         sig.params.push(ir::AbiParam::new(arg.into()));
     }
 
     if let Some(ret_type) = wsig.ret_type().into() {
@@ -296,27 +301,29 @@ impl<'a, 'b, 'c> TransEnv<'a, 'b, 'c> {
         if self.cx_addr.is_none() {
             let vmctx = self.get_vmctx_gv(&mut pos.func);
             self.cx_addr = pos
                 .func
                 .create_global_value(ir::GlobalValueData::IAddImm {
                     base: vmctx,
                     offset: imm64(self.static_env.cxTlsOffset),
                     global_type: native_pointer_type(),
-                }).into();
+                })
+                .into();
         }
         if self.realm_addr.is_none() {
             let vmctx = self.get_vmctx_gv(&mut pos.func);
             self.realm_addr = pos
                 .func
                 .create_global_value(ir::GlobalValueData::IAddImm {
                     base: vmctx,
                     offset: imm64(self.static_env.realmTlsOffset),
                     global_type: native_pointer_type(),
-                }).into();
+                })
+                .into();
         }
 
         let ptr = native_pointer_type();
         let mut flags = ir::MemFlags::new();
         flags.set_aligned();
         flags.set_notrap();
 
         let cx_addr_val = pos.ins().global_value(ptr, self.cx_addr.unwrap());
@@ -384,83 +391,79 @@ impl<'a, 'b, 'c> FuncEnvironment for Tra
     fn make_global(&mut self, func: &mut ir::Function, index: GlobalIndex) -> GlobalVariable {
         let global = self.env.global(index);
         if global.is_constant() {
             // Constant globals have a known value at compile time. We insert an instruction to
             // materialize the constant at the front of the entry block.
             let mut pos = FuncCursor::new(func);
             pos.next_ebb().expect("empty function");
             pos.next_inst();
-            GlobalVariable::Const(global.emit_constant(&mut pos))
-        } else {
-            // This is a global variable. Here we don't care if it is mutable or not.
-            let offset = global.tls_offset();
-            let mut gv = self.get_vmctx_gv(func);
+            return GlobalVariable::Const(global.emit_constant(&mut pos));
+        }
+
+        // This is a global variable. Here we don't care if it is mutable or not.
+        let vmctx_gv = self.get_vmctx_gv(func);
+        let offset = global.tls_offset();
 
-            // Some globals are represented as a pointer to the actual data, in which case we
-            // must do an extra dereference to get to them.
-            if global.is_indirect() {
-                gv = func.create_global_value(ir::GlobalValueData::Load {
-                    base: gv,
-                    offset: offset32(offset),
-                    global_type: native_pointer_type(),
-                    readonly: false,
-                });
-            } else {
-                gv = func.create_global_value(ir::GlobalValueData::IAddImm {
-                    base: gv,
-                    offset: imm64(offset),
-                    global_type: native_pointer_type(),
-                });
-            }
+        // Some globals are represented as a pointer to the actual data, in which case we
+        // must do an extra dereference to get to them.
+        let (base_gv, offset) = if global.is_indirect() {
+            let gv = func.create_global_value(ir::GlobalValueData::Load {
+                base: vmctx_gv,
+                offset: offset32(offset),
+                global_type: native_pointer_type(),
+                readonly: false,
+            });
+            (gv, 0.into())
+        } else {
+            (vmctx_gv, offset32(offset))
+        };
 
-            // Create a Cranelift global variable. We don't need to remember the reference, the
-            // function translator does that for us.
-            GlobalVariable::Memory {
-                gv,
-                ty: global.value_type().into(),
-            }
+        GlobalVariable::Memory {
+            gv: base_gv,
+            ty: global.value_type().into(),
+            offset,
         }
     }
 
     fn make_heap(&mut self, func: &mut ir::Function, index: MemoryIndex) -> ir::Heap {
         assert_eq!(index.index(), 0, "Only one WebAssembly memory supported");
         // Get the address of the `TlsData::memoryBase` field.
         let base_addr = self.get_vmctx_gv(func);
         // Get the `TlsData::memoryBase` field. We assume this is never modified during execution
         // of the function.
         let base = func.create_global_value(ir::GlobalValueData::Load {
             base: base_addr,
             offset: offset32(0),
             global_type: native_pointer_type(),
             readonly: true,
         });
-        let min_size = ir::immediates::Imm64::new(self.env.min_memory_length());
-        let guard_size = imm64(self.static_env.memoryGuardSize);
+        let min_size = ir::immediates::Uimm64::new(self.env.min_memory_length() as u64);
+        let guard_size = uimm64(self.static_env.memoryGuardSize);
 
         let bound = self.static_env.staticMemoryBound;
         let style = if bound > 0 {
             // We have a static heap.
-            let bound = (bound as i64).into();
+            let bound = (bound as u64).into();
             ir::HeapStyle::Static { bound }
         } else {
             // Get the `TlsData::boundsCheckLimit` field.
             let bound_gv = func.create_global_value(ir::GlobalValueData::Load {
                 base: base_addr,
                 offset: native_pointer_size().into(),
                 global_type: ir::types::I32,
                 readonly: false,
             });
             ir::HeapStyle::Dynamic { bound_gv }
         };
 
         func.create_heap(ir::HeapData {
             base,
             min_size,
-            guard_size,
+            offset_guard_size: guard_size,
             style,
             index_type: ir::types::I32,
         })
     }
 
     fn make_indirect_sig(&mut self, func: &mut ir::Function, index: SignatureIndex) -> ir::SigRef {
         let mut sigdata = ir::Signature::new(CallConv::Baldrdash);
         let wsig = self.env.signature(index);
@@ -493,19 +496,19 @@ impl<'a, 'b, 'c> FuncEnvironment for Tra
             base: table_desc.global,
             offset: offset32(native_pointer_size() as usize),
             global_type: native_pointer_type(),
             readonly: false,
         });
 
         func.create_table(ir::TableData {
             base_gv,
-            min_size: ir::immediates::Imm64::new(0),
+            min_size: ir::immediates::Uimm64::new(0),
             bound_gv,
-            element_size: ir::immediates::Imm64::new(i64::from(self.pointer_bytes()) * 2),
+            element_size: ir::immediates::Uimm64::new(u64::from(self.pointer_bytes()) * 2),
             index_type: ir::types::I32,
         })
     }
 
     fn make_direct_func(&mut self, func: &mut ir::Function, index: FuncIndex) -> ir::FuncRef {
         // Create a signature.
         let mut sigdata = ir::Signature::new(CallConv::Baldrdash);
         init_sig(&mut sigdata, &self.env, index);
new file mode 100644
--- /dev/null
+++ b/third_party/rust/cast/.cargo-checksum.json
@@ -0,0 +1,1 @@
+{"files":{"CHANGELOG.md":"b24b688b552ea12f4ef03b2c76e17ecfb8c05104d4f494c47b698fd7d94d3e3a","Cargo.toml":"3908d7c2421a4071d3fdd4a7c7a44c1c8779cf9d229cec307fd1a2b96398aa60","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"005b3f9b4687364514bbaea2a25e96d54ce6a59277d157386e8259cbcae8e095","README.md":"006ae145ee89fa14a9d755b206ec2011a3687408e9d5fe3943f2448767b01d62","ci/install.sh":"f3965bda34345579d0799ca2e581efd7ae51f3191aa9203b018f4ade8b986b15","ci/script.sh":"0f8329c7345731c12f35a392e8deeb2e265b75f107c5aca6eed584096896737f","src/lib.rs":"52418274bc4ec5c59dba1885de7324157e677739a2c9624b5d462d5d4c77b5e3","src/test.rs":"58ea38d755d5eae72b1df29fc602483fef888a111bb2e9c3a219e2b2a1ed222f"},"package":"926013f2860c46252efceabb19f4a6b308197505082c609025aa6706c011d427"}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/third_party/rust/cast/CHANGELOG.md
@@ -0,0 +1,42 @@
+# Change Log
+
+All notable changes to this project will be documented in this file.
+
+The format is based on [Keep a Changelog](http://keepachangelog.com/)
+and this project adheres to [Semantic Versioning](http://semver.org/).
+
+## [Unreleased]
+
+## [v0.2.2] - 2017-05-07
+
+### Fixed
+
+- UB in the checked cast from `f32` to `u128`.
+
+## [v0.2.1] - 2017-05-06
+
+### Added
+
+- Support for 128-bit integers, behind the `x128` Cargo feature (nightly
+  needed).
+
+## [v0.2.0] - 2017-02-08
+
+### Added
+
+- Now `cast::Error` implements the `std::error::Error` trait among other traits
+  like `Display`, `Clone`, etc.
+
+### Changed
+
+- [breaking-change] This crate now depends on the `std` crate by default but you
+  can make it `no_std` by opting out of the `std` Cargo feature.
+
+## v0.1.0 - 2016-02-07
+
+Initial release
+
+[Unreleased]: https://github.com/japaric/cast.rs/compare/v0.2.2...HEAD
+[v0.2.2]: https://github.com/japaric/cast.rs/compare/v0.2.1...v0.2.2
+[v0.2.1]: https://github.com/japaric/cast.rs/compare/v0.2.0...v0.2.1
+[v0.2.0]: https://github.com/japaric/cast.rs/compare/v0.1.0...v0.2.0
new file mode 100644
--- /dev/null
+++ b/third_party/rust/cast/Cargo.toml
@@ -0,0 +1,21 @@
+[package]
+authors = ["Jorge Aparicio <jorge@japaric.io>"]
+description = "Ergonomic, checked cast functions for primitive types"
+documentation = "https://docs.rs/cast"
+keywords = ["checked", "cast", "primitive", "integer", "float"]
+license = "MIT OR Apache-2.0"
+name = "cast"
+repository = "https://github.com/japaric/cast.rs"
+version = "0.2.2"
+
+[features]
+# Assume we should use `std` unless asked to do otherwise.
+default = ["std"]
+# Enable this to get a std::error::Error impl for convenient use with other
+# libraries.
+std = []
+# Enable this for i128/u128 support
+x128 = []
+
+[dev-dependencies]
+quickcheck = "0.4.1"
new file mode 100644
--- /dev/null
+++ b/third_party/rust/cast/LICENSE-APACHE
@@ -0,0 +1,201 @@
+                              Apache License
+                        Version 2.0, January 2004
+                     http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+   "License" shall mean the terms and conditions for use, reproduction,
+   and distribution as defined by Sections 1 through 9 of this document.
+
+   "Licensor" shall mean the copyright owner or entity authorized by
+   the copyright owner that is granting the License.
+
+   "Legal Entity" shall mean the union of the acting entity and all
+   other entities that control, are controlled by, or are under common
+   control with that entity. For the purposes of this definition,
+   "control" means (i) the power, direct or indirect, to cause the
+   direction or management of such entity, whether by contract or
+   otherwise, or (ii) ownership of fifty percent (50%) or more of the
+   outstanding shares, or (iii) beneficial ownership of such entity.
+
+   "You" (or "Your") shall mean an individual or Legal Entity
+   exercising permissions granted by this License.
+
+   "Source" form shall mean the preferred form for making modifications,
+   including but not limited to software source code, documentation
+   source, and configuration files.
+
+   "Object" form shall mean any form resulting from mechanical
+   transformation or translation of a Source form, including but
+   not limited to compiled object code, generated documentation,
+   and conversions to other media types.
+
+   "Work" shall mean the work of authorship, whether in Source or
+   Object form, made available under the License, as indicated by a
+   copyright notice that is included in or attached to the work
+   (an example is provided in the Appendix below).
+
+   "Derivative Works" shall mean any work, whether in Source or Object
+   form, that is based on (or derived from) the Work and for which the
+   editorial revisions, annotations, elaborations, or other modifications
+   represent, as a whole, an original work of authorship. For the purposes
+   of this License, Derivative Works shall not include works that remain
+   separable from, or merely link (or bind by name) to the interfaces of,
+   the Work and Derivative Works thereof.
+
+   "Contribution" shall mean any work of authorship, including
+   the original version of the Work and any modifications or additions
+   to that Work or Derivative Works thereof, that is intentionally
+   submitted to Licensor for inclusion in the Work by the copyright owner
+   or by an individual or Legal Entity authorized to submit on behalf of
+   the copyright owner. For the purposes of this definition, "submitted"
+   means any form of electronic, verbal, or written communication sent
+   to the Licensor or its representatives, including but not limited to
+   communication on electronic mailing lists, source code control systems,
+   and issue tracking systems that are managed by, or on behalf of, the
+   Licensor for the purpose of discussing and improving the Work, but
+   excluding communication that is conspicuously marked or otherwise
+   designated in writing by the copyright owner as "Not a Contribution."
+
+   "Contributor" shall mean Licensor and any individual or Legal Entity
+   on behalf of whom a Contribution has been received by Licensor and
+   subsequently incorporated within the Work.
+
+2. Grant of Copyright License. Subject to the terms and conditions of
+   this License, each Contributor hereby grants to You a perpetual,
+   worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+   copyright license to reproduce, prepare Derivative Works of,
+   publicly display, publicly perform, sublicense, and distribute the
+   Work and such Derivative Works in Source or Object form.
+
+3. Grant of Patent License. Subject to the terms and conditions of
+   this License, each Contributor hereby grants to You a perpetual,
+   worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+   (except as stated in this section) patent license to make, have made,
+   use, offer to sell, sell, import, and otherwise transfer the Work,
+   where such license applies only to those patent claims licensable
+   by such Contributor that are necessarily infringed by their
+   Contribution(s) alone or by combination of their Contribution(s)
+   with the Work to which such Contribution(s) was submitted. If You
+   institute patent litigation against any entity (including a
+   cross-claim or counterclaim in a lawsuit) alleging that the Work
+   or a Contribution incorporated within the Work constitutes direct
+   or contributory patent infringement, then any patent licenses
+   granted to You under this License for that Work shall terminate
+   as of the date such litigation is filed.
+
+4. Redistribution. You may reproduce and distribute copies of the
+   Work or Derivative Works thereof in any medium, with or without
+   modifications, and in Source or Object form, provided that You
+   meet the following conditions:
+
+   (a) You must give any other recipients of the Work or
+       Derivative Works a copy of this License; and
+
+   (b) You must cause any modified files to carry prominent notices
+       stating that You changed the files; and
+
+   (c) You must retain, in the Source form of any Derivative Works
+       that You distribute, all copyright, patent, trademark, and
+       attribution notices from the Source form of the Work,
+       excluding those notices that do not pertain to any part of
+       the Derivative Works; and
+
+   (d) If the Work includes a "NOTICE" text file as part of its
+       distribution, then any Derivative Works that You distribute must
+       include a readable copy of the attribution notices contained
+       within such NOTICE file, excluding those notices that do not
+       pertain to any part of the Derivative Works, in at least one
+       of the following places: within a NOTICE text file distributed
+       as part of the Derivative Works; within the Source form or
+       documentation, if provided along with the Derivative Works; or,
+       within a display generated by the Derivative Works, if and
+       wherever such third-party notices normally appear. The contents
+       of the NOTICE file are for informational purposes only and
+       do not modify the License. You may add Your own attribution
+       notices within Derivative Works that You distribute, alongside
+       or as an addendum to the NOTICE text from the Work, provided
+       that such additional attribution notices cannot be construed
+       as modifying the License.
+
+   You may add Your own copyright statement to Your modifications and
+   may provide additional or different license terms and conditions
+   for use, reproduction, or distribution of Your modifications, or
+   for any such Derivative Works as a whole, provided Your use,
+   reproduction, and distribution of the Work otherwise complies with
+   the conditions stated in this License.
+
+5. Submission of Contributions. Unless You explicitly state otherwise,
+   any Contribution intentionally submitted for inclusion in the Work
+   by You to the Licensor shall be under the terms and conditions of
+   this License, without any additional terms or conditions.
+   Notwithstanding the above, nothing herein shall supersede or modify
+   the terms of any separate license agreement you may have executed
+   with Licensor regarding such Contributions.
+
+6. Trademarks. This License does not grant permission to use the trade
+   names, trademarks, service marks, or product names of the Licensor,
+   except as required for reasonable and customary use in describing the
+   origin of the Work and reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty. Unless required by applicable law or
+   agreed to in writing, Licensor provides the Work (and each
+   Contributor provides its Contributions) on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+   implied, including, without limitation, any warranties or conditions
+   of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+   PARTICULAR PURPOSE. You are solely responsible for determining the
+   appropriateness of using or redistributing the Work and assume any
+   risks associated with Your exercise of permissions under this License.
+
+8. Limitation of Liability. In no event and under no legal theory,
+   whether in tort (including negligence), contract, or otherwise,
+   unless required by applicable law (such as deliberate and grossly
+   negligent acts) or agreed to in writing, shall any Contributor be
+   liable to You for damages, including any direct, indirect, special,
+   incidental, or consequential damages of any character arising as a
+   result of this License or out of the use or inability to use the
+   Work (including but not limited to damages for loss of goodwill,
+   work stoppage, computer failure or malfunction, or any and all
+   other commercial damages or losses), even if such Contributor
+   has been advised of the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability. While redistributing
+   the Work or Derivative Works thereof, You may choose to offer,
+   and charge a fee for, acceptance of support, warranty, indemnity,
+   or other liability obligations and/or rights consistent with this
+   License. However, in accepting such obligations, You may act only
+   on Your own behalf and on Your sole responsibility, not on behalf
+   of any other Contributor, and only if You agree to indemnify,
+   defend, and hold each Contributor harmless for any liability
+   incurred by, or claims asserted against, such Contributor by reason
+   of your accepting any such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work.
+
+   To apply the Apache License to your work, attach the following
+   boilerplate notice, with the fields enclosed by brackets "[]"
+   replaced with your own identifying information. (Don't include
+   the brackets!)  The text should be enclosed in the appropriate
+   comment syntax for the file format. We also recommend that a
+   file or class name and description of purpose be included on the
+   same "printed page" as the copyright notice for easier
+   identification within third-party archives.
+
+Copyright [yyyy] [name of copyright owner]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+	http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
new file mode 100644
--- /dev/null
+++ b/third_party/rust/cast/LICENSE-MIT
@@ -0,0 +1,25 @@
+Copyright (c) 2014-2017 Jorge Aparicio
+
+Permission is hereby granted, free of charge, to any
+person obtaining a copy of this software and associated
+documentation files (the "Software"), to deal in the
+Software without restriction, including without
+limitation the rights to use, copy, modify, merge,
+publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software
+is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice
+shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
+ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
+IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
new file mode 100644
--- /dev/null
+++ b/third_party/rust/cast/README.md
@@ -0,0 +1,44 @@
+[![crates.io](https://img.shields.io/crates/d/cast.svg)](https://crates.io/crates/cast)
+[![crates.io](https://img.shields.io/crates/v/cast.svg)](https://crates.io/crates/cast)
+
+# `cast`
+
+> Ergonomic, checked cast functions for primitive types
+
+``` rust
+extern crate cast;
+
+// `u8` and `u16` are checked cast functions, use them to cast from any numeric
+// primitive to `u8`/`u16` respectively
+use cast::{u8, u16, Error};
+
+// Infallible operations, like integer promotion, are equivalent to a normal
+// cast with `as`
+assert_eq!(u16(0u8), 0u16);
+
+// Everything else will return a `Result` depending on the success of the
+// operation
+assert_eq!(u8(0u16), Ok(0u8));
+assert_eq!(u8(256u16), Err(Error::Overflow));
+assert_eq!(u8(-1i8), Err(Error::Underflow));
+assert_eq!(u8(1. / 0.), Err(Error::Infinite));
+assert_eq!(u8(0. / 0.), Err(Error::NaN));
+```
+
+## [API docs](https://docs.rs/cast)
+
+## License
+
+Licensed under either of
+
+- Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or
+  http://www.apache.org/licenses/LICENSE-2.0)
+- MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
+
+at your option.
+
+### Contribution
+
+Unless you explicitly state otherwise, any contribution intentionally submitted
+for inclusion in the work by you, as defined in the Apache-2.0 license, shall be
+dual licensed as above, without any additional terms or conditions.
new file mode 100644
--- /dev/null
+++ b/third_party/rust/cast/ci/install.sh
@@ -0,0 +1,21 @@
+set -ex
+
+main() {
+    curl https://sh.rustup.rs -sSf | \
+        sh -s -- -y --default-toolchain $TRAVIS_RUST_VERSION
+
+    local latest=$(git ls-remote --tags --refs --exit-code https://github.com/japaric/cross \
+                       | cut -d/ -f3 \
+                       | grep -E '^v[0-9.]+$' \
+                       | sort --version-sort \
+                       | tail -n1)
+
+    curl -LSfs https://japaric.github.io/trust/install.sh | \
+        sh -s -- \
+           --force \
+           --git japaric/cross \
+           --tag $latest \
+           --target x86_64-unknown-linux-gnu
+}
+
+main
new file mode 100644
--- /dev/null
+++ b/third_party/rust/cast/ci/script.sh
@@ -0,0 +1,14 @@
+set -ex
+
+main() {
+    cross test --target $TARGET
+    cross test --target $TARGET --release
+
+    [ "$TRAVIS_RUST_VERSION" -eq "nightly" ] && cross test --feature x128 --target $TARGET
+    [ "$TRAVIS_RUST_VERSION" -eq "nightly" ] && cross test --feature x128 --target $TARGET --release
+
+    cross test --no-default-features --target $TARGET
+    cross test --no-default-features --target $TARGET --release
+}
+
+main
new file mode 100644
--- /dev/null
+++ b/third_party/rust/cast/src/lib.rs
@@ -0,0 +1,523 @@
+//! Ergonomic, checked cast functions for primitive types
+//!
+//! This crate provides one checked cast function for each numeric primitive.
+//! Use these functions to perform a cast from any other numeric primitive:
+//!
+//! ```
+//! extern crate cast;
+//!
+//! use cast::{u8, u16, Error};
+//!
+//! # fn main() {
+//! // Infallible operations, like integer promotion, are equivalent to a normal
+//! // cast with `as`
+//! assert_eq!(u16(0u8), 0u16);
+//!
+//! // Everything else will return a `Result` depending on the success of the
+//! // operation
+//! assert_eq!(u8(0u16), Ok(0u8));
+//! assert_eq!(u8(256u16), Err(Error::Overflow));
+//! assert_eq!(u8(-1i8), Err(Error::Underflow));
+//! assert_eq!(u8(1. / 0.), Err(Error::Infinite));
+//! assert_eq!(u8(0. / 0.), Err(Error::NaN));
+//! # }
+//! ```
+//!
+//! There are no namespace problems between these functions, the "primitive
+//! modules" in `core`/`std` and the built-in primitive types, so all them can
+//! be in the same scope:
+//!
+//! ```
+//! extern crate cast;
+//!
+//! use std::u8;
+//! use cast::{u8, u16};
+//!
+//! # fn main() {
+//! // `u8` as a type
+//! let x: u8 = 0;
+//! // `u8` as a module
+//! let y = u16(u8::MAX);
+//! // `u8` as a function
+//! let z = u8(y).unwrap();
+//! # }
+//! ```
+//!
+//! The checked cast functionality is also usable with type aliases via the
+//! `cast` static method:
+//!
+//! ```
+//! extern crate cast;
+//!
+//! use std::os::raw::c_ulonglong;
+//! // NOTE avoid shadowing `std::convert::From` - cf. rust-lang/rfcs#1311
+//! use cast::From as _0;
+//!
+//! # fn main() {
+//! assert_eq!(c_ulonglong::cast(0u8), 0u64);
+//! # }
+//! ```
+//!
+//! This crate also provides a `From` trait that can be used, for example,
+//! to create a generic function that accepts any type that can be infallibly
+//! casted to `u32`.
+//!
+//! ```
+//! extern crate cast;
+//!
+//! fn to_u32<T>(x: T) -> u32
+//!     // reads as: "where u32 can be casted from T with output u32"
+//!     where u32: cast::From<T, Output=u32>,
+//! {
+//!     cast::u32(x)
+//! }
+//!
+//! # fn main() {
+//! assert_eq!(to_u32(0u8), 0u32);
+//! assert_eq!(to_u32(1u16), 1u32);
+//! assert_eq!(to_u32(2u32), 2u32);
+//!
+//! // to_u32(-1i32);  // Compile error
+//! # }
+//! ```
+//!
+//! ## Building without `std`
+//!
+//! This crate can be used without Rust's `std` crate by declaring it as
+//! follows in your `Cargo.toml`:
+//!
+//! ``` toml
+//! cast = { version = "*", default-features = false }
+//! ```
+
+#![deny(missing_docs)]
+#![deny(warnings)]
+#![allow(const_err)]
+
+#![cfg_attr(not(feature = "std"), no_std)]
+
+#![cfg_attr(feature = "x128", feature(i128_type, i128))]
+
+#[cfg(feature = "std")]
+extern crate core;
+
+#[cfg(test)]
+#[macro_use]
+extern crate quickcheck;
+
+use core::fmt;
+#[cfg(feature="std")]
+use std::error;
+
+#[cfg(test)]
+mod test;
+
+/// Cast errors
+#[derive(Clone, Copy, Debug, Eq, PartialEq)]
+pub enum Error {
+    /// Infinite value casted to a type that can only represent finite values
+    Infinite,
+    /// NaN value casted to a type that can't represent a NaN value
+    NaN,
+    /// Source value is greater than the maximum value that the destination type
+    /// can hold
+    Overflow,
+    /// Source value is smaller than the minimum value that the destination type
+    /// can hold
+    Underflow,
+}
+
+impl Error {
+    /// A private helper function that implements `description`, because
+    /// `description` is only available when we have `std` enabled.
+    fn description_helper(&self) -> &str {
+        match *self {
+            Error::Infinite => "Cannot store infinite value in finite type",
+            Error::NaN => "Cannot store NaN in type which does not support it",
+            Error::Overflow => "Overflow during numeric conversion",
+            Error::Underflow => "Underflow during numeric conversion",
+        }
+    }
+}
+
+impl fmt::Display for Error {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "{}", self.description_helper())
+    }
+}
+
+#[cfg(feature="std")]
+impl error::Error for Error {
+    fn description(&self) -> &str {
+        self.description_helper()
+    }
+}
+
+/// The "cast from" operation
+pub trait From<Src> {
+    /// The result of the cast operation: either `Self` or `Result<Self, Error>`
+    type Output;
+
+    /// Checked cast from `Src` to `Self`
+    fn cast(Src) -> Self::Output;
+}
+
+macro_rules! fns {
+    ($($ty:ident),+) => {
+        $(
+            /// Checked cast function
+            #[inline]
+            pub fn $ty<T>(x: T) -> <$ty as From<T>>::Output
+                where $ty: From<T>
+            {
+                <$ty as From<T>>::cast(x)
+            }
+         )+
+    }
+}
+
+fns!(f32, f64, i8, i16, i32, i64, isize, u8, u16, u32, u64, usize);
+
+#[cfg(feature = "x128")]
+fns!(i128, u128);
+
+/// `$dst` can hold any value of `$src`
+macro_rules! promotion {
+    ($($src:ty => $($dst: ty),+);+;) => {
+        $(
+            $(
+                impl From<$src> for $dst {
+                    type Output = $dst;
+
+                    #[inline]
+                    fn cast(src: $src) -> $dst {
+                        src as $dst
+                    }
+                }
+            )+
+        )+
+    }
+}
+
+/// `$dst` can hold any positive value of `$src`
+macro_rules! half_promotion {
+    ($($src:ty => $($dst:ty),+);+;) => {
+        $(
+            $(
+                impl From<$src> for $dst {
+                    type Output = Result<$dst, Error>;
+
+                    #[inline]
+                    fn cast(src: $src) -> Self::Output {
+                        if src < 0 {
+                            Err(Error::Underflow)
+                        } else {
+                            Ok(src as $dst)
+                        }
+                    }
+                }
+            )+
+        )+
+    }
+}
+
+/// From an unsigned `$src` to a smaller `$dst`
+macro_rules! from_unsigned {
+    ($($src:ident => $($dst:ident),+);+;) => {
+        $(
+            $(
+                impl From<$src> for $dst {
+                    type Output = Result<$dst, Error>;
+
+                    #[inline]
+                    fn cast(src: $src) -> Self::Output {
+                        use core::$dst;
+
+                        if src > $dst::MAX as $src {
+                            Err(Error::Overflow)
+                        } else {
+                            Ok(src as $dst)
+                        }
+                    }
+                }
+            )+
+        )+
+    }
+}
+
+/// From a signed `$src` to a smaller `$dst`
+macro_rules! from_signed {
+    ($($src:ident => $($dst:ident),+);+;) => {
+        $(
+            $(
+                impl From<$src> for $dst {
+                    type Output = Result<$dst, Error>;
+
+                    #[inline]
+                    fn cast(src: $src) -> Self::Output {
+                        use core::$dst;
+
+                        Err(if src < $dst::MIN as $src {
+                            Error::Underflow
+                        } else if src > $dst::MAX as $src {
+                            Error::Overflow
+                        } else {
+                            return Ok(src as $dst);
+                        })
+                    }
+                }
+            )+
+        )+
+    }
+}
+
+/// From a float `$src` to an integer `$dst`
+macro_rules! from_float {
+    ($($src:ident => $($dst:ident),+);+;) => {
+        $(
+            $(
+                impl From<$src> for $dst {
+                    type Output = Result<$dst, Error>;
+
+                    #[inline]
+                    fn cast(src: $src) -> Self::Output {
+                        use core::{$dst, $src};
+
+                        Err(if src != src {
+                            Error::NaN
+                        } else if src == $src::INFINITY ||
+                            src == $src::NEG_INFINITY {
+                            Error::Infinite
+                        } else if src < $dst::MIN as $src {
+                            Error::Underflow
+                        } else if src > $dst::MAX as $src {
+                            Error::Overflow
+                        } else {
+                            return Ok(src as $dst);
+                        })
+                    }
+                }
+            )+
+        )+
+    }
+}
+
+/// From a float `$src` to an integer `$dst`, where $dst is large enough to contain
+/// all values of `$src`. We can't ever overflow here
+macro_rules! from_float_dst {
+    ($($src:ident => $($dst:ident),+);+;) => {
+        $(
+            $(
+                impl From<$src> for $dst {
+                    type Output = Result<$dst, Error>;
+
+                    #[inline]
+                    #[allow(unused_comparisons)]
+                    fn cast(src: $src) -> Self::Output {
+                        use core::{$dst, $src};
+
+                        Err(if src != src {
+                            Error::NaN
+                        } else if src == $src::INFINITY ||
+                            src == $src::NEG_INFINITY {
+                            Error::Infinite
+                        } else if ($dst::MIN == 0) && src < 0.0 {
+                            Error::Underflow
+                        } else {
+                            return Ok(src as $dst);
+                        })
+                    }
+                }
+            )+
+        )+
+    }
+}
+
+// PLAY TETRIS! ;-)
+
+#[cfg(target_pointer_width = "32")]
+mod _32 {
+    use {Error, From};
+
+    // Signed
+    promotion! {
+        i8    => f32, f64, i8, i16, i32, isize, i64;
+        i16   => f32, f64,     i16, i32, isize, i64;
+        i32   => f32, f64,          i32, isize, i64;
+        isize => f32, f64,          i32, isize, i64;
+        i64   => f32, f64,                      i64;
+    }
+
+    half_promotion! {
+        i8    =>                                     u8, u16, u32, usize, u64;
+        i16   =>                                         u16, u32, usize, u64;
+        i32   =>                                              u32, usize, u64;
+        isize =>                                              u32, usize, u64;
+        i64   =>                                                          u64;
+    }
+
+    from_signed! {
+
+        i16   =>           i8,                       u8;
+        i32   =>           i8, i16,                  u8, u16;
+        isize =>           i8, i16,                  u8, u16;
+        i64   =>           i8, i16, i32, isize,      u8, u16, u32, usize;
+    }
+
+    // Unsigned
+    promotion! {
+        u8    => f32, f64,     i16, i32, isize, i64, u8, u16, u32, usize, u64;
+        u16   => f32, f64,          i32, isize, i64,     u16, u32, usize, u64;
+        u32   => f32, f64,                      i64,          u32, usize, u64;
+        usize => f32, f64,                      i64,          u32, usize, u64;
+        u64   => f32, f64,                                                u64;
+    }
+
+    from_unsigned! {
+        u8    =>           i8;
+        u16   =>           i8, i16,                  u8;
+        u32   =>           i8, i16, i32, isize,      u8, u16;
+        usize =>           i8, i16, i32, isize,      u8, u16;
+        u64   =>           i8, i16, i32, isize, i64, u8, u16, u32, usize;
+    }
+
+    // Float
+    promotion! {
+        f32   => f32, f64;
+        f64   =>      f64;
+    }
+
+    from_float! {
+        f32   =>           i8, i16, i32, isize, i64, u8, u16, u32, usize, u64;
+        f64   =>           i8, i16, i32, isize, i64, u8, u16, u32, usize, u64;
+    }
+}
+
+#[cfg(target_pointer_width = "64")]
+mod _64 {
+    use {Error, From};
+
+    // Signed
+    promotion! {
+        i8    => f32, f64, i8, i16, i32, i64, isize;
+        i16   => f32, f64,     i16, i32, i64, isize;
+        i32   => f32, f64,          i32, i64, isize;
+        i64   => f32, f64,               i64, isize;
+        isize => f32, f64,               i64, isize;
+    }
+
+    half_promotion! {
+        i8    =>                                     u8, u16, u32, u64, usize;
+        i16   =>                                         u16, u32, u64, usize;
+        i32   =>                                              u32, u64, usize;
+        i64   =>                                                   u64, usize;
+        isize =>                                                   u64, usize;
+    }
+
+    from_signed! {
+
+        i16   =>           i8,                       u8;
+        i32   =>           i8, i16,                  u8, u16;
+        i64   =>           i8, i16, i32,             u8, u16, u32;
+        isize =>           i8, i16, i32,             u8, u16, u32;
+    }
+
+    // Unsigned
+    promotion! {
+        u8    => f32, f64,     i16, i32, i64, isize, u8, u16, u32, u64, usize;
+        u16   => f32, f64,          i32, i64, isize,     u16, u32, u64, usize;
+        u32   => f32, f64,               i64, isize,          u32, u64, usize;
+        u64   => f32, f64,                                         u64, usize;
+        usize => f32, f64,                                         u64, usize;
+    }
+
+    from_unsigned! {
+        u8    =>           i8;
+        u16   =>           i8, i16,                  u8;
+        u32   =>           i8, i16, i32,             u8, u16;
+        u64   =>           i8, i16, i32, i64, isize, u8, u16, u32;
+        usize =>           i8, i16, i32, i64, isize, u8, u16, u32;
+    }
+
+    // Float
+    promotion! {
+        f32  => f32, f64;
+        f64  =>      f64;
+    }
+
+    from_float! {
+        f32  =>           i8, i16, i32, i64, isize, u8, u16, u32, u64, usize;
+        f64  =>           i8, i16, i32, i64, isize, u8, u16, u32, u64, usize;
+    }
+}
+
+#[cfg(feature = "x128")]
+mod _x128 {
+    use {Error, From};
+
+    // Signed
+    promotion! {
+        i8    =>                              i128;
+        i16   =>                              i128;
+        i32   =>                              i128;
+        i64   =>                              i128;
+        isize =>                              i128;
+        i128  => f32, f64,                    i128;
+    }
+
+    half_promotion! {
+        i8    =>                                                              u128;
+        i16   =>                                                              u128;
+        i32   =>                                                              u128;
+        i64   =>                                                              u128;
+        isize =>                                                              u128;
+        i128  =>                                                              u128;
+    }
+
+    from_signed! {
+        i128  =>           i8, i16, i32, i64,       isize, u8, u16, u32, u64,       usize;
+    }
+
+    // Unsigned
+    promotion! {
+        u8    =>                              i128,                           u128;
+        u16   =>                              i128,                           u128;
+        u32   =>                              i128,                           u128;
+        u64   =>                              i128,                           u128;
+        usize =>                              i128,                           u128;
+        u128  =>      f64,                                                    u128;
+    }
+
+    from_unsigned! {
+        u128 => f32,       i8, i16, i32, i64, i128, isize, u8, u16, u32, u64,       usize;
+    }
+
+    // Float
+    from_float! {
+        f32  => i128;
+        f64  => i128, u128;
+    }
+    from_float_dst! {
+        f32  => u128;
+    }
+}
+
+// The missing piece
+impl From<f64> for f32 {
+    type Output = Result<f32, Error>;
+
+    #[inline]
+    fn cast(src: f64) -> Self::Output {
+        use core::{f32, f64};
+
+        if src != src || src == f64::INFINITY || src == f64::NEG_INFINITY {
+            Ok(src as f32)
+        } else if src < f32::MIN as f64 {
+            Err(Error::Underflow)
+        } else if src > f32::MAX as f64 {
+            Err(Error::Overflow)
+        } else {
+            Ok(src as f32)
+        }
+    }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/cast/src/test.rs
@@ -0,0 +1,191 @@
+// If `src` can be promoted to `$dst`, then it must be Ok to cast `dst` back to
+// `$src`
+macro_rules! promote_and_back {
+    ($($src:ident => $($dst:ident),+);+;) => {
+        mod demoting_to {
+            $(
+                mod $src {
+                    mod from {
+                        use From;
+
+                        $(
+                            quickcheck! {
+                                fn $dst(src: $src) -> bool {
+                                    $src::cast($dst::cast(src)).is_ok()
+                                }
+                            }
+                         )+
+                    }
+                }
+             )+
+        }
+    }
+}
+
+#[cfg(target_pointer_width = "32")]
+promote_and_back! {
+    i8    => f32, f64,     i16, i32, isize, i64                          ;
+    i16   => f32, f64,          i32, isize, i64                          ;
+    i32   => f32, f64,                      i64                          ;
+    isize => f32, f64,                      i64                          ;
+    i64   => f32, f64                                                    ;
+    u8    => f32, f64,     i16, i32, isize, i64,     u16, u32, usize, u64;
+    u16   => f32, f64,          i32, isize, i64,          u32, usize, u64;
+    u32   => f32, f64,                      i64,                      u64;
+    usize => f32, f64,                      i64,                      u64;
+    u64   => f32, f64                                                    ;
+}
+
+#[cfg(target_pointer_width = "64")]
+promote_and_back! {
+    i8    => f32, f64,     i16, i32, i64, isize                          ;
+    i16   => f32, f64,          i32, i64, isize                          ;
+    i32   => f32, f64,               i64, isize                          ;
+    i64   => f32, f64                                                    ;
+    isize => f32, f64                                                    ;
+    u8    => f32, f64,     i16, i32, i64, isize,     u16, u32, u64, usize;
+    u16   => f32, f64,          i32, i64, isize,          u32, u64, usize;
+    u32   => f32, f64,               i64, isize,               u64, usize;
+    u64   => f32, f64                                                    ;
+    usize => f32, f64                                                    ;
+}
+
+// TODO uncomment this once quickcheck supports Arbitrary for i128/u128
+// https://github.com/BurntSushi/quickcheck/issues/162
+/*#[cfg(feature = "x128")]
+promote_and_back! {
+    i8    =>           i128      ;
+    i16   =>           i128      ;
+    i32   =>           i128      ;
+    isize =>           i128      ;
+    i64   =>           i128      ;
+    i128  => f32, f64            ;
+    u8    =>           i128, u128;
+    u16   =>           i128, u128;
+    u32   =>           i128, u128;
+    usize =>           i128, u128;
+    u64   =>           i128, u128;
+    u128  => f32, f64            ;
+}*/
+
+// If it's Ok to cast `src` to `$dst`, it must also be Ok to cast `dst` back to
+// `$src`
+macro_rules! symmetric_cast_between {
+    ($($src:ident => $($dst:ident),+);+;) => {
+        mod symmetric_cast_between {
+            $(
+                mod $src {
+                    mod and {
+                        use quickcheck::TestResult;
+
+                        use From;
+
+                        $(
+                            quickcheck! {
+                                fn $dst(src: $src) -> TestResult {
+                                    if let Ok(dst) = $dst::cast(src) {
+                                        TestResult::from_bool(
+                                            $src::cast(dst).is_ok())
+                                    } else {
+                                        TestResult::discard()
+                                    }
+                                }
+                            }
+                         )+
+                    }
+                }
+             )+
+        }
+    }
+}
+
+#[cfg(target_pointer_width = "32")]
+symmetric_cast_between! {
+    u8    =>           i8                      ;
+    u16   =>           i8, i16                 ;
+    u32   =>           i8, i16, i32            ;
+    usize =>           i8, i16, i32            ;
+    u64   =>           i8, i16, i32, i64, isize;
+}
+
+#[cfg(target_pointer_width = "64")]
+symmetric_cast_between! {
+    u8    =>           i8                      ;
+    u16   =>           i8, i16                 ;
+    u32   =>           i8, i16, i32            ;
+    u64   =>           i8, i16, i32, i64, isize;
+    usize =>           i8, i16, i32, i64, isize;
+}
+
+// TODO uncomment this once quickcheck supports Arbitrary for i128/u128
+// https://github.com/BurntSushi/quickcheck/issues/162
+/*#[cfg(feature = "x128")]
+symmetric_cast_between! {
+    u128  => i8, i16, i32, isize, i64, i128;
+}*/
+
+macro_rules! from_float {
+    ($($src:ident => $($dst:ident),+);+;) => {
+        $(
+            mod $src {
+                mod inf {
+                    mod to {
+                        use {Error, From};
+
+                        $(
+                            #[test]
+                            fn $dst() {
+                                let _0: $src = 0.;
+                                let _1: $src = 1.;
+                                let inf = _1 / _0;
+                                let neg_inf = -_1 / _0;
+
+                                assert_eq!($dst::cast(inf),
+                                           Err(Error::Infinite));
+                                assert_eq!($dst::cast(neg_inf),
+                                           Err(Error::Infinite));
+                            }
+                         )+
+                    }
+                }
+
+                mod nan {
+                    mod to {
+                        use {Error, From};
+
+                        $(
+                            #[test]
+                            fn $dst() {
+                                let _0: $src = 0.;
+                                let nan = _0 / _0;
+
+                                assert_eq!($dst::cast(nan),
+                                           Err(Error::NaN));
+                            }
+                         )+
+                    }
+                }
+            }
+         )+
+    }
+}
+
+from_float! {
+    f32 => i8, i16, i32, i64, isize, u8, u16, u32, u64, usize;
+    f64 => i8, i16, i32, i64, isize, u8, u16, u32, u64, usize;
+}
+
+// TODO uncomment this once quickcheck supports Arbitrary for i128/u128
+// https://github.com/BurntSushi/quickcheck/issues/162
+/*#[cfg(feature = "x128")]
+from_float! {
+    f32 => i128, u128;
+    f64 => i128, u128;
+}*/
+
+#[test]
+#[cfg(feature = "x128")]
+fn test_fl_conversion() {
+    use u128;
+    assert_eq!(u128(42.0f32), Ok(42));
+}
--- a/third_party/rust/cranelift-bforest/.cargo-checksum.json
+++ b/third_party/rust/cranelift-bforest/.cargo-checksum.json
@@ -1,1 +1,1 @@
-{"files":{"Cargo.toml":"8c219cb955621bfeb89eb1175dc9d810dc98323ccb54360e623425308c970e72","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"af367c67340fa7f6fb9a35b0aa637dcf303957f7ae7427a5f4f6356801c8bb04","src/lib.rs":"01f8c9b8a077975c8f0803f793b8c20b583aaef2dc1f4400b9d90ba132ff4133","src/map.rs":"77eb9fd2ffdaafaf4daea609602a0c775c5012efae21c03547f63653271da163","src/node.rs":"309609acc70f1ce6be2f3c964430d23c0680bd7a647afab837a2aedc06235531","src/path.rs":"25326bacbb99189e873cb70e770f21c13fdef0fb2cd20f484830386fc4c75c6a","src/pool.rs":"196216124922dc42708a3aa944e98b6a57ef9bb770dab7e01f154b6382cab021","src/set.rs":"d4ff99fe51de9eefb4c774e919259d952ab5dde4dd3b99bd9974e4eedbb28938"},"package":"7b2d527b241af388ff017d72f2b0b323929a70cf97342c6ec1534e3b0f4dfaa0"}
\ No newline at end of file
+{"files":{"Cargo.toml":"591c2da0dad7eafa9aff626400b38e0b08927df674292ca6774f60e2bc02ac32","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"af367c67340fa7f6fb9a35b0aa637dcf303957f7ae7427a5f4f6356801c8bb04","src/lib.rs":"eb691a3bc63c3ed8a64d564cf656fdc56c62ade8b7882efd7b987353acc627bd","src/map.rs":"77eb9fd2ffdaafaf4daea609602a0c775c5012efae21c03547f63653271da163","src/node.rs":"309609acc70f1ce6be2f3c964430d23c0680bd7a647afab837a2aedc06235531","src/path.rs":"25326bacbb99189e873cb70e770f21c13fdef0fb2cd20f484830386fc4c75c6a","src/pool.rs":"196216124922dc42708a3aa944e98b6a57ef9bb770dab7e01f154b6382cab021","src/set.rs":"d4ff99fe51de9eefb4c774e919259d952ab5dde4dd3b99bd9974e4eedbb28938"},"package":"40f8ff24e9a6c89b8a846b14df9a34d2cac17cea7bdb5c81ed6b4744ee0e38bf"}
\ No newline at end of file
--- a/third_party/rust/cranelift-bforest/Cargo.toml
+++ b/third_party/rust/cranelift-bforest/Cargo.toml
@@ -7,27 +7,27 @@
 #
 # If you believe there's an error in this file please file an
 # issue against the rust-lang/cargo repository. If you're
 # editing this file be aware that the upstream Cargo.toml
 # will likely look very different (and much more reasonable)
 
 [package]
 name = "cranelift-bforest"
-version = "0.25.0"
+version = "0.26.0"
 authors = ["The Cranelift Project Developers"]
 description = "A forest of B+-trees"
 documentation = "https://cranelift.readthedocs.io/"
 readme = "README.md"
 keywords = ["btree", "forest", "set", "map"]
 categories = ["no-std"]
 license = "Apache-2.0 WITH LLVM-exception"
 repository = "https://github.com/CraneStation/cranelift"
 [dependencies.cranelift-entity]
-version = "0.25.0"
+version = "0.26.0"
 default-features = false
 
 [features]
 default = ["std"]
 std = ["cranelift-entity/std"]
 [badges.maintenance]
 status = "experimental"
 
--- a/third_party/rust/cranelift-bforest/src/lib.rs
+++ b/third_party/rust/cranelift-bforest/src/lib.rs
@@ -11,35 +11,32 @@
 //! - Keys and values are expected to be small and copyable. We optimize for 32-bit types.
 //! - A comparator object is used to compare keys, allowing smaller "context free" keys.
 //! - Empty trees have a very small 32-bit footprint.
 //! - All the trees in a forest can be cleared in constant time.
 
 #![deny(missing_docs, trivial_numeric_casts, unused_extern_crates)]
 #![warn(unused_import_braces)]
 #![cfg_attr(feature = "std", warn(unstable_features))]
-#![cfg_attr(
-    feature = "clippy",
-    plugin(clippy(conf_file = "../../clippy.toml"))
-)]
+#![cfg_attr(feature = "clippy", plugin(clippy(conf_file = "../../clippy.toml")))]
 #![cfg_attr(
     feature = "cargo-clippy",
     allow(new_without_default, new_without_default_derive)
 )]
 #![cfg_attr(
     feature = "cargo-clippy",
     warn(
-        float_arithmetic,
-        mut_mut,
-        nonminimal_bool,
-        option_map_unwrap_or,
-        option_map_unwrap_or_else,
-        print_stdout,
-        unicode_not_nfc,
-        use_self
+        clippy::float_arithmetic,
+        clippy::mut_mut,
+        clippy::nonminimal_bool,
+        clippy::option_map_unwrap_or,
+        clippy::option_map_unwrap_or_else,
+        clippy::print_stdout,
+        clippy::unicode_not_nfc,
+        clippy::use_self
     )
 )]
 // Turns on no_std and alloc features if std is not available.
 #![cfg_attr(not(feature = "std"), no_std)]
 #![cfg_attr(not(feature = "std"), feature(alloc))]
 
 /// This replaces `std` in builds with `core`.
 #[cfg(not(feature = "std"))]
--- 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":"0e4050095c283d025e30ccba0e3d9753b63340604b6373e4ea06d221eb3a97e1","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"b123f056d0d458396679c5f7f2a16d2762af0258fcda4ac14b6655a95e5a0022","src/base/mod.rs":"9320dfed2250bdb0347e01862b2ff7bf7db78920dae1719834b374de11131e87","src/base/types.rs":"a3e449db1f515d268f3ad21301740ba415444d399f8433dbc48979f78557f66a","src/cdsl/isa.rs":"b34150e2658dd7ab30e9846dece89f56a0acbfff0341927cec06bf0de1d9b419","src/cdsl/mod.rs":"311726d7e4ad9278eab301fd4f6e31e697b7d4260733c6a00fe39cd61db977d3","src/cdsl/regs.rs":"41cca844b390bba3ceefa147e7b0dec170aba2b5759a41ecb5b9cd7f2cc59f60","src/cdsl/types.rs":"f9756e483329f00a1d8a15e30bc05e8d4c8fa71ff1f649b808528ddeb5fbdfea","src/error.rs":"5110a4e3c1e97396ba02d9f5abbb8af4b586f0cc4d33a5c2473f1718cc4bef05","src/gen_registers.rs":"3d38ff5b0c6183209d4ba84bd1f14b1d84bea697c0589471aa5ce4abc209f20b","src/gen_types.rs":"5eb4e9bd0fda7f7644bb2428045f0bf16f2b698ff32cadcbbf7f2c7669f18de3","src/isa/arm32/mod.rs":"ceb8290344a245f11eb541d60c2678ddfe7beaf60cde491c22fd48090fa210ba","src/isa/arm64/mod.rs":"db7f828940372a21c62cf6f5aefca7cc05c974ba731b8db602da0a336e29ea1e","src/isa/mod.rs":"36c001f8ecdea4aaf8cadcad4f91fe79a82806e4f43182e216c2fa99cecf55dc","src/isa/riscv/mod.rs":"aecb127f8c06970a00dde8ad772fdebe5497b6e7f342fa2a0e859355ae027055","src/isa/x86/mod.rs":"2b3a181a226d66a8faf855d517fb4a13554a31020f6b8875ba75a2fe650f378a","src/lib.rs":"dd97d73d41ffee2d2cc62705f9f6f7ed6b9af982aff8d1fafb72590e097c513c","src/srcgen.rs":"abe118fb41a643ffc63577cc4b62de9a2286e1eeb34b95bff79648d0ea582886"},"package":"963262697a05d9aa63ca40f4670a7243e4525f4a098e10d654c3f5143fcef686"}
\ No newline at end of file
+{"files":{"Cargo.toml":"cdd4cff2d17ca34e3305e9fcf1e8277b0e9987e7369ce70da597e3957e56e408","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"b123f056d0d458396679c5f7f2a16d2762af0258fcda4ac14b6655a95e5a0022","src/base/mod.rs":"559075f0b76a744dd36224e06ff1c2e28ee70aaca9442fc724b116e37028ac52","src/base/settings.rs":"9cbe9bdd5141b9175074370a9b1d28f371249d586e999a31f76631739bf09c13","src/base/types.rs":"a3e449db1f515d268f3ad21301740ba415444d399f8433dbc48979f78557f66a","src/cdsl/isa.rs":"5c9a8173466e69d105245396abd342251eb00e704ab13f179ba1567b339f47e1","src/cdsl/mod.rs":"66ac1b5d095e431bcab88c4b9c5b1492a5d1ca87bcb9c9c3e544ede05b2ba925","src/cdsl/regs.rs":"41cca844b390bba3ceefa147e7b0dec170aba2b5759a41ecb5b9cd7f2cc59f60","src/cdsl/settings.rs":"724a4bd7cfd0608cfc8751ee7c38dbed90b91cfafd34585ed7df953807932794","src/cdsl/types.rs":"78f476f5f700697b94f2d2f00049af8684d3b27afc5684b2c87ea517aeb77e85","src/constant_hash.rs":"6522f86ebfd44efe9b47256d822d0e49d641ccdbb4fcc61d57bb94e6d52702c1","src/error.rs":"5110a4e3c1e97396ba02d9f5abbb8af4b586f0cc4d33a5c2473f1718cc4bef05","src/gen_registers.rs":"9bd381da256c19724964c6445db4fbac80d91174266dccfc5d3b72497a5332c9","src/gen_settings.rs":"a827a90cc1db7345e8081635169b77be497494e558c6e985eaa654386d5e8e48","src/gen_types.rs":"5eb4e9bd0fda7f7644bb2428045f0bf16f2b698ff32cadcbbf7f2c7669f18de3","src/isa/arm32/mod.rs":"b4049ff95164bbf244b6727e16974383e4d58c5be750f7ded3ef8cfe113e5373","src/isa/arm64/mod.rs":"759adfd4dd5c885644de26386797211efc82c5b47f2e147a58d57d24608b9cfb","src/isa/mod.rs":"d3a87bc45173f3743f25d3a004a9b40966c12feb7d95d794b5918bb9ccb988ac","src/isa/riscv/mod.rs":"6e3d96c48e9c289a13912d7f777bde805be327e4a56677d3f3bccf440ae4a09b","src/isa/x86/mod.rs":"e38c60a9d1aba3e5a48052c6185bab3f2b039e9cce639826becfe9f853c41499","src/lib.rs":"c4bfd9d2973e4a382f7a1ce8389cc1604aeba8478432a542ff3f1c24412c5b41","src/srcgen.rs":"e358b6232f0820e6e4525cdbe216206996ae5eb16a1df7a5fe41e3ce2e25b633","src/unique_table.rs":"f6041df1fa85f2a1ee914b84791e80165a0858a6253c212eaa99ff67cb56af26"},"package":"014c23ed3ebdc8377d41540af638245207dd169f421df042dfccc867465734ed"}
\ No newline at end of file
--- a/third_party/rust/cranelift-codegen-meta/Cargo.toml
+++ b/third_party/rust/cranelift-codegen-meta/Cargo.toml
@@ -7,21 +7,21 @@
 #
 # If you believe there's an error in this file please file an
 # issue against the rust-lang/cargo repository. If you're
 # editing this file be aware that the upstream Cargo.toml
 # will likely look very different (and much more reasonable)
 
 [package]
 name = "cranelift-codegen-meta"
-version = "0.25.0"
+version = "0.26.0"
 authors = ["The Cranelift Project Developers"]
 description = "Metaprogram for cranelift-codegen code generator library"
 readme = "README.md"
 license = "Apache-2.0 WITH LLVM-exception"
 repository = "https://github.com/CraneStation/cranelift"
 [dependencies.cranelift-entity]
-version = "0.25.0"
+version = "0.26.0"
 [badges.maintenance]
 status = "experimental"
 
 [badges.travis-ci]
 repository = "CraneStation/cranelift"
--- a/third_party/rust/cranelift-codegen-meta/src/base/mod.rs
+++ b/third_party/rust/cranelift-codegen-meta/src/base/mod.rs
@@ -1,3 +1,4 @@
 //! Definitions for the base Cranelift language.
 
+pub mod settings;
 pub mod types;
new file mode 100644
--- /dev/null
+++ b/third_party/rust/cranelift-codegen-meta/src/base/settings.rs
@@ -0,0 +1,164 @@
+use cdsl::settings::{SettingGroup, SettingGroupBuilder};
+
+pub fn generate() -> SettingGroup {
+    let mut settings = SettingGroupBuilder::new("shared");
+
+    settings.add_enum(
+        "opt_level",
+        r#"
+        Optimization level:
+
+        - default: Very profitable optimizations enabled, none slow.
+        - best: Enable all optimizations
+        - fastest: Optimize for compile time by disabling most optimizations.
+        "#,
+        vec!["default", "best", "fastest"],
+    );
+
+    settings.add_bool(
+        "enable_verifier",
+        r#"
+        Run the Cranelift IR verifier at strategic times during compilation.
+
+        This makes compilation slower but catches many bugs. The verifier is
+        disabled by default, except when reading Cranelift IR from a text file.
+        "#,
+        true,
+    );
+
+    // Note that Cranelift doesn't currently need an is_pie flag, because PIE is
+    // just PIC where symbols can't be pre-empted, which can be expressed with the
+    // `colocated` flag on external functions and global values.
+    settings.add_bool(
+        "is_pic",
+        "Enable Position-Independent Code generation",
+        false,
+    );
+
+    settings.add_bool(
+        "colocated_libcalls",
+        r#"
+            Use colocated libcalls.
+
+            Generate code that assumes that libcalls can be declared "colocated",
+            meaning they will be defined along with the current function, such that
+            they can use more efficient addressing.
+            "#,
+        false,
+    );
+
+    settings.add_bool(
+        "avoid_div_traps",
+        r#"
+            Generate explicit checks around native division instructions to avoid
+            their trapping.
+
+            This is primarily used by SpiderMonkey which doesn't install a signal
+            handler for SIGFPE, but expects a SIGILL trap for division by zero.
+
+            On ISAs like ARM where the native division instructions don't trap,
+            this setting has no effect - explicit checks are always inserted.
+            "#,
+        false,
+    );
+
+    settings.add_bool(
+        "enable_float",
+        r#"
+            Enable the use of floating-point instructions
+
+            Disabling use of floating-point instructions is not yet implemented.
+            "#,
+        true,
+    );
+
+    settings.add_bool(
+        "enable_nan_canonicalization",
+        r#"
+            Enable NaN canonicalization
+
+            This replaces NaNs with a single canonical value, for users requiring
+            entirely deterministic WebAssembly computation. This is not required
+            by the WebAssembly spec, so it is not enabled by default.
+            "#,
+        false,
+    );
+
+    settings.add_bool("enable_simd", "Enable the use of SIMD instructions.", true);
+
+    settings.add_bool(
+        "enable_atomics",
+        "Enable the use of atomic instructions",
+        true,
+    );
+
+    // Settings specific to the `baldrdash` calling convention.
+
+    settings.add_num(
+        "baldrdash_prologue_words",
+        r#"
+            Number of pointer-sized words pushed by the baldrdash prologue.
+
+            Functions with the `baldrdash` calling convention don't generate their
+            own prologue and epilogue. They depend on externally generated code
+            that pushes a fixed number of words in the prologue and restores them
+            in the epilogue.
+
+            This setting configures the number of pointer-sized words pushed on the
+            stack when the Cranelift-generated code is entered. This includes the
+            pushed return address on x86.
+            "#,
+        0,
+    );
+
+    // BaldrMonkey requires that not-yet-relocated function addresses be encoded
+    // as all-ones bitpatterns.
+    settings.add_bool(
+        "allones_funcaddrs",
+        "Emit not-yet-relocated function addresses as all-ones bit patterns.",
+        false,
+    );
+
+    // Stack probing options.
+
+    settings.add_bool(
+        "probestack_enabled",
+        r#"
+            Enable the use of stack probes, for calling conventions which support this
+            functionality.
+            "#,
+        true,
+    );
+
+    settings.add_bool(
+        "probestack_func_adjusts_sp",
+        r#"
+            Set this to true of the stack probe function modifies the stack pointer
+            itself.
+            "#,
+        false,
+    );
+
+    settings.add_num(
+        "probestack_size_log2",
+        r#"
+            The log2 of the size of the stack guard region.
+
+            Stack frames larger than this size will have stack overflow checked
+            by calling the probestack function.
+
+            The default is 12, which translates to a size of 4096.
+            "#,
+        12,
+    );
+
+    // Jump table options.
+
+    settings.add_bool(
+        "jump_tables_enabled",
+        "Enable the use of jump tables in generated machine code.",
+        true,
+    );
+
+    settings.finish()
+}
--- a/third_party/rust/cranelift-codegen-meta/src/cdsl/isa.rs
+++ b/third_party/rust/cranelift-codegen-meta/src/cdsl/isa.rs
@@ -1,38 +1,41 @@
 use cranelift_entity::PrimaryMap;
 
 use super::regs::{
     RegBank, RegBankBuilder, RegBankIndex, RegClass, RegClassBuilder, RegClassIndex, RegClassProto,
 };
+use super::settings::SettingGroup;
 
 pub struct TargetIsa {
     pub name: &'static str,
     pub reg_banks: PrimaryMap<RegBankIndex, RegBank>,
     pub reg_classes: PrimaryMap<RegClassIndex, RegClass>,
+    pub settings: SettingGroup,
 }
 
 impl TargetIsa {
-    pub fn new(name: &'static str) -> Self {
+    pub fn new(name: &'static str, settings: SettingGroup) -> Self {
         Self {
             name,
             reg_banks: PrimaryMap::new(),
             reg_classes: PrimaryMap::new(),
+            settings,
         }
     }
 }
 
 pub struct TargetIsaBuilder {
     isa: TargetIsa,
 }
 
 impl TargetIsaBuilder {
-    pub fn new(name: &'static str) -> Self {
+    pub fn new(name: &'static str, settings: SettingGroup) -> Self {
         Self {
-            isa: TargetIsa::new(name),
+            isa: TargetIsa::new(name, settings),
         }
     }
 
     pub fn add_reg_bank(&mut self, builder: RegBankBuilder) -> RegBankIndex {
         let first_unit = if self.isa.reg_banks.len() == 0 {
             0
         } else {
             let last = &self.isa.reg_banks.last().unwrap();
@@ -145,26 +148,25 @@ impl TargetIsaBuilder {
                     }
 
                     // Classes must be topologically ordered, so the intersection can't be the
                     // superclass.
                     assert!(intersect != rc1_mask);
 
                     // If the intersection is the second one, then it must be a subclass.
                     if intersect == rc2_mask {
-                        assert!(
-                            self.isa
-                                .reg_classes
-                                .get(*i1)
-                                .unwrap()
-                                .subclasses
-                                .iter()
-                                .find(|x| **x == *i2)
-                                .is_some()
-                        );
+                        assert!(self
+                            .isa
+                            .reg_classes
+                            .get(*i1)
+                            .unwrap()
+                            .subclasses
+                            .iter()
+                            .find(|x| **x == *i2)
+                            .is_some());
                     }
                 }
             }
         }
 
         // This limit should be coordinated with the `RegClassMask` and `RegClassIndex` types in
         // isa/registers.rs of the non-meta code.
         assert!(
@@ -176,14 +178,15 @@ impl TargetIsaBuilder {
         // kept in sync with the MAX_TRACKED_TOPRCS constant in isa/registers.rs of the non-meta
         // code.
         let num_toplevel = self
             .isa
             .reg_classes
             .values()
             .filter(|x| {
                 x.toprc == x.index && self.isa.reg_banks.get(x.bank).unwrap().pressure_tracking
-            }).count();
+            })
+            .count();
         assert!(num_toplevel <= 4, "Too many top-level register classes");
 
         self.isa
     }
 }
--- a/third_party/rust/cranelift-codegen-meta/src/cdsl/mod.rs
+++ b/third_party/rust/cranelift-codegen-meta/src/cdsl/mod.rs
@@ -1,19 +1,47 @@
 //! Cranelift DSL classes.
 //!
 //! This module defines the classes that are used to define Cranelift
 //! instructions and other entities.
 
 pub mod isa;
 pub mod regs;
+pub mod settings;
 pub mod types;
 
+/// A macro that converts boolean settings into predicates to look more natural.
+#[macro_export]
+macro_rules! predicate {
+    ($a:ident && $($b:tt)*) => {
+        PredicateNode::And(Box::new($a.into()), Box::new(predicate!($($b)*)))
+    };
+    ($a:ident) => {
+        $a.into()
+    };
+}
+
+#[macro_export]
+macro_rules! preset {
+    () => {
+        vec![]
+    };
+    ($($x:ident)&&*) => {
+        {
+            let mut v = Vec::new();
+            $(
+                v.push($x.into());
+            )*
+            v
+        }
+    };
+}
+
 /// Convert the string `s` to CamelCase.
-fn _camel_case(s: &str) -> String {
+pub fn camel_case(s: &str) -> String {
     let mut output_chars = String::with_capacity(s.len());
 
     let mut capitalize = true;
     for curr_char in s.chars() {
         if curr_char == '_' {
             capitalize = true;
         } else {
             if capitalize {
@@ -25,16 +53,16 @@ fn _camel_case(s: &str) -> String {
         }
     }
 
     output_chars
 }
 
 #[cfg(test)]
 mod tests {
-    use super::_camel_case as camel_case;
+    use super::camel_case;
 
     #[test]
     fn camel_case_works() {
         assert_eq!(camel_case("x"), "X");
         assert_eq!(camel_case("camel_case"), "CamelCase");
     }
 }
new file mode 100644
--- /dev/null
+++ b/third_party/rust/cranelift-codegen-meta/src/cdsl/settings.rs
@@ -0,0 +1,386 @@
+use std::iter;
+
+#[derive(Clone, Copy, Hash, PartialEq, Eq)]
+pub struct BoolSettingIndex(usize);
+
+#[derive(Hash, PartialEq, Eq)]
+pub struct BoolSetting {
+    pub default: bool,
+    pub bit_offset: u8,
+    pub predicate_number: u8,
+}
+
+#[derive(Hash, PartialEq, Eq)]
+pub enum SpecificSetting {
+    Bool(BoolSetting),
+    Enum(Vec<&'static str>),
+    Num(u8),
+}
+
+#[derive(Hash, PartialEq, Eq)]
+pub struct Setting {
+    pub name: &'static str,
+    pub comment: &'static str,
+    pub specific: SpecificSetting,
+    pub byte_offset: u8,
+}
+
+impl Setting {
+    pub fn default_byte(&self) -> u8 {
+        match self.specific {
+            SpecificSetting::Bool(BoolSetting {
+                default,
+                bit_offset,
+                ..
+            }) => {
+                if default {
+                    1 << bit_offset
+                } else {
+                    0
+                }
+            }
+            SpecificSetting::Enum(_) => 0,
+            SpecificSetting::Num(default) => default,
+        }
+    }
+
+    fn byte_for_value(&self, v: bool) -> u8 {
+        match self.specific {
+            SpecificSetting::Bool(BoolSetting { bit_offset, .. }) => {
+                if v {
+                    1 << bit_offset
+                } else {
+                    0
+                }
+            }
+            _ => panic!("byte_for_value shouldn't be used for non-boolean settings."),
+        }
+    }
+
+    fn byte_mask(&self) -> u8 {
+        match self.specific {
+            SpecificSetting::Bool(BoolSetting { bit_offset, .. }) => 1 << bit_offset,
+            _ => panic!("byte_for_value shouldn't be used for non-boolean settings."),
+        }
+    }
+}
+
+#[derive(Hash, PartialEq, Eq)]
+pub struct PresetIndex(usize);
+
+#[derive(Hash, PartialEq, Eq)]
+pub enum PresetType {
+    BoolSetting(BoolSettingIndex),
+    OtherPreset(PresetIndex),
+}
+
+impl Into<PresetType> for BoolSettingIndex {
+    fn into(self) -> PresetType {
+        PresetType::BoolSetting(self)
+    }
+}
+impl Into<PresetType> for PresetIndex {
+    fn into(self) -> PresetType {
+        PresetType::OtherPreset(self)
+    }
+}
+
+#[derive(Hash, PartialEq, Eq)]
+pub struct Preset {
+    pub name: &'static str,
+    values: Vec<BoolSettingIndex>,
+}
+
+impl Preset {
+    pub fn layout(&self, group: &SettingGroup) -> Vec<(u8, u8)> {
+        let mut layout: Vec<(u8, u8)> = iter::repeat((0, 0))
+            .take(group.settings_size as usize)
+            .collect();
+        for bool_index in &self.values {
+            let setting = &group.settings[bool_index.0];
+            let mask = setting.byte_mask();
+            let val = setting.byte_for_value(true);
+            assert!((val & !mask) == 0);
+            let (l_mask, l_val) = layout.get_mut(setting.byte_offset as usize).unwrap();
+            *l_mask |= mask;
+            *l_val = (*l_val & !mask) | val;
+        }
+        layout
+    }
+}
+
+pub struct SettingGroup {
+    pub name: &'static str,
+    pub settings: Vec<Setting>,
+    pub bool_start_byte_offset: u8,
+    pub settings_size: u8,
+    pub presets: Vec<Preset>,
+    pub predicates: Vec<Predicate>,
+}
+
+impl SettingGroup {
+    fn num_bool_settings(&self) -> u8 {
+        self.settings
+            .iter()
+            .filter(|s| {
+                if let SpecificSetting::Bool(_) = s.specific {
+                    true
+                } else {
+                    false
+                }
+            })
+            .count() as u8
+    }
+
+    pub fn byte_size(&self) -> u8 {
+        let num_predicates = self.num_bool_settings() + (self.predicates.len() as u8);
+        self.bool_start_byte_offset + (num_predicates + 7) / 8
+    }
+
+    pub fn get_bool(&self, name: &'static str) -> (BoolSettingIndex, &Self) {
+        for (i, s) in self.settings.iter().enumerate() {
+            if let SpecificSetting::Bool(_) = s.specific {
+                if s.name == name {
+                    return (BoolSettingIndex(i), self);
+                }
+            }
+        }
+        panic!("Should have found bool setting by name.");
+    }
+}
+
+/// This is the basic information needed to track the specific parts of a setting when building
+/// them.
+pub enum ProtoSpecificSetting {
+    Bool(bool, u8),
+    Enum(Vec<&'static str>),
+    Num(u8),
+}
+
+/// This is the information provided during building for a setting.
+struct ProtoSetting {
+    name: &'static str,
+    comment: &'static str,
+    specific: ProtoSpecificSetting,
+}
+
+#[derive(Hash, PartialEq, Eq)]
+pub enum PredicateNode {
+    OwnedBool(BoolSettingIndex),
+    SharedBool(&'static str, &'static str),
+    And(Box<PredicateNode>, Box<PredicateNode>),
+}
+
+impl Into<PredicateNode> for BoolSettingIndex {
+    fn into(self) -> PredicateNode {
+        PredicateNode::OwnedBool(self)
+    }
+}
+impl<'a> Into<PredicateNode> for (BoolSettingIndex, &'a SettingGroup) {
+    fn into(self) -> PredicateNode {
+        let (index, group) = (self.0, self.1);
+        let setting = &group.settings[index.0];
+        PredicateNode::SharedBool(group.name, setting.name)
+    }
+}
+
+impl PredicateNode {
+    fn render(&self, group: &SettingGroup) -> String {
+        match self {
+            PredicateNode::OwnedBool(bool_setting_index) => format!(
+                "{}.{}()",
+                group.name, group.settings[bool_setting_index.0].name
+            ),
+            PredicateNode::SharedBool(group_name, bool_name) => {
+                format!("{}.{}()", group_name, bool_name)
+            }
+            PredicateNode::And(lhs, rhs) => {
+                format!("{} && {}", lhs.render(group), rhs.render(group))
+            }
+        }
+    }
+}
+
+pub struct Predicate {
+    pub name: &'static str,
+    node: PredicateNode,
+    pub number: u8,
+}
+
+impl Predicate {
+    pub fn render(&self, group: &SettingGroup) -> String {
+        self.node.render(group)
+    }
+}
+
+pub struct SettingGroupBuilder {
+    name: &'static str,
+    settings: Vec<ProtoSetting>,
+    presets: Vec<Preset>,
+    predicates: Vec<Predicate>,
+    predicate_number: u8,
+}
+
+impl SettingGroupBuilder {
+    pub fn new(name: &'static str) -> Self {
+        Self {
+            name,
+            settings: Vec::new(),
+            presets: Vec::new(),
+            predicates: Vec::new(),
+            predicate_number: 0,
+        }
+    }
+
+    fn add_setting(
+        &mut self,
+        name: &'static str,
+        comment: &'static str,
+        specific: ProtoSpecificSetting,
+    ) {
+        self.settings.push(ProtoSetting {
+            name,
+            comment,
+            specific,
+        })
+    }
+
+    pub fn add_bool(
+        &mut self,
+        name: &'static str,
+        comment: &'static str,
+        default: bool,
+    ) -> BoolSettingIndex {
+        assert!(
+            self.predicates.len() == 0,
+            "predicates must be added after the boolean settings"
+        );
+        let predicate_number = self.predicate_number;
+        self.predicate_number += 1;
+        self.add_setting(
+            name,
+            comment,
+            ProtoSpecificSetting::Bool(default, predicate_number),
+        );
+        BoolSettingIndex(self.settings.len() - 1)
+    }
+
+    pub fn add_enum(
+        &mut self,
+        name: &'static str,
+        comment: &'static str,
+        values: Vec<&'static str>,
+    ) {
+        self.add_setting(name, comment, ProtoSpecificSetting::Enum(values));
+    }
+
+    pub fn add_num(&mut self, name: &'static str, comment: &'static str, default: u8) {
+        self.add_setting(name, comment, ProtoSpecificSetting::Num(default));
+    }
+
+    pub fn add_predicate(&mut self, name: &'static str, node: PredicateNode) {
+        let number = self.predicate_number;
+        self.predicate_number += 1;
+        self.predicates.push(Predicate { name, node, number });
+    }
+
+    pub fn add_preset(&mut self, name: &'static str, args: Vec<PresetType>) -> PresetIndex {
+        let mut values = Vec::new();
+        for arg in args {
+            match arg {
+                PresetType::OtherPreset(index) => {
+                    values.extend(self.presets[index.0].values.iter());
+                }
+                PresetType::BoolSetting(index) => values.push(index),
+            }
+        }
+        self.presets.push(Preset { name, values });
+        PresetIndex(self.presets.len() - 1)
+    }
+
+    /// Compute the layout of the byte vector used to represent this settings
+    /// group.
+    ///
+    /// The byte vector contains the following entries in order:
+    ///
+    /// 1. Byte-sized settings like `NumSetting` and `EnumSetting`.
+    /// 2. `BoolSetting` settings.
+    /// 3. Precomputed named predicates.
+    /// 4. Other numbered predicates, including anonymous predicates and parent
+    ///    predicates that need to be accessible by number.
+    ///
+    /// Set `self.settings_size` to the length of the byte vector prefix that
+    /// contains the settings. All bytes after that are computed, not
+    /// configured.
+    ///
+    /// Set `self.boolean_offset` to the beginning of the numbered predicates,
+    /// 2. in the list above.
+    ///
+    /// Assign `byte_offset` and `bit_offset` fields in all settings.
+    ///
+    /// After calling this method, no more settings can be added, but
+    /// additional predicates can be made accessible with `number_predicate()`.
+    pub fn finish(self) -> SettingGroup {
+        let mut group = SettingGroup {
+            name: self.name,
+            settings: Vec::new(),
+            bool_start_byte_offset: 0,
+            settings_size: 0,
+            presets: Vec::new(),
+            predicates: Vec::new(),
+        };
+
+        let mut byte_offset = 0;
+
+        // Assign the non-boolean settings first.
+        for s in &self.settings {
+            let specific = match s.specific {
+                ProtoSpecificSetting::Bool(..) => continue,
+                ProtoSpecificSetting::Enum(ref values) => SpecificSetting::Enum(values.clone()),
+                ProtoSpecificSetting::Num(default) => SpecificSetting::Num(default),
+            };
+
+            group.settings.push(Setting {
+                name: s.name,
+                comment: s.comment,
+                byte_offset,
+                specific,
+            });
+
+            byte_offset += 1;
+        }
+
+        group.bool_start_byte_offset = byte_offset;
+
+        // Then the boolean settings.
+        for s in &self.settings {
+            let (default, predicate_number) = match s.specific {
+                ProtoSpecificSetting::Bool(default, predicate_number) => {
+                    (default, predicate_number)
+                }
+                ProtoSpecificSetting::Enum(_) | ProtoSpecificSetting::Num(_) => continue,
+            };
+            group.settings.push(Setting {
+                name: s.name,
+                comment: s.comment,
+                byte_offset: byte_offset + predicate_number / 8,
+                specific: SpecificSetting::Bool(BoolSetting {
+                    default,
+                    bit_offset: predicate_number % 8,
+                    predicate_number,
+                }),
+            });
+        }
+
+        assert!(
+            group.predicates.len() == 0,
+            "settings_size is the byte size before adding predicates"
+        );
+        group.settings_size = group.byte_size();
+
+        group.predicates.extend(self.predicates);
+        group.presets.extend(self.presets);
+
+        group
+    }
+}
--- a/third_party/rust/cranelift-codegen-meta/src/cdsl/types.rs
+++ b/third_party/rust/cranelift-codegen-meta/src/cdsl/types.rs
@@ -185,29 +185,30 @@ impl LaneType {
             LaneType::BoolType(ref b) => *b as u64,
             LaneType::FloatType(ref f) => *f as u64,
             LaneType::IntType(ref i) => *i as u64,
         }
     }
 
     /// Find the unique number associated with this lane type.
     pub fn number(self) -> u8 {
-        LANE_BASE + match self {
-            LaneType::BoolType(base_types::Bool::B1) => 0,
-            LaneType::BoolType(base_types::Bool::B8) => 1,
-            LaneType::BoolType(base_types::Bool::B16) => 2,
-            LaneType::BoolType(base_types::Bool::B32) => 3,
-            LaneType::BoolType(base_types::Bool::B64) => 4,
-            LaneType::IntType(base_types::Int::I8) => 5,
-            LaneType::IntType(base_types::Int::I16) => 6,
-            LaneType::IntType(base_types::Int::I32) => 7,
-            LaneType::IntType(base_types::Int::I64) => 8,
-            LaneType::FloatType(base_types::Float::F32) => 9,
-            LaneType::FloatType(base_types::Float::F64) => 10,
-        }
+        LANE_BASE
+            + match self {
+                LaneType::BoolType(base_types::Bool::B1) => 0,
+                LaneType::BoolType(base_types::Bool::B8) => 1,
+                LaneType::BoolType(base_types::Bool::B16) => 2,
+                LaneType::BoolType(base_types::Bool::B32) => 3,
+                LaneType::BoolType(base_types::Bool::B64) => 4,
+                LaneType::IntType(base_types::Int::I8) => 5,
+                LaneType::IntType(base_types::Int::I16) => 6,
+                LaneType::IntType(base_types::Int::I32) => 7,
+                LaneType::IntType(base_types::Int::I64) => 8,
+                LaneType::FloatType(base_types::Float::F32) => 9,
+                LaneType::FloatType(base_types::Float::F64) => 10,
+            }
     }
 }
 
 impl fmt::Display for LaneType {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         match *self {
             LaneType::BoolType(_) => write!(f, "b{}", self.lane_bits()),
             LaneType::FloatType(_) => write!(f, "f{}", self.lane_bits()),
new file mode 100644
--- /dev/null
+++ b/third_party/rust/cranelift-codegen-meta/src/constant_hash.rs
@@ -0,0 +1,50 @@
+pub fn simple_hash(s: &str) -> usize {
+    let mut h: u32 = 5381;
+    for c in s.chars() {
+        h = (h ^ c as u32).wrapping_add(h.rotate_right(6));
+    }
+    h as usize
+}
+
+/// Compute an open addressed, quadratically probed hash table containing
+/// `items`. The returned table is a list containing the elements of the
+/// iterable `items` and `None` in unused slots.
+pub fn generate_table<T, H: Fn(&T) -> usize>(items: &Vec<T>, hash_function: H) -> Vec<Option<&T>> {
+    let size = (1.20 * items.len() as f64) as usize;
+    // TODO do we really need the multiply by two here?
+    let size = if size.is_power_of_two() {
+        size * 2
+    } else {
+        size.next_power_of_two()
+    };
+
+    let mut table: Vec<Option<&T>> = Vec::new();
+    table.resize(size, None);
+
+    for i in items {
+        let mut h = hash_function(i) % size;
+        let mut s = 0;
+        while table[h].is_some() {
+            s += 1;
+            h = (h + s) % size;
+        }
+        table[h] = Some(i);
+    }
+
+    table
+}
+
+#[test]
+fn test_generate_table() {
+    let v = vec!["Hello".to_string(), "world".to_string()];
+    let table = generate_table(&v, |s| simple_hash(&s));
+    assert_eq!(
+        table,
+        vec![
+            None,
+            Some(&"Hello".to_string()),
+            Some(&"world".to_string()),
+            None
+        ]
+    );
+}
--- a/third_party/rust/cranelift-codegen-meta/src/gen_registers.rs
+++ b/third_party/rust/cranelift-codegen-meta/src/gen_registers.rs
@@ -73,17 +73,17 @@ fn gen_regbank_units(reg_bank: &RegBank,
         if (unit as usize) < reg_bank.names.len() {
             fmt.line(&format!("{} = {},", reg_bank.names[unit as usize], v));
             continue;
         }
         fmt.line(&format!("{}{} = {},", reg_bank.prefix, unit, v));
     }
 }
 
-fn gen_isa(isa: &TargetIsa, fmt: &mut Formatter) -> Result<(), error::Error> {
+fn gen_isa(isa: &TargetIsa, fmt: &mut Formatter) {
     // Emit RegInfo.
     fmt.line("pub static INFO: RegInfo = RegInfo {");
 
     fmt.indent(|fmt| {
         fmt.line("banks: &[");
         // Bank descriptors.
         fmt.indent(|fmt| {
             for reg_bank in isa.reg_banks.values() {
@@ -123,18 +123,16 @@ fn gen_isa(isa: &TargetIsa, fmt: &mut Fo
     fmt.indent(|fmt| {
         fmt.line("fn into(self) -> RegUnit {");
         fmt.indent(|fmt| {
             fmt.line("self as RegUnit");
         });
         fmt.line("}")
     });
     fmt.line("}");
-
-    Ok(())
 }
 
-pub fn generate(isa: TargetIsa, base_filename: &str, out_dir: &str) -> Result<(), error::Error> {
+pub fn generate(isa: &TargetIsa, base_filename: &str, out_dir: &str) -> Result<(), error::Error> {
     let mut fmt = Formatter::new();
-    gen_isa(&isa, &mut fmt)?;
+    gen_isa(&isa, &mut fmt);
     fmt.update_file(&format!("{}-{}.rs", base_filename, isa.name), out_dir)?;
     Ok(())
 }
new file mode 100644
--- /dev/null
+++ b/third_party/rust/cranelift-codegen-meta/src/gen_settings.rs
@@ -0,0 +1,447 @@
+use base;
+use cdsl::camel_case;
+use cdsl::isa::TargetIsa;
+use cdsl::settings::{BoolSetting, Predicate, Preset, Setting, SettingGroup, SpecificSetting};
+use constant_hash::{generate_table, simple_hash};
+use error;
+use srcgen::{Formatter, Match};
+use std::collections::HashMap;
+use unique_table::UniqueTable;
+
+enum ParentGroup {
+    None,
+    Shared,
+}
+
+/// Emits the constructor of the Flags structure.
+fn gen_constructor(group: &SettingGroup, parent: ParentGroup, fmt: &mut Formatter) {
+    let args = match parent {
+        ParentGroup::None => "builder: Builder",
+        ParentGroup::Shared => "shared: &settings::Flags, builder: Builder",
+    };
+    fmt.line("impl Flags {");
+    fmt.indent(|fmt| {
+        fmt.doc_comment(&format!("Create flags {} settings group.", group.name));
+        fmt.line("#[allow(unused_variables)]");
+        fmt.line(&format!("pub fn new({}) -> Self {{", args));
+        fmt.indent(|fmt| {
+            fmt.line(&format!(
+                "let bvec = builder.state_for(\"{}\");",
+                group.name
+            ));
+            fmt.line(&format!(
+                "let mut {} = Self {{ bytes: [0; {}] }};",
+                group.name,
+                group.byte_size()
+            ));
+            fmt.line(&format!(
+                "debug_assert_eq!(bvec.len(), {});",
+                group.settings_size
+            ));
+            fmt.line(&format!(
+                "{}.bytes[0..{}].copy_from_slice(&bvec);",
+                group.name, group.settings_size
+            ));
+
+            // Now compute the predicates.
+            for p in &group.predicates {
+                fmt.comment(&format!("Precompute #{}.", p.number));
+                fmt.line(&format!("if {} {{", p.render(group)));
+                fmt.indent(|fmt| {
+                    fmt.line(&format!(
+                        "{}.bytes[{}] |= 1 << {};",
+                        group.name,
+                        group.bool_start_byte_offset + p.number / 8,
+                        p.number % 8
+                    ));
+                });
+                fmt.line("}");
+            }
+
+            fmt.line(group.name);
+        });
+        fmt.line("}");
+    });
+    fmt.line("}");
+}
+
+/// Emit Display and FromStr implementations for enum settings.
+fn gen_to_and_from_str(name: &str, values: &[&'static str], fmt: &mut Formatter) {
+    fmt.line(&format!("impl fmt::Display for {} {{", name));
+    fmt.indent(|fmt| {
+        fmt.line("fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {");
+        fmt.indent(|fmt| {
+            fmt.line("f.write_str(match *self {");
+            fmt.indent(|fmt| {
+                for v in values.iter() {
+                    fmt.line(&format!("{}::{} => \"{}\",", name, camel_case(v), v));
+                }
+            });
+            fmt.line("})");
+        });
+        fmt.line("}");
+    });
+    fmt.line("}");
+
+    fmt.line(&format!("impl str::FromStr for {} {{", name));
+    fmt.indent(|fmt| {
+        fmt.line("type Err = ();");
+        fmt.line("fn from_str(s: &str) -> Result<Self, Self::Err> {");
+        fmt.indent(|fmt| {
+            fmt.line("match s {");
+            fmt.indent(|fmt| {
+                for v in values.iter() {
+                    fmt.line(&format!("\"{}\" => Ok({}::{}),", v, name, camel_case(v)));
+                }
+                fmt.line("_ => Err(()),");
+            });
+            fmt.line("}");
+        });
+        fmt.line("}");
+    });
+    fmt.line("}");
+}
+
+/// Emit real enum for the Enum settings.
+fn gen_enum_types(group: &SettingGroup, fmt: &mut Formatter) {
+    for setting in group.settings.iter() {
+        let values = match setting.specific {
+            SpecificSetting::Bool(_) | SpecificSetting::Num(_) => continue,
+            SpecificSetting::Enum(ref values) => values,
+        };
+        let name = camel_case(setting.name);
+
+        fmt.doc_comment(&format!("Values for `{}.{}`.", group.name, setting.name));
+        fmt.line("#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]");
+        fmt.line(&format!("pub enum {} {{", name));
+        fmt.indent(|fmt| {
+            for v in values.iter() {
+                fmt.doc_comment(&format!("`{}`.", v));
+                fmt.line(&format!("{},", camel_case(v)));
+            }
+        });
+        fmt.line("}");
+
+        gen_to_and_from_str(&name, values, fmt);
+    }
+}
+
+/// Emit a getter function for `setting`.
+fn gen_getter(setting: &Setting, fmt: &mut Formatter) {
+    fmt.doc_comment(setting.comment);
+    match setting.specific {
+        SpecificSetting::Bool(BoolSetting {
+            predicate_number, ..
+        }) => {
+            fmt.line(&format!("pub fn {}(&self) -> bool {{", setting.name));
+            fmt.indent(|fmt| {
+                fmt.line(&format!("self.numbered_predicate({})", predicate_number));
+            });
+            fmt.line("}");
+        }
+        SpecificSetting::Enum(ref values) => {
+            let ty = camel_case(setting.name);
+            fmt.line(&format!("pub fn {}(&self) -> {} {{", setting.name, ty));
+            fmt.indent(|fmt| {
+                let mut m = Match::new(format!("self.bytes[{}]", setting.byte_offset));
+                for (i, v) in values.iter().enumerate() {
+                    m.arm(
+                        format!("{}", i),
+                        vec![],
+                        format!("{}::{}", ty, camel_case(v)),
+                    );
+                }
+                m.arm("_", vec![], "panic!(\"Invalid enum value\")");
+                fmt.add_match(m);
+            });
+            fmt.line("}");
+        }
+        SpecificSetting::Num(_) => {
+            fmt.line(&format!("pub fn {}(&self) -> u8 {{", setting.name));
+            fmt.indent(|fmt| {
+                fmt.line(&format!("self.bytes[{}]", setting.byte_offset));
+            });
+            fmt.line("}");
+        }
+    }
+}
+
+fn gen_pred_getter(predicate: &Predicate, group: &SettingGroup, fmt: &mut Formatter) {
+    fmt.doc_comment(&format!(
+        "Computed predicate `{}`.",
+        predicate.render(group)
+    ));
+    fmt.line(&format!("pub fn {}(&self) -> bool {{", predicate.name));
+    fmt.indent(|fmt| {
+        fmt.line(&format!("self.numbered_predicate({})", predicate.number));
+    });
+    fmt.line("}");
+}
+
+/// Emits getters for each setting value.
+fn gen_getters(group: &SettingGroup, fmt: &mut Formatter) {
+    fmt.doc_comment("User-defined settings.");
+    fmt.line("#[allow(dead_code)]");
+    fmt.line("impl Flags {");
+    fmt.indent(|fmt| {
+        fmt.doc_comment("Get a view of the boolean predicates.");
+        fmt.line("pub fn predicate_view(&self) -> ::settings::PredicateView {");
+        fmt.indent(|fmt| {
+            fmt.line(&format!(
+                "::settings::PredicateView::new(&self.bytes[{}..])",
+                group.bool_start_byte_offset
+            ));
+        });
+        fmt.line("}");
+
+        if group.settings.len() > 0 {
+            fmt.doc_comment("Dynamic numbered predicate getter.");
+            fmt.line("fn numbered_predicate(&self, p: usize) -> bool {");
+            fmt.indent(|fmt| {
+                fmt.line(&format!(
+                    "self.bytes[{} + p / 8] & (1 << (p % 8)) != 0",
+                    group.bool_start_byte_offset
+                ));
+            });
+            fmt.line("}");
+        }
+
+        for setting in &group.settings {
+            gen_getter(&setting, fmt);
+        }
+        for predicate in &group.predicates {
+            gen_pred_getter(&predicate, &group, fmt);
+        }
+    });
+    fmt.line("}");
+}
+
+#[derive(Hash, PartialEq, Eq)]
+enum SettingOrPreset<'a> {
+    Setting(&'a Setting),
+    Preset(&'a Preset),
+}
+
+impl<'a> SettingOrPreset<'a> {
+    fn name(&self) -> &str {
+        match self {
+            SettingOrPreset::Setting(s) => s.name,
+            SettingOrPreset::Preset(p) => p.name,
+        }
+    }
+}
+
+/// Emits DESCRIPTORS, ENUMERATORS, HASH_TABLE and PRESETS.
+fn gen_descriptors(group: &SettingGroup, fmt: &mut Formatter) {
+    let mut enum_table: UniqueTable<&'static str> = UniqueTable::new();
+
+    let mut descriptor_index_map: HashMap<SettingOrPreset, usize> = HashMap::new();
+
+    // Generate descriptors.
+    fmt.line(&format!(
+        "static DESCRIPTORS: [detail::Descriptor; {}] = [",
+        group.settings.len() + group.presets.len()
+    ));
+    fmt.indent(|fmt| {
+        for (idx, setting) in group.settings.iter().enumerate() {
+            fmt.line("detail::Descriptor {");
+            fmt.indent(|fmt| {
+                fmt.line(&format!("name: \"{}\",", setting.name));
+                fmt.line(&format!("offset: {},", setting.byte_offset));
+                match &setting.specific {
+                    SpecificSetting::Bool(BoolSetting { bit_offset, .. }) => {
+                        fmt.line(&format!(
+                            "detail: detail::Detail::Bool {{ bit: {} }},",
+                            bit_offset
+                        ));
+                    }
+                    SpecificSetting::Enum(values) => {
+                        let offset = enum_table.add(values);
+                        fmt.line(&format!(
+                            "detail: detail::Detail::Enum {{ last: {}, enumerators: {} }},",
+                            values.len() - 1,
+                            offset
+                        ));
+                    }
+                    SpecificSetting::Num(_) => {
+                        fmt.line("detail: detail::Detail::Num,");
+                    }
+                }
+
+                descriptor_index_map.insert(SettingOrPreset::Setting(setting), idx);
+            });
+            fmt.line("},");
+        }
+
+        for (idx, preset) in group.presets.iter().enumerate() {
+            fmt.line("detail::Descriptor {");
+            fmt.indent(|fmt| {
+                fmt.line(&format!("name: \"{}\",", preset.name));
+                fmt.line(&format!("offset: {},", (idx as u8) * group.settings_size));
+                fmt.line("detail: detail::Detail::Preset,");
+            });
+            fmt.line("},");
+
+            descriptor_index_map.insert(SettingOrPreset::Preset(preset), idx);
+        }
+    });
+    fmt.line("];");
+
+    // Generate enumerators.
+    fmt.line(&format!(
+        "static ENUMERATORS: [&str; {}] = [",
+        enum_table.len()
+    ));
+    fmt.indent(|fmt| {
+        for enum_val in enum_table.iter() {
+            fmt.line(&format!("\"{}\",", enum_val));
+        }
+    });
+    fmt.line("];");
+
+    // Generate hash table.
+    let mut hash_entries: Vec<SettingOrPreset> = Vec::new();
+    hash_entries.extend(
+        group
+            .settings
+            .iter()
+            .map(|x| SettingOrPreset::Setting(x))
+            .collect::<Vec<SettingOrPreset>>(),
+    );
+    hash_entries.extend(
+        group
+            .presets
+            .iter()
+            .map(|x| SettingOrPreset::Preset(x))
+            .collect::<Vec<SettingOrPreset>>(),
+    );
+    let hash_table = generate_table(&hash_entries, |entry| simple_hash(entry.name()));
+    fmt.line(&format!(
+        "static HASH_TABLE: [u16; {}] = [",
+        hash_table.len()
+    ));
+    fmt.indent(|fmt| {
+        for h in &hash_table {
+            match h {
+                Some(setting_or_preset) => fmt.line(&format!(
+                    "{},",
+                    &descriptor_index_map
+                        .get(setting_or_preset)
+                        .unwrap()
+                        .to_string()
+                )),
+                None => fmt.line("0xffff,"),
+            }
+        }
+    });
+    fmt.line("];");
+
+    // Generate presets.
+    fmt.line(&format!(
+        "static PRESETS: [(u8, u8); {}] = [",
+        group.presets.len()
+    ));
+    fmt.indent(|fmt| {
+        for preset in &group.presets {
+            fmt.comment(preset.name);
+            for (mask, value) in preset.layout(&group) {
+                fmt.line(&format!("(0b{:08b}, 0b{:08b}),", mask, value));
+            }
+        }
+    });
+    fmt.line("];");
+}
+
+fn gen_template(group: &SettingGroup, fmt: &mut Formatter) {
+    let mut default_bytes: Vec<u8> = Vec::new();
+    default_bytes.resize(group.settings_size as usize, 0);
+    for setting in &group.settings {
+        *default_bytes.get_mut(setting.byte_offset as usize).unwrap() |= setting.default_byte();
+    }
+
+    let default_bytes: Vec<String> = default_bytes
+        .iter()
+        .map(|x| format!("{:#04x}", x))
+        .collect();
+    let default_bytes_str = default_bytes.join(", ");
+
+    fmt.line("static TEMPLATE: detail::Template = detail::Template {");
+    fmt.indent(|fmt| {
+        fmt.line(&format!("name: \"{}\",", group.name));
+        fmt.line("descriptors: &DESCRIPTORS,");
+        fmt.line("enumerators: &ENUMERATORS,");
+        fmt.line("hash_table: &HASH_TABLE,");
+        fmt.line(&format!("defaults: &[{}],", default_bytes_str));
+        fmt.line("presets: &PRESETS,");
+    });
+    fmt.line("};");
+
+    fmt.doc_comment(&format!(
+        "Create a `settings::Builder` for the {} settings group.",
+        group.name
+    ));
+    fmt.line("pub fn builder() -> Builder {");
+    fmt.indent(|fmt| {
+        fmt.line("Builder::new(&TEMPLATE)");
+    });
+    fmt.line("}");
+}
+
+fn gen_display(group: &SettingGroup, fmt: &mut Formatter) {
+    fmt.line("impl fmt::Display for Flags {");
+    fmt.indent(|fmt| {
+        fmt.line("fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {");
+        fmt.indent(|fmt| {
+            fmt.line(&format!("writeln!(f, \"[{}]\")?;", group.name));
+            fmt.line("for d in &DESCRIPTORS {");
+            fmt.indent(|fmt| {
+                fmt.line("if !d.detail.is_preset() {");
+                fmt.indent(|fmt| {
+                    fmt.line("write!(f, \"{} = \", d.name)?;");
+                    fmt.line(
+                        "TEMPLATE.format_toml_value(d.detail, self.bytes[d.offset as usize], f)?;",
+                    );
+                    fmt.line("writeln!(f)?;");
+                });
+                fmt.line("}");
+            });
+            fmt.line("}");
+            fmt.line("Ok(())");
+        });
+        fmt.line("}")
+    });
+    fmt.line("}");
+}
+
+fn gen_group(group: &SettingGroup, parent: ParentGroup, fmt: &mut Formatter) {
+    // Generate struct.
+    fmt.line("#[derive(Clone)]");
+    fmt.doc_comment(&format!("Flags group `{}`.", group.name));
+    fmt.line("pub struct Flags {");
+    fmt.indent(|fmt| {
+        fmt.line(&format!("bytes: [u8; {}],", group.byte_size()));
+    });
+    fmt.line("}");
+
+    gen_constructor(group, parent, fmt);
+    gen_enum_types(group, fmt);
+    gen_getters(group, fmt);
+    gen_descriptors(group, fmt);
+    gen_template(group, fmt);
+    gen_display(group, fmt);
+}
+
+pub fn generate_common(filename: &str, out_dir: &str) -> Result<SettingGroup, error::Error> {
+    let settings = base::settings::generate();
+    let mut fmt = Formatter::new();
+    gen_group(&settings, ParentGroup::None, &mut fmt);
+    fmt.update_file(filename, out_dir)?;
+    Ok(settings)
+}
+
+pub fn generate(isa: &TargetIsa, prefix: &str, out_dir: &str) -> Result<(), error::Error> {
+    let mut fmt = Formatter::new();
+    gen_group(&isa.settings, ParentGroup::Shared, &mut fmt);
+    fmt.update_file(&format!("{}-{}.rs", prefix, isa.name), out_dir)?;
+    Ok(())
+}
--- a/third_party/rust/cranelift-codegen-meta/src/isa/arm32/mod.rs
+++ b/third_party/rust/cranelift-codegen-meta/src/isa/arm32/mod.rs
@@ -1,13 +1,19 @@
 use cdsl::isa::{TargetIsa, TargetIsaBuilder};
 use cdsl::regs::{RegBankBuilder, RegClassBuilder};
+use cdsl::settings::{SettingGroup, SettingGroupBuilder};
 
-pub fn define() -> TargetIsa {
-    let mut isa = TargetIsaBuilder::new("arm32");
+fn define_settings(_shared: &SettingGroup) -> SettingGroup {
+    let setting = SettingGroupBuilder::new("arm32");
+    setting.finish()
+}
+
+pub fn define(shared_settings: &SettingGroup) -> TargetIsa {
+    let mut isa = TargetIsaBuilder::new("arm32", define_settings(shared_settings));
 
     let builder = RegBankBuilder::new("FloatRegs", "s")
         .units(64)
         .track_pressure(true);
     let float_regs = isa.add_reg_bank(builder);
 
     let builder = RegBankBuilder::new("IntRegs", "r")
         .units(16)
--- a/third_party/rust/cranelift-codegen-meta/src/isa/arm64/mod.rs
+++ b/third_party/rust/cranelift-codegen-meta/src/isa/arm64/mod.rs
@@ -1,13 +1,19 @@
 use cdsl::isa::{TargetIsa, TargetIsaBuilder};
 use cdsl::regs::{RegBankBuilder, RegClassBuilder};
+use cdsl::settings::{SettingGroup, SettingGroupBuilder};
 
-pub fn define() -> TargetIsa {
-    let mut isa = TargetIsaBuilder::new("arm64");
+fn define_settings(_shared: &SettingGroup) -> SettingGroup {
+    let setting = SettingGroupBuilder::new("arm64");
+    setting.finish()
+}
+
+pub fn define(shared_settings: &SettingGroup) -> TargetIsa {
+    let mut isa = TargetIsaBuilder::new("arm64", define_settings(shared_settings));
 
     // The `x31` regunit serves as the stack pointer / zero register depending on context. We
     // reserve it and don't model the difference.
     let builder = RegBankBuilder::new("IntRegs", "x")
         .units(32)
         .track_pressure(true);
     let int_regs = isa.add_reg_bank(builder);
 
--- a/third_party/rust/cranelift-codegen-meta/src/isa/mod.rs
+++ b/third_party/rust/cranelift-codegen-meta/src/isa/mod.rs
@@ -1,9 +1,10 @@
 use cdsl::isa::TargetIsa;
+use cdsl::settings::SettingGroup;
 use std::fmt;
 
 mod arm32;
 mod arm64;
 mod riscv;
 mod x86;
 
 /// Represents known ISA target.
@@ -56,16 +57,16 @@ impl fmt::Display for Isa {
             Isa::Riscv => write!(f, "riscv"),
             Isa::X86 => write!(f, "x86"),
             Isa::Arm32 => write!(f, "arm32"),
             Isa::Arm64 => write!(f, "arm64"),
         }
     }
 }
 
-pub fn define_all() -> Vec<TargetIsa> {
+pub fn define_all(shared_settings: &SettingGroup) -> Vec<TargetIsa> {
     vec![
-        riscv::define(),
-        arm32::define(),
-        arm64::define(),
-        x86::define(),
+        riscv::define(shared_settings),
+        arm32::define(shared_settings),
+        arm64::define(shared_settings),
+        x86::define(shared_settings),
     ]
 }
--- a/third_party/rust/cranelift-codegen-meta/src/isa/riscv/mod.rs
+++ b/third_party/rust/cranelift-codegen-meta/src/isa/riscv/mod.rs
@@ -1,13 +1,66 @@
 use cdsl::isa::{TargetIsa, TargetIsaBuilder};
 use cdsl::regs::{RegBankBuilder, RegClassBuilder};
+use cdsl::settings::{PredicateNode, SettingGroup, SettingGroupBuilder};
 
-pub fn define() -> TargetIsa {
-    let mut isa = TargetIsaBuilder::new("riscv");
+fn define_settings(shared: &SettingGroup) -> SettingGroup {
+    let mut setting = SettingGroupBuilder::new("riscv");
+
+    let supports_m = setting.add_bool(
+        "supports_m",
+        "CPU supports the 'M' extension (mul/div)",
+        false,
+    );
+    let supports_a = setting.add_bool(
+        "supports_a",
+        "CPU supports the 'A' extension (atomics)",
+        false,
+    );
+    let supports_f = setting.add_bool(
+        "supports_f",
+        "CPU supports the 'F' extension (float)",
+        false,
+    );
+    let supports_d = setting.add_bool(
+        "supports_d",
+        "CPU supports the 'D' extension (double)",
+        false,
+    );
+
+    let enable_m = setting.add_bool(
+        "enable_m",
+        "Enable the use of 'M' instructions if available",
+        true,
+    );
+
+    setting.add_bool(
+        "enable_e",
+        "Enable the 'RV32E' instruction set with only 16 registers",
+        true,
+    );
+
+    let shared_enable_atomics = shared.get_bool("enable_atomics");
+    let shared_enable_float = shared.get_bool("enable_float");
+    let shared_enable_simd = shared.get_bool("enable_simd");
+
+    setting.add_predicate("use_m", predicate!(supports_m && enable_m));
+    setting.add_predicate("use_a", predicate!(supports_a && shared_enable_atomics));
+    setting.add_predicate("use_f", predicate!(supports_f && shared_enable_float));
+    setting.add_predicate("use_d", predicate!(supports_d && shared_enable_float));
+    setting.add_predicate(
+        "full_float",
+        predicate!(shared_enable_simd && supports_f && supports_d),
+    );
+
+    setting.finish()
+}
+
+pub fn define(shared_settings: &SettingGroup) -> TargetIsa {
+    let mut isa = TargetIsaBuilder::new("riscv", define_settings(shared_settings));
 
     let builder = RegBankBuilder::new("IntRegs", "x")
         .units(32)
         .track_pressure(true);
     let int_regs = isa.add_reg_bank(builder);
 
     let builder = RegBankBuilder::new("FloatRegs", "f")
         .units(32)
--- a/third_party/rust/cranelift-codegen-meta/src/isa/x86/mod.rs
+++ b/third_party/rust/cranelift-codegen-meta/src/isa/x86/mod.rs
@@ -1,14 +1,79 @@
 use cdsl::isa::{TargetIsa, TargetIsaBuilder};
 use cdsl::regs::{RegBankBuilder, RegClassBuilder};
+use cdsl::settings::{PredicateNode, SettingGroup, SettingGroupBuilder};
 
-pub fn define() -> TargetIsa {
-    let mut isa = TargetIsaBuilder::new("x86");
+pub fn define_settings(_shared: &SettingGroup) -> SettingGroup {
+    let mut settings = SettingGroupBuilder::new("x86");
+
+    // CPUID.01H:ECX
+    let has_sse3 = settings.add_bool("has_sse3", "SSE3: CPUID.01H:ECX.SSE3[bit 0]", false);
+    let has_ssse3 = settings.add_bool("has_ssse3", "SSSE3: CPUID.01H:ECX.SSSE3[bit 9]", false);
+    let has_sse41 = settings.add_bool("has_sse41", "SSE4.1: CPUID.01H:ECX.SSE4_1[bit 19]", false);
+    let has_sse42 = settings.add_bool("has_sse42", "SSE4.2: CPUID.01H:ECX.SSE4_2[bit 20]", false);
+    let has_popcnt = settings.add_bool("has_popcnt", "POPCNT: CPUID.01H:ECX.POPCNT[bit 23]", false);
+    settings.add_bool("has_avx", "AVX: CPUID.01H:ECX.AVX[bit 28]", false);
+
+    // CPUID.(EAX=07H, ECX=0H):EBX
+    let has_bmi1 = settings.add_bool(
+        "has_bmi1",
+        "BMI1: CPUID.(EAX=07H, ECX=0H):EBX.BMI1[bit 3]",
+        false,
+    );
+    let has_bmi2 = settings.add_bool(
+        "has_bmi2",
+        "BMI2: CPUID.(EAX=07H, ECX=0H):EBX.BMI2[bit 8]",
+        false,
+    );
+
+    // CPUID.EAX=80000001H:ECX
+    let has_lzcnt = settings.add_bool(
+        "has_lzcnt",
+        "LZCNT: CPUID.EAX=80000001H:ECX.LZCNT[bit 5]",
+        false,
+    );
 
+    settings.add_predicate("use_sse41", predicate!(has_sse41));
+    settings.add_predicate("use_sse42", predicate!(has_sse41 && has_sse42));
+    settings.add_predicate("use_popcnt", predicate!(has_popcnt && has_sse42));
+    settings.add_predicate("use_bmi1", predicate!(has_bmi1));
+    settings.add_predicate("use_lznct", predicate!(has_lzcnt));
+
+    settings.add_preset("baseline", preset!());
+    let nehalem = settings.add_preset(
+        "nehalem",
+        preset!(has_sse3 && has_ssse3 && has_sse41 && has_sse42 && has_popcnt),
+    );
+    let haswell = settings.add_preset(
+        "haswell",
+        preset!(nehalem && has_bmi1 && has_bmi2 && has_lzcnt),
+    );
+    let broadwell = settings.add_preset("broadwell", preset!(haswell));
+    let skylake = settings.add_preset("skylake", preset!(broadwell));
+    let cannonlake = settings.add_preset("cannonlake", preset!(skylake));
+    settings.add_preset("icelake", preset!(cannonlake));
+    settings.add_preset(
+        "znver1",
+        preset!(
+            has_sse3
+                && has_ssse3
+                && has_sse41
+                && has_sse42
+                && has_popcnt
+                && has_bmi1
+                && has_bmi2
+                && has_lzcnt
+        ),
+    );
+
+    settings.finish()
+}
+
+fn define_registers(isa: &mut TargetIsaBuilder) {
     let builder = RegBankBuilder::new("IntRegs", "r")
         .units(16)
         .names(vec!["rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi"])
         .track_pressure(true);
     let int_regs = isa.add_reg_bank(builder);
 
     let builder = RegBankBuilder::new("FloatRegs", "xmm")
         .units(16)
@@ -33,11 +98,19 @@ pub fn define() -> TargetIsa {
     let builder = RegClassBuilder::subclass_of("GPR8", gpr, 0, 8);
     let gpr8 = isa.add_reg_class(builder);
 
     let builder = RegClassBuilder::subclass_of("ABCD", gpr8, 0, 4);
     isa.add_reg_class(builder);
 
     let builder = RegClassBuilder::subclass_of("FPR8", fpr, 0, 8);
     isa.add_reg_class(builder);
+}
+
+pub fn define(shared_settings: &SettingGroup) -> TargetIsa {
+    let settings = define_settings(shared_settings);
+
+    let mut isa = TargetIsaBuilder::new("x86", settings);
+
+    define_registers(&mut isa);
 
     isa.finish()
 }
--- a/third_party/rust/cranelift-codegen-meta/src/lib.rs
+++ b/third_party/rust/cranelift-codegen-meta/src/lib.rs
@@ -1,11 +1,16 @@
 #[macro_use]
 extern crate cranelift_entity;
 
+#[macro_use]
+mod cdsl;
+
 pub mod error;
 pub mod gen_registers;
+pub mod gen_settings;
 pub mod gen_types;
 pub mod isa;
 
 mod base;
-mod cdsl;
+mod constant_hash;
 mod srcgen;
+mod unique_table;
--- a/third_party/rust/cranelift-codegen-meta/src/srcgen.rs
+++ b/third_party/rust/cranelift-codegen-meta/src/srcgen.rs
@@ -1,14 +1,15 @@
 //! Source code generator.
 //!
 //! The `srcgen` module contains generic helper routines and classes for
 //! generating source code.
 
-use std::collections::{BTreeMap, HashSet};
+use std::cmp;
+use std::collections::{BTreeMap, BTreeSet};
 use std::fs;
 use std::io::Write;
 use std::path;
 
 use error;
 
 static SHIFTWIDTH: usize = 4;
 
@@ -93,32 +94,60 @@ impl Formatter {
     }
 
     /// Add one or more lines after stripping common indentation.
     pub fn _multi_line(&mut self, s: &str) {
         parse_multiline(s).into_iter().for_each(|l| self.line(&l));
     }
 
     /// Add a comment line.
-    pub fn _comment(&mut self, s: &str) {
+    pub fn comment(&mut self, s: &str) {
         let commented_line = format!("// {}", s);
         self.line(&commented_line);
     }
 
     /// Add a (multi-line) documentation comment.
     pub fn doc_comment(&mut self, contents: &str) {
         parse_multiline(contents)
             .iter()
-            .map(|l| format!("/// {}", l))
+            .map(|l| {
+                if l.len() == 0 {
+                    "///".into()
+                } else {
+                    format!("/// {}", l)
+                }
+            })
             .for_each(|s| self.line(s.as_str()));
     }
 
     /// Add a match expression.
-    fn _add_match(&mut self, _m: &_Match) {
-        unimplemented!();
+    pub fn add_match(&mut self, m: Match) {
+        self.line(&format!("match {} {{", m.expr));
+        self.indent(|fmt| {
+            for ((fields, body), names) in m.arms.iter() {
+                // name { fields } | name { fields } => { body }
+                let conditions: Vec<String> = names
+                    .iter()
+                    .map(|name| {
+                        if fields.len() > 0 {
+                            format!("{} {{ {} }}", name, fields.join(", "))
+                        } else {
+                            name.clone()
+                        }
+                    })
+                    .collect();
+                let lhs = conditions.join(" | ");
+                fmt.line(&format!("{} => {{", lhs));
+                fmt.indent(|fmt| {
+                    fmt.line(body);
+                });
+                fmt.line("}");
+            }
+        });
+        self.line("}");
     }
 }
 
 /// Compute the indentation of s, or None of an empty line.
 fn _indent(s: &str) -> Option<usize> {
     if s.is_empty() {
         None
     } else {
@@ -130,36 +159,38 @@ fn _indent(s: &str) -> Option<usize> {
 /// Given a multi-line string, split it into a sequence of lines after
 /// stripping a common indentation. This is useful for strings defined with
 /// doc strings.
 fn parse_multiline(s: &str) -> Vec<String> {
     // Convert tabs into spaces.
     let expanded_tab = format!("{:-1$}", " ", SHIFTWIDTH);
     let lines: Vec<String> = s.lines().map(|l| l.replace("\t", &expanded_tab)).collect();
 
-    // Determine minimum indentation, ignoring the first line.
+    // Determine minimum indentation, ignoring the first line and empty lines.
     let indent = lines
         .iter()
         .skip(1)
+        .filter(|l| !l.trim().is_empty())
         .map(|l| l.len() - l.trim_left().len())
         .min();
 
     // Strip off leading blank lines.
     let mut lines_iter = lines.iter().skip_while(|l| l.is_empty());
     let mut trimmed = Vec::with_capacity(lines.len());
 
     // Remove indentation (first line is special)
     if let Some(s) = lines_iter.next().map(|l| l.trim()).map(|l| l.to_string()) {
         trimmed.push(s);
     }
 
     // Remove trailing whitespace from other lines.
     let mut other_lines = if let Some(indent) = indent {
+        // Note that empty lines may have fewer than `indent` chars.
         lines_iter
-            .map(|l| &l[indent..])
+            .map(|l| &l[cmp::min(indent, l.len())..])
             .map(|l| l.trim_right())
             .map(|l| l.to_string())
             .collect::<Vec<_>>()
     } else {
         lines_iter
             .map(|l| l.trim_right())
             .map(|l| l.to_string())
             .collect::<Vec<_>>()
@@ -181,70 +212,104 @@ fn parse_multiline(s: &str) -> Vec<Strin
 }
 
 /// Match formatting class.
 ///
 /// Match objects collect all the information needed to emit a Rust `match`
 /// expression, automatically deduplicating overlapping identical arms.
 ///
 /// Note that this class is ignorant of Rust types, and considers two fields
-/// with the same name to be equivalent. A BTreeMap is used to represent the
-/// arms in order to make the order deterministic.
-struct _Match<'a> {
-    _expr: &'a str,
-    arms: BTreeMap<(Vec<&'a str>, &'a str), HashSet<&'a str>>,
+/// with the same name to be equivalent. BTreeMap/BTreeSet are used to
+/// represent the arms in order to make the order deterministic.
+pub struct Match {
+    expr: String,
+    arms: BTreeMap<(Vec<String>, String), BTreeSet<String>>,
 }
 
-impl<'a> _Match<'a> {
+impl Match {
     /// Create a new match statement on `expr`.
-    fn _new(expr: &'a str) -> Self {
+    pub fn new<T: Into<String>>(expr: T) -> Self {
         Self {
-            _expr: expr,
+            expr: expr.into(),
             arms: BTreeMap::new(),
         }
     }
 
     /// Add an arm to the Match statement.
-    fn _arm(&mut self, name: &'a str, fields: Vec<&'a str>, body: &'a str) {
+    pub fn arm<T: Into<String>>(&mut self, name: T, fields: Vec<T>, body: T) {
         // let key = (fields, body);
-        let match_arm = self.arms.entry((fields, body)).or_insert_with(HashSet::new);
-        match_arm.insert(name);
+        let body = body.into();
+        let fields = fields.into_iter().map(|x| x.into()).collect();
+        let match_arm = self
+            .arms
+            .entry((fields, body))
+            .or_insert_with(BTreeSet::new);
+        match_arm.insert(name.into());
     }
 }
 
 #[cfg(test)]
 mod srcgen_tests {
-    use super::_Match;
     use super::parse_multiline;
     use super::Formatter;
+    use super::Match;
+
+    fn from_raw_string(s: impl Into<String>) -> Vec<String> {
+        s.into()
+            .trim()
+            .split("\n")
+            .into_iter()
+            .map(|x| format!("{}\n", x))
+            .collect()
+    }
 
     #[test]
     fn adding_arms_works() {
-        let mut m = _Match::_new("x");
-        m._arm("Orange", vec!["a", "b"], "some body");
-        m._arm("Yellow", vec!["a", "b"], "some body");
-        m._arm("Green", vec!["a", "b"], "different body");
-        m._arm("Blue", vec!["x", "y"], "some body");
+        let mut m = Match::new("x");
+        m.arm("Orange", vec!["a", "b"], "some body");
+        m.arm("Yellow", vec!["a", "b"], "some body");
+        m.arm("Green", vec!["a", "b"], "different body");
+        m.arm("Blue", vec!["x", "y"], "some body");
         assert_eq!(m.arms.len(), 3);
+
+        let mut fmt = Formatter::new();
+        fmt.add_match(m);
+
+        let expected_lines = from_raw_string(
+            r#"
+match x {
+    Green { a, b } => {
+        different body
+    }
+    Orange { a, b } | Yellow { a, b } => {
+        some body
+    }
+    Blue { x, y } => {
+        some body
+    }
+}
+        "#,
+        );
+        assert_eq!(fmt.lines, expected_lines);
     }
 
     #[test]
     fn parse_multiline_works() {
         let input = "\n    hello\n    world\n";
         let expected = vec!["hello", "world"];
         let output = parse_multiline(input);
         assert_eq!(output, expected);
     }
 
     #[test]
     fn formatter_basic_example_works() {
         let mut fmt = Formatter::new();
         fmt.line("Hello line 1");
         fmt.indent_push();
-        fmt._comment("Nested comment");
+        fmt.comment("Nested comment");
         fmt.indent_pop();
         fmt.line("Back home again");
         let expected_lines = vec![
             "Hello line 1\n",
             "    // Nested comment\n",
             "Back home again\n",
         ];
         assert_eq!(fmt.lines, expected_lines);
@@ -289,9 +354,29 @@ mod srcgen_tests {
 
     #[test]
     fn fmt_can_add_doc_comments() {
         let mut fmt = Formatter::new();
         fmt.doc_comment("documentation\nis\ngood");
         let expected_lines = vec!["/// documentation\n", "/// is\n", "/// good\n"];
         assert_eq!(fmt.lines, expected_lines);
     }
+
+    #[test]
+    fn fmt_can_add_doc_comments_with_empty_lines() {
+        let mut fmt = Formatter::new();
+        fmt.doc_comment(
+            r#"documentation
+        can be really good.
+
+        If you stick to writing it.
+"#,
+        );
+        let expected_lines = from_raw_string(
+            r#"
+/// documentation
+/// can be really good.
+///
+/// If you stick to writing it."#,
+        );
+        assert_eq!(fmt.lines, expected_lines);
+    }
 }
new file mode 100644
--- /dev/null
+++ b/third_party/rust/cranelift-codegen-meta/src/unique_table.rs
@@ -0,0 +1,68 @@
+use std::slice;
+
+/// A table of sequences which tries to avoid common subsequences.
+pub struct UniqueTable<T: PartialEq + Clone> {
+    table: Vec<T>,
+}
+
+impl<T: PartialEq + Clone> UniqueTable<T> {
+    pub fn new() -> Self {
+        Self { table: Vec::new() }
+    }
+    pub fn add(&mut self, values: &Vec<T>) -> usize {
+        if let Some(offset) = find_subsequence(values, &self.table) {
+            offset
+        } else {
+            let offset = self.table.len();
+            self.table.extend((*values).clone());
+            offset
+        }
+    }
+    pub fn len(&self) -> usize {
+        self.table.len()
+    }
+    pub fn iter(&self) -> slice::Iter<T> {
+        self.table.iter()
+    }
+}
+
+/// Try to find the subsequence `sub` in the `whole` sequence. Returns None if
+/// it's not been found, or Some(index) if it has been. Naive implementation
+/// until proven we need something better.
+fn find_subsequence<T: PartialEq>(sub: &Vec<T>, whole: &Vec<T>) -> Option<usize> {
+    assert!(sub.len() > 0);
+    // We want i + sub.len() <= whole.len(), i.e. i < whole.len() + 1 - sub.len().
+    if whole.len() < sub.len() {
+        return None;
+    }
+    let max = whole.len() + 1 - sub.len();
+    for i in 0..max {
+        let mut found: Option<usize> = Some(i);
+        for j in 0..sub.len() {
+            if sub[j] != whole[i + j] {
+                found = None;
+                break;
+            }
+        }
+        if found.is_some() {
+            return found;
+        }
+    }
+    return None;
+}
+
+#[test]
+fn test_find_subsequence() {
+    assert_eq!(find_subsequence(&vec![1], &vec![4]), None);
+    assert_eq!(find_subsequence(&vec![1], &vec![1]), Some(0));
+    assert_eq!(find_subsequence(&vec![1, 2], &vec![1]), None);
+    assert_eq!(find_subsequence(&vec![1, 2], &vec![1, 2]), Some(0));
+    assert_eq!(find_subsequence(&vec![1, 2], &vec![1, 3]), None);
+    assert_eq!(find_subsequence(&vec![1, 2], &vec![0, 1, 2]), Some(1));
+    assert_eq!(find_subsequence(&vec![1, 2], &vec![0, 1, 3, 1]), None);
+    assert_eq!(find_subsequence(&vec![1, 2], &vec![0, 1, 3, 1, 2]), Some(3));
+    assert_eq!(
+        find_subsequence(&vec![1, 1, 3], &vec![1, 1, 1, 3, 3]),
+        Some(1)
+    );
+}
--- 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":"d6b246e5928dba1141afc7402f2ac29dfd6e467640efc77282e5cb9080f1bf99","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"e5127227a7db4a8aa92fa6613ed71801025790e696bb41b0323fb7f3c6f7495a","build.rs":"dc816beb002843cd9fcdb47dae9a0a8e3612882411f18bed34d7fda1aa108d90","meta-python/base/__init__.py":"4fac8bb055541dc964383bb04223bae6dfbfe348abf5e23f83655966cbb4aa8f","meta-python/base/entities.py":"0e146dd56dfb93cac88f9557a3501c9804cff584c2723db27435842bb5e2a1b7","meta-python/base/formats.py":"f9fb41210bc1f99a78cb7a60ee9f01c603412c6b1db7e69abbcc0f573cf9fb40","meta-python/base/immediates.py":"f42682d86bda7b569ec2fc2debd9036355999e61caaa9fbf8307e0be8a164814","meta-python/base/instructions.py":"4c3f8ee6c29e8cc9e19172f707890d613ed4173bda9b9de7857dae2b28babcbd","meta-python/base/legalize.py":"57b71ec3599fbf998c1926e4b48566661b7feec01dbd8bd177d0d2aaa26a44c2","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":"b72a80a54e09366878e92dca3a1508af394bf71a0c4b07a05e54058901373d34","meta-python/cdsl/__init__.py":"b531693b8228553ca8bd07e1dcd1aa5855f1ad3741b431d758fc27fdd162b024","meta-python/cdsl/ast.py":"b7c09f69b28b5754f494912ca5b77722dbd4ee416d5fad79cb48322eb544ea9f","meta-python/cdsl/formats.py":"fedfeaec754b40d6a9cc92b827976782c615d8eab1c7f47f6b47510cbef585f4","meta-python/cdsl/instructions.py":"b0ddfd8fd22889bd1e610c103d47087c9c6ae5882862ed44921dafc2ae0463a0","meta-python/cdsl/isa.py":"dc530a4dd5642e3379398dfc8a90ad6ae1692302de63851370bdfa8abf4cdce0","meta-python/cdsl/operands.py":"e24914eae4059b88781bf5a5d7a14ecf98b10a701ed6cf6e88d15981b2ccbfdf","meta-python/cdsl/predicates.py":"def3f91712744671df9cf3d4f9c255a2061f341198689e31addf7db4efb63e36","meta-python/cdsl/registers.py":"939dafd1b8976a6cd456c9a5e4b374af81fafb9da979ea3a1f6d14e4645914a6","meta-python/cdsl/settings.py":"18dc27dd98a82c814c6aeb2686b40d1fed23661bef5e8b4cbf0fb4e7d39f4755","meta-python/cdsl/test_ast.py":"947e934e2862445a158bf266dff58a8c88aae31fb34a7f823309ee58a15c5393","meta-python/cdsl/test_package.py":"ffa53d20e023ecb89137294bb13614f4de9b09e1bf05d9772131570bf78f7987","meta-python/cdsl/test_ti.py":"57966c9eb027fa73bbc7ad81094ff55232053fbb2e16d78849ae3b6e9b1c2989","meta-python/cdsl/test_typevar.py":"714b2d564af1a843629279501436d681cd6590d1988b59e9f50ec940506538bb","meta-python/cdsl/test_xform.py":"ddb6633c7941bbf68570701cb887a81d6b4b27f4bc45eabccf2ce287ad9b77e9","meta-python/cdsl/ti.py":"a1a7ff79f8a2196aee491a3aafbd4f1b231004bbb5281992fc8f4e43f4fb951f","meta-python/cdsl/types.py":"adee4bbc1a9478288fa4b53ee1edeb5ee3296dba2c70bfbe01e923895064999e","meta-python/cdsl/typevar.py":"b5669934eddaf5b9cc0c27b966e2566b5f669f1c5a345f005960930fb499097e","meta-python/cdsl/xform.py":"5cdad80f12d50aa9491cd3d39797e6c0444936bb0874199d7c34e6d735658b34","meta-python/check.sh":"9e2f70f2d762c840f1d49519b024b4c1b93168137184b5e3e605e55813c62ea5","meta-python/constant_hash.py":"c752e6dadf3a9a5bd00c978e85ab27a20c49138a1ccdc6fc9a1904797a4bfe48","meta-python/gen_binemit.py":"76472fb199a330b934ba9ad0a1bbacfb52f0eae7c9a66d83f0d7890970323a2d","meta-python/gen_build_deps.py":"3920c5c89451c26102f7d87c61de64c94e915a545bc8a35d2e49106aecf019ec","meta-python/gen_encoding.py":"0b57d9d74a72a1b3b11721166fdbaa8b8c4b2d7493fc10b88736ac330b83256f","meta-python/gen_instr.py":"7ccd6a6bb1ce1800ea9c2c37e462ac7ded4f908e311d708080f7d21d92578316","meta-python/gen_legalizer.py":"187a47f1702e07487fb8a13076aadcf9c2de3e801d367424dc847ff7b0ed70f1","meta-python/gen_settings.py":"44c231ab8d2aa4f18cbe4fb5a33fb72103503d58f5af22c7b545eeffbf97da79","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":"dc758c5bf95b9271e70203c481df0dc9b3363c4f730cfc564e4e3f5f275a6433","meta-python/isa/x86/instructions.py":"530cde78e6b9f6e4ea2192985f4c5c77a987cdc19001d50fb47fa8e36a62f52e","meta-python/isa/x86/legalize.py":"1375ded072c29459e7c0e40ecb02f28d5395d9d8c603eb70e338b2bf2991c9cd","meta-python/isa/x86/recipes.py":"ca56edb2bb87389e2db95d0f0e0fdbf9b27242192de764d60971828bb9a02e60","meta-python/isa/x86/registers.py":"ff934491d07ec6b51fbfd454b865a7c7c191ffbd31b1804615735266b120f4b2","meta-python/isa/x86/settings.py":"d779a768475cf00c2a8d3ddb5cd0a70ce34662e0ebb52ee26a7e1a495ec41aa2","meta-python/mypy.ini":"5ec2f7cc0bbc4fd0435643d6b72e715bd9568a3a0fe14c043f9e559c405b66fb","meta-python/semantics/__init__.py":"e8a25a111f2d9cc9fc7aa498a572a86403d31fe50a7ba59dd2e2560a17804e92","meta-python/semantics/elaborate.py":"3a3fbba83a6818c2d1ce236fd0413111380875a0307f7a5f4b5dd66d8ef714b1","meta-python/semantics/macros.py":"b218c52e1bd4f019dc14a27d315b4f3405a10e5bdc6f2523fe709c8faf91b418","meta-python/semantics/primitives.py":"4e5eb0c90fcc295686732c8c66ad7a793997645c9a676c97babf06823fd2b60d","meta-python/semantics/smtlib.py":"825edfbb9221bf59c02fea26e55d17cf32194da7a9f56ed0e035c44353481055","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":"f16edce7cb2ce53e55b1fc56b6f5ba6a0fc61b291ee4513ec859e36d69f0e285","meta-python/test_srcgen.py":"d6d7775e19a5b2621360c00eb6d92dfcb4568e49220993e0ceaac9628dbfd661","meta-python/unique_table.py":"5bd500667430c15f6ae586603d8612fb3bda07b072e40d86286e08392bdc3127","src/abi.rs":"29f505fdfcb6ec14e561bb408b99ab30ab69b96d1e283a1dcd55db9aff02dbe4","src/binemit/memorysink.rs":"8437e5f5c1b3e68b8e2d0de6fb3a4982f7a06390a0f8820b6379492408df8964","src/binemit/mod.rs":"2f95ea5f6ee20b8d56bdedcacdd41a609c5b999c02affca341d6a71eb59bc113","src/binemit/relaxation.rs":"5facfa8e15a26cba42210102a6fd735df1ba291adf512dabc85c0951239291f8","src/binemit/shrink.rs":"428679a02e44a7b3621a43c7d2e8d2f3b2cb50a36179a4d9862205c0ba34ae50","src/bitset.rs":"67fd02dd2acb9af73e45426e5cab1d2a74d568a11d11ee17ae6a4421f96cf741","src/cfg_printer.rs":"8c0fda88060c204985a6406ba46d7f0a69be96bb18c9fcfc70055d50986068ab","src/constant_hash.rs":"493cdf8f607eab01bb52f93d616fb6190c7c86d3a02e530b0ced30993d4bfda0","src/context.rs":"a44197bd5e05599b643c420d87ca4ad218a8c3ab2fb7b88655b2479014b117b2","src/cursor.rs":"523899307d471f63e9ca35ee4b3340cf55041561a05b199e11cc60f6ad2714f4","src/dbg.rs":"bae915e1f7544f725817b368aed00a6aaa9e394a454dc847d65ad44e54d78cb9","src/dce.rs":"6d015824ae0325f01bb523606d7e15dd5feeb72a75b947f40385feeba94555c8","src/divconst_magic_numbers.rs":"eac50e2353e17ab6f7d1da3bd8e0e8dc9e3122a160efba594d407eb6a8936cc7","src/dominator_tree.rs":"73032e0e7a0ab694aa3181222bccb40630bd6fbda33885a391fd662f7de7d540","src/flowgraph.rs":"fccfade2b24038e18d469e273976f418757159fde140642b5faeb3c664a756ce","src/fx.rs":"2fb53f141b3e6be1882a1e4afac4bc607ce694f045d9329ee823e0aca415898e","src/ir/builder.rs":"19aa7cef76b7577bdd9d769fb1260080a959f9bfdbac569fb1e38307a721a03c","src/ir/condcodes.rs":"5456a25798516245b0923c9e12ae0af5cc98c097fc6f3bc0bf2d7af5008667f7","src/ir/dfg.rs":"cf44ceda665e32d5bd4563d90094fdf519937adbd29096c7291065a2ebdcfbfe","src/ir/entities.rs":"1505347c2baa256b04f69384d1391f52e007d533cb4319d3826cf3046ec1df27","src/ir/extfunc.rs":"9a3535730a39a6b71ca9f1ed679f588e6c3fa48ee7a50489d90803f3134db4a6","src/ir/extname.rs":"5b50dddd0801dfe736433191502e405c879221a6e362be0e2919176b90b4d74c","src/ir/function.rs":"55feb0b0a2bf4a0d194a4d11fc297616c78d5edfa41504795742fd25e7af1399","src/ir/globalvalue.rs":"bf9b76430f6ba564d4e5db85dbebfddf952678be6914326a5549b569c064d03d","src/ir/heap.rs":"dc9d4f0eade20d58b3e2678c329452fbd5965c46d6121cbf5889f2588ae88772","src/ir/immediates.rs":"5f57bc2a46b7ca11e1e495e657cedbf493194025eceb6591ba8792aff6910f88","src/ir/instructions.rs":"2dd2ad70947122e791f41f6cbc7879fd201d4f96d19c138b56559428ba655dab","src/ir/jumptable.rs":"3fc108096e5404c4c30220cfaa4e359caa83bad747268bea88bbc0ac4b1bcd13","src/ir/layout.rs":"77210d256e39d339736ced5518c8d666da6359f656b972d6b6b19581ccaec329","src/ir/libcall.rs":"b35c8d0c90e686a176f9bd157ef6ab3819e8a0b974d0d24007a910ffb0d15f51","src/ir/memflags.rs":"5819e1171c620f171020bf26df9513eb6bee9890da8a7ebabbd1506b1d123f91","src/ir/mod.rs":"16566fb92fc16498d5a2699fa76dfdbc39665a4e8bae3040c03e4f3d2f07e3cb","src/ir/progpoint.rs":"d5191447f82bb612ae25ebceb5ecc2099a902be5aaecd5b9d418dcbd8a2747a5","src/ir/sourceloc.rs":"79eb71609b844839994fc735cd72edf53179eb659303a4150634928e207cee4f","src/ir/stackslot.rs":"d5d0c61555bf7060c58603047356b7db53b5b296497daed8eac356b9e724902d","src/ir/table.rs":"810e92631257e1e54577563df1da9709134438d0eab3db5e540500e69437a16b","src/ir/trapcode.rs":"233d73e4a2abbfc767aac7868d4adbb24cedaf8e7e42a640d590bda2e776784a","src/ir/types.rs":"1f93f886dba75f6bc267b35e2fc6ed1564074a8885af13d6c85c28574acf8436","src/ir/valueloc.rs":"5055897d9acba6d9c396b126889f9b2c7ff3f54a27c1ec5fe70d1a059d633b36","src/isa/arm32/abi.rs":"50ca3161a0f11ba1c2d5b0ff7523d332503cb6a6182695246e4284a486e18cab","src/isa/arm32/binemit.rs":"3197df7b15c223f3a9f2708311375ff423bb247381cf21e26da079f7933f5279","src/isa/arm32/enc_tables.rs":"dacb50bdacfa2085a6283818563e19874590d223e5decb5c91b968e0348e2bf7","src/isa/arm32/mod.rs":"798049325ca439444a5508f63ebb53bf2e0ab16b128c43417017bbdb2fd95742","src/isa/arm32/registers.rs":"0e5c32a218d685c6d37fb46788baedf6bede6be7d4f715808c13620636dfc472","src/isa/arm32/settings.rs":"145f59227c6087e7872f66a6d2183c66e061c40466e7b427a733136e41e41207","src/isa/arm64/abi.rs":"bfd0065a6c26eb407872959c9d7f64169591afa4d69816370e0900aa1ad4e46f","src/isa/arm64/binemit.rs":"159ab9eca03ac4aa7f55d51ab20585a5971d95a74c61953d1899ac863b06e2ec","src/isa/arm64/enc_tables.rs":"00ec8f53402f6cb73716db1adb3aca564574833cab58dc12b4dc6ba8c4529a73","src/isa/arm64/mod.rs":"4eef5f904f2219262c59dae7056af5adb7764074309dffc0be5b2357781dd1a6","src/isa/arm64/registers.rs":"7a8b207ed28737efc737e8e65ce79e7e7d3eecd23599890230dca8474c985026","src/isa/arm64/settings.rs":"7b466fcc2c58bc1846a72f08ec58900b3cf622ab2922ee9128e6dfe254907bf5","src/isa/call_conv.rs":"4bc8f8cc540ed54cf1e4c4688a1a8a975ed49a039a48d44a2c6b97f847b65ea8","src/isa/constraints.rs":"324d7c8655565f13b90a6c9587c9fb6c545ab3086201f434e1324fc5d6e5b3c7","src/isa/enc_tables.rs":"946a9fcdf7d0541e7e65aeafdf18b6a5cb9e3ea29a1ce3bf05c155f910acca3a","src/isa/encoding.rs":"032347d4e624449af7a35f7ba012339bc49fabae97b971818e922d6ca4510e59","src/isa/mod.rs":"a7f966ec68dd709f685157812c7cb40ed012b175666509b9d05fec57b60fdb37","src/isa/registers.rs":"c0014dc940e8a6da628c60e49f6261cebaee1e06e0ea1c172de5f797e600535c","src/isa/riscv/abi.rs":"1de6d0070126e0127ca6a63551a14d1b5c030cf9628538fd732301fd2bd34b5e","src/isa/riscv/binemit.rs":"3bdad2791447f51bfe5ecedb73b1aed8a6a8809790b1f26e3ff624a89163a026","src/isa/riscv/enc_tables.rs":"6bc179f95ef5634b64fb42ab67929c0aeb70ac8efccfc47dd8c9b1dbfe64a446","src/isa/riscv/mod.rs":"de0dd32005f6b0510e3c8a31bb7e58ab7e7cffb674169a08558794950db87126","src/isa/riscv/registers.rs":"794ac61343a8db66dc99b2ca964ea3986b47b37fe8b72575c644c1cdaabd2991","src/isa/riscv/settings.rs":"78ced69b82d89f83b5612a91d0acdac2616f9091b380ee3e4715adb31f95b232","src/isa/stack.rs":"ec96130c446cd7d637722f1603e38d5164498368b652f4b0454baf3227385ad4","src/isa/x86/abi.rs":"6a9f8a3c9ee0f09118be1f962c473f8f5269cc4eba25519ca84df25b8835cceb","src/isa/x86/binemit.rs":"f90820a1f9c4ad02f3507625d35f014f644d8cea93b0216bcc60cc05cc84eacc","src/isa/x86/enc_tables.rs":"aa4bd2992d08ad97e94aafa022cafd853e0978c7c139558885715f57bfcf49e7","src/isa/x86/mod.rs":"bc83c0e619e8603885359c472b4113bc83b8867dd2d8e83b27f798301c6df93c","src/isa/x86/registers.rs":"783ebbe4c3b4711fe1eac2cfd3bbea7c31a53c15c6028397c038ef4eb0b2aa06","src/isa/x86/settings.rs":"dcce098045c1115cd55f256dcd3e0ccaa5a0c9ad93b14fb8a4c680e95caf2b73","src/iterators.rs":"f85f52d3fa707a0eb974c92215b3e976923ce8f9481219f7812e0f2869c2bd37","src/legalizer/boundary.rs":"e86400b42ef60d42e05ed7d2c24dc815f16652b49ab0ee9048edadd460bd411d","src/legalizer/call.rs":"12f380d126765f0bc2da1cf298088fa98451e2d6bf56c34b755ff7077d14a4f1","src/legalizer/globalvalue.rs":"be6fc6e310dedde48e172453eccaa7cb416baa92e1adfc55f565d51159c930cc","src/legalizer/heap.rs":"c44a0845254187dfe7456b0b9efbfea25ae566772bc64b41ed93dd32a71f8e8a","src/legalizer/libcall.rs":"bf18267f502bf9bfbc3ff51bc05df480293a84422ea7f4c37dd0c75e97952766","src/legalizer/mod.rs":"f516c4e22fb66099678f753121dfa92128f2c4524ea4196e1b400e06e6649d44","src/legalizer/split.rs":"6869c2cc436215ed22abffa85c783ae205374eb74f6ec0fc0ddec2b983e799fe","src/legalizer/table.rs":"2aca27ea564c2ef02ed833c495156b9e1ddcee3c8a1b1e70347ab5907a381605","src/lib.rs":"1542f5cae0d80c408f190d225890da959e0b4033687b6c2480e83254341cba83","src/licm.rs":"dcdf4744a01489939955dd02d43be3522cfbc448d92b30796d512b10e784c503","src/loop_analysis.rs":"ab74f702649ddd16d3d91400c3c2aafed4f09d9af210f5e180dff15a82caf8ac","src/nan_canonicalization.rs":"e2b1f9935d14af9abe553de1eda5483cffdaa7098dd1a17ba9a98fa04280b22c","src/partition_slice.rs":"55b9e857f452baf4d6312779861f9ef93b3d5300467e752230ec6af14943efe3","src/postopt.rs":"f1fe06398c644cad19fd427323c74acdb237b5853ffb72148a2b2012b906e2a3","src/predicates.rs":"8e4c4afde65420d33621aedd80e4ce270d334c1b62a17d7879273a1719d49b41","src/print_errors.rs":"54282bd8480b0bab29cbf3c257cdb3faafb566f0c40f88e1ff6c41e742f99ff6","src/ref_slice.rs":"9be914b705eefcc6b4e38db573f56ad7b978f4b65c2f6f8f5516df78fb2206a4","src/regalloc/affinity.rs":"47e28f9ae7cebfc9b1006480143a3a5ab1b118ec761a163c4a670b63fdc47d0a","src/regalloc/coalescing.rs":"5ffab5529e5840e0dc3f13930788caf75ae9e15ce90d4f64f9f625b2ee495605","src/regalloc/coloring.rs":"baf4861cabfc897755bef0b25a8367148bd2468717b3571763a5cc599407e5c2","src/regalloc/context.rs":"794f9f0fb3b980feb3be57b95c152767cb318b81aca48c27197b01b7d529c48d","src/regalloc/diversion.rs":"cbb942a197081f9e537f3fed71a7ec6d6d1edc18b8536fa46a1dda316f46c776","src/regalloc/live_value_tracker.rs":"054efd9e8da0f33a158082f67a7c2c14f7c8632b1fc28d54941ca7bc9d5a46d6","src/regalloc/liveness.rs":"6886e52e68aee5b2e26fb0b6e073905e7fa963eb597657fc966e5758cda4c254","src/regalloc/liverange.rs":"3c6a34e35a912dce48fa9a579e82e14a7e64334d5572b0d74dbfbf42dd380804","src/regalloc/mod.rs":"6254df639f9289fd578e01b7dca99bc9c9e3c6680c6d031405e8df8d0cff31ad","src/regalloc/pressure.rs":"7c73ca1f54559b1d9f8ce587bdc067e74f3d47901058f7ae1e9277516624236f","src/regalloc/register_set.rs":"294a66b676189e4da3cbb9c66474e0dd1a86a00b8cc71d03762994ae0654e11f","src/regalloc/reload.rs":"6525e9488e797b49b7892ac7596d6100793bb1db97c5025b17e6b32546fbe2fe","src/regalloc/solver.rs":"853c6f16f68e75add56981b132d92e556a94d8cbd13fed311df2d75da08de03a","src/regalloc/spilling.rs":"aae3faab22dcd8704179941a5b9b8e2b160d43a7daa02cebca1d31b9d368794b","src/regalloc/virtregs.rs":"23447a8e6196681cfb2388e0204626a0ac992735eb01f3eed4781c1cdfb688e4","src/result.rs":"d43abf9b22c5ad772200889bba339bcc4455c7abb9f2f3a2af65fbbaf1130009","src/scoped_hash_map.rs":"102797c380a588f7c16d26bf3b6c9cff28d37c2d8168a382b265194cd8969212","src/settings.rs":"18f3b43b5ec916b5969a62a6bbf0b7b8f039a5f7930e406bb7e8f181f2dc0d2d","src/simple_gvn.rs":"05576f7e90555c668c91df0b63a0468fbf2ed1aee9bc4118b73461f8719ead1a","src/simple_preopt.rs":"cfafd0398bba0b3e2b91b5bf10617bd4048ba2b22345b3e5bfc403239903960a","src/stack_layout.rs":"ce0b4b188cc46fa5070139124ffb2d263d44acd08703e7043a40b5c1afa952fb","src/timing.rs":"79acc12600ace2b144f1d7d82e01c023596e418a84042cf70ef93df928cdcabf","src/topo_order.rs":"73ec442db1cc9a282cf9c5b715ad2f60c4d2872080c16fd04ef7091d56816fbd","src/unreachable_code.rs":"6fdea8f9afe9fbffe411bfef48fec7937cb41d51036fd190a3d0a5f0cc2894c6","src/verifier/cssa.rs":"8f41765d18474575faa7c44a0345549dabe0af07141e2f004a7db1c67486ce77","src/verifier/flags.rs":"0665b4cbeef762c3871ba3cc55b0b1a27c513e25cbd3f93a725aa3d636a23c72","src/verifier/liveness.rs":"6e827f05461bd6fb21b0ce99f02fae374f2d6ea6e7e14ba61e88983a1c6fac4b","src/verifier/locations.rs":"a83f7d58118a838651c80f55e2455736e79235691692488d8431b77be8093a58","src/verifier/mod.rs":"4e17623e454bf115661ddaf0be0c2554e87dd4fc83a0a7a18dc8337d66ee5de5","src/write.rs":"1e810d79ff90aa37c76e16df8d6e69af6e35f5d7c6fae325243d8e2d0568ac4d"},"package":"e92fa0fa287cf00a6739c46aba114957e0a8eeeb4f0d1aa65d6ed0699c34ca6b"}
\ No newline at end of file
+{"files":{"Cargo.toml":"d9dfa768b55bf0c8d669f9a5e3075f222153672a04036b324ac6ce3cc5a4e047","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"e5127227a7db4a8aa92fa6613ed71801025790e696bb41b0323fb7f3c6f7495a","build.rs":"cb22f35d8804da1227f345d53e09a3ba5d62af60842e77629dcc9e370a6af080","meta-python/base/__init__.py":"4fac8bb055541dc964383bb04223bae6dfbfe348abf5e23f83655966cbb4aa8f","meta-python/base/entities.py":"0e146dd56dfb93cac88f9557a3501c9804cff584c2723db27435842bb5e2a1b7","meta-python/base/formats.py":"f9fb41210bc1f99a78cb7a60ee9f01c603412c6b1db7e69abbcc0f573cf9fb40","meta-python/base/immediates.py":"f42682d86bda7b569ec2fc2debd9036355999e61caaa9fbf8307e0be8a164814","meta-python/base/instructions.py":"4874aae8ea4ef3a1ac59fe9fc7b18c031ac9c72e3559c1c834df76c7144aa5c4","meta-python/base/legalize.py":"57b71ec3599fbf998c1926e4b48566661b7feec01dbd8bd177d0d2aaa26a44c2","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":"b72a80a54e09366878e92dca3a1508af394bf71a0c4b07a05e54058901373d34","meta-python/cdsl/__init__.py":"b531693b8228553ca8bd07e1dcd1aa5855f1ad3741b431d758fc27fdd162b024","meta-python/cdsl/ast.py":"b7c09f69b28b5754f494912ca5b77722dbd4ee416d5fad79cb48322eb544ea9f","meta-python/cdsl/formats.py":"fedfeaec754b40d6a9cc92b827976782c615d8eab1c7f47f6b47510cbef585f4","meta-python/cdsl/instructions.py":"b0ddfd8fd22889bd1e610c103d47087c9c6ae5882862ed44921dafc2ae0463a0","meta-python/cdsl/isa.py":"dc530a4dd5642e3379398dfc8a90ad6ae1692302de63851370bdfa8abf4cdce0","meta-python/cdsl/operands.py":"e24914eae4059b88781bf5a5d7a14ecf98b10a701ed6cf6e88d15981b2ccbfdf","meta-python/cdsl/predicates.py":"def3f91712744671df9cf3d4f9c255a2061f341198689e31addf7db4efb63e36","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":"57966c9eb027fa73bbc7ad81094ff55232053fbb2e16d78849ae3b6e9b1c2989","meta-python/cdsl/test_typevar.py":"714b2d564af1a843629279501436d681cd6590d1988b59e9f50ec940506538bb","meta-python/cdsl/test_xform.py":"ddb6633c7941bbf68570701cb887a81d6b4b27f4bc45eabccf2ce287ad9b77e9","meta-python/cdsl/ti.py":"a1a7ff79f8a2196aee491a3aafbd4f1b231004bbb5281992fc8f4e43f4fb951f","meta-python/cdsl/types.py":"adee4bbc1a9478288fa4b53ee1edeb5ee3296dba2c70bfbe01e923895064999e","meta-python/cdsl/typevar.py":"b5669934eddaf5b9cc0c27b966e2566b5f669f1c5a345f005960930fb499097e","meta-python/cdsl/xform.py":"5cdad80f12d50aa9491cd3d39797e6c0444936bb0874199d7c34e6d735658b34","meta-python/check.sh":"707cda14534882e8d4593f93c056390560394c9bc8a687e99f10a56d7b09cb92","meta-python/constant_hash.py":"c752e6dadf3a9a5bd00c978e85ab27a20c49138a1ccdc6fc9a1904797a4bfe48","meta-python/gen_binemit.py":"76472fb199a330b934ba9ad0a1bbacfb52f0eae7c9a66d83f0d7890970323a2d","meta-python/gen_build_deps.py":"3920c5c89451c26102f7d87c61de64c94e915a545bc8a35d2e49106aecf019ec","meta-python/gen_encoding.py":"0b57d9d74a72a1b3b11721166fdbaa8b8c4b2d7493fc10b88736ac330b83256f","meta-python/gen_instr.py":"7ccd6a6bb1ce1800ea9c2c37e462ac7ded4f908e311d708080f7d21d92578316","meta-python/gen_legalizer.py":"187a47f1702e07487fb8a13076aadcf9c2de3e801d367424dc847ff7b0ed70f1","meta-python/gen_settings.py":"c2fce1d2f3811bf11ab07cbabf4fca0250e01aa4b09ab55ec7fa251bf8ca28fa","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":"3885bcb2558e754de812f8239b4b509a32a42bcb8d3158d0b8899b18f3d90ac5","meta-python/isa/x86/instructions.py":"530cde78e6b9f6e4ea2192985f4c5c77a987cdc19001d50fb47fa8e36a62f52e","meta-python/isa/x86/legalize.py":"1375ded072c29459e7c0e40ecb02f28d5395d9d8c603eb70e338b2bf2991c9cd","meta-python/isa/x86/recipes.py":"37fd53909174f9f8cc35156bd06b8e82d75d353d67586f169f5dfdf2bb39a805","meta-python/isa/x86/registers.py":"ff934491d07ec6b51fbfd454b865a7c7c191ffbd31b1804615735266b120f4b2","meta-python/isa/x86/settings.py":"d779a768475cf00c2a8d3ddb5cd0a70ce34662e0ebb52ee26a7e1a495ec41aa2","meta-python/mypy.ini":"5ec2f7cc0bbc4fd0435643d6b72e715bd9568a3a0fe14c043f9e559c405b66fb","meta-python/semantics/__init__.py":"e8a25a111f2d9cc9fc7aa498a572a86403d31fe50a7ba59dd2e2560a17804e92","meta-python/semantics/elaborate.py":"3a3fbba83a6818c2d1ce236fd0413111380875a0307f7a5f4b5dd66d8ef714b1","meta-python/semantics/macros.py":"b218c52e1bd4f019dc14a27d315b4f3405a10e5bdc6f2523fe709c8faf91b418","meta-python/semantics/primitives.py":"4e5eb0c90fcc295686732c8c66ad7a793997645c9a676c97babf06823fd2b60d","meta-python/semantics/smtlib.py":"825edfbb9221bf59c02fea26e55d17cf32194da7a9f56ed0e035c44353481055","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":"f16edce7cb2ce53e55b1fc56b6f5ba6a0fc61b291ee4513ec859e36d69f0e285","meta-python/test_srcgen.py":"d6d7775e19a5b2621360c00eb6d92dfcb4568e49220993e0ceaac9628dbfd661","meta-python/unique_table.py":"5bd500667430c15f6ae586603d8612fb3bda07b072e40d86286e08392bdc3127","src/abi.rs":"29f505fdfcb6ec14e561bb408b99ab30ab69b96d1e283a1dcd55db9aff02dbe4","src/binemit/memorysink.rs":"8437e5f5c1b3e68b8e2d0de6fb3a4982f7a06390a0f8820b6379492408df8964","src/binemit/mod.rs":"2f95ea5f6ee20b8d56bdedcacdd41a609c5b999c02affca341d6a71eb59bc113","src/binemit/relaxation.rs":"c814a42504e849d5c29fd935d8e4c74146f802f775e96f7df4a86576bd942660","src/binemit/shrink.rs":"428679a02e44a7b3621a43c7d2e8d2f3b2cb50a36179a4d9862205c0ba34ae50","src/bitset.rs":"67fd02dd2acb9af73e45426e5cab1d2a74d568a11d11ee17ae6a4421f96cf741","src/cfg_printer.rs":"8c0fda88060c204985a6406ba46d7f0a69be96bb18c9fcfc70055d50986068ab","src/constant_hash.rs":"442c010f832191225c3d21815e99bd087cfd3367e5a8ffe6204e75f53bd355c9","src/context.rs":"a44197bd5e05599b643c420d87ca4ad218a8c3ab2fb7b88655b2479014b117b2","src/cursor.rs":"523899307d471f63e9ca35ee4b3340cf55041561a05b199e11cc60f6ad2714f4","src/dbg.rs":"bae915e1f7544f725817b368aed00a6aaa9e394a454dc847d65ad44e54d78cb9","src/dce.rs":"6d015824ae0325f01bb523606d7e15dd5feeb72a75b947f40385feeba94555c8","src/divconst_magic_numbers.rs":"eac50e2353e17ab6f7d1da3bd8e0e8dc9e3122a160efba594d407eb6a8936cc7","src/dominator_tree.rs":"73032e0e7a0ab694aa3181222bccb40630bd6fbda33885a391fd662f7de7d540","src/flowgraph.rs":"fccfade2b24038e18d469e273976f418757159fde140642b5faeb3c664a756ce","src/fx.rs":"2fb53f141b3e6be1882a1e4afac4bc607ce694f045d9329ee823e0aca415898e","src/ir/builder.rs":"19aa7cef76b7577bdd9d769fb1260080a959f9bfdbac569fb1e38307a721a03c","src/ir/condcodes.rs":"5456a25798516245b0923c9e12ae0af5cc98c097fc6f3bc0bf2d7af5008667f7","src/ir/dfg.rs":"f5cd6efb9cfc158d3f13671e7d739746f1f009230ea0865baac5edc3f32a0122","src/ir/entities.rs":"1505347c2baa256b04f69384d1391f52e007d533cb4319d3826cf3046ec1df27","src/ir/extfunc.rs":"9a3535730a39a6b71ca9f1ed679f588e6c3fa48ee7a50489d90803f3134db4a6","src/ir/extname.rs":"5b50dddd0801dfe736433191502e405c879221a6e362be0e2919176b90b4d74c","src/ir/function.rs":"55feb0b0a2bf4a0d194a4d11fc297616c78d5edfa41504795742fd25e7af1399","src/ir/globalvalue.rs":"bf9b76430f6ba564d4e5db85dbebfddf952678be6914326a5549b569c064d03d","src/ir/heap.rs":"2e6c5ed8f4a1ac3cd37e5115ae978d48d61b9af100da0cff1b1b6d696907958e","src/ir/immediates.rs":"ccf1210052346a62a0914251a2da8c40e75b00e58102ef7975719b79eb644dd2","src/ir/instructions.rs":"2dd2ad70947122e791f41f6cbc7879fd201d4f96d19c138b56559428ba655dab","src/ir/jumptable.rs":"3fc108096e5404c4c30220cfaa4e359caa83bad747268bea88bbc0ac4b1bcd13","src/ir/layout.rs":"77210d256e39d339736ced5518c8d666da6359f656b972d6b6b19581ccaec329","src/ir/libcall.rs":"b35c8d0c90e686a176f9bd157ef6ab3819e8a0b974d0d24007a910ffb0d15f51","src/ir/memflags.rs":"26654b642e36bf11c0871e2b3e20cbdbaf8e53218a0bfef7b7bcfd9e838b51fc","src/ir/mod.rs":"16566fb92fc16498d5a2699fa76dfdbc39665a4e8bae3040c03e4f3d2f07e3cb","src/ir/progpoint.rs":"911046269d250102f8ae473411fda7ca7f1acd3d48a9392cacfe3b2e5188c321","src/ir/sourceloc.rs":"79eb71609b844839994fc735cd72edf53179eb659303a4150634928e207cee4f","src/ir/stackslot.rs":"d5d0c61555bf7060c58603047356b7db53b5b296497daed8eac356b9e724902d","src/ir/table.rs":"3550a5fb5af0d4992b4c7d23a3e790a411ad39c1351fa03b54add691e6232163","src/ir/trapcode.rs":"9d78e03784dbdaffb60228e82f4f6277dd78422668e9afa7614a0552158a93cd","src/ir/types.rs":"a56cf1844817171276907fa18f973783d4b6223e77bf3ee94dce7db442946433","src/ir/valueloc.rs":"5055897d9acba6d9c396b126889f9b2c7ff3f54a27c1ec5fe70d1a059d633b36","src/isa/arm32/abi.rs":"50ca3161a0f11ba1c2d5b0ff7523d332503cb6a6182695246e4284a486e18cab","src/isa/arm32/binemit.rs":"3197df7b15c223f3a9f2708311375ff423bb247381cf21e26da079f7933f5279","src/isa/arm32/enc_tables.rs":"dacb50bdacfa2085a6283818563e19874590d223e5decb5c91b968e0348e2bf7","src/isa/arm32/mod.rs":"798049325ca439444a5508f63ebb53bf2e0ab16b128c43417017bbdb2fd95742","src/isa/arm32/registers.rs":"0e5c32a218d685c6d37fb46788baedf6bede6be7d4f715808c13620636dfc472","src/isa/arm32/settings.rs":"145f59227c6087e7872f66a6d2183c66e061c40466e7b427a733136e41e41207","src/isa/arm64/abi.rs":"bfd0065a6c26eb407872959c9d7f64169591afa4d69816370e0900aa1ad4e46f","src/isa/arm64/binemit.rs":"159ab9eca03ac4aa7f55d51ab20585a5971d95a74c61953d1899ac863b06e2ec","src/isa/arm64/enc_tables.rs":"00ec8f53402f6cb73716db1adb3aca564574833cab58dc12b4dc6ba8c4529a73","src/isa/arm64/mod.rs":"4eef5f904f2219262c59dae7056af5adb7764074309dffc0be5b2357781dd1a6","src/isa/arm64/registers.rs":"7a8b207ed28737efc737e8e65ce79e7e7d3eecd23599890230dca8474c985026","src/isa/arm64/settings.rs":"7b466fcc2c58bc1846a72f08ec58900b3cf622ab2922ee9128e6dfe254907bf5","src/isa/call_conv.rs":"00d8ea90af7bc414d8bbe4eadcff4484c53ec74979a8677ff5e215d17d43dcac","src/isa/constraints.rs":"324d7c8655565f13b90a6c9587c9fb6c545ab3086201f434e1324fc5d6e5b3c7","src/isa/enc_tables.rs":"946a9fcdf7d0541e7e65aeafdf18b6a5cb9e3ea29a1ce3bf05c155f910acca3a","src/isa/encoding.rs":"032347d4e624449af7a35f7ba012339bc49fabae97b971818e922d6ca4510e59","src/isa/mod.rs":"da05b44fd82305c4b2fdcc16a7dbcc5281cf919cf6df09c305561e6e7772c719","src/isa/registers.rs":"dc0ab116f10adc0aa27bc9b7c688106966d221e0654bec7ec53ceaea3a8b784b","src/isa/riscv/abi.rs":"1de6d0070126e0127ca6a63551a14d1b5c030cf9628538fd732301fd2bd34b5e","src/isa/riscv/binemit.rs":"3bdad2791447f51bfe5ecedb73b1aed8a6a8809790b1f26e3ff624a89163a026","src/isa/riscv/enc_tables.rs":"6bc179f95ef5634b64fb42ab67929c0aeb70ac8efccfc47dd8c9b1dbfe64a446","src/isa/riscv/mod.rs":"de0dd32005f6b0510e3c8a31bb7e58ab7e7cffb674169a08558794950db87126","src/isa/riscv/registers.rs":"794ac61343a8db66dc99b2ca964ea3986b47b37fe8b72575c644c1cdaabd2991","src/isa/riscv/settings.rs":"78ced69b82d89f83b5612a91d0acdac2616f9091b380ee3e4715adb31f95b232","src/isa/stack.rs":"ec96130c446cd7d637722f1603e38d5164498368b652f4b0454baf3227385ad4","src/isa/x86/abi.rs":"c11c288c59edf834043b06eda3a271394e0dba6c719900f0a201ec6108197b69","src/isa/x86/binemit.rs":"f90820a1f9c4ad02f3507625d35f014f644d8cea93b0216bcc60cc05cc84eacc","src/isa/x86/enc_tables.rs":"aa4bd2992d08ad97e94aafa022cafd853e0978c7c139558885715f57bfcf49e7","src/isa/x86/mod.rs":"bc83c0e619e8603885359c472b4113bc83b8867dd2d8e83b27f798301c6df93c","src/isa/x86/registers.rs":"783ebbe4c3b4711fe1eac2cfd3bbea7c31a53c15c6028397c038ef4eb0b2aa06","src/isa/x86/settings.rs":"dcce098045c1115cd55f256dcd3e0ccaa5a0c9ad93b14fb8a4c680e95caf2b73","src/iterators.rs":"f85f52d3fa707a0eb974c92215b3e976923ce8f9481219f7812e0f2869c2bd37","src/legalizer/boundary.rs":"cbc6035ac90b9d2c8e621e3a058e3120afa144ee07f901d3370d01340e0331f9","src/legalizer/call.rs":"12f380d126765f0bc2da1cf298088fa98451e2d6bf56c34b755ff7077d14a4f1","src/legalizer/globalvalue.rs":"a8b7784692354cbe3577532103171bf9ca8a22aa077c6d06d91b055eb4be4f8a","src/legalizer/heap.rs":"86f642d07ac65fd29de6ad23907849e13747bc90b4c4fb18039d6ff3cfd2dc8a","src/legalizer/libcall.rs":"bf18267f502bf9bfbc3ff51bc05df480293a84422ea7f4c37dd0c75e97952766","src/legalizer/mod.rs":"bb79f504a3bfce92c4787d9c2a9385d81b0c02eb15fbe01ff66f355d95348c3a","src/legalizer/split.rs":"2e0ab9c35006d3743bdbd1ee6a4332b05af2c3e81137fed102422bac4a5ebc3f","src/legalizer/table.rs":"a695262e045e71456c641b576eeebed0c8666495a7e1a70abe60f861b599fae5","src/lib.rs":"7e08cb847189bd7faa3dd205867505f7f8ed97671d32e392848ec0d71a1df422","src/licm.rs":"dcdf4744a01489939955dd02d43be3522cfbc448d92b30796d512b10e784c503","src/loop_analysis.rs":"ab74f702649ddd16d3d91400c3c2aafed4f09d9af210f5e180dff15a82caf8ac","src/nan_canonicalization.rs":"e2b1f9935d14af9abe553de1eda5483cffdaa7098dd1a17ba9a98fa04280b22c","src/partition_slice.rs":"55b9e857f452baf4d6312779861f9ef93b3d5300467e752230ec6af14943efe3","src/postopt.rs":"f1fe06398c644cad19fd427323c74acdb237b5853ffb72148a2b2012b906e2a3","src/predicates.rs":"8e4c4afde65420d33621aedd80e4ce270d334c1b62a17d7879273a1719d49b41","src/print_errors.rs":"9db532d3ee4bb5d8265cbf36d371f2941a6dc0ea6f86d663dcdf54ede1bedd21","src/ref_slice.rs":"9be914b705eefcc6b4e38db573f56ad7b978f4b65c2f6f8f5516df78fb2206a4","src/regalloc/affinity.rs":"47e28f9ae7cebfc9b1006480143a3a5ab1b118ec761a163c4a670b63fdc47d0a","src/regalloc/coalescing.rs":"5ffab5529e5840e0dc3f13930788caf75ae9e15ce90d4f64f9f625b2ee495605","src/regalloc/coloring.rs":"beb4893d82e0a7965417c158c51e3752896b591f9db7d1c4803caa2b34154a29","src/regalloc/context.rs":"6ff7bfc76c63ff18850c1354c1e5e72287cc0a7d65d52ef9804223c750a09f7c","src/regalloc/diversion.rs":"cbb942a197081f9e537f3fed71a7ec6d6d1edc18b8536fa46a1dda316f46c776","src/regalloc/live_value_tracker.rs":"054efd9e8da0f33a158082f67a7c2c14f7c8632b1fc28d54941ca7bc9d5a46d6","src/regalloc/liveness.rs":"b21e4855c0339c1b15b1b62e63bb1a569c4256b42d08c3c21b6e7fc4634c5e62","src/regalloc/liverange.rs":"3c6a34e35a912dce48fa9a579e82e14a7e64334d5572b0d74dbfbf42dd380804","src/regalloc/mod.rs":"6254df639f9289fd578e01b7dca99bc9c9e3c6680c6d031405e8df8d0cff31ad","src/regalloc/pressure.rs":"7c73ca1f54559b1d9f8ce587bdc067e74f3d47901058f7ae1e9277516624236f","src/regalloc/register_set.rs":"dcdf30ec4ffeac26eabf85f585209a04617eef00bf59e6a1c0462f1dc3454700","src/regalloc/reload.rs":"714e598e968ca9498da969af2343cab7983ddbe160cef0a2d36543618885acf7","src/regalloc/solver.rs":"853c6f16f68e75add56981b132d92e556a94d8cbd13fed311df2d75da08de03a","src/regalloc/spilling.rs":"6ab899e036a50965b0b7d5fa9aef9077c68ae6932315ec2e14d71c2f3791d78f","src/regalloc/virtregs.rs":"5b12892ad360f8c2a8f7b1ffe40e467a88e64aa1c77c8012149c6653e46fb3d6","src/result.rs":"d43abf9b22c5ad772200889bba339bcc4455c7abb9f2f3a2af65fbbaf1130009","src/scoped_hash_map.rs":"102797c380a588f7c16d26bf3b6c9cff28d37c2d8168a382b265194cd8969212","src/settings.rs":"18f3b43b5ec916b5969a62a6bbf0b7b8f039a5f7930e406bb7e8f181f2dc0d2d","src/simple_gvn.rs":"05576f7e90555c668c91df0b63a0468fbf2ed1aee9bc4118b73461f8719ead1a","src/simple_preopt.rs":"cfafd0398bba0b3e2b91b5bf10617bd4048ba2b22345b3e5bfc403239903960a","src/stack_layout.rs":"ce0b4b188cc46fa5070139124ffb2d263d44acd08703e7043a40b5c1afa952fb","src/timing.rs":"7c05d910efbbca4138678cd463d5a1709bedc2c3fdbea239f3a47798252af05f","src/topo_order.rs":"73ec442db1cc9a282cf9c5b715ad2f60c4d2872080c16fd04ef7091d56816fbd","src/unreachable_code.rs":"6fdea8f9afe9fbffe411bfef48fec7937cb41d51036fd190a3d0a5f0cc2894c6","src/verifier/cssa.rs":"8f41765d18474575faa7c44a0345549dabe0af07141e2f004a7db1c67486ce77","src/verifier/flags.rs":"0665b4cbeef762c3871ba3cc55b0b1a27c513e25cbd3f93a725aa3d636a23c72","src/verifier/liveness.rs":"6e827f05461bd6fb21b0ce99f02fae374f2d6ea6e7e14ba61e88983a1c6fac4b","src/verifier/locations.rs":"a83f7d58118a838651c80f55e2455736e79235691692488d8431b77be8093a58","src/verifier/mod.rs":"9cad0ca7502bef8d99bb3519105630c364a276d6501fd6f3acbebd3692075efa","src/write.rs":"1e810d79ff90aa37c76e16df8d6e69af6e35f5d7c6fae325243d8e2d0568ac4d"},"package":"42f5b809bd885c368e01aeec8fe04f21dcb07569834b907d75b4a7bed8d067eb"}
\ No newline at end of file
--- a/third_party/rust/cranelift-codegen/Cargo.toml
+++ b/third_party/rust/cranelift-codegen/Cargo.toml
@@ -7,32 +7,32 @@
 #
 # If you believe there's an error in this file please file an
 # issue against the rust-lang/cargo repository. If you're
 # editing this file be aware that the upstream Cargo.toml
 # will likely look very different (and much more reasonable)
 
 [package]
 name = "cranelift-codegen"
-version = "0.25.0"
+version = "0.26.0"
 authors = ["The Cranelift Project Developers"]
 build = "build.rs"
 description = "Low-level code generator library"
 documentation = "https://cranelift.readthedocs.io/"
 readme = "README.md"
 keywords = ["compile", "compiler", "jit"]
 categories = ["no-std"]
 license = "Apache-2.0 WITH LLVM-exception"
 repository = "https://github.com/CraneStation/cranelift"
 [dependencies.cranelift-bforest]
-version = "0.25.0"
+version = "0.26.0"
 default-features = false
 
 [dependencies.cranelift-entity]
-version = "0.25.0"
+version = "0.26.0"
 default-features = false
 
 [dependencies.failure]
 version = "0.1.1"
 features = ["derive"]
 default-features = false
 
 [dependencies.failure_derive]
@@ -46,17 +46,17 @@ optional = true
 [dependencies.log]
 version = "0.4.4"
 default-features = false
 
 [dependencies.target-lexicon]
 version = "0.2.0"
 default-features = false
 [build-dependencies.cranelift-codegen-meta]
-version = "0.25.0"
+version = "0.26.0"
 
 [features]
 core = ["hashmap_core"]
 default = ["std"]
 std = ["cranelift-entity/std", "cranelift-bforest/std", "target-lexicon/std"]
 testing_hooks = []
 [badges.maintenance]
 status = "experimental"
--- a/third_party/rust/cranelift-codegen/build.rs
+++ b/third_party/rust/cranelift-codegen/build.rs
@@ -18,18 +18,21 @@
 // The build script expects to be run from the directory where this build.rs file lives. The
 // current directory is used to find the sources.
 
 extern crate cranelift_codegen_meta as meta;
 
 use meta::isa::Isa;
 use std::env;
 use std::process;
+use std::time::Instant;
 
 fn main() {
+    let start_time = Instant::now();
+
     let out_dir = env::var("OUT_DIR").expect("The OUT_DIR environment variable must be set");
     let target_triple = env::var("TARGET").expect("The TARGET environment variable must be set");
     let cranelift_targets = env::var("CRANELIFT_TARGETS").ok();
     let cranelift_targets = cranelift_targets.as_ref().map(|s| s.as_ref());
     let python = identify_python();
 
     // Configure isa targets cfg.
     match isa_targets(cranelift_targets, &target_triple) {
@@ -74,31 +77,45 @@ fn main() {
         process::exit(status.code().unwrap());
     }
 
     // DEVELOPMENT:
     // ------------------------------------------------------------------------
     // Now that the Python build process is complete, generate files that are
     // emitted by the `meta` crate.
     // ------------------------------------------------------------------------
-    let isas = meta::isa::define_all();
 
-    if let Err(err) = meta::gen_types::generate("types.rs", &out_dir) {
+    if let Err(err) = generate_meta(&out_dir) {
         eprintln!("Error: {}", err);
         process::exit(1);
     }
 
-    for isa in isas {
-        if let Err(err) = meta::gen_registers::generate(isa, "registers", &out_dir) {
-            eprintln!("Error: {}", err);
-            process::exit(1);
-        }
+    if let Ok(_) = env::var("CRANELIFT_VERBOSE") {
+        println!(
+            "cargo:warning=Build step took {:?}.",
+            Instant::now() - start_time
+        );
+        println!("cargo:warning=Generated files are in {}", out_dir);
     }
 }
 
+fn generate_meta(out_dir: &str) -> Result<(), meta::error::Error> {
+    let shared_settings = meta::gen_settings::generate_common("new_settings.rs", &out_dir)?;
+    let isas = meta::isa::define_all(&shared_settings);
+
+    meta::gen_types::generate("types.rs", &out_dir)?;
+
+    for isa in &isas {
+        meta::gen_registers::generate(&isa, "registers", &out_dir)?;
+        meta::gen_settings::generate(&isa, "new_settings", &out_dir)?;
+    }
+
+    Ok(())
+}
+
 fn identify_python() -> &'static str {
     for python in &["python", "python3", "python2.7"] {
         if process::Command::new(python)
             .arg("--version")
             .status()
             .is_ok()
         {
             return python;
--- a/third_party/rust/cranelift-codegen/meta-python/base/instructions.py
+++ b/third_party/rust/cranelift-codegen/meta-python/base/instructions.py
@@ -176,16 +176,20 @@ indirect_jump_table_br = Instruction(
     Branch indirectly via a jump table entry.
 
     Unconditionally jump via a jump table entry that was previously loaded
     with the ``jump_table_entry`` instruction.
     """,
     ins=(addr, JT),
     is_branch=True, is_indirect_branch=True, is_terminator=True)
 
+debugtrap = Instruction('debugtrap', r"""
+    Encodes an assembly debug trap.
+    """, can_load=True, can_store=True, other_side_effects=True)
+
 code = Operand('code', trapcode)
 trap = Instruction(
         'trap', r"""
         Terminate execution unconditionally.
         """,
         ins=code, is_terminator=True, can_trap=True)
 
 trapz = Instruction(
--- a/third_party/rust/cranelift-codegen/meta-python/cdsl/settings.py
+++ b/third_party/rust/cranelift-codegen/meta-python/cdsl/settings.py
@@ -335,17 +335,17 @@ class SettingGroup(object):
 
     def byte_size(self):
         # type: () -> int
         """
         Compute the number of bytes required to hold all settings and
         precomputed predicates.
 
         This is the size of the byte-sized settings plus all the numbered
-        predcate bits rounded up to a whole number of bytes.
+        predicate bits rounded up to a whole number of bytes.
         """
         return self.boolean_offset + (len(self.predicate_number) + 7) // 8
 
 
 class Preset(object):
     """
     A collection of setting values that are applied at once.
 
--- a/third_party/rust/cranelift-codegen/meta-python/check.sh
+++ b/third_party/rust/cranelift-codegen/meta-python/check.sh
@@ -12,17 +12,21 @@ function runif {
         echo "$1 not found"
     fi
 }
 
 # Style linting.
 runif flake8 .
 
 # Type checking.
-runif mypy --py2 build.py
+# TODO: Re-enable mypy on Travis osx. Pip currently installs mypy into a
+# directory which is not in the PATH.
+if [ "${TRAVIS_OS_NAME:-other}" != "osx" ]; then
+    runif mypy --py2 build.py
+fi
 
 # Python unit tests.
 runif python2.7 -m unittest discover
 
 # Then run the unit tests again with Python 3.
 # We get deprecation warnings about assertRaisesRegexp which was renamed in
 # Python 3, but there doesn't seem to be an easy workaround.
 runif python3 -Wignore:Deprecation -m unittest discover
--- a/third_party/rust/cranelift-codegen/meta-python/gen_settings.py
+++ b/third_party/rust/cranelift-codegen/meta-python/gen_settings.py
@@ -250,18 +250,18 @@ def gen_display(sgrp, fmt):
                     fmt.line('write!(f, "{} = ", d.name)?;')
                     fmt.line(
                             'TEMPLATE.format_toml_value(d.detail, ' +
                             'self.bytes[d.offset as usize], f)?;')
                     fmt.line('writeln!(f)?;')
             fmt.line('Ok(())')
 
 
-def gen_constructor(sgrp, parent, fmt):
-    # type: (SettingGroup, PredContext, srcgen.Formatter) -> None
+def gen_constructor(sgrp, fmt):
+    # type: (SettingGroup, srcgen.Formatter) -> None
     """
     Generate a Flags constructor.
     """
 
     with fmt.indented('impl Flags {', '}'):
         args = 'builder: Builder'
         if sgrp.parent:
             p = sgrp.parent
@@ -305,17 +305,17 @@ def gen_group(sgrp, fmt):
     """
     Generate a Flags struct representing `sgrp`.
     """
     fmt.line('#[derive(Clone)]')
     fmt.doc_comment('Flags group `{}`.'.format(sgrp.name))
     with fmt.indented('pub struct Flags {', '}'):
         fmt.line('bytes: [u8; {}],'.format(sgrp.byte_size()))
 
-    gen_constructor(sgrp, None, fmt)
+    gen_constructor(sgrp, fmt)
     gen_enum_types(sgrp, fmt)
     gen_getters(sgrp, fmt)
     gen_descriptors(sgrp, fmt)
     gen_template(sgrp, fmt)
     gen_display(sgrp, fmt)
 
 
 def generate(isas, out_dir):
--- a/third_party/rust/cranelift-codegen/meta-python/isa/x86/encodings.py
+++ b/third_party/rust/cranelift-codegen/meta-python/isa/x86/encodings.py
@@ -516,22 +516,27 @@ enc_both(base.brnz.b1, r.t8jccd_abcd, 0x
 X86_64.enc(base.jump_table_entry.i64.any.any, *r.jt_entry.rex(0x63, w=1))
 X86_32.enc(base.jump_table_entry.i32.any.any, *r.jt_entry(0x8b))
 
 X86_64.enc(base.jump_table_base.i64, *r.jt_base.rex(0x8d, w=1))
 X86_32.enc(base.jump_table_base.i32, *r.jt_base(0x8d))
 
 enc_x86_64(base.indirect_jump_table_br.i64, r.indirect_jmp, 0xff, rrr=4)
 X86_32.enc(base.indirect_jump_table_br.i32, *r.indirect_jmp(0xff, rrr=4))
+
 #
 # Trap as ud2
 #
 X86_32.enc(base.trap, *r.trap(0x0f, 0x0b))
 X86_64.enc(base.trap, *r.trap(0x0f, 0x0b))
 
+# Debug trap as int3
+X86_32.enc(base.debugtrap, r.debugtrap, 0)
+X86_64.enc(base.debugtrap, r.debugtrap, 0)
+
 # Using a standard EncRecipe, not the TailRecipe.
 X86_32.enc(base.trapif, r.trapif, 0)
 X86_64.enc(base.trapif, r.trapif, 0)
 X86_32.enc(base.trapff, r.trapff, 0)
 X86_64.enc(base.trapff, r.trapff, 0)
 
 #
 # Comparisons
--- a/third_party/rust/cranelift-codegen/meta-python/isa/x86/recipes.py
+++ b/third_party/rust/cranelift-codegen/meta-python/isa/x86/recipes.py
@@ -290,16 +290,21 @@ def valid_scale(iform):
               IsEqual(iform.imm, 4),
               IsEqual(iform.imm, 8))
 
 
 # A null unary instruction that takes a GPR register. Can be used for identity
 # copies and no-op conversions.
 null = EncRecipe('null', Unary, base_size=0, ins=GPR, outs=0, emit='')
 
+debugtrap = EncRecipe('debugtrap', NullAry, base_size=1, ins=(), outs=(),
+                      emit='''
+                      sink.put1(0xcc);
+                      ''')
+
 # XX opcode, no ModR/M.
 trap = TailRecipe(
         'trap', Trap, base_size=0, ins=(), outs=(),
         emit='''
         sink.trap(code, func.srclocs[inst]);
         PUT_OP(bits, BASE_REX, sink);
         ''')
 
--- a/third_party/rust/cranelift-codegen/src/binemit/relaxation.rs
+++ b/third_party/rust/cranelift-codegen/src/binemit/relaxation.rs
@@ -181,17 +181,18 @@ fn relax_branch(
                 // validity directly because we don't have a RegDiversions active so
                 // we don't know which registers are actually in use.
                 debug!("  trying [{}]: constraints differ", encinfo.display(enc));
                 false
             } else {
                 debug!("  trying [{}]: OK", encinfo.display(enc));
                 true
             }
-        }) {
+        })
+    {
         cur.func.encodings[inst] = enc;
         return encinfo.byte_size(enc, inst, &divert, &cur.func);
     }
 
     // Note: On some RISC ISAs, conditional branches have shorter range than unconditional
     // branches, so one way of extending the range of a conditional branch is to invert its
     // condition and make it branch over an unconditional jump which has the larger range.
     //
--- a/third_party/rust/cranelift-codegen/src/constant_hash.rs
+++ b/third_party/rust/cranelift-codegen/src/constant_hash.rs
@@ -51,17 +51,17 @@ pub fn probe<K: Copy + Eq, T: Table<K> +
         // entries. This means that this loop will always terminate if the hash table has even
         // one unused entry.
         debug_assert!(step < table.len());
         idx += step;
     }
 }
 
 /// A primitive hash function for matching opcodes.
-/// Must match `lib/codegen/meta-python/constant_hash.py`.
+/// Must match `lib/codegen/meta-python/constant_hash.py` and `lib/codegen/meta/constant_hash.rs`.
 pub fn simple_hash(s: &str) -> usize {
     let mut h: u32 = 5381;
     for c in s.chars() {
         h = (h ^ c as u32).wrapping_add(h.rotate_right(6));
     }
     h as usize
 }
 
--- a/third_party/rust/cranelift-codegen/src/ir/dfg.rs
+++ b/third_party/rust/cranelift-codegen/src/ir/dfg.rs
@@ -797,19 +797,19 @@ impl DataFlowGraph {
         } else {
             panic!("{} must be an EBB parameter", val);
         };
         self.ebbs[ebb]
             .params
             .remove(num as usize, &mut self.value_lists);
         for index in num..(self.num_ebb_params(ebb) as u16) {
             match self.values[self.ebbs[ebb]
-                                  .params
-                                  .get(index as usize, &self.value_lists)
-                                  .unwrap()]
+                .params
+                .get(index as usize, &self.value_lists)
+                .unwrap()]
             {
                 ValueData::Param { ref mut num, .. } => {
                     *num -= 1;
                 }
                 _ => panic!(
                     "{} must be an EBB parameter",
                     self.ebbs[ebb]
                         .params
--- a/third_party/rust/cranelift-codegen/src/ir/heap.rs
+++ b/third_party/rust/cranelift-codegen/src/ir/heap.rs
@@ -1,26 +1,26 @@
 //! Heaps.
 
-use ir::immediates::Imm64;
+use ir::immediates::Uimm64;
 use ir::{GlobalValue, Type};
 use std::fmt;
 
 /// Information about a heap declaration.
 #[derive(Clone)]
 pub struct HeapData {
     /// The address of the start of the heap's storage.
     pub base: GlobalValue,
 
     /// Guaranteed minimum heap size in bytes. Heap accesses before `min_size` don't need bounds
     /// checking.
-    pub min_size: Imm64,
+    pub min_size: Uimm64,
 
-    /// Size in bytes of the guard pages following the heap.
-    pub guard_size: Imm64,
+    /// Size in bytes of the offset-guard pages following the heap.
+    pub offset_guard_size: Uimm64,
 
     /// Heap style, with additional style-specific info.
     pub style: HeapStyle,
 
     /// The index type for the heap.
     pub index_type: Type,
 }
 
@@ -29,20 +29,20 @@ pub struct HeapData {
 pub enum HeapStyle {
     /// A dynamic heap can be relocated to a different base address when it is grown.
     Dynamic {
         /// Global value providing the current bound of the heap in bytes.
         bound_gv: GlobalValue,
     },
 
     /// A static heap has a fixed base address and a number of not-yet-allocated pages before the
-    /// guard pages.
+    /// offset-guard pages.
     Static {
-        /// Heap bound in bytes. The guard pages are allocated after the bound.
-        bound: Imm64,
+        /// Heap bound in bytes. The offset-guard pages are allocated after the bound.
+        bound: Uimm64,
     },
 }
 
 impl fmt::Display for HeapData {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         f.write_str(match self.style {
             HeapStyle::Dynamic { .. } => "dynamic",
             HeapStyle::Static { .. } => "static",
@@ -50,13 +50,13 @@ impl fmt::Display for HeapData {
 
         write!(f, " {}, min {}", self.base, self.min_size)?;
         match self.style {
             HeapStyle::Dynamic { bound_gv } => write!(f, ", bound {}", bound_gv)?,
             HeapStyle::Static { bound } => write!(f, ", bound {}", bound)?,
         }
         write!(
             f,
-            ", guard {}, index_type {}",
-            self.guard_size, self.index_type
+            ", offset_guard {}, index_type {}",
+            self.offset_guard_size, self.index_type
         )
     }
 }
--- a/third_party/rust/cranelift-codegen/src/ir/immediates.rs
+++ b/third_party/rust/cranelift-codegen/src/ir/immediates.rs
@@ -4,17 +4,17 @@
 //! Each type here should have a corresponding definition in the `cranelift.immediates` Python
 //! module in the meta language.
 
 use std::fmt::{self, Display, Formatter};
 use std::mem;
 use std::str::FromStr;
 use std::{i32, u32};
 
-/// 64-bit immediate integer operand.
+/// 64-bit immediate signed integer operand.
 ///
 /// An `Imm64` operand can also be used to represent immediate values of smaller integer types by
 /// sign-extending to `i64`.
 #[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
 pub struct Imm64(i64);
 
 impl Imm64 {
     /// Create a new `Imm64` representing the signed number `x`.
@@ -35,58 +35,128 @@ impl Into<i64> for Imm64 {
 }
 
 impl From<i64> for Imm64 {
     fn from(x: i64) -> Self {
         Imm64(x)
     }
 }
 
+impl Display for Imm64 {
+    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+        let x = self.0;
+        if -10_000 < x && x < 10_000 {
+            // Use decimal for small numbers.
+            write!(f, "{}", x)
+        } else {
+            write_hex(x as u64, f)
+        }
+    }
+}
+
+/// Parse a 64-bit signed number.
+fn parse_i64(s: &str) -> Result<i64, &'static str> {
+    let negative = s.starts_with('-');
+    let s2 = if negative || s.starts_with('+') {
+        &s[1..]
+    } else {
+        s
+    };
+
+    let mut value = parse_u64(s2)?;
+
+    // We support the range-and-a-half from -2^63 .. 2^64-1.
+    if negative {
+        value = value.wrapping_neg();
+        // Don't allow large negative values to wrap around and become positive.
+        if value as i64 > 0 {
+            return Err("Negative number too small");
+        }
+    }
+    Ok(value as i64)
+}
+
+impl FromStr for Imm64 {
+    type Err = &'static str;
+
+    // Parse a decimal or hexadecimal `Imm64`, formatted as above.
+    fn from_str(s: &str) -> Result<Self, &'static str> {
+        parse_i64(s).map(Self::new)
+    }
+}
+
+/// 64-bit immediate unsigned integer operand.
+///
+/// A `Uimm64` operand can also be used to represent immediate values of smaller integer types by
+/// zero-extending to `i64`.
+#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
+pub struct Uimm64(u64);
+
+impl Uimm64 {
+    /// Create a new `Uimm64` representing the unsigned number `x`.
+    pub fn new(x: u64) -> Self {
+        Uimm64(x)
+    }
+
+    /// Return self negated.
+    pub fn wrapping_neg(self) -> Self {
+        Uimm64(self.0.wrapping_neg())
+    }
+}
+
+impl Into<u64> for Uimm64 {
+    fn into(self) -> u64 {
+        self.0
+    }
+}
+
+impl From<u64> for Uimm64 {
+    fn from(x: u64) -> Self {
+        Uimm64(x)
+    }
+}
+
 /// Hexadecimal with a multiple of 4 digits and group separators:
 ///
 ///   0xfff0
 ///   0x0001_ffff
 ///   0xffff_ffff_fff8_4400
 ///
-fn write_hex(x: i64, f: &mut Formatter) -> fmt::Result {
+fn write_hex(x: u64, f: &mut Formatter) -> fmt::Result {
     let mut pos = (64 - x.leading_zeros() - 1) & 0xf0;
     write!(f, "0x{:04x}", (x >> pos) & 0xffff)?;
     while pos > 0 {
         pos -= 16;
         write!(f, "_{:04x}", (x >> pos) & 0xffff)?;
     }
     Ok(())
 }
 
-impl Display for Imm64 {
+impl Display for Uimm64 {
     fn fmt(&self, f: &mut Formatter) -> fmt::Result {
         let x = self.0;
-        if -10_000 < x && x < 10_000 {
+        if x < 10_000 {
             // Use decimal for small numbers.
             write!(f, "{}", x)
         } else {
             write_hex(x, f)
         }
     }
 }
 
-/// Parse a 64-bit number.
-fn parse_i64(s: &str) -> Result<i64, &'static str> {
+/// Parse a 64-bit unsigned number.
+fn parse_u64(s: &str) -> Result<u64, &'static str> {
     let mut value: u64 = 0;
     let mut digits = 0;
-    let negative = s.starts_with('-');
-    let s2 = if negative || s.starts_with('+') {
-        &s[1..]
-    } else {
-        s
-    };
 
-    if s2.starts_with("0x") {
+    if s.starts_with("-0x") {
+        return Err("Invalid character in hexadecimal number");
+    } else if s.starts_with("0x") {
         // Hexadecimal.
-        for ch in s2[2..].chars() {
+        for ch in s[2..].chars() {
             match ch.to_digit(16) {
                 Some(digit) => {
                     digits += 1;
                     if digits > 16 {
                         return Err("Too many hexadecimal digits");
                     }
                     // This can't overflow given the digit limit.
                     value = (value << 4) | u64::from(digit);
@@ -96,17 +166,17 @@ fn parse_i64(s: &str) -> Result<i64, &'s
                     if ch != '_' {
                         return Err("Invalid character in hexadecimal number");
                     }
                 }
             }
         }
     } else {
         // Decimal number, possibly negative.
-        for ch in s2.chars() {
+        for ch in s.chars() {
             match ch.to_digit(16) {
                 Some(digit) => {
                     digits += 1;
                     match value.checked_mul(10) {
                         None => return Err("Too large decimal number"),
                         Some(v) => value = v,
                     }
                     match value.checked_add(u64::from(digit)) {
@@ -123,33 +193,25 @@ fn parse_i64(s: &str) -> Result<i64, &'s
             }
         }
     }
 
     if digits == 0 {
         return Err("No digits in number");
     }
 
-    // We support the range-and-a-half from -2^63 .. 2^64-1.
-    if negative {
-        value = value.wrapping_neg();
-        // Don't allow large negative values to wrap around and become positive.
-        if value as i64 > 0 {
-            return Err("Negative number too small");
-        }
-    }
-    Ok(value as i64)
+    Ok(value)
 }
 
-impl FromStr for Imm64 {
+impl FromStr for Uimm64 {
     type Err = &'static str;
 
-    // Parse a decimal or hexadecimal `Imm64`, formatted as above.
+    // Parse a decimal or hexadecimal `Uimm64`, formatted as above.
     fn from_str(s: &str) -> Result<Self, &'static str> {
-        parse_i64(s).map(Self::new)
+        parse_u64(s).map(Self::new)
     }
 }
 
 /// 8-bit unsigned integer immediate operand.
 ///
 /// This is used to indicate lane indexes typically.
 pub type Uimm8 = u8;
 
@@ -177,17 +239,17 @@ impl From<u32> for Uimm32 {
     }
 }
 
 impl Display for Uimm32 {
     fn fmt(&self, f: &mut Formatter) -> fmt::Result {
         if self.0 < 10_000 {
             write!(f, "{}", self.0)
         } else {
-            write_hex(i64::from(self.0), f)
+            write_hex(u64::from(self.0), f)
         }
     }
 }
 
 impl FromStr for Uimm32 {
     type Err = &'static str;
 
     // Parse a decimal or hexadecimal `Uimm32`, formatted as above.
@@ -263,17 +325,17 @@ impl Display for Offset32 {
 
         // Always include a sign.
         write!(f, "{}", if self.0 < 0 { '-' } else { '+' })?;
 
         let val = i64::from(self.0).abs();
         if val < 10_000 {
             write!(f, "{}", val)
         } else {
-            write_hex(val, f)
+            write_hex(val as u64, f)
         }
     }
 }
 
 impl FromStr for Offset32 {
     type Err = &'static str;
 
     // Parse a decimal or hexadecimal `Offset32`, formatted as above.
@@ -678,16 +740,30 @@ mod tests {
         assert_eq!(Imm64(9999).to_string(), "9999");
         assert_eq!(Imm64(10000).to_string(), "0x2710");
         assert_eq!(Imm64(-9999).to_string(), "-9999");
         assert_eq!(Imm64(-10000).to_string(), "0xffff_ffff_ffff_d8f0");
         assert_eq!(Imm64(0xffff).to_string(), "0xffff");
         assert_eq!(Imm64(0x10000).to_string(), "0x0001_0000");
     }
 
+    #[test]
+    fn format_uimm64() {
+        assert_eq!(Uimm64(0).to_string(), "0");
+        assert_eq!(Uimm64(9999).to_string(), "9999");
+        assert_eq!(Uimm64(10000).to_string(), "0x2710");
+        assert_eq!(Uimm64(-9999i64 as u64).to_string(), "0xffff_ffff_ffff_d8f1");
+        assert_eq!(
+            Uimm64(-10000i64 as u64).to_string(),
+            "0xffff_ffff_ffff_d8f0"
+        );
+        assert_eq!(Uimm64(0xffff).to_string(), "0xffff");
+        assert_eq!(Uimm64(0x10000).to_string(), "0x0001_0000");
+    }
+
     // Verify that `text` can be parsed as a `T` into a value that displays as `want`.
     fn parse_ok<T: FromStr + Display>(text: &str, want: &str)
     where
         <T as FromStr>::Err: Display,
     {
         match text.parse::<T>() {
             Err(s) => panic!("\"{}\".parse() error: {}", text, s),
             Ok(x) => assert_eq!(x.to_string(), want),
@@ -746,16 +822,56 @@ mod tests {
         parse_err::<Imm64>("--", "Invalid character in decimal number");
         parse_err::<Imm64>("-0x-", "Invalid character in hexadecimal number");
 
         // Hex count overflow.
         parse_err::<Imm64>("0x0_0000_0000_0000_0000", "Too many hexadecimal digits");
     }
 
     #[test]
+    fn parse_uimm64() {
+        parse_ok::<Uimm64>("0", "0");
+        parse_ok::<Uimm64>("1", "1");
+        parse_ok::<Uimm64>("0x0", "0");
+        parse_ok::<Uimm64>("0xf", "15");
+        parse_ok::<Uimm64>("0xffffffff_fffffff7", "0xffff_ffff_ffff_fff7");
+
+        // Probe limits.
+        parse_ok::<Uimm64>("0xffffffff_ffffffff", "0xffff_ffff_ffff_ffff");
+        parse_ok::<Uimm64>("0x80000000_00000000", "0x8000_0000_0000_0000");
+        parse_ok::<Uimm64>("18446744073709551615", "0xffff_ffff_ffff_ffff");
+        // Overflow both the `checked_add` and `checked_mul`.
+        parse_err::<Uimm64>("18446744073709551616", "Too large decimal number");
+        parse_err::<Uimm64>("184467440737095516100", "Too large decimal number");
+
+        // Underscores are allowed where digits go.
+        parse_ok::<Uimm64>("0_0", "0");
+        parse_ok::<Uimm64>("_10_", "10");
+        parse_ok::<Uimm64>("0x97_88_bb", "0x0097_88bb");
+        parse_ok::<Uimm64>("0x_97_", "151");
+
+        parse_err::<Uimm64>("", "No digits in number");
+        parse_err::<Uimm64>("_", "No digits in number");
+        parse_err::<Uimm64>("0x", "No digits in number");
+        parse_err::<Uimm64>("0x_", "No digits in number");
+        parse_err::<Uimm64>("-", "Invalid character in decimal number");
+        parse_err::<Uimm64>("-0x", "Invalid character in hexadecimal number");
+        parse_err::<Uimm64>(" ", "Invalid character in decimal number");
+        parse_err::<Uimm64>("0 ", "Invalid character in decimal number");
+        parse_err::<Uimm64>(" 0", "Invalid character in decimal number");
+        parse_err::<Uimm64>("--", "Invalid character in decimal number");
+        parse_err::<Uimm64>("-0x-", "Invalid character in hexadecimal number");
+        parse_err::<Uimm64>("-0", "Invalid character in decimal number");
+        parse_err::<Uimm64>("-1", "Invalid character in decimal number");
+
+        // Hex count overflow.
+        parse_err::<Uimm64>("0x0_0000_0000_0000_0000", "Too many hexadecimal digits");
+    }
+
+    #[test]
     fn format_offset32() {
         assert_eq!(Offset32(0).to_string(), "");
         assert_eq!(Offset32(1).to_string(), "+1");
         assert_eq!(Offset32(-1).to_string(), "-1");
         assert_eq!(Offset32(9999).to_string(), "+9999");
         assert_eq!(Offset32(10000).to_string(), "+0x2710");
         assert_eq!(Offset32(-9999).to_string(), "-9999");
         assert_eq!(Offset32(-10000).to_string(), "-0x2710");
--- a/third_party/rust/cranelift-codegen/src/ir/memflags.rs
+++ b/third_party/rust/cranelift-codegen/src/ir/memflags.rs
@@ -21,16 +21,25 @@ pub struct MemFlags {
 }
 
 impl MemFlags {
     /// Create a new empty set of flags.
     pub fn new() -> Self {
         Self { bits: 0 }
     }
 
+    /// Create a set of flags representing an access from a "trusted" address, meaning it's
+    /// known to be aligned and non-trapping.
+    pub fn trusted() -> Self {
+        let mut result = Self::new();
+        result.set_notrap();
+        result.set_aligned();
+        result
+    }
+
     /// Read a flag bit.
     fn read(self, bit: FlagBit) -> bool {
         self.bits & (1 << bit as usize) != 0
     }
 
     /// Set a flag bit.
     fn set(&mut self, bit: FlagBit) {
         self.bits |= 1 << bit as usize
--- a/third_party/rust/cranelift-codegen/src/ir/progpoint.rs
+++ b/third_party/rust/cranelift-codegen/src/ir/progpoint.rs
@@ -80,19 +80,19 @@ impl From<ValueDef> for ExpandedProgramP
             ValueDef::Param(ebb, _) => ebb.into(),
         }
     }
 }
 
 impl From<ProgramPoint> for ExpandedProgramPoint {
     fn from(pp: ProgramPoint) -> Self {
         if pp.0 & 1 == 0 {
-            ExpandedProgramPoint::Inst(Inst::new((pp.0 / 2) as usize))
+            ExpandedProgramPoint::Inst(Inst::from_u32(pp.0 / 2))
         } else {
-            ExpandedProgramPoint::Ebb(Ebb::new((pp.0 / 2) as usize))
+            ExpandedProgramPoint::Ebb(Ebb::from_u32(pp.0 / 2))
         }
     }
 }
 
 impl fmt::Display for ExpandedProgramPoint {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         match *self {
             ExpandedProgramPoint::Inst(x) => write!(f, "{}", x),
--- a/third_party/rust/cranelift-codegen/src/ir/table.rs
+++ b/third_party/rust/cranelift-codegen/src/ir/table.rs
@@ -1,29 +1,29 @@
 //! Tables.
 
-use ir::immediates::Imm64;
+use ir::immediates::Uimm64;
 use ir::{GlobalValue, Type};
 use std::fmt;
 
 /// Information about a table declaration.
 #[derive(Clone)]
 pub struct TableData {
     /// Global value giving the address of the start of the table.
     pub base_gv: GlobalValue,
 
     /// Guaranteed minimum table size in elements. Table accesses before `min_size` don't need
     /// bounds checking.
-    pub min_size: Imm64,
+    pub min_size: Uimm64,
 
     /// Global value giving the current bound of the table, in elements.
     pub bound_gv: GlobalValue,
 
     /// The size of a table element, in bytes.
-    pub element_size: Imm64,
+    pub element_size: Uimm64,
 
     /// The index type for the table.
     pub index_type: Type,
 }
 
 impl fmt::Display for TableData {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         f.write_str("dynamic")?;
--- a/third_party/rust/cranelift-codegen/src/ir/trapcode.rs
+++ b/third_party/rust/cranelift-codegen/src/ir/trapcode.rs
@@ -12,17 +12,18 @@ pub enum TrapCode {
     ///
     /// On some platforms, a stack overflow may also be indicated by a segmentation fault from the
     /// stack guard page.
     StackOverflow,
 
     /// A `heap_addr` instruction detected an out-of-bounds error.
     ///
     /// Note that not all out-of-bounds heap accesses are reported this way;
-    /// some are detected by a segmentation fault on the heap guard pages.
+    /// some are detected by a segmentation fault on the heap unmapped or
+    /// offset-guard pages.
     HeapOutOfBounds,
 
     /// A `table_addr` instruction detected an out-of-bounds error.
     TableOutOfBounds,
 
     /// Other bounds checking error.
     OutOfBounds,
 
--- a/third_party/rust/cranelift-codegen/src/ir/types.rs
+++ b/third_party/rust/cranelift-codegen/src/ir/types.rs
@@ -1,12 +1,13 @@
 //! Common types for the Cranelift code generator.
 
 use std::default::Default;
 use std::fmt::{self, Debug, Display, Formatter};
+use target_lexicon::{PointerWidth, Triple};
 
 /// The type of an SSA value.
 ///
 /// The `INVALID` type isn't a real type, and is used as a placeholder in the IR where a type
 /// field is present put no type is needed, such as the controlling type variable for a
 /// non-polymorphic instruction.
 ///
 /// Basic integer types: `I8`, `I16`, `I32`, and `I64`. These types are sign-agnostic.
@@ -266,16 +267,26 @@ impl Type {
 
     /// True iff:
     ///
     /// 1. `self.lane_count() == other.lane_count()` and
     /// 2. `self.lane_bits() >= other.lane_bits()`
     pub fn wider_or_equal(self, other: Self) -> bool {
         self.lane_count() == other.lane_count() && self.lane_bits() >= other.lane_bits()
     }
+
+    /// Return the pointer type for the given target triple.
+    pub fn triple_pointer_type(triple: &Triple) -> Self {
+        match triple.pointer_width() {
+            Ok(PointerWidth::U16) => I16,
+            Ok(PointerWidth::U32) => I32,
+            Ok(PointerWidth::U64) => I64,
+            Err(()) => panic!("unable to determine architecture pointer width"),
+        }
+    }
 }
 
 impl Display for Type {
     fn fmt(&self, f: &mut Formatter) -> fmt::Result {
         if self.is_bool() {
             write!(f, "b{}", self.lane_bits())
         } else if self.is_int() {
             write!(f, "i{}", self.lane_bits())
--- a/third_party/rust/cranelift-codegen/src/isa/call_conv.rs
+++ b/third_party/rust/cranelift-codegen/src/isa/call_conv.rs
@@ -16,17 +16,17 @@ pub enum CallConv {
     /// SpiderMonkey WebAssembly convention
     Baldrdash,
     /// Specialized convention for the probestack function
     Probestack,
 }
 
 impl CallConv {
     /// Return the default calling convention for the given target triple.
-    pub fn default_for_triple(triple: &Triple) -> Self {
+    pub fn triple_default(triple: &Triple) -> Self {
         match triple.default_calling_convention() {
             // Default to System V for unknown targets because most everything
             // uses System V.
             Ok(CallingConvention::SystemV) | Err(()) => CallConv::SystemV,
             Ok(CallingConvention::WindowsFastcall) => CallConv::WindowsFastcall,
         }
     }
 }
--- a/third_party/rust/cranelift-codegen/src/isa/mod.rs
+++ b/third_party/rust/cranelift-codegen/src/isa/mod.rs
@@ -203,17 +203,17 @@ pub trait TargetIsa: fmt::Display + Sync
     /// Get the target triple that was used to make this trait object.
     fn triple(&self) -> &Triple;
 
     /// Get the ISA-independent flags that were used to make this trait object.
     fn flags(&self) -> &settings::Flags;
 
     /// Get the default calling convention of this target.
     fn default_call_conv(&self) -> CallConv {
-        CallConv::default_for_triple(self.triple())
+        CallConv::triple_default(self.triple())
     }
 
     /// Get the pointer type of this ISA.
     fn pointer_type(&self) -> ir::Type {
         ir::Type::int(u16::from(self.pointer_bits())).unwrap()
     }
 
     /// Get the width of pointers on this ISA.
--- a/third_party/rust/cranelift-codegen/src/isa/registers.rs
+++ b/third_party/rust/cranelift-codegen/src/isa/registers.rs
@@ -84,17 +84,18 @@ impl RegBank {
             None => {
                 // Try a regular prefixed name.
                 if name.starts_with(self.prefix) {
                     name[self.prefix.len()..].parse().ok()
                 } else {
                     None
                 }
             }
-        }.and_then(|offset| {
+        }
+        .and_then(|offset| {
             if offset < self.units {
                 Some(offset + self.first_unit)
             } else {
                 None
             }
         })
     }
 
--- a/third_party/rust/cranelift-codegen/src/isa/x86/abi.rs
+++ b/third_party/rust/cranelift-codegen/src/isa/x86/abi.rs
@@ -93,17 +93,18 @@ impl ArgAssigner for Args {
         if ty.is_int() && self.call_conv == CallConv::Baldrdash {
             match arg.purpose {
                 // This is SpiderMonkey's `WasmTlsReg`.
                 ArgumentPurpose::VMContext => {
                     return ArgumentLoc::Reg(if self.pointer_bits == 64 {
                         RU::r14
                     } else {
                         RU::rsi
-                    } as RegUnit).into()
+                    } as RegUnit)
+                    .into()
                 }
                 // This is SpiderMonkey's `WasmTableCallSigReg`.
                 ArgumentPurpose::SignatureId => return ArgumentLoc::Reg(RU::r10 as RegUnit).into(),
                 _ => {}
             }
         }
 
         // Try to use a GPR.
--- a/third_party/rust/cranelift-codegen/src/legalizer/boundary.rs
+++ b/third_party/rust/cranelift-codegen/src/legalizer/boundary.rs
@@ -570,17 +570,18 @@ pub fn handle_return_abi(inst: Inst, fun
         .signature
         .returns
         .iter()
         .rev()
         .take_while(|&rt| {
             rt.purpose == ArgumentPurpose::Link
                 || rt.purpose == ArgumentPurpose::StructReturn
                 || rt.purpose == ArgumentPurpose::VMContext
-        }).count();
+        })
+        .count();
     let abi_args = func.signature.returns.len() - special_args;
 
     let pos = &mut FuncCursor::new(func).at_inst(inst);
     pos.use_srcloc(inst);
 
     legalize_inst_arguments(pos, cfg, abi_args, |func, abi_arg| {
         func.signature.returns[abi_arg]
     });
@@ -689,17 +690,18 @@ fn spill_call_arguments(pos: &mut FuncCu
                         if locations[arg] != ValueLoc::Stack(ss) {
                             Some((idx, arg, ss))
                         } else {
                             None
                         }
                     }
                     _ => None,
                 }
-            }).collect::<Vec<_>>()
+            })
+            .collect::<Vec<_>>()
     };
 
     if arglist.is_empty() {
         return false;
     }
 
     // Insert the spill instructions and rewrite call arguments.
     for (idx, arg, ss) in arglist {
--- a/third_party/rust/cranelift-codegen/src/legalizer/globalvalue.rs
+++ b/third_party/rust/cranelift-codegen/src/legalizer/globalvalue.rs
@@ -105,19 +105,17 @@ fn load_addr(
         pos.func
             .special_param(ir::ArgumentPurpose::VMContext)
             .expect("Missing vmctx parameter")
     } else {
         pos.ins().global_value(ptr_ty, base)
     };
 
     // Global-value loads are always notrap and aligned. They may be readonly.
-    let mut mflags = ir::MemFlags::new();
-    mflags.set_notrap();
-    mflags.set_aligned();
+    let mut mflags = ir::MemFlags::trusted();
     if readonly {
         mflags.set_readonly();
     }
 
     // Perform the load.
     pos.func
         .dfg
         .replace(inst)
--- a/third_party/rust/cranelift-codegen/src/legalizer/heap.rs
+++ b/third_party/rust/cranelift-codegen/src/legalizer/heap.rs
@@ -44,17 +44,17 @@ pub fn expand_heap_addr(
 fn dynamic_addr(
     inst: ir::Inst,
     heap: ir::Heap,
     offset: ir::Value,
     access_size: u32,
     bound_gv: ir::GlobalValue,
     func: &mut ir::Function,
 ) {
-    let access_size = i64::from(access_size);
+    let access_size = u64::from(access_size);
     let offset_ty = func.dfg.value_type(offset);
     let addr_ty = func.dfg.value_type(func.dfg.first_result(inst));
     let min_size = func.heaps[heap].min_size.into();
     let mut pos = FuncCursor::new(func).at_inst(inst);
     pos.use_srcloc(inst);
 
     // Start with the bounds check. Trap if `offset + access_size > bound`.
     let bound = pos.ins().global_value(offset_ty, bound_gv);
@@ -62,23 +62,23 @@ fn dynamic_addr(
     if access_size == 1 {
         // `offset > bound - 1` is the same as `offset >= bound`.
         oob = pos
             .ins()
             .icmp(IntCC::UnsignedGreaterThanOrEqual, offset, bound);
     } else if access_size <= min_size {
         // We know that bound >= min_size, so here we can compare `offset > bound - access_size`
         // without wrapping.
-        let adj_bound = pos.ins().iadd_imm(bound, -access_size);
+        let adj_bound = pos.ins().iadd_imm(bound, -(access_size as i64));
         oob = pos
             .ins()
             .icmp(IntCC::UnsignedGreaterThan, offset, adj_bound);
     } else {
         // We need an overflow check for the adjusted offset.
-        let access_size_val = pos.ins().iconst(offset_ty, access_size);
+        let access_size_val = pos.ins().iconst(offset_ty, access_size as i64);
         let (adj_offset, overflow) = pos.ins().iadd_cout(offset, access_size_val);
         pos.ins().trapnz(overflow, ir::TrapCode::HeapOutOfBounds);
         oob = pos
             .ins()
             .icmp(IntCC::UnsignedGreaterThan, adj_offset, bound);
     }
     pos.ins().trapnz(oob, ir::TrapCode::HeapOutOfBounds);
 
@@ -86,21 +86,21 @@ fn dynamic_addr(
 }
 
 /// Expand a `heap_addr` for a static heap.
 fn static_addr(
     inst: ir::Inst,
     heap: ir::Heap,
     offset: ir::Value,
     access_size: u32,
-    bound: i64,
+    bound: u64,
     func: &mut ir::Function,
     cfg: &mut ControlFlowGraph,
 ) {
-    let access_size = i64::from(access_size);
+    let access_size = u64::from(access_size);
     let offset_ty = func.dfg.value_type(offset);
     let addr_ty = func.dfg.value_type(func.dfg.first_result(inst));
     let mut pos = FuncCursor::new(func).at_inst(inst);
     pos.use_srcloc(inst);
 
     // Start with the bounds check. Trap if `offset + access_size > bound`.
     if access_size > bound {
         // This will simply always trap since `offset >= 0`.
@@ -112,29 +112,29 @@ fn static_addr(
         let new_ebb = pos.func.dfg.make_ebb();
         pos.insert_ebb(new_ebb);
         cfg.recompute_ebb(pos.func, curr_ebb);
         cfg.recompute_ebb(pos.func, new_ebb);
         return;
     }
 
     // Check `offset > limit` which is now known non-negative.
-    let limit = bound - access_size;
+    let limit = bound - u64::from(access_size);
 
     // We may be able to omit the check entirely for 32-bit offsets if the heap bound is 4 GB or
     // more.
     if offset_ty != ir::types::I32 || limit < 0xffff_ffff {
         let oob = if limit & 1 == 1 {
             // Prefer testing `offset >= limit - 1` when limit is odd because an even number is
             // likely to be a convenient constant on ARM and other RISC architectures.
             pos.ins()
-                .icmp_imm(IntCC::UnsignedGreaterThanOrEqual, offset, limit - 1)
+                .icmp_imm(IntCC::UnsignedGreaterThanOrEqual, offset, limit as i64 - 1)
         } else {
             pos.ins()
-                .icmp_imm(IntCC::UnsignedGreaterThan, offset, limit)
+                .icmp_imm(IntCC::UnsignedGreaterThan, offset, limit as i64)
         };
         pos.ins().trapnz(oob, ir::TrapCode::HeapOutOfBounds);
     }
 
     compute_addr(inst, heap, addr_ty, offset, offset_ty, pos.func);
 }
 
 /// Emit code for the base address computation of a `heap_addr` instruction.
--- a/third_party/rust/cranelift-codegen/src/legalizer/mod.rs
+++ b/third_party/rust/cranelift-codegen/src/legalizer/mod.rs
@@ -395,20 +395,18 @@ fn expand_stack_load(
         _ => panic!(
             "Expected stack_load: {}",
             pos.func.dfg.display_inst(inst, None)
         ),
     };
 
     let addr = pos.ins().stack_addr(addr_ty, stack_slot, offset);
 
-    let mut mflags = MemFlags::new();
     // Stack slots are required to be accessible and aligned.
-    mflags.set_notrap();
-    mflags.set_aligned();
+    let mflags = MemFlags::trusted();
     pos.func.dfg.replace(inst).load(ty, mflags, addr, 0);
 }
 
 /// Expand illegal `stack_store` instructions.
 fn expand_stack_store(
     inst: ir::Inst,
     func: &mut ir::Function,
     _cfg: &mut ControlFlowGraph,
--- a/third_party/rust/cranelift-codegen/src/legalizer/split.rs
+++ b/third_party/rust/cranelift-codegen/src/legalizer/split.rs
@@ -160,17 +160,18 @@ fn split_any(
 
             // The `hi` part goes at the end. Since multiple repairs may have been scheduled to the
             // same EBB, there could be multiple arguments missing.
             if num_args > num_fixed_args + repair.hi_num {
                 *args
                     .get_mut(
                         num_fixed_args + repair.hi_num,
                         &mut pos.func.dfg.value_lists,
-                    ).unwrap() = hi;
+                    )
+                    .unwrap() = hi;
             } else {
                 // We need to append one or more arguments. If we're adding more than one argument,
                 // there must be pending repairs on the stack that will fill in the correct values
                 // instead of `hi`.
                 args.extend(
                     iter::repeat(hi).take(1 + num_fixed_args + repair.hi_num - num_args),
                     &mut pos.func.dfg.value_lists,
                 );
--- a/third_party/rust/cranelift-codegen/src/legalizer/table.rs
+++ b/third_party/rust/cranelift-codegen/src/legalizer/table.rs
@@ -87,27 +87,25 @@ fn compute_addr(
     }
 
     // Add the table base address base
     let base_gv = pos.func.tables[table].base_gv;
     let base = pos.ins().global_value(addr_ty, base_gv);
 
     let element_size = pos.func.tables[table].element_size;
     let mut offset;
-    let element_size_i64: i64 = element_size.into();
-    debug_assert!(element_size_i64 >= 0);
-    let element_size_u64 = element_size_i64 as u64;
-    if element_size_u64 == 1 {
+    let element_size: u64 = element_size.into();
+    if element_size == 1 {
         offset = index;
-    } else if element_size_u64.is_power_of_two() {
+    } else if element_size.is_power_of_two() {
         offset = pos
             .ins()
-            .ishl_imm(index, i64::from(element_size_u64.trailing_zeros()));
+            .ishl_imm(index, i64::from(element_size.trailing_zeros()));
     } else {
-        offset = pos.ins().imul_imm(index, element_size);
+        offset = pos.ins().imul_imm(index, element_size as i64);
     }
 
     if element_offset == Offset32::new(0) {
         pos.func.dfg.replace(inst).iadd(base, offset);
     } else {
         let imm: i64 = element_offset.into();
         offset = pos.ins().iadd(base, offset);
         pos.func.dfg.replace(inst).iadd_imm(offset, imm);
--- a/third_party/rust/cranelift-codegen/src/lib.rs
+++ b/third_party/rust/cranelift-codegen/src/lib.rs
@@ -1,17 +1,14 @@
 //! Cranelift code generation library.
 
 #![deny(missing_docs, trivial_numeric_casts, unused_extern_crates)]
 #![warn(unused_import_braces)]
 #![cfg_attr(feature = "std", deny(unstable_features))]
-#![cfg_attr(
-    feature = "clippy",
-    plugin(clippy(conf_file = "../../clippy.toml"))
-)]
+#![cfg_attr(feature = "clippy", plugin(clippy(conf_file = "../../clippy.toml")))]
 #![cfg_attr(feature="cargo-clippy", allow(
 // Produces only a false positive:
                 while_let_loop,
 // Produces many false positives, but did produce some valid lints, now fixed:
                 needless_lifetimes,
 // Generated code makes some style transgressions, but readability doesn't suffer much:
                 many_single_char_names,
                 identity_op,
@@ -28,24 +25,24 @@
 // These are relatively minor style issues, but would be easy to fix:
                 new_without_default,
                 new_without_default_derive,
                 should_implement_trait,
                 len_without_is_empty))]
 #![cfg_attr(
     feature = "cargo-clippy",
     warn(
-        float_arithmetic,
-        mut_mut,
-        nonminimal_bool,
-        option_map_unwrap_or,
-        option_map_unwrap_or_else,
-        print_stdout,
-        unicode_not_nfc,
-        use_self
+        clippy::float_arithmetic,
+        clippy::mut_mut,
+        clippy::nonminimal_bool,
+        clippy::option_map_unwrap_or,
+        clippy::option_map_unwrap_or_else,
+        clippy::print_stdout,
+        clippy::unicode_not_nfc,
+        clippy::use_self
     )
 )]
 // Turns on no_std and alloc features if std is not available.
 #![cfg_attr(not(feature = "std"), no_std)]
 #![cfg_attr(not(feature = "std"), feature(alloc))]
 // TODO: Remove this workaround once https://github.com/rust-lang/rust/issues/27747 is done.
 #![cfg_attr(not(feature = "std"), feature(slice_concat_ext))]
 
--- a/third_party/rust/cranelift-codegen/src/print_errors.rs
+++ b/third_party/rust/cranelift-codegen/src/print_errors.rs
@@ -25,24 +25,26 @@ pub fn pretty_verifier_error<'a>(
     let mut w = String::new();
     let num_errors = errors.len();
 
     decorate_function(
         &mut PrettyVerifierError(func_w.unwrap_or_else(|| Box::new(PlainWriter)), &mut errors),
         &mut w,
         func,
         isa,
-    ).unwrap();
+    )
+    .unwrap();
 
     writeln!(
         w,
         "\n; {} verifier error{} detected (see above). Compilation aborted.",
         num_errors,
         if num_errors == 1 { "" } else { "s" }
-    ).unwrap();
+    )
+    .unwrap();
 
     w
 }
 
 struct PrettyVerifierError<'a>(Box<FuncWriter + 'a>, &'a mut Vec<VerifierError>);
 
 impl<'a> FuncWriter for PrettyVerifierError<'a> {
     fn write_ebb_header(
--- a/third_party/rust/cranelift-codegen/src/regalloc/coloring.rs
+++ b/third_party/rust/cranelift-codegen/src/regalloc/coloring.rs
@@ -909,22 +909,20 @@ impl<'a> Context<'a> {
             NotABranch => false,
             SingleDest(ebb, _) => {
                 let lr = &self.liveness[value];
                 lr.is_livein(ebb, ctx)
             }
             Table(jt, ebb) => {
                 let lr = &self.liveness[value];
                 !lr.is_local()
-                    && (ebb.map_or(false, |ebb| lr.is_livein(ebb, ctx)) || self
-                        .cur
-                        .func
-                        .jump_tables[jt]
-                        .iter()
-                        .any(|ebb| lr.is_livein(*ebb, ctx)))
+                    && (ebb.map_or(false, |ebb| lr.is_livein(ebb, ctx))
+                        || self.cur.func.jump_tables[jt]
+                            .iter()
+                            .any(|ebb| lr.is_livein(*ebb, ctx)))
             }
         }
     }
 
     /// Emit `regmove` instructions as needed to move the live registers into place before the
     /// instruction. Also update `self.divert` accordingly.
     ///
     /// The `self.cur` cursor is expected to point at the instruction. The register moves are
--- a/third_party/rust/cranelift-codegen/src/regalloc/context.rs
+++ b/third_party/rust/cranelift-codegen/src/regalloc/context.rs
@@ -111,17 +111,18 @@ impl Context {
                 && verify_liveness(isa, func, cfg, &self.liveness, &mut errors).is_ok()
                 && verify_cssa(
                     func,
                     cfg,
                     domtree,
                     &self.liveness,
                     &self.virtregs,
                     &mut errors,
-                ).is_ok();
+                )
+                .is_ok();
 
             if !ok {
                 return Err(errors.into());
             }
         }
 
         // Pass: Spilling.
         self.spilling.run(
@@ -139,17 +140,18 @@ impl Context {
                 && verify_liveness(isa, func, cfg, &self.liveness, &mut errors).is_ok()
                 && verify_cssa(
                     func,
                     cfg,
                     domtree,
                     &self.liveness,
                     &self.virtregs,
                     &mut errors,
-                ).is_ok();
+                )
+                .is_ok();
 
             if !ok {
                 return Err(errors.into());
             }
         }
 
         // Pass: Reload.
         self.reload.run(
@@ -166,17 +168,18 @@ impl Context {
                 && verify_liveness(isa, func, cfg, &self.liveness, &mut errors).is_ok()
                 && verify_cssa(
                     func,
                     cfg,
                     domtree,
                     &self.liveness,
                     &self.virtregs,
                     &mut errors,
-                ).is_ok();
+                )
+                .is_ok();
 
             if !ok {
                 return Err(errors.into());
             }
         }
 
         // Pass: Coloring.
         self.coloring
@@ -188,17 +191,18 @@ impl Context {
                 && verify_locations(isa, func, Some(&self.liveness), &mut errors).is_ok()
                 && verify_cssa(
                     func,
                     cfg,
                     domtree,
                     &self.liveness,
                     &self.virtregs,
                     &mut errors,
-                ).is_ok();
+                )
+                .is_ok();
 
             if !ok {
                 return Err(errors.into());
             }
         }
 
         // Even if we arrive here, (non-fatal) errors might have been reported, so we
         // must make sure absolutely nothing is wrong
--- a/third_party/rust/cranelift-codegen/src/regalloc/liveness.rs
+++ b/third_party/rust/cranelift-codegen/src/regalloc/liveness.rs
@@ -215,17 +215,18 @@ fn get_or_create<'a>(
                     .operand_constraints(func.encodings[inst])
                     .and_then(|rc| rc.outs.get(rnum))
                     .map(Affinity::new)
                     .or_else(|| {
                         // If this is a call, get the return value affinity.
                         func.dfg
                             .call_signature(inst)
                             .map(|sig| Affinity::abi(&func.dfg.signatures[sig].returns[rnum], isa))
-                    }).unwrap_or_default();
+                    })
+                    .unwrap_or_default();
             }
             ValueDef::Param(ebb, num) => {
                 def = ebb.into();
                 if func.layout.entry_block() == Some(ebb) {
                     // The affinity for entry block parameters can be inferred from the function
                     // signature.
                     affinity = Affinity::abi(&func.signature.params[num], isa);
                 } else {
--- a/third_party/rust/cranelift-codegen/src/regalloc/register_set.rs
+++ b/third_party/rust/cranelift-codegen/src/regalloc/register_set.rs
@@ -202,17 +202,18 @@ impl<'a> fmt::Display for DisplayRegiste
                                 f,
                                 "{}",
                                 bank.names
                                     .get(offset as usize)
                                     .and_then(|name| name.chars().nth(1))
                                     .unwrap_or_else(|| char::from_digit(
                                         u32::from(offset % 10),
                                         10
-                                    ).unwrap())
+                                    )
+                                    .unwrap())
                             )?;
                         }
                     }
                 }
             }
         }
         write!(f, " ]")
     }
--- a/third_party/rust/cranelift-codegen/src/regalloc/reload.rs
+++ b/third_party/rust/cranelift-codegen/src/regalloc/reload.rs
@@ -259,19 +259,19 @@ impl<'a> Context<'a> {
                         self.insert_spill(ebb, lv.value, reg);
                     }
                 }
             }
         }
 
         // Same thing for spilled call return values.
         let retvals = &defs[self.cur.func.dfg[inst]
-                                .opcode()
-                                .constraints()
-                                .num_fixed_results()..];
+            .opcode()
+            .constraints()
+            .num_fixed_results()..];
         if !retvals.is_empty() {
             let sig = self
                 .cur
                 .func
                 .dfg
                 .call_signature(inst)
                 .expect("Extra results on non-call instruction");
             for (i, lv) in retvals.iter().enumerate() {
--- a/third_party/rust/cranelift-codegen/src/regalloc/spilling.rs
+++ b/third_party/rust/cranelift-codegen/src/regalloc/spilling.rs
@@ -499,17 +499,18 @@ impl<'a> Context<'a> {
                 if let Affinity::Reg(rci) = lv.affinity {
                     let rc = self.reginfo.rc(rci);
                     if (mask & (1 << rc.toprc)) != 0 && !self.spills.contains(&lv.value) {
                         // Here, `lv` is a viable spill candidate.
                         return Some(lv.value);
                     }
                 }
                 None
-            }).min_by(|&a, &b| {
+            })
+            .min_by(|&a, &b| {
                 // Find the minimum candidate according to the RPO of their defs.
                 self.domtree.rpo_cmp(
                     self.cur.func.dfg.value_def(a),
                     self.cur.func.dfg.value_def(b),
                     &self.cur.func.layout,
                 )
             })
     }
--- a/third_party/rust/cranelift-codegen/src/regalloc/virtregs.rs
+++ b/third_party/rust/cranelift-codegen/src/regalloc/virtregs.rs
@@ -8,17 +8,16 @@
 //! that is, one value is passed as an EBB argument to a branch and the other is the EBB parameter
 //! value itself.
 //!
 //! If any values in a virtual register are spilled, they will use the same stack slot. This avoids
 //! memory-to-memory copies when a spilled value is passed as an EBB argument.
 
 use dbg::DisplayList;
 use dominator_tree::DominatorTreePreorder;
-use entity::EntityRef;
 use entity::{EntityList, ListPool};
 use entity::{Keys, PrimaryMap, SecondaryMap};
 use ir::{Function, Value};
 use packed_option::PackedOption;
 use ref_slice::ref_slice;
 use std::cmp::Ordering;
 use std::fmt;
 use std::vec::Vec;
@@ -253,25 +252,25 @@ enum UFEntry {
 /// The rank of a set is an upper bound on the number of links that must be followed from a member
 /// of the set to the set leader.
 ///
 /// A singleton set is the same as a set with rank 0. It contains only the leader value.
 impl UFEntry {
     /// Decode a table entry.
     fn decode(x: i32) -> Self {
         if x < 0 {
-            UFEntry::Link(Value::new((!x) as usize))
+            UFEntry::Link(Value::from_u32((!x) as u32))
         } else {
             UFEntry::Rank(x as u32)
         }
     }
 
     /// Encode a link entry.
     fn encode_link(v: Value) -> i32 {
-        !(v.index() as i32)
+        !(v.as_u32() as i32)
     }
 }
 
 /// Union-find algorithm for building virtual registers.
 ///
 /// Before values are added to virtual registers, it is possible to use a union-find algorithm to
 /// construct virtual registers efficiently. This support implemented here is used as follows:
 ///
--- a/third_party/rust/cranelift-codegen/src/timing.rs
+++ b/third_party/rust/cranelift-codegen/src/timing.rs
@@ -32,17 +32,17 @@ macro_rules! define_passes {
             pub fn $pass() -> TimingToken {
                 details::start_pass($enum::$pass)
             }
         )+
     }
 }
 
 // Pass definitions.
-define_passes!{
+define_passes! {
     Pass, NUM_PASSES, DESCRIPTIONS;
 
     process_file: "Processing test file",
     parse_text: "Parsing textual Cranelift IR",
     wasm_translate_module: "Translate WASM module",
     wasm_translate_function: "Translate WASM function",
 
     verifier: "Verify Cranelift IR",
@@ -171,17 +171,17 @@ mod details {
                 }
                 writeln!(f, " {}", desc)?;
             }
             writeln!(f, "======== ========  ==================================")
         }
     }
 
     /// Information about passes in a single thread.
-    thread_local!{
+    thread_local! {
         static CURRENT_PASS: Cell<Pass> = Cell::new(Pass::None);
         static PASS_TIME: RefCell<PassTimes> = RefCell::new(Default::default());
     }
 
     /// Start timing `pass` as a child of the currently running pass, if any.
     ///
     /// This function is called by the publicly exposed pass functions.
     pub(super) fn start_pass(pass: Pass) -> TimingToken {
--- a/third_party/rust/cranelift-codegen/src/verifier/mod.rs
+++ b/third_party/rust/cranelift-codegen/src/verifier/mod.rs
@@ -882,21 +882,21 @@ impl<'a> Verifier<'a> {
                         errors,
                         loc_inst,
                         "{} is defined by {} which is not in the layout",
                         v,
                         ebb
                     );
                 }
                 // The defining EBB dominates the instruction using this value.
-                if is_reachable && !self.expected_domtree.dominates(
-                    ebb,
-                    loc_inst,
-                    &self.func.layout,
-                ) {
+                if is_reachable
+                    && !self
+                        .expected_domtree
+                        .dominates(ebb, loc_inst, &self.func.layout)
+                {
                     return fatal!(
                         errors,
                         loc_inst,
                         "uses value arg from non-dominating {}",
                         ebb
                     );
                 }
             }
@@ -1554,17 +1554,18 @@ impl<'a> Verifier<'a> {
                 );
             }
 
             let mut encodings = isa
                 .legal_encodings(
                     &self.func,
                     &self.func.dfg[inst],
                     self.func.dfg.ctrl_typevar(inst),
-                ).peekable();
+                )
+                .peekable();
 
             if encodings.peek().is_none() {
                 return nonfatal!(
                     errors,
                     inst,
                     "Instruction failed to re-encode {}",
                     isa.encoding_info().display(encoding)
                 );
--- a/third_party/rust/cranelift-entity/.cargo-checksum.json
+++ b/third_party/rust/cranelift-entity/.cargo-checksum.json
@@ -1,1 +1,1 @@
-{"files":{"Cargo.toml":"18b45cd5e51eaa9c5591e303a4fcdb759e740be967d02aaa154aaafc25281daa","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"96ceffbfd88fb06e3b41aa4d3087cffbbf8441d04eba7ab09662a72ab600a321","src/iter.rs":"cd2336dc29891e4e5060fb24f1d2f885a4606ea6580e9bd0f261843f12e31a1b","src/keys.rs":"5eca885b3e7ba19936c24066253bf47ebbd9d0a808a84dc910041e8e7be86349","src/lib.rs":"ccbf78e58d56ef1cb811e5ba451d6e8aa69a84c95f5cfe89c0d1f7ecdd26d15b","src/list.rs":"15d9762396439eb2e835401a7b85e190e097fa5eb863decfb67fb677f1093335","src/map.rs":"bcf7a78077056e4194581cbeb4b9d6bdd263ae1c6b261a0fc011ccda5f39bb4f","src/packed_option.rs":"19b2d49e0233e05e3dc39424187644af546934fe92b7200543fe10728ec831f6","src/primary.rs":"457f72222869abfc06109473d8a7435cf8acaef3888b4bd559608e135aa96395","src/set.rs":"fd687531bb01db9a22ed09486e378fdfe5842c84b603620f83fe8a42109df3cb","src/sparse.rs":"d2b7bd25c7e2b5ef2194feb08c635447953a4548d42ae26d080bb4ca44dfcc20"},"package":"fc9a0329208e5e0d7d4d6e64cd50985d4c4cbfdbeeb594ae2157a094b98e8dcc"}
\ No newline at end of file
+{"files":{"Cargo.toml":"a76fe4900987624504c61e99cf0c20c8dad64a42e77f0e43c0150c416679dd70","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"96ceffbfd88fb06e3b41aa4d3087cffbbf8441d04eba7ab09662a72ab600a321","src/boxed_slice.rs":"b17fae8f1bd8d970221ea0ff185a62dce0da2324abe95c8c8577b06c56cd11cb","src/iter.rs":"cd2336dc29891e4e5060fb24f1d2f885a4606ea6580e9bd0f261843f12e31a1b","src/keys.rs":"5eca885b3e7ba19936c24066253bf47ebbd9d0a808a84dc910041e8e7be86349","src/lib.rs":"dc3255cc56a089c696de14077ab7f49ceb95011c96ded22c6ca06d8418ff3b78","src/list.rs":"15d9762396439eb2e835401a7b85e190e097fa5eb863decfb67fb677f1093335","src/map.rs":"059ef89fa5022b56521162a2fe4b837d2bee84fdfcefd2c9973a910a6fa3417d","src/packed_option.rs":"19b2d49e0233e05e3dc39424187644af546934fe92b7200543fe10728ec831f6","src/primary.rs":"ccbafce1bc2fe15e35f844d32b511b3d422885dd9b4eaa20818b6f865cdb45f8","src/set.rs":"e227411e689c43c2cfea622ff46288598f05dfbe0e8ba652cfb04c6e3ecc192f","src/sparse.rs":"1a0a30f10203df406bd628aedb5242f71f51d35873142062c5b060ce3feae1ea"},"package":"d4df40e26c0cf7b4d86919cb995bb412ee3001cc18e4f3c83a903f30b7007d8b"}
\ No newline at end of file
--- a/third_party/rust/cranelift-entity/Cargo.toml
+++ b/third_party/rust/cranelift-entity/Cargo.toml
@@ -7,17 +7,17 @@
 #
 # If you believe there's an error in this file please file an
 # issue against the rust-lang/cargo repository. If you're
 # editing this file be aware that the upstream Cargo.toml
 # will likely look very different (and much more reasonable)
 
 [package]
 name = "cranelift-entity"
-version = "0.25.0"
+version = "0.26.0"
 authors = ["The Cranelift Project Developers"]
 description = "Data structures using entity references as mapping keys"
 documentation = "https://cranelift.readthedocs.io/"
 readme = "README.md"
 keywords = ["entity", "set", "map"]
 categories = ["no-std"]
 license = "Apache-2.0 WITH LLVM-exception"
 repository = "https://github.com/CraneStation/cranelift"
new file mode 100644
--- /dev/null
+++ b/third_party/rust/cranelift-entity/src/boxed_slice.rs
@@ -0,0 +1,315 @@
+//! Boxed slices for `PrimaryMap`.
+
+use iter::{Iter, IterMut};
+use keys::Keys;
+use std::marker::PhantomData;
+use std::ops::{Index, IndexMut};
+use std::slice;
+use EntityRef;
+
+/// A slice mapping `K -> V` allocating dense entity references.
+///
+/// The `BoxedSlice` data structure uses the dense index space to implement a map with a boxed
+/// slice.
+#[derive(Debug, Clone)]
+pub struct BoxedSlice<K, V>
+where
+    K: EntityRef,
+{
+    elems: Box<[V]>,
+    unused: PhantomData<K>,
+}
+
+impl<K, V> BoxedSlice<K, V>
+where
+    K: EntityRef,
+{
+    /// Create a new slice from a raw pointer. A safer way to create slices is
+    /// to use `PrimaryMap::into_boxed_slice()`.
+    pub unsafe fn from_raw(raw: *mut [V]) -> Self {
+        Self {
+            elems: Box::from_raw(raw),
+            unused: PhantomData,
+        }
+    }
+
+    /// Check if `k` is a valid key in the map.
+    pub fn is_valid(&self, k: K) -> bool {
+        k.index() < self.elems.len()
+    }
+
+    /// Get the element at `k` if it exists.
+    pub fn get(&self, k: K) -> Option<&V> {
+        self.elems.get(k.index())
+    }
+
+    /// Get the element at `k` if it exists, mutable version.
+    pub fn get_mut(&mut self, k: K) -> Option<&mut V> {
+        self.elems.get_mut(k.index())
+    }
+
+    /// Is this map completely empty?
+    pub fn is_empty(&self) -> bool {
+        self.elems.is_empty()
+    }
+
+    /// Get the total number of entity references created.
+    pub fn len(&self) -> usize {
+        self.elems.len()
+    }
+
+    /// Iterate over all the keys in this map.
+    pub fn keys(&self) -> Keys<K> {
+        Keys::with_len(self.elems.len())
+    }
+
+    /// Iterate over all the values in this map.
+    pub fn values(&self) -> slice::Iter<V> {
+        self.elems.iter()
+    }
+
+    /// Iterate over all the values in this map, mutable edition.
+    pub fn values_mut(&mut self) -> slice::IterMut<V> {
+        self.elems.iter_mut()
+    }
+
+    /// Iterate over all the keys and values in this map.
+    pub fn iter(&self) -> Iter<K, V> {
+        Iter::new(self.elems.iter())
+    }
+
+    /// Iterate over all the keys and values in this map, mutable edition.
+    pub fn iter_mut(&mut self) -> IterMut<K, V> {
+        IterMut::new(self.elems.iter_mut())
+    }
+
+    /// Get the key that will be assigned to the next pushed value.
+    pub fn next_key(&self) -> K {
+        K::new(self.elems.len())
+    }
+
+    /// Returns the last element that was inserted in the map.
+    pub fn last(&self) -> Option<&V> {
+        self.elems.last()
+    }
+}
+
+/// Immutable indexing into a `BoxedSlice`.
+/// The indexed value must be in the map.
+impl<K, V> Index<K> for BoxedSlice<K, V>
+where
+    K: EntityRef,
+{
+    type Output = V;
+
+    fn index(&self, k: K) -> &V {
+        &self.elems[k.index()]
+    }
+}
+
+/// Mutable indexing into a `BoxedSlice`.
+impl<K, V> IndexMut<K> for BoxedSlice<K, V>
+where
+    K: EntityRef,
+{
+    fn index_mut(&mut self, k: K) -> &mut V {
+        &mut self.elems[k.index()]
+    }
+}
+
+impl<'a, K, V> IntoIterator for &'a BoxedSlice<K, V>
+where
+    K: EntityRef,
+{
+    type Item = (K, &'a V);
+    type IntoIter = Iter<'a, K, V>;
+
+    fn into_iter(self) -> Self::IntoIter {
+        Iter::new(self.elems.iter())
+    }
+}
+
+impl<'a, K, V> IntoIterator for &'a mut BoxedSlice<K, V>
+where
+    K: EntityRef,
+{
+    type Item = (K, &'a mut V);
+    type IntoIter = IterMut<'a, K, V>;
+
+    fn into_iter(self) -> Self::IntoIter {
+        IterMut::new(self.elems.iter_mut())
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use primary::PrimaryMap;
+
+    // `EntityRef` impl for testing.
+    #[derive(Clone, Copy, Debug, PartialEq, Eq)]
+    struct E(u32);
+
+    impl EntityRef for E {
+        fn new(i: usize) -> Self {
+            E(i as u32)
+        }
+        fn index(self) -> usize {
+            self.0 as usize
+        }
+    }
+
+    #[test]
+    fn basic() {
+        let r0 = E(0);
+        let r1 = E(1);
+        let p = PrimaryMap::<E, isize>::new();
+        let m = p.into_boxed_slice();
+
+        let v: Vec<E> = m.keys().collect();
+        assert_eq!(v, []);
+
+        assert!(!m.is_valid(r0));
+        assert!(!m.is_valid(r1));
+    }
+
+    #[test]
+    fn iter() {
+        let mut p: PrimaryMap<E, usize> = PrimaryMap::new();
+        p.push(12);
+        p.push(33);
+        let mut m = p.into_boxed_slice();
+
+        let mut i = 0;
+        for (key, value) in &m {
+            assert_eq!(key.index(), i);
+            match i {
+                0 => assert_eq!(*value, 12),
+                1 => assert_eq!(*value, 33),
+                _ => panic!(),
+            }
+            i += 1;
+        }
+        i = 0;
+        for (key_mut, value_mut) in m.iter_mut() {
+            assert_eq!(key_mut.index(), i);
+            match i {
+                0 => assert_eq!(*value_mut, 12),
+                1 => assert_eq!(*value_mut, 33),
+                _ => panic!(),
+            }
+            i += 1;
+        }
+    }
+
+    #[test]
+    fn iter_rev() {
+        let mut p: PrimaryMap<E, usize> = PrimaryMap::new();
+        p.push(12);
+        p.push(33);
+        let mut m = p.into_boxed_slice();
+
+        let mut i = 2;
+        for (key, value) in m.iter().rev() {
+            i -= 1;
+            assert_eq!(key.index(), i);
+            match i {
+                0 => assert_eq!(*value, 12),
+                1 => assert_eq!(*value, 33),
+                _ => panic!(),
+            }
+        }
+
+        i = 2;
+        for (key, value) in m.iter_mut().rev() {
+            i -= 1;
+            assert_eq!(key.index(), i);
+            match i {
+                0 => assert_eq!(*value, 12),
+                1 => assert_eq!(*value, 33),
+                _ => panic!(),
+            }
+        }
+    }
+    #[test]
+    fn keys() {
+        let mut p: PrimaryMap<E, usize> = PrimaryMap::new();
+        p.push(12);
+        p.push(33);
+        let m = p.into_boxed_slice();
+
+        let mut i = 0;
+        for key in m.keys() {
+            assert_eq!(key.index(), i);
+            i += 1;
+        }
+    }
+
+    #[test]
+    fn keys_rev() {
+        let mut p: PrimaryMap<E, usize> = PrimaryMap::new();
+        p.push(12);
+        p.push(33);
+        let m = p.into_boxed_slice();
+
+        let mut i = 2;
+        for key in m.keys().rev() {
+            i -= 1;
+            assert_eq!(key.index(), i);
+        }
+    }
+
+    #[test]
+    fn values() {
+        let mut p: PrimaryMap<E, usize> = PrimaryMap::new();
+        p.push(12);
+        p.push(33);
+        let mut m = p.into_boxed_slice();
+
+        let mut i = 0;
+        for value in m.values() {
+            match i {
+                0 => assert_eq!(*value, 12),
+                1 => assert_eq!(*value, 33),
+                _ => panic!(),
+            }
+            i += 1;
+        }
+        i = 0;
+        for value_mut in m.values_mut() {
+            match i {
+                0 => assert_eq!(*value_mut, 12),
+                1 => assert_eq!(*value_mut, 33),
+                _ => panic!(),
+            }
+            i += 1;
+        }
+    }
+
+    #[test]
+    fn values_rev() {
+        let mut p: PrimaryMap<E, usize> = PrimaryMap::new();
+        p.push(12);
+        p.push(33);
+        let mut m = p.into_boxed_slice();
+
+        let mut i = 2;
+        for value in m.values().rev() {
+            i -= 1;
+            match i {
+                0 => assert_eq!(*value, 12),
+                1 => assert_eq!(*value, 33),
+                _ => panic!(),
+            }
+        }
+        i = 2;
+        for value_mut in m.values_mut().rev() {
+            i -= 1;
+            match i {
+                0 => assert_eq!(*value_mut, 12),
+                1 => assert_eq!(*value_mut, 33),
+                _ => panic!(),
+            }
+        }
+    }
+}
--- a/third_party/rust/cranelift-entity/src/lib.rs
+++ b/third_party/rust/cranelift-entity/src/lib.rs
@@ -27,35 +27,32 @@
 //!   been inserted into the primary map. Instead, any unknown entities are not in the set.
 //! - [`EntityList`](struct.EntityList.html) is a compact representation of lists of entity
 //!   references allocated from an associated memory pool. It has a much smaller footprint than
 //!   `Vec`.
 
 #![deny(missing_docs, trivial_numeric_casts, unused_extern_crates)]
 #![warn(unused_import_braces)]
 #![cfg_attr(feature = "std", deny(unstable_features))]
-#![cfg_attr(
-    feature = "clippy",
-    plugin(clippy(conf_file = "../../clippy.toml"))
-)]
+#![cfg_attr(feature = "clippy", plugin(clippy(conf_file = "../../clippy.toml")))]
 #![cfg_attr(
     feature = "cargo-clippy",
     allow(new_without_default, new_without_default_derive)
 )]
 #![cfg_attr(
     feature = "cargo-clippy",
     warn(
-        float_arithmetic,
-        mut_mut,
-        nonminimal_bool,
-        option_map_unwrap_or,
-        option_map_unwrap_or_else,
-        print_stdout,
-        unicode_not_nfc,
-        use_self
+        clippy::float_arithmetic,
+        clippy::mut_mut,
+        clippy::nonminimal_bool,
+        clippy::option_map_unwrap_or,
+        clippy::option_map_unwrap_or_else,
+        clippy::print_stdout,
+        clippy::unicode_not_nfc,
+        clippy::use_self
     )
 )]
 // Turns on no_std and alloc features if std is not available.
 #![cfg_attr(not(feature = "std"), no_std)]
 #![cfg_attr(not(feature = "std"), feature(alloc))]
 
 /// This replaces `std` in builds with `core`.
 #[cfg(not(feature = "std"))]
@@ -96,16 +93,31 @@ macro_rules! entity_impl {
             }
         }
 
         impl $crate::packed_option::ReservedValue for $entity {
             fn reserved_value() -> $entity {
                 $entity($crate::__core::u32::MAX)
             }
         }
+
+        impl $entity {
+            /// Return the underlying index value as a `u32`.
+            #[allow(dead_code)]
+            pub fn from_u32(x: u32) -> Self {
+                debug_assert!(x < $crate::__core::u32::MAX);
+                $entity(x)
+            }
+
+            /// Return the underlying index value as a `u32`.
+            #[allow(dead_code)]
+            pub fn as_u32(self) -> u32 {
+                self.0
+            }
+        }
     };
 
     // Include basic `Display` impl using the given display prefix.
     // Display an `Ebb` reference as "ebb12".
     ($entity:ident, $display_prefix:expr) => {
         entity_impl!($entity);
 
         impl $crate::__core::fmt::Display for $entity {
@@ -119,23 +131,25 @@ macro_rules! entity_impl {
                 (self as &$crate::__core::fmt::Display).fmt(f)
             }
         }
     };
 }
 
 pub mod packed_option;
 
+mod boxed_slice;
 mod iter;
 mod keys;
 mod list;
 mod map;
 mod primary;
 mod set;
 mod sparse;
 
+pub use self::boxed_slice::BoxedSlice;
 pub use self::iter::{Iter, IterMut};
 pub use self::keys::Keys;
 pub use self::list::{EntityList, ListPool};
 pub use self::map::SecondaryMap;
 pub use self::primary::PrimaryMap;
 pub use self::set::EntitySet;
 pub use self::sparse::{SparseMap, SparseMapValue, SparseSet};
--- a/third_party/rust/cranelift-entity/src/map.rs
+++ b/third_party/rust/cranelift-entity/src/map.rs
@@ -1,15 +1,17 @@
 //! Densely numbered entity references as mapping keys.
 
+use iter::{Iter, IterMut};
+use keys::Keys;
 use std::marker::PhantomData;
 use std::ops::{Index, IndexMut};
 use std::slice;
 use std::vec::Vec;
-use {EntityRef, Iter, IterMut, Keys};
+use EntityRef;
 
 /// A mapping `K -> V` for densely indexed entity references.
 ///
 /// The `SecondaryMap` data structure uses the dense index space to implement a map with a vector.
 /// Unlike `PrimaryMap`, an `SecondaryMap` can't be used to allocate entity references. It is used to
 /// associate secondary information with entities.
 ///
 /// The map does not track if an entry for a key has been inserted or not. Instead it behaves as if
--- a/third_party/rust/cranelift-entity/src/primary.rs
+++ b/third_party/rust/cranelift-entity/src/primary.rs
@@ -1,29 +1,34 @@
 //! Densely numbered entity references as mapping keys.
+use boxed_slice::BoxedSlice;
+use iter::{Iter, IterMut};
+use keys::Keys;
+use std::iter::FromIterator;
 use std::marker::PhantomData;
 use std::ops::{Index, IndexMut};
 use std::slice;
 use std::vec::Vec;
-use {EntityRef, Iter, IterMut, Keys};
+use EntityRef;
 
 /// A primary mapping `K -> V` allocating dense entity references.
 ///
 /// The `PrimaryMap` data structure uses the dense index space to implement a map with a vector.
 ///
 /// A primary map contains the main definition of an entity, and it can be used to allocate new
 /// entity references with the `push` method.
 ///
 /// There should only be a single `PrimaryMap` instance for a given `EntityRef` type, otherwise
 /// conflicting references will be created. Using unknown keys for indexing will cause a panic.
 ///
 /// Note that `PrimaryMap` doesn't implement `Deref` or `DerefMut`, which would allow
 /// `&PrimaryMap<K, V>` to convert to `&[V]`. One of the main advantages of `PrimaryMap` is
 /// that it only allows indexing with the distinct `EntityRef` key type, so converting to a
-/// plain slice would make it easier to use incorrectly.
+/// plain slice would make it easier to use incorrectly. To make a slice of a `PrimaryMap`, use
+/// `into_boxed_slice`.
 #[derive(Debug, Clone)]
 pub struct PrimaryMap<K, V>
 where
     K: EntityRef,
 {
     elems: Vec<V>,
     unused: PhantomData<K>,
 }
@@ -35,16 +40,24 @@ where
     /// Create a new empty map.
     pub fn new() -> Self {
         Self {
             elems: Vec::new(),
             unused: PhantomData,
         }
     }
 
+    /// Create a new empty map with the given capacity.
+    pub fn with_capacity(capacity: usize) -> Self {
+        Self {
+            elems: Vec::with_capacity(capacity),
+            unused: PhantomData,
+        }
+    }
+
     /// Check if `k` is a valid key in the map.
     pub fn is_valid(&self, k: K) -> bool {
         k.index() < self.elems.len()
     }
 
     /// Get the element at `k` if it exists.
     pub fn get(&self, k: K) -> Option<&V> {
         self.elems.get(k.index())
@@ -116,16 +129,21 @@ where
     pub fn reserve(&mut self, additional: usize) {
         self.elems.reserve(additional)
     }
 
     /// Reserves the minimum capacity for exactly `additional` more elements to be inserted.
     pub fn reserve_exact(&mut self, additional: usize) {
         self.elems.reserve_exact(additional)
     }
+
+    /// Consumes this `PrimaryMap` and produces a `BoxedSlice`.
+    pub fn into_boxed_slice(self) -> BoxedSlice<K, V> {
+        unsafe { BoxedSlice::<K, V>::from_raw(Box::<[V]>::into_raw(self.elems.into_boxed_slice())) }
+    }
 }
 
 /// Immutable indexing into an `PrimaryMap`.
 /// The indexed value must be in the map.
 impl<K, V> Index<K> for PrimaryMap<K, V>
 where
     K: EntityRef,
 {
@@ -165,16 +183,31 @@ where
     type Item = (K, &'a mut V);
     type IntoIter = IterMut<'a, K, V>;
 
     fn into_iter(self) -> Self::IntoIter {
         IterMut::new(self.elems.iter_mut())
     }
 }
 
+impl<K, V> FromIterator<V> for PrimaryMap<K, V>
+where
+    K: EntityRef,
+{
+    fn from_iter<T>(iter: T) -> Self
+    where
+        T: IntoIterator<Item = V>,
+    {
+        Self {
+            elems: Vec::from_iter(iter),
+            unused: PhantomData,
+        }
+    }
+}
+
 #[cfg(test)]
 mod tests {
     use super::*;
 
     // `EntityRef` impl for testing.
     #[derive(Clone, Copy, Debug, PartialEq, Eq)]
     struct E(u32);
 
@@ -341,9 +374,22 @@ mod tests {
             i -= 1;
             match i {
                 0 => assert_eq!(*value_mut, 12),
                 1 => assert_eq!(*value_mut, 33),
                 _ => panic!(),
             }
         }
     }
+
+    #[test]
+    fn from_iter() {
+        let mut m: PrimaryMap<E, usize> = PrimaryMap::new();
+        m.push(12);
+        m.push(33);
+
+        let n = m.values().collect::<PrimaryMap<E, _>>();
+        assert!(m.len() == n.len());
+        for (me, ne) in m.values().zip(n.values()) {
+            assert!(*me == **ne);
+        }
+    }
 }
--- a/third_party/rust/cranelift-entity/src/set.rs
+++ b/third_party/rust/cranelift-entity/src/set.rs
@@ -1,13 +1,14 @@
 //! Densely numbered entity references as set keys.
 
+use keys::Keys;
 use std::marker::PhantomData;
 use std::vec::Vec;
-use {EntityRef, Keys};
+use EntityRef;
 
 /// A set of `K` for densely indexed entity references.
 ///
 /// The `EntitySet` data structure uses the dense index space to implement a set with a bitvector.
 /// Like `SecondaryMap`, an `EntitySet` is used to associate secondary information with entities.
 #[derive(Debug, Clone)]
 pub struct EntitySet<K>
 where
--- a/third_party/rust/cranelift-entity/src/sparse.rs
+++ b/third_party/rust/cranelift-entity/src/sparse.rs
@@ -2,21 +2,22 @@
 //!
 //! This module provides a `SparseMap` data structure which implements a sparse mapping from an
 //! `EntityRef` key to a value type that may be on the larger side. This implementation is based on
 //! the paper:
 //!
 //! > Briggs, Torczon, *An efficient representation for sparse sets*,
 //!   ACM Letters on Programming Languages and Systems, Volume 2, Issue 1-4, March-Dec. 1993.
 
+use map::SecondaryMap;
 use std::mem;
 use std::slice;
 use std::u32;
 use std::vec::Vec;
-use {EntityRef, SecondaryMap};
+use EntityRef;
 
 /// Trait for extracting keys from values stored in a `SparseMap`.
 ///
 /// All values stored in a `SparseMap` must keep track of their own key in the map and implement
 /// this trait to provide access to the key.
 pub trait SparseMapValue<K> {
     /// Get the key of this sparse map value. This key is not allowed to change while the value
     /// is a member of the map.
--- a/third_party/rust/cranelift-frontend/.cargo-checksum.json
+++ b/third_party/rust/cranelift-frontend/.cargo-checksum.json
@@ -1,1 +1,1 @@
-{"files":{"Cargo.toml":"597db8d588c5ed61feb5d54e82f9750575f41211de66c965241186694aec244f","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"dea43e8044284df50f8b8772e9b48ba8b109b45c74111ff73619775d57ad8d67","src/frontend.rs":"98fed7c08319790af423c40498ed8dd856a52b3535d2ecaf4a835392bd951996","src/lib.rs":"9c223914fb7530a669a7487b3b1cf3138df0aed79d152da3d3e03012382244f2","src/ssa.rs":"2b03fd5c88cda8a318827282ed960a61192d6685881ebd8b3d6e8fa92ca6bdc6","src/switch.rs":"bda005663d7976353250c8016ec1f46d0aa03ef289542e4db1b87a071387f7a4","src/variable.rs":"b8de0a43f72ca45bfa0833aee312f3c3f396cf3920545bbdcb9da98fb0de26df"},"package":"98d9eb4a2343435d520499236c805725c88d6d55eefb9a6ad0819b7970c76bdd"}
\ No newline at end of file
+{"files":{"Cargo.toml":"1f837e21c9d7fc5fa7d16477c84fb8482621ca085ed366383d486c5ae6fc5e30","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"dea43e8044284df50f8b8772e9b48ba8b109b45c74111ff73619775d57ad8d67","src/frontend.rs":"9eac4e937d75663e93d8b37d1aedff586d4fe59daec1818eec2a040f8259fcbd","src/lib.rs":"230b18a01a6b0bf7ed8be2f56fff03c5edec64029c069fcce8594a3fb8eb3368","src/ssa.rs":"1a45f96c2fd9f32c11c3eb3ab639e47a15c4b4507509125fba94e243f562b7f2","src/switch.rs":"bda005663d7976353250c8016ec1f46d0aa03ef289542e4db1b87a071387f7a4","src/variable.rs":"b8de0a43f72ca45bfa0833aee312f3c3f396cf3920545bbdcb9da98fb0de26df"},"package":"789907218eeebebcea8122c2053d71affac91c96ce72cea35ebfdbbf547e82af"}
\ No newline at end of file
--- a/third_party/rust/cranelift-frontend/Cargo.toml
+++ b/third_party/rust/cranelift-frontend/Cargo.toml
@@ -7,26 +7,26 @@
 #
 # If you believe there's an error in this file please file an
 # issue against the rust-lang/cargo repository. If you're
 # editing this file be aware that the upstream Cargo.toml
 # will likely look very different (and much more reasonable)
 
 [package]
 name = "cranelift-frontend"
-version = "0.25.0"
+version = "0.26.0"
 authors = ["The Cranelift Project Developers"]
 description = "Cranelift IR builder helper"
 documentation = "https://cranelift.readthedocs.io/"
 readme = "README.md"
 categories = ["no-std"]
 license = "Apache-2.0 WITH LLVM-exception"
 repository = "https://github.com/CraneStation/cranelift"
 [dependencies.cranelift-codegen]
-version = "0.25.0"
+version = "0.26.0"
 default-features = false
 
 [dependencies.hashmap_core]
 version = "0.1.9"
 optional = true
 
 [dependencies.log]
 version = "0.4.4"
--- a/third_party/rust/cranelift-frontend/src/frontend.rs
+++ b/third_party/rust/cranelift-frontend/src/frontend.rs
@@ -509,20 +509,22 @@ impl<'a> FunctionBuilder<'a> {
     /// Returns `true` if and only if the current `Ebb` is sealed and has no predecessors declared.
     ///
     /// The entry block of a function is never unreachable.
     pub fn is_unreachable(&self) -> bool {
         let is_entry = match self.func.layout.entry_block() {
             None => false,
             Some(entry) => self.position.ebb.unwrap() == entry,
         };
-        !is_entry && self.func_ctx.ssa.is_sealed(self.position.ebb.unwrap()) && !self
-            .func_ctx
-            .ssa
-            .has_any_predecessors(self.position.ebb.unwrap())
+        !is_entry
+            && self.func_ctx.ssa.is_sealed(self.position.ebb.unwrap())
+            && !self
+                .func_ctx
+                .ssa
+                .has_any_predecessors(self.position.ebb.unwrap())
     }
 
     /// Returns `true` if and only if no instructions have been added since the last call to
     /// `switch_to_block`.
     pub fn is_pristine(&self) -> bool {
         self.func_ctx.ebbs[self.position.ebb.unwrap()].pristine
     }
 
@@ -764,17 +766,18 @@ impl<'a> FunctionBuilder<'a> {
         // Load all of the memory first in case `dest` overlaps.
         let registers: Vec<_> = (0..load_and_store_amount)
             .map(|i| {
                 let offset = (access_size * i) as i32;
                 (
                     self.ins().load(config.pointer_type(), flags, src, offset),
                     offset,
                 )
-            }).collect();
+            })
+            .collect();
 
         for (value, offset) in registers {
             self.ins().store(flags, value, dest, offset);
         }
     }
 }
 
 fn greatest_divisible_power_of_two(size: u64) -> u64 {
--- a/third_party/rust/cranelift-frontend/src/lib.rs
+++ b/third_party/rust/cranelift-frontend/src/lib.rs
@@ -159,24 +159,24 @@
 
 #![deny(missing_docs, trivial_numeric_casts, unused_extern_crates)]
 #![warn(unused_import_braces)]
 #![cfg_attr(feature = "std", deny(unstable_features))]
 #![cfg_attr(feature = "cargo-clippy", allow(new_without_default))]
 #![cfg_attr(
     feature = "cargo-clippy",
     warn(
-        float_arithmetic,
-        mut_mut,
-        nonminimal_bool,
-        option_map_unwrap_or,
-        option_map_unwrap_or_else,
-        print_stdout,
-        unicode_not_nfc,
-        use_self
+        clippy::float_arithmetic,
+        clippy::mut_mut,
+        clippy::nonminimal_bool,
+        clippy::option_map_unwrap_or,
+        clippy::option_map_unwrap_or_else,
+        clippy::print_stdout,
+        clippy::unicode_not_nfc,
+        clippy::use_self
     )
 )]
 #![cfg_attr(not(feature = "std"), no_std)]
 #![cfg_attr(not(feature = "std"), feature(alloc))]
 
 #[cfg(not(feature = "std"))]
 #[macro_use]
 extern crate alloc;
--- a/third_party/rust/cranelift-frontend/src/ssa.rs
+++ b/third_party/rust/cranelift-frontend/src/ssa.rs
@@ -187,19 +187,19 @@ impl SSABuilder {
             && self.results.is_empty()
             && self.side_effects.is_empty()
     }
 }
 
 /// Small enum used for clarity in some functions.
 #[derive(Debug)]
 enum ZeroOneOrMore<T> {
-    Zero(),
+    Zero,
     One(T),
-    More(),
+    More,
 }
 
 #[derive(Debug)]
 enum UseVarCases {
     Unsealed(Value),
     SealedOnePredecessor(Block),
     SealedMultiplePredecessors(Value, Ebb),
 }
@@ -521,39 +521,39 @@ impl SSABuilder {
     /// block parameters as needed.
     fn finish_predecessors_lookup(
         &mut self,
         func: &mut Function,
         temp_arg_val: Value,
         temp_arg_var: Variable,
         dest_ebb: Ebb,
     ) {
-        let mut pred_values: ZeroOneOrMore<Value> = ZeroOneOrMore::Zero();
+        let mut pred_values: ZeroOneOrMore<Value> = ZeroOneOrMore::Zero;
 
         // Iterate over the predecessors.
         for _ in 0..self.predecessors(dest_ebb).len() {
             // For each predecessor, we query what is the local SSA value corresponding
             // to var and we put it as an argument of the branch instruction.
             let pred_val = self.results.pop().unwrap();
             match pred_values {
-                ZeroOneOrMore::Zero() => {
+                ZeroOneOrMore::Zero => {
                     if pred_val != temp_arg_val {
                         pred_values = ZeroOneOrMore::One(pred_val);
                     }
                 }
                 ZeroOneOrMore::One(old_val) => {
                     if pred_val != temp_arg_val && pred_val != old_val {
-                        pred_values = ZeroOneOrMore::More();
+                        pred_values = ZeroOneOrMore::More;
                     }
                 }
-                ZeroOneOrMore::More() => {}
+                ZeroOneOrMore::More => {}
             }
         }
         let result_val = match pred_values {
-            ZeroOneOrMore::Zero() => {
+            ZeroOneOrMore::Zero => {
                 // The variable is used but never defined before. This is an irregularity in the
                 // code, but rather than throwing an error we silently initialize the variable to
                 // 0. This will have no effect since this situation happens in unreachable code.
                 if !func.layout.is_ebb_inserted(dest_ebb) {
                     func.layout.append_ebb(dest_ebb);
                 }
                 self.side_effects.instructions_added_to_ebbs.push(dest_ebb);
                 let zero = emit_zero(
@@ -578,17 +578,17 @@ impl SSABuilder {
                         func.dfg.value_type(temp_arg_val),
                         FuncCursor::new(func).at_first_insertion_point(dest_ebb),
                     );
                 }
                 func.dfg.remove_ebb_param(temp_arg_val);
                 func.dfg.change_to_alias(temp_arg_val, resolved);
                 resolved
             }
-            ZeroOneOrMore::More() => {
+            ZeroOneOrMore::More => {
                 // There is disagreement in the predecessors on which value to use so we have
                 // to keep the ebb argument. To avoid borrowing `self` for the whole loop,
                 // temporarily detach the predecessors list and replace it with an empty list.
                 let mut preds = mem::replace(self.predecessors_mut(dest_ebb), Vec::new());
                 for &mut PredBlock {
                     block: ref mut pred_block,
                     branch: ref mut last_inst,
                 } in &mut preds
--- a/third_party/rust/cranelift-wasm/.cargo-checksum.json
+++ b/third_party/rust/cranelift-wasm/.cargo-checksum.json
@@ -1,1 +1,1 @@
-{"files":{"Cargo.toml":"aca5579a3fbaa96d6cfda23012215879f7df0a07313e2e9acdc49e167d31e1c3","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"046f81212a5705bfaa925b6de195652141b727d63ef602af57d5073659deea64","src/code_translator.rs":"474d07684fee27fcbd48997a7772458d8eff0a69a31b74293066a892c87067f9","src/environ/dummy.rs":"aafca1a2cda88cb67d4c082f7ccb6296812586216f417c501224b6790d345446","src/environ/mod.rs":"8c5287366c354acb144593fadbbe45c14106e0b7ec101077c4f3f213901c584d","src/environ/spec.rs":"a627a1a92a2a652d037f63a9def019ebbf4c953de1cb194f2e73095744d07476","src/func_translator.rs":"1c6b7d0d3da14c1ff7df1c22d2ade14da5d87d0be70f647145ea180da762aa2f","src/lib.rs":"b94abdc2fe638aff7b5fc00ffb2fc4812590a68241b8462b82888aa9114c2f64","src/module_translator.rs":"8e441cc4cb05d6bdd7be41f2ba937390f85f3e3b07578e03a0f9e642f963bc02","src/sections_translator.rs":"62d7d53abc88060c4d63721a99530d26a3ed09cb99e1f19238bcefd8b86b958a","src/state.rs":"4523d611d2c4889eb809ee6c2bfbf29d4d83230580be3c724009ba8988cc25b6","src/translation_utils.rs":"363d75509bca5d87548881dcbb3c52642980be8fa6d62c2ea4b39524560ac65c","tests/wasm_testsuite.rs":"9ea05ab8d188f047f3307e5ca0c1ea10784d65d338f7ea3544d59e6fa6a202f2"},"package":"5022a3a3d1044fdc8c97909b5e8d701884982dcfb43885034d004cfdd9b7d577"}
\ No newline at end of file
+{"files":{"Cargo.toml":"741858026996a107f1c9fa0f0c741d615892f5f9e1789bee0da75ce53814c369","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"046f81212a5705bfaa925b6de195652141b727d63ef602af57d5073659deea64","src/code_translator.rs":"0a8d7e8b7987d825f88ebcb4298ab582d80ddad248449fe763ce5593dd3fde51","src/environ/dummy.rs":"df84b9344bda02ed001d5f1ce6a1ecf3a91bda109ff261f27dc23a988504c654","src/environ/mod.rs":"8c5287366c354acb144593fadbbe45c14106e0b7ec101077c4f3f213901c584d","src/environ/spec.rs":"ed02f232326fe998efe3fa0d324f9793dc9005eaa8e0245471e4c05070238ea1","src/func_translator.rs":"1c6b7d0d3da14c1ff7df1c22d2ade14da5d87d0be70f647145ea180da762aa2f","src/lib.rs":"cb99b6156001dbafcecc07cdd0f7c1e45f39595de8fdf08a4fde88e10c670888","src/module_translator.rs":"8e441cc4cb05d6bdd7be41f2ba937390f85f3e3b07578e03a0f9e642f963bc02","src/sections_translator.rs":"a8a348cbac99758282c96c21ed494dfb0626fe1f5c2ff320f323004b494d8f46","src/state.rs":"e34db3dd896c1a122132bcd3a080a2195f4978a7a68e948fe3d7b770c6e8a8d5","src/translation_utils.rs":"5274820a4929edeefb13143f8a8cd08b61a4f536f3933de6e05c050cc1bb1f04","tests/wasm_testsuite.rs":"896d9114984847fb257859c585b06424e0ed166845ce06c2183f4aa397bd7504"},"package":"49723365dab9a48b354bdc24cb6d9d5719bc1d3b858ffd2ea179d0d7d885804a"}
\ No newline at end of file
--- a/third_party/rust/cranelift-wasm/Cargo.toml
+++ b/third_party/rust/cranelift-wasm/Cargo.toml
@@ -7,34 +7,37 @@
 #
 # If you believe there's an error in this file please file an
 # issue against the rust-lang/cargo repository. If you're
 # editing this file be aware that the upstream Cargo.toml
 # will likely look very different (and much more reasonable)
 
 [package]
 name = "cranelift-wasm"
-version = "0.25.0"
+version = "0.26.0"
 authors = ["The Cranelift Project Developers"]
 description = "Translator from WebAssembly to Cranelift IR"
 readme = "README.md"
 keywords = ["webassembly", "wasm"]
 categories = ["no-std", "wasm"]
 license = "Apache-2.0 WITH LLVM-exception"
 repository = "https://github.com/CraneStation/cranelift"
+[dependencies.cast]
+version = "0.2.2"
+
 [dependencies.cranelift-codegen]
-version = "0.25.0"
+version = "0.26.0"
 default-features = false
 
 [dependencies.cranelift-entity]
-version = "0.25.0"
+version = "0.26.0"
 default-features = false
 
 [dependencies.cranelift-frontend]
-version = "0.25.0"
+version = "0.26.0"
 default-features = false
 
 [dependencies.failure]
 version = "0.1.1"
 features = ["derive"]
 default-features = false
 
 [dependencies.failure_derive]
--- a/third_party/rust/cranelift-wasm/src/code_translator.rs
+++ b/third_party/rust/cranelift-wasm/src/code_translator.rs
@@ -21,17 +21,16 @@
 //!    is;
 //!
 //! That is why `translate_function_body` takes an object having the `WasmRuntime` trait as
 //! argument.
 use cranelift_codegen::ir::condcodes::{FloatCC, IntCC};
 use cranelift_codegen::ir::types::*;
 use cranelift_codegen::ir::{self, InstBuilder, JumpTableData, MemFlags};
 use cranelift_codegen::packed_option::ReservedValue;
-use cranelift_entity::EntityRef;
 use cranelift_frontend::{FunctionBuilder, Variable};
 use environ::{FuncEnvironment, GlobalVariable, ReturnMode, WasmError, WasmResult};
 use state::{ControlStackFrame, TranslationState};
 use std::collections::{hash_map, HashMap};
 use std::vec::Vec;
 use std::{i32, u32};
 use translation_utils::{f32_translation, f64_translation, num_return_values, type_to_type};
 use translation_utils::{FuncIndex, MemoryIndex, SignatureIndex, TableIndex};
@@ -70,36 +69,33 @@ pub fn translate_operator<FE: FuncEnviro
             builder.def_var(Variable::with_u32(local_index), val);
         }
         /********************************** Globals ****************************************
          *  `get_global` and `set_global` are handled by the environment.
          ***********************************************************************************/
         Operator::GetGlobal { global_index } => {
             let val = match state.get_global(builder.func, global_index, environ) {
                 GlobalVariable::Const(val) => val,
-                GlobalVariable::Memory { gv, ty } => {
+                GlobalVariable::Memory { gv, offset, ty } => {
                     let addr = builder.ins().global_value(environ.pointer_type(), gv);
-                    let mut flags = ir::MemFlags::new();
-                    flags.set_notrap();
-                    flags.set_aligned();
-                    builder.ins().load(ty, flags, addr, 0)
+                    let flags = ir::MemFlags::trusted();
+                    builder.ins().load(ty, flags, addr, offset)
                 }
             };
             state.push1(val);
         }
         Operator::SetGlobal { global_index } => {
             match state.get_global(builder.func, global_index, environ) {
                 GlobalVariable::Const(_) => panic!("global #{} is a constant", global_index),
-                GlobalVariable::Memory { gv, .. } => {
+                GlobalVariable::Memory { gv, offset, ty } => {
                     let addr = builder.ins().global_value(environ.pointer_type(), gv);
-                    let mut flags = ir::MemFlags::new();
-                    flags.set_notrap();
-                    flags.set_aligned();
+                    let flags = ir::MemFlags::trusted();
                     let val = state.pop1();
-                    builder.ins().store(flags, val, addr, 0);
+                    debug_assert_eq!(ty, builder.func.dfg.value_type(val));
+                    builder.ins().store(flags, val, addr, offset);
                 }
             }
         }
         /********************************* Stack misc ***************************************
          *  `drop`, `nop`, `unreachable` and `select`.
          ***********************************************************************************/
         Operator::Drop => {
             state.pop1();
@@ -353,17 +349,17 @@ pub fn translate_operator<FE: FuncEnviro
          * The call instructions pop off their arguments from the stack and append their
          * return values to it. `call_indirect` needs environment support because there is an
          * argument referring to an index in the external functions table of the module.
          ************************************************************************************/
         Operator::Call { function_index } => {
             let (fref, num_args) = state.get_direct_func(builder.func, function_index, environ);
             let call = environ.translate_call(
                 builder.cursor(),
-                FuncIndex::new(function_index as usize),
+                FuncIndex::from_u32(function_index),
                 fref,
                 state.peekn(num_args),
             )?;
             let inst_results = builder.inst_results(call);
             debug_assert_eq!(
                 inst_results.len(),
                 builder.func.dfg.signatures[builder.func.dfg.ext_funcs[fref].signature]
                     .returns
@@ -376,19 +372,19 @@ pub fn translate_operator<FE: FuncEnviro
         Operator::CallIndirect { index, table_index } => {
             // `index` is the index of the function's signature and `table_index` is the index of
             // the table to search the function in.
             let (sigref, num_args) = state.get_indirect_sig(builder.func, index, environ);
             let table = state.get_table(builder.func, table_index, environ);
             let callee = state.pop1();
             let call = environ.translate_call_indirect(
                 builder.cursor(),
-                TableIndex::new(table_index as usize),
+                TableIndex::from_u32(table_index),
                 table,
-                SignatureIndex::new(index as usize),
+                SignatureIndex::from_u32(index),
                 sigref,
                 callee,
                 state.peekn(num_args),
             )?;
             let inst_results = builder.inst_results(call);
             debug_assert_eq!(
                 inst_results.len(),
                 builder.func.dfg.signatures[sigref].returns.len(),
@@ -399,23 +395,23 @@ pub fn translate_operator<FE: FuncEnviro
         }
         /******************************* Memory management ***********************************
          * Memory management is handled by environment. It is usually translated into calls to
          * special functions.
          ************************************************************************************/
         Operator::MemoryGrow { reserved } => {
             // The WebAssembly MVP only supports one linear memory, but we expect the reserved
             // argument to be a memory index.
-            let heap_index = MemoryIndex::new(reserved as usize);
+            let heap_index = MemoryIndex::from_u32(reserved);
             let heap = state.get_heap(builder.func, reserved, environ);
             let val = state.pop1();
             state.push1(environ.translate_memory_grow(builder.cursor(), heap_index, heap, val)?)
         }
         Operator::MemorySize { reserved } => {
-            let heap_index = MemoryIndex::new(reserved as usize);
+            let heap_index = MemoryIndex::from_u32(reserved);
             let heap = state.get_heap(builder.func, reserved, environ);
             state.push1(environ.translate_memory_size(builder.cursor(), heap_index, heap)?);
         }
         /******************************* Load instructions ***********************************
          * Wasm specifies an integer alignment flag but we drop it in Cranelift.
          * The memory base address is provided by the environment.
          ************************************************************************************/
         Operator::I32Load8U {
@@ -987,30 +983,30 @@ fn get_heap_addr(
     heap: ir::Heap,
     addr32: ir::Value,
     offset: u32,
     addr_ty: Type,
     builder: &mut FunctionBuilder,
 ) -> (ir::Value, i32) {
     use std::cmp::min;
 
-    let guard_size: i64 = builder.func.heaps[heap].guard_size.into();
-    debug_assert!(guard_size > 0, "Heap guard pages currently required");
+    let mut adjusted_offset = u64::from(offset);
+    let offset_guard_size: u64 = builder.func.heaps[heap].offset_guard_size.into();
 
     // Generate `heap_addr` instructions that are friendly to CSE by checking offsets that are
-    // multiples of the guard size. Add one to make sure that we check the pointer itself is in
-    // bounds.
-    //
-    // For accesses on the outer skirts of the guard pages, we expect that we get a trap
-    // even if the access goes beyond the guard pages. This is because the first byte pointed to is
-    // inside the guard pages.
-    let check_size = min(
-        i64::from(u32::MAX),
-        1 + (i64::from(offset) / guard_size) * guard_size,
-    ) as u32;
+    // multiples of the offset-guard size. Add one to make sure that we check the pointer itself
+    // is in bounds.
+    if offset_guard_size != 0 {
+        adjusted_offset = adjusted_offset / offset_guard_size * offset_guard_size;
+    }
+
+    // For accesses on the outer skirts of the offset-guard pages, we expect that we get a trap
+    // even if the access goes beyond the offset-guard pages. This is because the first byte
+    // pointed to is inside the offset-guard pages.
+    let check_size = min(u64::from(u32::MAX), 1 + adjusted_offset) as u32;
     let base = builder.ins().heap_addr(addr_ty, heap, addr32, check_size);
 
     // Native load/store instructions take a signed `Offset32` immediate, so adjust the base
     // pointer if necessary.
     if offset > i32::MAX as u32 {
         // Offset doesn't fit in the load/store instruction.
         let adj = builder.ins().iadd_imm(base, i64::from(i32::MAX) + 1);
         (adj, (offset - (i32::MAX as u32 + 1)) as i32)
--- a/third_party/rust/cranelift-wasm/src/environ/dummy.rs
+++ b/third_party/rust/cranelift-wasm/src/environ/dummy.rs
@@ -1,29 +1,30 @@
 //! "Dummy" implementations of `ModuleEnvironment` and `FuncEnvironment` for testing
 //! wasm translation.
 
+use cast;
 use cranelift_codegen::cursor::FuncCursor;
-use cranelift_codegen::ir::immediates::{Imm64, Offset32};
+use cranelift_codegen::ir::immediates::{Offset32, Uimm64};
 use cranelift_codegen::ir::types::*;
 use cranelift_codegen::ir::{self, InstBuilder};
 use cranelift_codegen::isa::TargetFrontendConfig;
 use cranelift_entity::{EntityRef, PrimaryMap};
 use environ::{FuncEnvironment, GlobalVariable, ModuleEnvironment, ReturnMode, WasmResult};
 use func_translator::FuncTranslator;
 use std::string::String;
 use std::vec::Vec;
 use translation_utils::{
     DefinedFuncIndex, FuncIndex, Global, GlobalIndex, Memory, MemoryIndex, SignatureIndex, Table,
     TableIndex,
 };
 
 /// Compute a `ir::ExternalName` for a given wasm function index.
 fn get_func_name(func_index: FuncIndex) -> ir::ExternalName {
-    ir::ExternalName::user(0, func_index.index() as u32)
+    ir::ExternalName::user(0, func_index.as_u32())
 }
 
 /// A collection of names under which a given entity is exported.
 pub struct Exportable<T> {
     /// A wasm entity.
     pub entity: T,
 
     /// Names under which the entity is exported.
@@ -164,25 +165,21 @@ impl<'dummy_environment> DummyFuncEnviro
 
 impl<'dummy_environment> FuncEnvironment for DummyFuncEnvironment<'dummy_environment> {
     fn target_config(&self) -> TargetFrontendConfig {
         self.mod_info.config
     }
 
     fn make_global(&mut self, func: &mut ir::Function, index: GlobalIndex) -> GlobalVariable {
         // Just create a dummy `vmctx` global.
-        let offset = ((index.index() * 8) as i64 + 8).into();
+        let offset = cast::i32((index.index() * 8) + 8).unwrap().into();
         let vmctx = func.create_global_value(ir::GlobalValueData::VMContext {});
-        let iadd = func.create_global_value(ir::GlobalValueData::IAddImm {
-            base: vmctx,
-            offset,
-            global_type: self.pointer_type(),
-        });
         GlobalVariable::Memory {
-            gv: iadd,
+            gv: vmctx,
+            offset: offset,
             ty: self.mod_info.globals[index].entity.ty,
         }
     }
 
     fn make_heap(&mut self, func: &mut ir::Function, _index: MemoryIndex) -> ir::Heap {
         // Create a static heap whose base address is stored at `vmctx+0`.
         let addr = func.create_global_value(ir::GlobalValueData::VMContext);
         let gv = func.create_global_value(ir::GlobalValueData::Load {
@@ -190,17 +187,17 @@ impl<'dummy_environment> FuncEnvironment
             offset: Offset32::new(0),
             global_type: self.pointer_type(),
             readonly: true,
         });
 
         func.create_heap(ir::HeapData {
             base: gv,
             min_size: 0.into(),
-            guard_size: 0x8000_0000.into(),
+            offset_guard_size: 0x8000_0000.into(),
             style: ir::HeapStyle::Static {
                 bound: 0x1_0000_0000.into(),
             },
             index_type: I32,
         })
     }
 
     fn make_table(&mut self, func: &mut ir::Function, _index: TableIndex) -> ir::Table {
@@ -216,19 +213,19 @@ impl<'dummy_environment> FuncEnvironment
             base: vmctx,
             offset: Offset32::new(0),
             global_type: I32,
             readonly: true,
         });
 
         func.create_table(ir::TableData {
             base_gv,
-            min_size: Imm64::new(0),
+            min_size: Uimm64::new(0),
             bound_gv,
-            element_size: Imm64::new(i64::from(self.pointer_bytes()) * 2),
+            element_size: Uimm64::from(u64::from(self.pointer_bytes()) * 2),
             index_type: I32,
         })
     }
 
     fn make_indirect_sig(&mut self, func: &mut ir::Function, index: SignatureIndex) -> ir::SigRef {
         // A real implementation would probably change the calling convention and add `vmctx` and
         // signature index arguments.
         func.import_signature(self.vmctx_sig(index))
@@ -268,19 +265,17 @@ impl<'dummy_environment> FuncEnvironment
         // TODO: Generate bounds checking code.
         let ptr = self.pointer_type();
         let callee_offset = if ptr == I32 {
             pos.ins().imul_imm(callee, 4)
         } else {
             let ext = pos.ins().uextend(I64, callee);
             pos.ins().imul_imm(ext, 4)
         };
-        let mut mflags = ir::MemFlags::new();
-        mflags.set_notrap();
-        mflags.set_aligned();
+        let mflags = ir::MemFlags::trusted();
         let func_ptr = pos.ins().load(ptr, mflags, callee_offset, 0);
 
         // Build a value list for the indirect call instruction containing the callee, call_args,
         // and the vmctx parameter.
         let mut args = ir::ValueList::default();
         args.push(func_ptr, &mut pos.func.dfg.value_lists);
         args.extend(call_args.iter().cloned(), &mut pos.func.dfg.value_lists);
         args.push(vmctx, &mut pos.func.dfg.value_lists);
@@ -337,20 +332,16 @@ impl<'dummy_environment> FuncEnvironment
     }
 }
 
 impl<'data> ModuleEnvironment<'data> for DummyEnvironment {
     fn target_config(&self) -> TargetFrontendConfig {
         self.info.config
     }
 
-    fn get_func_name(&self, func_index: FuncIndex) -> ir::ExternalName {
-        get_func_name(func_index)
-    }
-
     fn declare_signature(&mut self, sig: &ir::Signature) {
         self.info.signatures.push(sig.clone());
     }
 
     fn get_signature(&self, sig_index: SignatureIndex) -> &ir::Signature {
         &self.info.signatures[sig_index]
     }
 
--- a/third_party/rust/cranelift-wasm/src/environ/spec.rs
+++ b/third_party/rust/cranelift-wasm/src/environ/spec.rs
@@ -1,11 +1,12 @@
 //! All the runtime support necessary for the wasm to cranelift translation is formalized by the
 //! traits `FunctionEnvironment` and `ModuleEnvironment`.
 use cranelift_codegen::cursor::FuncCursor;
+use cranelift_codegen::ir::immediates::Offset32;
 use cranelift_codegen::ir::{self, InstBuilder};
 use cranelift_codegen::isa::TargetFrontendConfig;
 use std::convert::From;
 use std::vec::Vec;
 use translation_utils::{
     FuncIndex, Global, GlobalIndex, Memory, MemoryIndex, SignatureIndex, Table, TableIndex,
 };
 use wasmparser::BinaryReaderError;
@@ -15,36 +16,34 @@ use wasmparser::BinaryReaderError;
 pub enum GlobalVariable {
     /// This is a constant global with a value known at compile time.
     Const(ir::Value),
 
     /// This is a variable in memory that should be referenced through a `GlobalValue`.
     Memory {
         /// The address of the global variable storage.
         gv: ir::GlobalValue,
+        /// An offset to add to the address.
+        offset: Offset32,
         /// The global variable's type.
         ty: ir::Type,
     },
 }
 
 /// A WebAssembly translation error.
 ///
 /// When a WebAssembly function can't be translated, one of these error codes will be returned
 /// to describe the failure.
 #[derive(Fail, Debug, PartialEq, Eq)]
 pub enum WasmError {
     /// The input WebAssembly code is invalid.
     ///
     /// This error code is used by a WebAssembly translator when it encounters invalid WebAssembly
     /// code. This should never happen for validated WebAssembly code.
-    #[fail(
-        display = "Invalid input WebAssembly code at offset {}: {}",
-        _1,
-        _0
-    )]
+    #[fail(display = "Invalid input WebAssembly code at offset {}: {}", _1, _0)]
     InvalidWebAssembly {
         /// A string describing the validation error.
         message: &'static str,
         /// The bytecode offset where the error occurred.
         offset: usize,
     },
 
     /// A feature used by the WebAssembly code is not supported by the embedding environment.
@@ -234,19 +233,16 @@ pub trait FuncEnvironment {
 
 /// An object satisfying the `ModuleEnvironment` trait can be passed as argument to the
 /// [`translate_module`](fn.translate_module.html) function. These methods should not be called
 /// by the user, they are only for `cranelift-wasm` internal use.
 pub trait ModuleEnvironment<'data> {
     /// Get the information needed to produce Cranelift IR for the current target.
     fn target_config(&self) -> TargetFrontendConfig;
 
-    /// Return the name for the given function index.
-    fn get_func_name(&self, func_index: FuncIndex) -> ir::ExternalName;
-
     /// Declares a function signature to the environment.
     fn declare_signature(&mut self, sig: &ir::Signature);
 
     /// Return the signature with the given index.
     fn get_signature(&self, sig_index: SignatureIndex) -> &ir::Signature;
 
     /// Declares a function import to the environment.
     fn declare_func_import(
--- a/third_party/rust/cranelift-wasm/src/lib.rs
+++ b/third_party/rust/cranelift-wasm/src/lib.rs
@@ -7,43 +7,41 @@
 //! The crate provides a `DummyEnvironment` struct that will allow to translate the code of the
 //! functions but will fail at execution.
 //!
 //! The main function of this module is [`translate_module`](fn.translate_module.html).
 
 #![deny(missing_docs, trivial_numeric_casts, unused_extern_crates)]
 #![warn(unused_import_braces)]
 #![cfg_attr(feature = "std", deny(unstable_features))]
-#![cfg_attr(
-    feature = "clippy",
-    plugin(clippy(conf_file = "../../clippy.toml"))
-)]
+#![cfg_attr(feature = "clippy", plugin(clippy(conf_file = "../../clippy.toml")))]
 #![cfg_attr(
     feature = "cargo-clippy",
     allow(new_without_default, new_without_default_derive)
 )]
 #![cfg_attr(
     feature = "cargo-clippy",
     warn(
-        float_arithmetic,
-        mut_mut,
-        nonminimal_bool,
-        option_map_unwrap_or,
-        option_map_unwrap_or_else,
-        print_stdout,
-        unicode_not_nfc,
-        use_self
+        clippy::float_arithmetic,
+        clippy::mut_mut,
+        clippy::nonminimal_bool,
+        clippy::option_map_unwrap_or,
+        clippy::option_map_unwrap_or_else,
+        clippy::print_stdout,
+        clippy::unicode_not_nfc,
+        clippy::use_self
     )
 )]
 #![cfg_attr(not(feature = "std"), no_std)]
 #![cfg_attr(not(feature = "std"), feature(alloc))]
 
 extern crate cranelift_codegen;
 #[macro_use]
 extern crate cranelift_entity;
+extern crate cast;
 extern crate cranelift_frontend;
 #[cfg(test)]
 extern crate target_lexicon;
 extern crate wasmparser;
 
 extern crate failure;
 #[macro_use]
 extern crate failure_derive;
@@ -62,17 +60,18 @@ mod translation_utils;
 pub use environ::{
     DummyEnvironment, FuncEnvironment, GlobalVariable, ModuleEnvironment, ReturnMode, WasmError,
     WasmResult,
 };
 pub use func_translator::FuncTranslator;
 pub use module_translator::translate_module;
 pub use translation_utils::{
     DefinedFuncIndex, DefinedGlobalIndex, DefinedMemoryIndex, DefinedTableIndex, FuncIndex, Global,
-    GlobalIndex, GlobalInit, Memory, MemoryIndex, SignatureIndex, Table, TableIndex,
+    GlobalIndex, GlobalInit, Memory, MemoryIndex, SignatureIndex, Table, TableElementType,
+    TableIndex,
 };
 
 #[cfg(not(feature = "std"))]
 mod std {
     extern crate alloc;
 
     pub use self::alloc::string;
     pub use self::alloc::vec;
--- a/third_party/rust/cranelift-wasm/src/sections_translator.rs
+++ b/third_party/rust/cranelift-wasm/src/sections_translator.rs
@@ -65,56 +65,52 @@ pub fn parse_import_section<'data>(
         // The input has already been validated, so we should be able to
         // assume valid UTF-8 and use `from_utf8_unchecked` if performance
         // becomes a concern here.
         let module_name = from_utf8(import.module).unwrap();
         let field_name = from_utf8(import.field).unwrap();
 
         match import.ty {
             ImportSectionEntryType::Function(sig) => {
-                environ.declare_func_import(
-                    SignatureIndex::new(sig as usize),
-                    module_name,
-                    field_name,
-                );
+                environ.declare_func_import(SignatureIndex::from_u32(sig), module_name, field_name);
             }
             ImportSectionEntryType::Memory(MemoryType {
                 limits: ref memlimits,
                 shared,
             }) => {
                 environ.declare_memory_import(
                     Memory {
-                        pages_count: memlimits.initial as usize,
-                        maximum: memlimits.maximum.map(|x| x as usize),
+                        minimum: memlimits.initial,
+                        maximum: memlimits.maximum,
                         shared,
                     },
                     module_name,
                     field_name,
                 );
             }
             ImportSectionEntryType::Global(ref ty) => {
                 environ.declare_global_import(
                     Global {
                         ty: type_to_type(ty.content_type).unwrap(),
                         mutability: ty.mutable,
-                        initializer: GlobalInit::Import(),
+                        initializer: GlobalInit::Import,
                     },
                     module_name,
                     field_name,
                 );
             }
             ImportSectionEntryType::Table(ref tab) => {
                 environ.declare_table_import(
                     Table {
                         ty: match type_to_type(tab.element_type) {
                             Ok(t) => TableElementType::Val(t),
-                            Err(()) => TableElementType::Func(),
+                            Err(()) => TableElementType::Func,
                         },
-                        size: tab.limits.initial as usize,
-                        maximum: tab.limits.maximum.map(|x| x as usize),
+                        minimum: tab.limits.initial,
+                        maximum: tab.limits.maximum,
                     },
                     module_name,
                     field_name,
                 );
             }
         }
     }
     Ok(())
@@ -122,50 +118,50 @@ pub fn parse_import_section<'data>(
 
 /// Parses the Function section of the wasm module.
 pub fn parse_function_section(
     functions: FunctionSectionReader,
     environ: &mut ModuleEnvironment,
 ) -> WasmResult<()> {
     for entry in functions {
         let sigindex = entry?;
-        environ.declare_func_type(SignatureIndex::new(sigindex as usize));
+        environ.declare_func_type(SignatureIndex::from_u32(sigindex));
     }
     Ok(())
 }
 
 /// Parses the Table section of the wasm module.
 pub fn parse_table_section(
     tables: TableSectionReader,
     environ: &mut ModuleEnvironment,
 ) -> WasmResult<()> {
     for entry in tables {
         let table = entry?;
         environ.declare_table(Table {
             ty: match type_to_type(table.element_type) {
                 Ok(t) => TableElementType::Val(t),
-                Err(()) => TableElementType::Func(),
+                Err(()) => TableElementType::Func,
             },
-            size: table.limits.initial as usize,
-            maximum: table.limits.maximum.map(|x| x as usize),
+            minimum: table.limits.initial,
+            maximum: table.limits.maximum,
         });
     }
     Ok(())
 }
 
 /// Parses the Memory section of the wasm module.
 pub fn parse_memory_section(
     memories: MemorySectionReader,
     environ: &mut ModuleEnvironment,
 ) -> WasmResult<()> {
     for entry in memories {
         let memory = entry?;
         environ.declare_memory(Memory {
-            pages_count: memory.limits.initial as usize,
-            maximum: memory.limits.maximum.map(|x| x as usize),
+            minimum: memory.limits.initial,
+            maximum: memory.limits.maximum,
             shared: memory.shared,
         });
     }
     Ok(())
 }
 
 /// Parses the Global section of the wasm module.
 pub fn parse_global_section(
@@ -182,17 +178,17 @@ pub fn parse_global_section(
         } = entry?;
         let mut init_expr_reader = init_expr.get_binary_reader();
         let initializer = match init_expr_reader.read_operator()? {
             Operator::I32Const { value } => GlobalInit::I32Const(value),
             Operator::I64Const { value } => GlobalInit::I64Const(value),
             Operator::F32Const { value } => GlobalInit::F32Const(value.bits()),
             Operator::F64Const { value } => GlobalInit::F64Const(value.bits()),
             Operator::GetGlobal { global_index } => {
-                GlobalInit::GlobalRef(GlobalIndex::new(global_index as usize))
+                GlobalInit::GetGlobal(GlobalIndex::from_u32(global_index))
             }
             ref s => panic!("unsupported init expr in global section: {:?}", s),
         };
         let global = Global {
             ty: type_to_type(content_type).unwrap(),
             mutability: mutable,
             initializer,
         };
@@ -225,17 +221,17 @@ pub fn parse_export_section<'data>(
             ExternalKind::Global => environ.declare_global_export(GlobalIndex::new(index), name),
         }
     }
     Ok(())
 }
 
 /// Parses the Start section of the wasm module.
 pub fn parse_start_section(index: u32, environ: &mut ModuleEnvironment) -> WasmResult<()> {
-    environ.declare_start_func(FuncIndex::new(index as usize));
+    environ.declare_start_func(FuncIndex::from_u32(index));
     Ok(())
 }
 
 /// Parses the Element section of the wasm module.
 pub fn parse_element_section<'data>(
     elements: ElementSectionReader<'data>,
     environ: &mut ModuleEnvironment,
 ) -> WasmResult<()> {
@@ -244,32 +240,32 @@ pub fn parse_element_section<'data>(
             table_index,
             init_expr,
             items,
         } = entry?;
         let mut init_expr_reader = init_expr.get_binary_reader();
         let (base, offset) = match init_expr_reader.read_operator()? {
             Operator::I32Const { value } => (None, value as u32 as usize),
             Operator::GetGlobal { global_index } => match environ
-                .get_global(GlobalIndex::new(global_index as usize))
+                .get_global(GlobalIndex::from_u32(global_index))
                 .initializer
             {
                 GlobalInit::I32Const(value) => (None, value as u32 as usize),
-                GlobalInit::Import() => (Some(GlobalIndex::new(global_index as usize)), 0),
+                GlobalInit::Import => (Some(GlobalIndex::from_u32(global_index)), 0),
                 _ => panic!("should not happen"),
             },
             ref s => panic!("unsupported init expr in element section: {:?}", s),
         };
         let items_reader = items.get_items_reader()?;
         let mut elems = Vec::new();
         for item in items_reader {
             let x = item?;
-            elems.push(FuncIndex::new(x as usize));
+            elems.push(FuncIndex::from_u32(x));
         }
-        environ.declare_table_elements(TableIndex::new(table_index as usize), base, offset, elems)
+        environ.declare_table_elements(TableIndex::from_u32(table_index), base, offset, elems)
     }
     Ok(())
 }
 
 /// Parses the Code section of the wasm module.
 pub fn parse_code_section<'data>(
     code: CodeSectionReader<'data>,
     environ: &mut ModuleEnvironment<'data>,
@@ -292,26 +288,26 @@ pub fn parse_data_section<'data>(
             memory_index,
             init_expr,
             data,
         } = entry?;
         let mut init_expr_reader = init_expr.get_binary_reader();
         let (base, offset) = match init_expr_reader.read_operator()? {
             Operator::I32Const { value } => (None, value as u32 as usize),
             Operator::GetGlobal { global_index } => match environ
-                .get_global(GlobalIndex::new(global_index as usize))
+                .get_global(GlobalIndex::from_u32(global_index))
                 .initializer
             {
                 GlobalInit::I32Const(value) => (None, value as u32 as usize),
-                GlobalInit::Import() => (Some(GlobalIndex::new(global_index as usize)), 0),
+                GlobalInit::Import => (Some(GlobalIndex::from_u32(global_index)), 0),
                 _ => panic!("should not happen"),
             },
             ref s => panic!("unsupported init expr in data section: {:?}", s),
         };
         environ.declare_data_initialization(
-            MemoryIndex::new(memory_index as usize),
+            MemoryIndex::from_u32(memory_index),
             base,
             offset,
             data,
         );
     }
     Ok(())
 }
--- a/third_party/rust/cranelift-wasm/src/state.rs
+++ b/third_party/rust/cranelift-wasm/src/state.rs
@@ -1,15 +1,14 @@
 //! WebAssembly function translation state.
 //!
 //! The `TranslationState` struct defined in this module is used to keep track of the WebAssembly
 //! value and control stacks during the translation of a single function.
 
 use cranelift_codegen::ir::{self, Ebb, Inst, Value};
-use cranelift_entity::EntityRef;
 use environ::{FuncEnvironment, GlobalVariable};
 use std::collections::HashMap;
 use std::vec::Vec;
 use translation_utils::{FuncIndex, GlobalIndex, MemoryIndex, SignatureIndex, TableIndex};
 
 /// A control stack frame can be an `if`, a `block` or a `loop`, each one having the following
 /// fields:
 ///
@@ -282,81 +281,81 @@ impl TranslationState {
     /// `index`. Create the reference if necessary.
     /// Also return the WebAssembly type of the global.
     pub fn get_global<FE: FuncEnvironment + ?Sized>(
         &mut self,
         func: &mut ir::Function,
         index: u32,
         environ: &mut FE,
     ) -> GlobalVariable {
-        let index = GlobalIndex::new(index as usize);
+        let index = GlobalIndex::from_u32(index);
         *self
             .globals
             .entry(index)
             .or_insert_with(|| environ.make_global(func, index))
     }
 
     /// Get the `Heap` reference that should be used to access linear memory `index`.
     /// Create the reference if necessary.
     pub fn get_heap<FE: FuncEnvironment + ?Sized>(
         &mut self,
         func: &mut ir::Function,
         index: u32,
         environ: &mut FE,
     ) -> ir::Heap {
-        let index = MemoryIndex::new(index as usize);
+        let index = MemoryIndex::from_u32(index);
         *self
             .heaps
             .entry(index)
             .or_insert_with(|| environ.make_heap(func, index))
     }
 
     /// Get the `Table` reference that should be used to access table `index`.
     /// Create the reference if necessary.
     pub fn get_table<FE: FuncEnvironment + ?Sized>(
         &mut self,
         func: &mut ir::Function,
         index: u32,
         environ: &mut FE,
     ) -> ir::Table {
-        let index = TableIndex::new(index as usize);
+        let index = TableIndex::from_u32(index);
         *self
             .tables
             .entry(index)
             .or_insert_with(|| environ.make_table(func, index))
     }
 
     /// Get the `SigRef` reference that should be used to make an indirect call with signature
     /// `index`. Also return the number of WebAssembly arguments in the signature.
     ///
     /// Create the signature if necessary.
     pub fn get_indirect_sig<FE: FuncEnvironment + ?Sized>(
         &mut self,
         func: &mut ir::Function,
         index: u32,
         environ: &mut FE,
     ) -> (ir::SigRef, usize) {
-        let index = SignatureIndex::new(index as usize);
+        let index = SignatureIndex::from_u32(index);
         *self.signatures.entry(index).or_insert_with(|| {
             let sig = environ.make_indirect_sig(func, index);
             (sig, normal_args(&func.dfg.signatures[sig]))
         })
     }
 
     /// Get the `FuncRef` reference that should be used to make a direct call to function
     /// `index`. Also return the number of WebAssembly arguments in the signature.
     ///
     /// Create the function reference if necessary.
     pub fn get_direct_func<FE: FuncEnvironment + ?Sized>(
         &mut self,
         func: &mut ir::Function,
         index: u32,
         environ: &mut FE,
     ) -> (ir::FuncRef, usize) {
-        let index = FuncIndex::new(index as usize);
+        let index = FuncIndex::from_u32(index);
         *self.functions.entry(index).or_insert_with(|| {
             let fref = environ.make_direct_func(func, index);
             let sig = func.dfg.ext_funcs[fref].signature;
             (fref, normal_args(&func.dfg.signatures[sig]))
         })
     }
 }
 
--- a/third_party/rust/cranelift-wasm/src/translation_utils.rs
+++ b/third_party/rust/cranelift-wasm/src/translation_utils.rs
@@ -66,46 +66,48 @@ pub enum GlobalInit {
     I32Const(i32),
     /// An `i64.const`.
     I64Const(i64),
     /// An `f32.const`.
     F32Const(u32),
     /// An `f64.const`.
     F64Const(u64),
     /// A `get_global` of another global.
-    GlobalRef(GlobalIndex),
+    GetGlobal(GlobalIndex),
     ///< The global is imported from, and thus initialized by, a different module.
-    Import(),
+    Import,
 }
 
 /// WebAssembly table.
 #[derive(Debug, Clone, Copy)]
 pub struct Table {
     /// The type of data stored in elements of the table.
     pub ty: TableElementType,
     /// The minimum number of elements in the table.
-    pub size: usize,
+    pub minimum: u32,
     /// The maximum number of elements in the table.
-    pub maximum: Option<usize>,
+    pub maximum: Option<u32>,
 }
 
 /// WebAssembly table element. Can be a function or a scalar type.
 #[derive(Debug, Clone, Copy)]
 pub enum TableElementType {
+    /// A scalar type.
     Val(ir::Type),
-    Func(),
+    /// A function.
+    Func,
 }
 
 /// WebAssembly linear memory.
 #[derive(Debug, Clone, Copy)]
 pub struct Memory {
     /// The minimum number of pages in the memory.
-    pub pages_count: usize,
+    pub minimum: u32,
     /// The maximum number of pages in the memory.
-    pub maximum: Option<usize>,
+    pub maximum: Option<u32>,
     /// Whether the memory may be shared between multiple threads.
     pub shared: bool,
 }
 
 /// Helper function translating wasmparser types to Cranelift types when possible.
 pub fn type_to_type(ty: wasmparser::Type) -> Result<ir::Type, ()> {
     Ok(match ty {
         wasmparser::Type::I32 => ir::types::I32,
--- a/third_party/rust/cranelift-wasm/tests/wasm_testsuite.rs
+++ b/third_party/rust/cranelift-wasm/tests/wasm_testsuite.rs
@@ -25,17 +25,18 @@ fn testsuite() {
         .filter(|p| {
             // Ignore files starting with `.`, which could be editor temporary files
             if let Some(stem) = p.path().file_stem() {
                 if let Some(stemstr) = stem.to_str() {
                     return !stemstr.starts_with('.');
                 }
             }
             false
-        }).collect();
+        })
+        .collect();
     paths.sort_by_key(|dir| dir.path());
     let flags = Flags::new(settings::builder());
     for path in paths {
         let path = path.path();
         handle_module(&path, &flags, ReturnMode::NormalReturns);
     }
 }