зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1577717: Bump Cranelift to fc88520b88bcaad4e4a92f28a5e17347af20edbd; r=jseward
Differential Revision: https://phabricator.services.mozilla.com/D44116 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
6f85a36322
Коммит
5c56119a6c
|
@ -25,7 +25,7 @@ replace-with = "vendored-sources"
|
|||
[source."https://github.com/CraneStation/Cranelift"]
|
||||
git = "https://github.com/CraneStation/Cranelift"
|
||||
replace-with = "vendored-sources"
|
||||
rev = "164f91a1f473e582e18e48d056c51787d9a1c24d"
|
||||
rev = "fc88520b88bcaad4e4a92f28a5e17347af20edbd"
|
||||
|
||||
[source.crates-io]
|
||||
replace-with = "vendored-sources"
|
||||
|
|
|
@ -198,8 +198,8 @@ name = "baldrdash"
|
|||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bindgen 0.51.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cranelift-codegen 0.40.0 (git+https://github.com/CraneStation/Cranelift?rev=164f91a1f473e582e18e48d056c51787d9a1c24d)",
|
||||
"cranelift-wasm 0.40.0 (git+https://github.com/CraneStation/Cranelift?rev=164f91a1f473e582e18e48d056c51787d9a1c24d)",
|
||||
"cranelift-codegen 0.40.0 (git+https://github.com/CraneStation/Cranelift?rev=fc88520b88bcaad4e4a92f28a5e17347af20edbd)",
|
||||
"cranelift-wasm 0.40.0 (git+https://github.com/CraneStation/Cranelift?rev=fc88520b88bcaad4e4a92f28a5e17347af20edbd)",
|
||||
"env_logger 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"target-lexicon 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -611,19 +611,19 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "cranelift-bforest"
|
||||
version = "0.40.0"
|
||||
source = "git+https://github.com/CraneStation/Cranelift?rev=164f91a1f473e582e18e48d056c51787d9a1c24d#164f91a1f473e582e18e48d056c51787d9a1c24d"
|
||||
source = "git+https://github.com/CraneStation/Cranelift?rev=fc88520b88bcaad4e4a92f28a5e17347af20edbd#fc88520b88bcaad4e4a92f28a5e17347af20edbd"
|
||||
dependencies = [
|
||||
"cranelift-entity 0.40.0 (git+https://github.com/CraneStation/Cranelift?rev=164f91a1f473e582e18e48d056c51787d9a1c24d)",
|
||||
"cranelift-entity 0.40.0 (git+https://github.com/CraneStation/Cranelift?rev=fc88520b88bcaad4e4a92f28a5e17347af20edbd)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-codegen"
|
||||
version = "0.40.0"
|
||||
source = "git+https://github.com/CraneStation/Cranelift?rev=164f91a1f473e582e18e48d056c51787d9a1c24d#164f91a1f473e582e18e48d056c51787d9a1c24d"
|
||||
source = "git+https://github.com/CraneStation/Cranelift?rev=fc88520b88bcaad4e4a92f28a5e17347af20edbd#fc88520b88bcaad4e4a92f28a5e17347af20edbd"
|
||||
dependencies = [
|
||||
"cranelift-bforest 0.40.0 (git+https://github.com/CraneStation/Cranelift?rev=164f91a1f473e582e18e48d056c51787d9a1c24d)",
|
||||
"cranelift-codegen-meta 0.40.0 (git+https://github.com/CraneStation/Cranelift?rev=164f91a1f473e582e18e48d056c51787d9a1c24d)",
|
||||
"cranelift-entity 0.40.0 (git+https://github.com/CraneStation/Cranelift?rev=164f91a1f473e582e18e48d056c51787d9a1c24d)",
|
||||
"cranelift-bforest 0.40.0 (git+https://github.com/CraneStation/Cranelift?rev=fc88520b88bcaad4e4a92f28a5e17347af20edbd)",
|
||||
"cranelift-codegen-meta 0.40.0 (git+https://github.com/CraneStation/Cranelift?rev=fc88520b88bcaad4e4a92f28a5e17347af20edbd)",
|
||||
"cranelift-entity 0.40.0 (git+https://github.com/CraneStation/Cranelift?rev=fc88520b88bcaad4e4a92f28a5e17347af20edbd)",
|
||||
"failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"failure_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -633,22 +633,22 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "cranelift-codegen-meta"
|
||||
version = "0.40.0"
|
||||
source = "git+https://github.com/CraneStation/Cranelift?rev=164f91a1f473e582e18e48d056c51787d9a1c24d#164f91a1f473e582e18e48d056c51787d9a1c24d"
|
||||
source = "git+https://github.com/CraneStation/Cranelift?rev=fc88520b88bcaad4e4a92f28a5e17347af20edbd#fc88520b88bcaad4e4a92f28a5e17347af20edbd"
|
||||
dependencies = [
|
||||
"cranelift-entity 0.40.0 (git+https://github.com/CraneStation/Cranelift?rev=164f91a1f473e582e18e48d056c51787d9a1c24d)",
|
||||
"cranelift-entity 0.40.0 (git+https://github.com/CraneStation/Cranelift?rev=fc88520b88bcaad4e4a92f28a5e17347af20edbd)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-entity"
|
||||
version = "0.40.0"
|
||||
source = "git+https://github.com/CraneStation/Cranelift?rev=164f91a1f473e582e18e48d056c51787d9a1c24d#164f91a1f473e582e18e48d056c51787d9a1c24d"
|
||||
source = "git+https://github.com/CraneStation/Cranelift?rev=fc88520b88bcaad4e4a92f28a5e17347af20edbd#fc88520b88bcaad4e4a92f28a5e17347af20edbd"
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-frontend"
|
||||
version = "0.40.0"
|
||||
source = "git+https://github.com/CraneStation/Cranelift?rev=164f91a1f473e582e18e48d056c51787d9a1c24d#164f91a1f473e582e18e48d056c51787d9a1c24d"
|
||||
source = "git+https://github.com/CraneStation/Cranelift?rev=fc88520b88bcaad4e4a92f28a5e17347af20edbd#fc88520b88bcaad4e4a92f28a5e17347af20edbd"
|
||||
dependencies = [
|
||||
"cranelift-codegen 0.40.0 (git+https://github.com/CraneStation/Cranelift?rev=164f91a1f473e582e18e48d056c51787d9a1c24d)",
|
||||
"cranelift-codegen 0.40.0 (git+https://github.com/CraneStation/Cranelift?rev=fc88520b88bcaad4e4a92f28a5e17347af20edbd)",
|
||||
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"target-lexicon 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
@ -656,11 +656,11 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "cranelift-wasm"
|
||||
version = "0.40.0"
|
||||
source = "git+https://github.com/CraneStation/Cranelift?rev=164f91a1f473e582e18e48d056c51787d9a1c24d#164f91a1f473e582e18e48d056c51787d9a1c24d"
|
||||
source = "git+https://github.com/CraneStation/Cranelift?rev=fc88520b88bcaad4e4a92f28a5e17347af20edbd#fc88520b88bcaad4e4a92f28a5e17347af20edbd"
|
||||
dependencies = [
|
||||
"cranelift-codegen 0.40.0 (git+https://github.com/CraneStation/Cranelift?rev=164f91a1f473e582e18e48d056c51787d9a1c24d)",
|
||||
"cranelift-entity 0.40.0 (git+https://github.com/CraneStation/Cranelift?rev=164f91a1f473e582e18e48d056c51787d9a1c24d)",
|
||||
"cranelift-frontend 0.40.0 (git+https://github.com/CraneStation/Cranelift?rev=164f91a1f473e582e18e48d056c51787d9a1c24d)",
|
||||
"cranelift-codegen 0.40.0 (git+https://github.com/CraneStation/Cranelift?rev=fc88520b88bcaad4e4a92f28a5e17347af20edbd)",
|
||||
"cranelift-entity 0.40.0 (git+https://github.com/CraneStation/Cranelift?rev=fc88520b88bcaad4e4a92f28a5e17347af20edbd)",
|
||||
"cranelift-frontend 0.40.0 (git+https://github.com/CraneStation/Cranelift?rev=fc88520b88bcaad4e4a92f28a5e17347af20edbd)",
|
||||
"failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"failure_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -3917,12 +3917,12 @@ dependencies = [
|
|||
"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.40.0 (git+https://github.com/CraneStation/Cranelift?rev=164f91a1f473e582e18e48d056c51787d9a1c24d)" = "<none>"
|
||||
"checksum cranelift-codegen 0.40.0 (git+https://github.com/CraneStation/Cranelift?rev=164f91a1f473e582e18e48d056c51787d9a1c24d)" = "<none>"
|
||||
"checksum cranelift-codegen-meta 0.40.0 (git+https://github.com/CraneStation/Cranelift?rev=164f91a1f473e582e18e48d056c51787d9a1c24d)" = "<none>"
|
||||
"checksum cranelift-entity 0.40.0 (git+https://github.com/CraneStation/Cranelift?rev=164f91a1f473e582e18e48d056c51787d9a1c24d)" = "<none>"
|
||||
"checksum cranelift-frontend 0.40.0 (git+https://github.com/CraneStation/Cranelift?rev=164f91a1f473e582e18e48d056c51787d9a1c24d)" = "<none>"
|
||||
"checksum cranelift-wasm 0.40.0 (git+https://github.com/CraneStation/Cranelift?rev=164f91a1f473e582e18e48d056c51787d9a1c24d)" = "<none>"
|
||||
"checksum cranelift-bforest 0.40.0 (git+https://github.com/CraneStation/Cranelift?rev=fc88520b88bcaad4e4a92f28a5e17347af20edbd)" = "<none>"
|
||||
"checksum cranelift-codegen 0.40.0 (git+https://github.com/CraneStation/Cranelift?rev=fc88520b88bcaad4e4a92f28a5e17347af20edbd)" = "<none>"
|
||||
"checksum cranelift-codegen-meta 0.40.0 (git+https://github.com/CraneStation/Cranelift?rev=fc88520b88bcaad4e4a92f28a5e17347af20edbd)" = "<none>"
|
||||
"checksum cranelift-entity 0.40.0 (git+https://github.com/CraneStation/Cranelift?rev=fc88520b88bcaad4e4a92f28a5e17347af20edbd)" = "<none>"
|
||||
"checksum cranelift-frontend 0.40.0 (git+https://github.com/CraneStation/Cranelift?rev=fc88520b88bcaad4e4a92f28a5e17347af20edbd)" = "<none>"
|
||||
"checksum cranelift-wasm 0.40.0 (git+https://github.com/CraneStation/Cranelift?rev=fc88520b88bcaad4e4a92f28a5e17347af20edbd)" = "<none>"
|
||||
"checksum crc 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bd5d02c0aac6bd68393ed69e00bbc2457f3e89075c6349db7189618dc4ddc1d7"
|
||||
"checksum crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1"
|
||||
"checksum crossbeam-channel 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "8d4f5844607ce8da3fff431e7dba56cda8bfcc570aa50bee36adba8a32b8cad7"
|
||||
|
|
|
@ -63,11 +63,11 @@ packed_simd = { git = "https://github.com/hsivonen/packed_simd", branch = "rust_
|
|||
|
||||
[patch.crates-io.cranelift-codegen]
|
||||
git = "https://github.com/CraneStation/Cranelift"
|
||||
rev = "164f91a1f473e582e18e48d056c51787d9a1c24d"
|
||||
rev = "fc88520b88bcaad4e4a92f28a5e17347af20edbd"
|
||||
|
||||
[patch.crates-io.cranelift-wasm]
|
||||
git = "https://github.com/CraneStation/Cranelift"
|
||||
rev = "164f91a1f473e582e18e48d056c51787d9a1c24d"
|
||||
rev = "fc88520b88bcaad4e4a92f28a5e17347af20edbd"
|
||||
|
||||
[patch.crates-io.coreaudio-sys]
|
||||
path = "third_party/rust/coreaudio-sys"
|
||||
|
|
|
@ -1 +1 @@
|
|||
{"files":{"Cargo.toml":"2ef029c7de319de8f2007c17a7b5baeddd980f37b8cc84197bad5332f6c97d9a","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"b123f056d0d458396679c5f7f2a16d2762af0258fcda4ac14b6655a95e5a0022","src/cdsl/ast.rs":"1c9bf45110e47710ea160f30b3f3b00b531a8d91ff365bae856dd9d44b928253","src/cdsl/cpu_modes.rs":"7c59ae347d6f9c769d6356fe49c8406934153eefa59d9bf37c182474fcbb9715","src/cdsl/encodings.rs":"da6fa16c95fe4a586c2d00ef4ccf79b4b0f64cd8923b3ca5a5a527da1e799a4f","src/cdsl/formats.rs":"811dcf12f6e9c5be72f18543675ff52c3996edd029064bd0643f878d2ceca3bd","src/cdsl/instructions.rs":"0e702c6d005ce209b46e9f883d02725acbc018bb90f8402c26c71b6bf61a42ed","src/cdsl/isa.rs":"9b6030a935f69b07726d239c23a78d654566785f1fed61ccefdaf7d4f0a97d0e","src/cdsl/mod.rs":"c85f62a7d8d6bedc81c673b8d02be01181f79f272dbc0325a76d52e7eec732e8","src/cdsl/operands.rs":"1cda258798d861c4f467783b5c70c1202a57f554861017eead6477af2ee34063","src/cdsl/recipes.rs":"9f50f29f243f2ed8dbca3ef8b2722e9671bc164b2956254a95ed62641315eab7","src/cdsl/regs.rs":"8a92798a92b2c34c5e572e03602454c72a896d31ac301f15f43d17c101d4da6e","src/cdsl/settings.rs":"7da3c5a9df8e47ed6ca7f1d820e28eae45e783f3759f6c55730d2f17d88f1013","src/cdsl/type_inference.rs":"695d4fd2720f43569a52f29998bd92562951f0b4e7844cc0a239640e0c7d0b0f","src/cdsl/types.rs":"3418eb1f5d77fd3ba586b089c0d77ee45f4e581b1a6e06ec4feeddd9d2589239","src/cdsl/typevar.rs":"c66b14b43baba2e7940b74ada263ab65455c2f46cc06de3990e88d790bb061d0","src/cdsl/xform.rs":"64e9b70ef1265c0331ee9d71c1a1f33dba3f6975b1639385c34d68456cda0e0e","src/constant_hash.rs":"66d6f42c1e98cd4dbc95009997dc00256b57c11d2c2d9eac63b33e458c68a56f","src/default_map.rs":"8bbd6f4d9f93ef2126538cda633e6d9c80a5c7dc79b8d5a759c8be1fe2dbc605","src/error.rs":"5110a4e3c1e97396ba02d9f5abbb8af4b586f0cc4d33a5c2473f1718cc4bef05","src/gen_binemit.rs":"51d661541c6226d2ed8f4724813f66effd6124af9af89c66137a8b55edd950fd","src/gen_encodings.rs":"024b6ea8086fa1559333245753e909f306adeab7c8dfdc915610877413cba585","src/gen_inst.rs":"e3a54b53f4a3d2d98474094d0d662c4ba66c594f876f68562e9ba6ddc2d71226","src/gen_legalizer.rs":"e02c9f49ba9fa2bb04dbf3137011d5457c187fbdffab971b0be01693c4b83a9b","src/gen_registers.rs":"a544a2b91fafe08639e39e50bea0892fda89fe2f6eaf111b2d5f3e98e4d07b86","src/gen_settings.rs":"765ca86fa735342c1875021c34a92cbc39836ba3ad1c12aa615204372a1f7b61","src/gen_types.rs":"c062eaf3a2ed7368b87213922906107bbaec184fe821184a34dacb4e5b0fc3dc","src/isa/arm32/mod.rs":"a2500871fb270e5624f5561f24fe510f08708cdca2ab1c3163848b67694f7a7a","src/isa/arm64/mod.rs":"dc210e8dc9f179d87d2c5a72d7795a9e34bb30afb91c8053c362d43635629d19","src/isa/mod.rs":"fce60d19dd3c099ebee3ac5ae64a2bee363f13da9ff5a4960d3c1a0bee71d29a","src/isa/riscv/encodings.rs":"d53f80b2f166e19945c0c2c89a988a1b26d393f571212a09c5abcd9e694e4857","src/isa/riscv/mod.rs":"895492f0f379cfb02aba1cbb9759dc489bbb4d51ec40759af9f4d71c45c17a86","src/isa/riscv/recipes.rs":"8edffb212f1e5174c3e148a49311f2b7e2a1ac79a5b1ea9b641d4f88aa1c3040","src/isa/x86/encodings.rs":"37ea803b62dc4bcec2b9eee65366aa2f2fb3bfddd220ab926dc691a832b2392a","src/isa/x86/instructions.rs":"eea5fa7dd804d435dfdf289fc47f4bcc77db8dfce068d78d0a428155604b9626","src/isa/x86/legalize.rs":"192d7b9dc61e967165e43bc6da424316868a576b35aad2455c4465733c0d56b8","src/isa/x86/mod.rs":"6ed9f102238c1cb9029ec953e37629767438580cf9df8b4f2d1eace75ecd86fc","src/isa/x86/recipes.rs":"28543b64e2b0476fe84ccedb9bbc0ebec8592ecc756329f6a57197be9d58c0da","src/isa/x86/registers.rs":"c0bc60336a8c8b7b4db92dc623e9419a60af14dd6252f0b19e227e46f7166178","src/isa/x86/settings.rs":"134386d3719d8559a4df1a304c76b350cfaf79877d9894b95630c80e7b72fb50","src/lib.rs":"bc458358fd81d092f368b243d07682259dbed7a336b1eed5bcdf5228368289e9","src/shared/entities.rs":"80b8ff57a09c7b2f9dab755abbcc2738317de474776fe1de0d2a581310aa9af8","src/shared/formats.rs":"ae566a4970d7067165618d2a24a3a46444e21f8a2ac1cff767b2f70420fc2bae","src/shared/immediates.rs":"804c4c9ffa2fe55d90279ee158aaa6bd6c7f0c604d63d7457a98e82269cec9a7","src/shared/instructions.rs":"b2d8dbc2503ec3dfa8101ecddc34126e852b9e397f6ea11e5a5ecf3d8d7d27ae","src/shared/legalize.rs":"1c32c28f603b11f89e1ba9c4d301b0b8036fd81254d227836202b84573a9a446","src/shared/mod.rs":"f5bb50d8292e46380afdd83a320cb5d6021e1483741e67b1e277053c28f9b943","src/shared/settings.rs":"e2696406c7c699e125fc629d6634c75cedf96ca76871fe4e9c0adbe03eead037","src/shared/types.rs":"9d08f21523867acb89d23ce6ac60681babb0a141068c0a54948491df6644a2f3","src/srcgen.rs":"79fee2f603b33f76f7c9c8b9452c745a363d732c40c0814d84001ff3ef805677","src/unique_table.rs":"90b7203b29241a1ede70f0a3e50d96799e0b41d8f7455170d6ffb127f87f3cc3"},"package":null}
|
||||
{"files":{"Cargo.toml":"2ef029c7de319de8f2007c17a7b5baeddd980f37b8cc84197bad5332f6c97d9a","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"b123f056d0d458396679c5f7f2a16d2762af0258fcda4ac14b6655a95e5a0022","src/cdsl/ast.rs":"1c9bf45110e47710ea160f30b3f3b00b531a8d91ff365bae856dd9d44b928253","src/cdsl/cpu_modes.rs":"7c59ae347d6f9c769d6356fe49c8406934153eefa59d9bf37c182474fcbb9715","src/cdsl/encodings.rs":"da6fa16c95fe4a586c2d00ef4ccf79b4b0f64cd8923b3ca5a5a527da1e799a4f","src/cdsl/formats.rs":"811dcf12f6e9c5be72f18543675ff52c3996edd029064bd0643f878d2ceca3bd","src/cdsl/instructions.rs":"0e702c6d005ce209b46e9f883d02725acbc018bb90f8402c26c71b6bf61a42ed","src/cdsl/isa.rs":"9b6030a935f69b07726d239c23a78d654566785f1fed61ccefdaf7d4f0a97d0e","src/cdsl/mod.rs":"c85f62a7d8d6bedc81c673b8d02be01181f79f272dbc0325a76d52e7eec732e8","src/cdsl/operands.rs":"1cda258798d861c4f467783b5c70c1202a57f554861017eead6477af2ee34063","src/cdsl/recipes.rs":"9f50f29f243f2ed8dbca3ef8b2722e9671bc164b2956254a95ed62641315eab7","src/cdsl/regs.rs":"8a92798a92b2c34c5e572e03602454c72a896d31ac301f15f43d17c101d4da6e","src/cdsl/settings.rs":"7da3c5a9df8e47ed6ca7f1d820e28eae45e783f3759f6c55730d2f17d88f1013","src/cdsl/type_inference.rs":"695d4fd2720f43569a52f29998bd92562951f0b4e7844cc0a239640e0c7d0b0f","src/cdsl/types.rs":"3418eb1f5d77fd3ba586b089c0d77ee45f4e581b1a6e06ec4feeddd9d2589239","src/cdsl/typevar.rs":"c66b14b43baba2e7940b74ada263ab65455c2f46cc06de3990e88d790bb061d0","src/cdsl/xform.rs":"64e9b70ef1265c0331ee9d71c1a1f33dba3f6975b1639385c34d68456cda0e0e","src/constant_hash.rs":"66d6f42c1e98cd4dbc95009997dc00256b57c11d2c2d9eac63b33e458c68a56f","src/default_map.rs":"8bbd6f4d9f93ef2126538cda633e6d9c80a5c7dc79b8d5a759c8be1fe2dbc605","src/error.rs":"5110a4e3c1e97396ba02d9f5abbb8af4b586f0cc4d33a5c2473f1718cc4bef05","src/gen_binemit.rs":"80c27e9c66d2ac3dc8a41cc545f046bd4297ba6530805539e86461984fd2667d","src/gen_encodings.rs":"9fb5ebe9a926ad7d45614c3bcfce0f0cadea3477f3e9bea45dfa63baf947e73f","src/gen_inst.rs":"e3a54b53f4a3d2d98474094d0d662c4ba66c594f876f68562e9ba6ddc2d71226","src/gen_legalizer.rs":"e02c9f49ba9fa2bb04dbf3137011d5457c187fbdffab971b0be01693c4b83a9b","src/gen_registers.rs":"a544a2b91fafe08639e39e50bea0892fda89fe2f6eaf111b2d5f3e98e4d07b86","src/gen_settings.rs":"765ca86fa735342c1875021c34a92cbc39836ba3ad1c12aa615204372a1f7b61","src/gen_types.rs":"c062eaf3a2ed7368b87213922906107bbaec184fe821184a34dacb4e5b0fc3dc","src/isa/arm32/mod.rs":"a2500871fb270e5624f5561f24fe510f08708cdca2ab1c3163848b67694f7a7a","src/isa/arm64/mod.rs":"dc210e8dc9f179d87d2c5a72d7795a9e34bb30afb91c8053c362d43635629d19","src/isa/mod.rs":"fce60d19dd3c099ebee3ac5ae64a2bee363f13da9ff5a4960d3c1a0bee71d29a","src/isa/riscv/encodings.rs":"d53f80b2f166e19945c0c2c89a988a1b26d393f571212a09c5abcd9e694e4857","src/isa/riscv/mod.rs":"895492f0f379cfb02aba1cbb9759dc489bbb4d51ec40759af9f4d71c45c17a86","src/isa/riscv/recipes.rs":"8edffb212f1e5174c3e148a49311f2b7e2a1ac79a5b1ea9b641d4f88aa1c3040","src/isa/x86/encodings.rs":"9bdb43f7bb9d639f4cf073e3865a0ad03d98de45b91d637716365dc0c85abbd7","src/isa/x86/instructions.rs":"eea5fa7dd804d435dfdf289fc47f4bcc77db8dfce068d78d0a428155604b9626","src/isa/x86/legalize.rs":"192d7b9dc61e967165e43bc6da424316868a576b35aad2455c4465733c0d56b8","src/isa/x86/mod.rs":"6ed9f102238c1cb9029ec953e37629767438580cf9df8b4f2d1eace75ecd86fc","src/isa/x86/recipes.rs":"e3d6d95bc56c92c83985fd6f20415e04b5da89270ba6069e6d1410bc3c720d7a","src/isa/x86/registers.rs":"c0bc60336a8c8b7b4db92dc623e9419a60af14dd6252f0b19e227e46f7166178","src/isa/x86/settings.rs":"4e84ff135d6f21595bbd8f56d2e561abd3c123566f2332ac93bb4a9c627f0c00","src/lib.rs":"bc458358fd81d092f368b243d07682259dbed7a336b1eed5bcdf5228368289e9","src/shared/entities.rs":"80b8ff57a09c7b2f9dab755abbcc2738317de474776fe1de0d2a581310aa9af8","src/shared/formats.rs":"9c51381b531576c577a92abba9f825a8b60aaaedba53f39d2ea3be879987a466","src/shared/immediates.rs":"9a83d69734d06279bb20050c0f610caf06322d3cb11591cdd0ebf8724274b792","src/shared/instructions.rs":"029791f400bdb0cbdfa9d1ac544063d69c473e2ceecda3ab3e9b483579a53395","src/shared/legalize.rs":"1c32c28f603b11f89e1ba9c4d301b0b8036fd81254d227836202b84573a9a446","src/shared/mod.rs":"f5bb50d8292e46380afdd83a320cb5d6021e1483741e67b1e277053c28f9b943","src/shared/settings.rs":"e2696406c7c699e125fc629d6634c75cedf96ca76871fe4e9c0adbe03eead037","src/shared/types.rs":"9d08f21523867acb89d23ce6ac60681babb0a141068c0a54948491df6644a2f3","src/srcgen.rs":"79fee2f603b33f76f7c9c8b9452c745a363d732c40c0814d84001ff3ef805677","src/unique_table.rs":"90b7203b29241a1ede70f0a3e50d96799e0b41d8f7455170d6ffb127f87f3cc3"},"package":null}
|
|
@ -137,7 +137,7 @@ fn unwrap_values(
|
|||
values_slice,
|
||||
i
|
||||
);
|
||||
fmt.line(format!("{}, ", stack.stack_base_mask()));
|
||||
fmt.line(format!("{},", stack.stack_base_mask()));
|
||||
fmt.line("&func.stack_slots,");
|
||||
});
|
||||
fmt.line(").unwrap();");
|
||||
|
|
|
@ -142,6 +142,7 @@ fn emit_instp(instp: &InstructionPredicate, has_func: bool, fmt: &mut Formatter)
|
|||
fn emit_recipe_predicates(isa: &TargetIsa, fmt: &mut Formatter) {
|
||||
let mut predicate_names = HashMap::new();
|
||||
|
||||
fmt.comment(format!("{} recipe predicates.", isa.name));
|
||||
for recipe in isa.recipes.values() {
|
||||
let (isap, instp) = match (&recipe.isa_predicate, &recipe.inst_predicate) {
|
||||
(None, None) => continue,
|
||||
|
@ -177,8 +178,15 @@ fn emit_recipe_predicates(isa: &TargetIsa, fmt: &mut Formatter) {
|
|||
});
|
||||
fmtln!(fmt, "}");
|
||||
}
|
||||
fmt.empty_line();
|
||||
|
||||
// Generate the static table.
|
||||
fmt.doc_comment(format!(
|
||||
r#"{} recipe predicate table.
|
||||
|
||||
One entry per recipe, set to Some only when the recipe is guarded by a predicate."#,
|
||||
isa.name
|
||||
));
|
||||
fmtln!(
|
||||
fmt,
|
||||
"pub static RECIPE_PREDICATES: [RecipePredicate; {}] = [",
|
||||
|
@ -193,11 +201,13 @@ fn emit_recipe_predicates(isa: &TargetIsa, fmt: &mut Formatter) {
|
|||
}
|
||||
});
|
||||
fmtln!(fmt, "];");
|
||||
fmt.empty_line();
|
||||
}
|
||||
|
||||
/// Emit private functions for matching instruction predicates as well as a static
|
||||
/// `INST_PREDICATES` array indexed by predicate number.
|
||||
fn emit_inst_predicates(isa: &TargetIsa, fmt: &mut Formatter) {
|
||||
fmt.comment(format!("{} instruction predicates.", isa.name));
|
||||
for (id, instp) in isa.encodings_predicates.iter() {
|
||||
fmtln!(fmt, "fn inst_predicate_{}(func: &crate::ir::Function, inst: &crate::ir::InstructionData) -> bool {{", id.index());
|
||||
fmt.indent(|fmt| {
|
||||
|
@ -205,8 +215,16 @@ fn emit_inst_predicates(isa: &TargetIsa, fmt: &mut Formatter) {
|
|||
});
|
||||
fmtln!(fmt, "}");
|
||||
}
|
||||
fmt.empty_line();
|
||||
|
||||
// Generate the static table.
|
||||
fmt.doc_comment(format!(
|
||||
r#"{} instruction predicate table.
|
||||
|
||||
One entry per instruction predicate, so the encoding bytecode can embed indexes into this
|
||||
table."#,
|
||||
isa.name
|
||||
));
|
||||
fmtln!(
|
||||
fmt,
|
||||
"pub static INST_PREDICATES: [InstPredicate; {}] = [",
|
||||
|
@ -218,12 +236,18 @@ fn emit_inst_predicates(isa: &TargetIsa, fmt: &mut Formatter) {
|
|||
}
|
||||
});
|
||||
fmtln!(fmt, "];");
|
||||
fmt.empty_line();
|
||||
}
|
||||
|
||||
/// Emit a table of encoding recipe names keyed by recipe number.
|
||||
///
|
||||
/// This is used for pretty-printing encodings.
|
||||
fn emit_recipe_names(isa: &TargetIsa, fmt: &mut Formatter) {
|
||||
fmt.doc_comment(format!(
|
||||
r#"{} recipe names, using the same recipe index spaces as the one specified by the
|
||||
corresponding binemit file."#,
|
||||
isa.name
|
||||
));
|
||||
fmtln!(
|
||||
fmt,
|
||||
"static RECIPE_NAMES: [&str; {}] = [",
|
||||
|
@ -235,6 +259,7 @@ fn emit_recipe_names(isa: &TargetIsa, fmt: &mut Formatter) {
|
|||
}
|
||||
});
|
||||
fmtln!(fmt, "];");
|
||||
fmt.empty_line();
|
||||
}
|
||||
|
||||
/// Returns a set of all the registers involved in fixed register constraints.
|
||||
|
@ -353,6 +378,12 @@ fn emit_operand_constraints(
|
|||
///
|
||||
/// These are used by the register allocator to pick registers that can be properly encoded.
|
||||
fn emit_recipe_constraints(isa: &TargetIsa, fmt: &mut Formatter) {
|
||||
fmt.doc_comment(format!(
|
||||
r#"{} recipe constraints list, using the same recipe index spaces as the one
|
||||
specified by the corresponding binemit file. These constraints are used by register
|
||||
allocation to select the right location to use for input and output values."#,
|
||||
isa.name
|
||||
));
|
||||
fmtln!(
|
||||
fmt,
|
||||
"static RECIPE_CONSTRAINTS: [RecipeConstraints; {}] = [",
|
||||
|
@ -437,10 +468,17 @@ fn emit_recipe_constraints(isa: &TargetIsa, fmt: &mut Formatter) {
|
|||
}
|
||||
});
|
||||
fmtln!(fmt, "];");
|
||||
fmt.empty_line();
|
||||
}
|
||||
|
||||
/// Emit a table of encoding recipe code size information.
|
||||
fn emit_recipe_sizing(isa: &TargetIsa, fmt: &mut Formatter) {
|
||||
fmt.doc_comment(format!(
|
||||
r#"{} recipe sizing descriptors, using the same recipe index spaces as the one
|
||||
specified by the corresponding binemit file. These are used to compute the final size of an
|
||||
instruction, as well as to compute the range of branches."#,
|
||||
isa.name
|
||||
));
|
||||
fmtln!(
|
||||
fmt,
|
||||
"static RECIPE_SIZING: [RecipeSizing; {}] = [",
|
||||
|
@ -468,6 +506,7 @@ fn emit_recipe_sizing(isa: &TargetIsa, fmt: &mut Formatter) {
|
|||
}
|
||||
});
|
||||
fmtln!(fmt, "];");
|
||||
fmt.empty_line();
|
||||
}
|
||||
|
||||
/// Level 1 table mapping types to `Level2` objects.
|
||||
|
@ -878,7 +917,7 @@ fn encode_level2_hashtables<'a>(
|
|||
}
|
||||
}
|
||||
|
||||
fn emit_tables(defs: &SharedDefinitions, isa: &TargetIsa, fmt: &mut Formatter) {
|
||||
fn emit_encoding_tables(defs: &SharedDefinitions, isa: &TargetIsa, fmt: &mut Formatter) {
|
||||
// Level 1 tables, one per CPU mode.
|
||||
let mut level1_tables: HashMap<&'static str, Level1Table> = HashMap::new();
|
||||
|
||||
|
@ -923,6 +962,13 @@ fn emit_tables(defs: &SharedDefinitions, isa: &TargetIsa, fmt: &mut Formatter) {
|
|||
let level2_offset_type = offset_type(enc_lists.len());
|
||||
|
||||
// Emit encoding lists.
|
||||
fmt.doc_comment(
|
||||
format!(r#"{} encoding lists.
|
||||
|
||||
This contains the entire encodings bytecode for every single instruction; the encodings
|
||||
interpreter knows where to start from thanks to the initial lookup in the level 1 and level 2
|
||||
table entries below."#, isa.name)
|
||||
);
|
||||
fmtln!(fmt, "pub static ENCLISTS: [u16; {}] = [", enc_lists.len());
|
||||
fmt.indent(|fmt| {
|
||||
let mut line = Vec::new();
|
||||
|
@ -943,8 +989,17 @@ fn emit_tables(defs: &SharedDefinitions, isa: &TargetIsa, fmt: &mut Formatter) {
|
|||
}
|
||||
});
|
||||
fmtln!(fmt, "];");
|
||||
fmt.empty_line();
|
||||
|
||||
// Emit the full concatenation of level 2 hash tables.
|
||||
fmt.doc_comment(format!(
|
||||
r#"{} level 2 hash tables.
|
||||
|
||||
This hash table, keyed by instruction opcode, contains all the starting offsets for the
|
||||
encodings interpreter, for all the CPU modes. It is jumped to after a lookup on the
|
||||
instruction's controlling type in the level 1 hash table."#,
|
||||
isa.name
|
||||
));
|
||||
fmtln!(
|
||||
fmt,
|
||||
"pub static LEVEL2: [Level2Entry<{}>; {}] = [",
|
||||
|
@ -971,6 +1026,7 @@ fn emit_tables(defs: &SharedDefinitions, isa: &TargetIsa, fmt: &mut Formatter) {
|
|||
}
|
||||
});
|
||||
fmtln!(fmt, "];");
|
||||
fmt.empty_line();
|
||||
|
||||
// Emit a level 1 hash table for each CPU mode.
|
||||
for cpu_mode in &isa.cpu_modes {
|
||||
|
@ -987,6 +1043,16 @@ fn emit_tables(defs: &SharedDefinitions, isa: &TargetIsa, fmt: &mut Formatter) {
|
|||
},
|
||||
);
|
||||
|
||||
fmt.doc_comment(format!(
|
||||
r#"{} level 1 hash table for the CPU mode {}.
|
||||
|
||||
This hash table, keyed by instruction controlling type, contains all the level 2
|
||||
hash-tables offsets for the given CPU mode, as well as a legalization identifier indicating
|
||||
which legalization scheme to apply when the instruction doesn't have any valid encoding for
|
||||
this CPU mode.
|
||||
"#,
|
||||
isa.name, cpu_mode.name
|
||||
));
|
||||
fmtln!(
|
||||
fmt,
|
||||
"pub static LEVEL1_{}: [Level1Entry<{}>; {}] = [",
|
||||
|
@ -1033,6 +1099,7 @@ fn emit_tables(defs: &SharedDefinitions, isa: &TargetIsa, fmt: &mut Formatter) {
|
|||
}
|
||||
});
|
||||
fmtln!(fmt, "];");
|
||||
fmt.empty_line();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1043,7 +1110,7 @@ fn gen_isa(defs: &SharedDefinitions, isa: &TargetIsa, fmt: &mut Formatter) {
|
|||
// Make the `INST_PREDICATES` table.
|
||||
emit_inst_predicates(isa, fmt);
|
||||
|
||||
emit_tables(defs, isa, fmt);
|
||||
emit_encoding_tables(defs, isa, fmt);
|
||||
|
||||
emit_recipe_names(isa, fmt);
|
||||
emit_recipe_constraints(isa, fmt);
|
||||
|
|
|
@ -270,7 +270,7 @@ impl PerCpuModeEncodings {
|
|||
/// Add the same encoding to both X86_32 and X86_64; assumes configuration (e.g. REX, operand binding) has already happened
|
||||
fn enc_32_64_maybe_isap(
|
||||
&mut self,
|
||||
inst: BoundInstruction,
|
||||
inst: impl Clone + Into<InstSpec>,
|
||||
template: Template,
|
||||
isap: Option<SettingPredicateNumber>,
|
||||
) {
|
||||
|
@ -280,7 +280,7 @@ impl PerCpuModeEncodings {
|
|||
|
||||
fn enc32_maybe_isap(
|
||||
&mut self,
|
||||
inst: BoundInstruction,
|
||||
inst: impl Into<InstSpec>,
|
||||
template: Template,
|
||||
isap: Option<SettingPredicateNumber>,
|
||||
) {
|
||||
|
@ -292,7 +292,7 @@ impl PerCpuModeEncodings {
|
|||
|
||||
fn enc64_maybe_isap(
|
||||
&mut self,
|
||||
inst: BoundInstruction,
|
||||
inst: impl Into<InstSpec>,
|
||||
template: Template,
|
||||
isap: Option<SettingPredicateNumber>,
|
||||
) {
|
||||
|
@ -432,6 +432,7 @@ pub fn define(
|
|||
let uload8_complex = shared.by_name("uload8_complex");
|
||||
let ushr = shared.by_name("ushr");
|
||||
let ushr_imm = shared.by_name("ushr_imm");
|
||||
let vconst = shared.by_name("vconst");
|
||||
let x86_bsf = x86.by_name("x86_bsf");
|
||||
let x86_bsr = x86.by_name("x86_bsr");
|
||||
let x86_cvtt2si = x86.by_name("x86_cvtt2si");
|
||||
|
@ -578,6 +579,7 @@ pub fn define(
|
|||
let rec_urm = r.template("urm");
|
||||
let rec_urm_noflags = r.template("urm_noflags");
|
||||
let rec_urm_noflags_abcd = r.template("urm_noflags_abcd");
|
||||
let rec_vconst = r.template("vconst");
|
||||
|
||||
// Predicates shorthands.
|
||||
let all_ones_funcaddrs_and_not_is_pic =
|
||||
|
@ -589,8 +591,9 @@ pub fn define(
|
|||
let use_popcnt = settings.predicate_by_name("use_popcnt");
|
||||
let use_lzcnt = settings.predicate_by_name("use_lzcnt");
|
||||
let use_bmi1 = settings.predicate_by_name("use_bmi1");
|
||||
let use_ssse3 = settings.predicate_by_name("use_ssse3");
|
||||
let use_sse41 = settings.predicate_by_name("use_sse41");
|
||||
let use_ssse3_simd = settings.predicate_by_name("use_ssse3_simd");
|
||||
let use_sse41_simd = settings.predicate_by_name("use_sse41_simd");
|
||||
|
||||
// Definitions.
|
||||
let mut e = PerCpuModeEncodings::new();
|
||||
|
@ -1694,8 +1697,8 @@ pub fn define(
|
|||
for ty in ValueType::all_lane_types().filter(|t| t.lane_bits() == 8) {
|
||||
let instruction = x86_pshufb.bind_vector_from_lane(ty, sse_vector_size);
|
||||
let template = rec_fa.nonrex().opcodes(vec![0x66, 0x0f, 0x38, 00]);
|
||||
e.enc32_isap(instruction.clone(), template.clone(), use_ssse3);
|
||||
e.enc64_isap(instruction, template, use_ssse3);
|
||||
e.enc32_isap(instruction.clone(), template.clone(), use_ssse3_simd);
|
||||
e.enc64_isap(instruction, template, use_ssse3_simd);
|
||||
}
|
||||
|
||||
// PSHUFD, 32-bit shuffle using one XMM register and a u8 immediate
|
||||
|
@ -1726,10 +1729,10 @@ pub fn define(
|
|||
// SIMD insertlane
|
||||
let mut insertlane_mapping: HashMap<u64, (Vec<u8>, Option<SettingPredicateNumber>)> =
|
||||
HashMap::new();
|
||||
insertlane_mapping.insert(8, (vec![0x66, 0x0f, 0x3a, 0x20], Some(use_sse41))); // PINSRB
|
||||
insertlane_mapping.insert(8, (vec![0x66, 0x0f, 0x3a, 0x20], Some(use_sse41_simd))); // PINSRB
|
||||
insertlane_mapping.insert(16, (vec![0x66, 0x0f, 0xc4], None)); // PINSRW from SSE2
|
||||
insertlane_mapping.insert(32, (vec![0x66, 0x0f, 0x3a, 0x22], Some(use_sse41))); // PINSRD
|
||||
insertlane_mapping.insert(64, (vec![0x66, 0x0f, 0x3a, 0x22], Some(use_sse41))); // PINSRQ, only x86_64
|
||||
insertlane_mapping.insert(32, (vec![0x66, 0x0f, 0x3a, 0x22], Some(use_sse41_simd))); // PINSRD
|
||||
insertlane_mapping.insert(64, (vec![0x66, 0x0f, 0x3a, 0x22], Some(use_sse41_simd))); // PINSRQ, only x86_64
|
||||
|
||||
for ty in ValueType::all_lane_types() {
|
||||
if let Some((opcode, isap)) = insertlane_mapping.get(&ty.lane_bits()) {
|
||||
|
@ -1747,10 +1750,10 @@ pub fn define(
|
|||
// SIMD extractlane
|
||||
let mut extractlane_mapping: HashMap<u64, (Vec<u8>, Option<SettingPredicateNumber>)> =
|
||||
HashMap::new();
|
||||
extractlane_mapping.insert(8, (vec![0x66, 0x0f, 0x3a, 0x14], Some(use_sse41))); // PEXTRB
|
||||
extractlane_mapping.insert(8, (vec![0x66, 0x0f, 0x3a, 0x14], Some(use_sse41_simd))); // PEXTRB
|
||||
extractlane_mapping.insert(16, (vec![0x66, 0x0f, 0xc5], None)); // PEXTRW from zSSE2, SSE4.1 has a PEXTRW that can move to reg/m16 but the opcode is four bytes
|
||||
extractlane_mapping.insert(32, (vec![0x66, 0x0f, 0x3a, 0x16], Some(use_sse41))); // PEXTRD
|
||||
extractlane_mapping.insert(64, (vec![0x66, 0x0f, 0x3a, 0x16], Some(use_sse41))); // PEXTRQ, only x86_64
|
||||
extractlane_mapping.insert(32, (vec![0x66, 0x0f, 0x3a, 0x16], Some(use_sse41_simd))); // PEXTRD
|
||||
extractlane_mapping.insert(64, (vec![0x66, 0x0f, 0x3a, 0x16], Some(use_sse41_simd))); // PEXTRQ, only x86_64
|
||||
|
||||
for ty in ValueType::all_lane_types() {
|
||||
if let Some((opcode, isap)) = extractlane_mapping.get(&ty.lane_bits()) {
|
||||
|
@ -1784,6 +1787,18 @@ pub fn define(
|
|||
}
|
||||
}
|
||||
|
||||
// SIMD vconst using MOVUPS
|
||||
// TODO it would be ideal if eventually this became the more efficient MOVAPS but we would have
|
||||
// to guarantee that the constants are aligned when emitted and there is currently no mechanism
|
||||
// for that; alternately, constants could be loaded into XMM registers using a sequence like:
|
||||
// MOVQ + MOVHPD + MOVQ + MOVLPD (this allows the constants to be immediates instead of stored
|
||||
// in memory) but some performance measurements are needed.
|
||||
for ty in ValueType::all_lane_types().filter(|t| t.lane_bits() >= 8) {
|
||||
let instruction = vconst.bind_vector_from_lane(ty, sse_vector_size);
|
||||
let template = rec_vconst.nonrex().opcodes(vec![0x0f, 0x10]);
|
||||
e.enc_32_64_maybe_isap(instruction, template, None); // from SSE
|
||||
}
|
||||
|
||||
// Reference type instructions
|
||||
|
||||
// Null references implemented as iconst 0.
|
||||
|
|
|
@ -399,6 +399,7 @@ pub fn define<'shared>(
|
|||
let f_unary_ieee32 = formats.by_name("UnaryIeee32");
|
||||
let f_unary_ieee64 = formats.by_name("UnaryIeee64");
|
||||
let f_unary_imm = formats.by_name("UnaryImm");
|
||||
let f_unary_imm128 = formats.by_name("UnaryImm128");
|
||||
|
||||
// Predicates shorthands.
|
||||
let use_sse41 = settings.predicate_by_name("use_sse41");
|
||||
|
@ -2382,6 +2383,19 @@ pub fn define<'shared>(
|
|||
),
|
||||
);
|
||||
|
||||
recipes.add_template_recipe(
|
||||
EncodingRecipeBuilder::new("vconst", f_unary_imm128, 5)
|
||||
.operands_out(vec![fpr])
|
||||
.clobbers_flags(false)
|
||||
.emit(
|
||||
r#"
|
||||
{{PUT_OP}}(bits, rex2(0, out_reg0), sink);
|
||||
modrm_riprel(out_reg0, sink);
|
||||
const_disp4(imm, func, sink);
|
||||
"#,
|
||||
),
|
||||
);
|
||||
|
||||
recipes.add_template_recipe(
|
||||
EncodingRecipeBuilder::new("jt_base", f_branch_table_base, 5)
|
||||
.operands_out(vec![gpr])
|
||||
|
|
|
@ -32,12 +32,23 @@ pub fn define(shared: &SettingGroup) -> SettingGroup {
|
|||
|
||||
let shared_enable_simd = shared.get_bool("enable_simd");
|
||||
|
||||
settings.add_predicate("use_ssse3", predicate!(shared_enable_simd && has_ssse3));
|
||||
settings.add_predicate("use_sse41", predicate!(shared_enable_simd && has_sse41));
|
||||
settings.add_predicate("use_ssse3", predicate!(has_ssse3));
|
||||
settings.add_predicate("use_sse41", predicate!(has_sse41));
|
||||
settings.add_predicate("use_sse42", predicate!(has_sse41 && has_sse42));
|
||||
|
||||
settings.add_predicate(
|
||||
"use_sse42",
|
||||
"use_ssse3_simd",
|
||||
predicate!(shared_enable_simd && has_ssse3),
|
||||
);
|
||||
settings.add_predicate(
|
||||
"use_sse41_simd",
|
||||
predicate!(shared_enable_simd && has_sse41),
|
||||
);
|
||||
settings.add_predicate(
|
||||
"use_sse42_simd",
|
||||
predicate!(shared_enable_simd && 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_lzcnt", predicate!(has_lzcnt));
|
||||
|
|
|
@ -5,6 +5,7 @@ pub fn define(immediates: &OperandKinds, entities: &OperandKinds) -> FormatRegis
|
|||
// Shorthands for immediates.
|
||||
let uimm8 = immediates.by_name("uimm8");
|
||||
let uimm32 = immediates.by_name("uimm32");
|
||||
let uimm128 = immediates.by_name("uimm128");
|
||||
let imm64 = immediates.by_name("imm64");
|
||||
let ieee32 = immediates.by_name("ieee32");
|
||||
let ieee64 = immediates.by_name("ieee64");
|
||||
|
@ -30,6 +31,7 @@ pub fn define(immediates: &OperandKinds, entities: &OperandKinds) -> FormatRegis
|
|||
|
||||
registry.insert(Builder::new("Unary").value());
|
||||
registry.insert(Builder::new("UnaryImm").imm(imm64));
|
||||
registry.insert(Builder::new("UnaryImm128").imm(uimm128));
|
||||
registry.insert(Builder::new("UnaryIeee32").imm(ieee32));
|
||||
registry.insert(Builder::new("UnaryIeee64").imm(ieee64));
|
||||
registry.insert(Builder::new("UnaryBool").imm(boolean));
|
||||
|
|
|
@ -29,6 +29,16 @@ pub fn define() -> Vec<OperandKind> {
|
|||
.build();
|
||||
kinds.push(uimm32);
|
||||
|
||||
// An unsigned 128-bit immediate integer operand.
|
||||
//
|
||||
// This operand is used to pass entire 128-bit vectors as immediates to
|
||||
// instructions like const.
|
||||
let uimm128 = Builder::new_imm("uimm128")
|
||||
.doc("A 128-bit immediate unsigned integer.")
|
||||
.rust_type("ir::Constant")
|
||||
.build();
|
||||
kinds.push(uimm128);
|
||||
|
||||
// A 32-bit immediate signed offset.
|
||||
//
|
||||
// This is used to represent an immediate address offset in load/store
|
||||
|
|
|
@ -30,6 +30,7 @@ pub fn define(
|
|||
let uimm8 = immediates.by_name("uimm8");
|
||||
let uimm32 = immediates.by_name("uimm32");
|
||||
let imm64 = immediates.by_name("imm64");
|
||||
let uimm128 = immediates.by_name("uimm128");
|
||||
let offset32 = immediates.by_name("offset32");
|
||||
let memflags = immediates.by_name("memflags");
|
||||
let ieee32 = immediates.by_name("ieee32");
|
||||
|
@ -1088,6 +1089,22 @@ pub fn define(
|
|||
.operands_out(vec![a]),
|
||||
);
|
||||
|
||||
let N = &operand_doc("N", uimm128, "The 16 immediate bytes of a 128-bit vector");
|
||||
let a = &operand_doc("a", TxN, "A constant vector value");
|
||||
|
||||
ig.push(
|
||||
Inst::new(
|
||||
"vconst",
|
||||
r#"
|
||||
SIMD vector constant.
|
||||
|
||||
Construct a vector with the given immediate bytes.
|
||||
"#,
|
||||
)
|
||||
.operands_in(vec![N])
|
||||
.operands_out(vec![a]),
|
||||
);
|
||||
|
||||
let a = &operand_doc("a", Ref, "A constant reference null value");
|
||||
|
||||
ig.push(
|
||||
|
|
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
|
@ -16,7 +16,7 @@
|
|||
use super::{Addend, CodeInfo, CodeOffset, CodeSink, Reloc};
|
||||
use crate::binemit::stackmap::Stackmap;
|
||||
use crate::ir::entities::Value;
|
||||
use crate::ir::{ExternalName, Function, JumpTable, SourceLoc, TrapCode};
|
||||
use crate::ir::{ConstantOffset, ExternalName, Function, JumpTable, SourceLoc, TrapCode};
|
||||
use crate::isa::TargetIsa;
|
||||
use core::ptr::write_unaligned;
|
||||
|
||||
|
@ -78,6 +78,9 @@ pub trait RelocSink {
|
|||
/// Add a relocation referencing an external symbol at the current offset.
|
||||
fn reloc_external(&mut self, _: CodeOffset, _: Reloc, _: &ExternalName, _: Addend);
|
||||
|
||||
/// Add a relocation referencing a constant.
|
||||
fn reloc_constant(&mut self, _: CodeOffset, _: Reloc, _: ConstantOffset);
|
||||
|
||||
/// Add a relocation referencing a jump table.
|
||||
fn reloc_jt(&mut self, _: CodeOffset, _: Reloc, _: JumpTable);
|
||||
}
|
||||
|
@ -132,6 +135,11 @@ impl<'a> CodeSink for MemoryCodeSink<'a> {
|
|||
self.relocs.reloc_external(ofs, rel, name, addend);
|
||||
}
|
||||
|
||||
fn reloc_constant(&mut self, rel: Reloc, constant_offset: ConstantOffset) {
|
||||
let ofs = self.offset();
|
||||
self.relocs.reloc_constant(ofs, rel, constant_offset);
|
||||
}
|
||||
|
||||
fn reloc_jt(&mut self, rel: Reloc, jt: JumpTable) {
|
||||
let ofs = self.offset();
|
||||
self.relocs.reloc_jt(ofs, rel, jt);
|
||||
|
@ -169,6 +177,7 @@ pub struct NullRelocSink {}
|
|||
impl RelocSink for NullRelocSink {
|
||||
fn reloc_ebb(&mut self, _: u32, _: Reloc, _: u32) {}
|
||||
fn reloc_external(&mut self, _: u32, _: Reloc, _: &ExternalName, _: i64) {}
|
||||
fn reloc_constant(&mut self, _: CodeOffset, _: Reloc, _: ConstantOffset) {}
|
||||
fn reloc_jt(&mut self, _: u32, _: Reloc, _: JumpTable) {}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ pub use self::relaxation::relax_branches;
|
|||
pub use self::shrink::shrink_instructions;
|
||||
pub use self::stackmap::Stackmap;
|
||||
use crate::ir::entities::Value;
|
||||
use crate::ir::{ExternalName, Function, Inst, JumpTable, SourceLoc, TrapCode};
|
||||
use crate::ir::{ConstantOffset, ExternalName, Function, Inst, JumpTable, SourceLoc, TrapCode};
|
||||
use crate::isa::TargetIsa;
|
||||
pub use crate::regalloc::RegDiversions;
|
||||
use core::fmt;
|
||||
|
@ -133,6 +133,9 @@ pub trait CodeSink {
|
|||
/// Add a relocation referencing an external symbol plus the addend at the current offset.
|
||||
fn reloc_external(&mut self, _: Reloc, _: &ExternalName, _: Addend);
|
||||
|
||||
/// Add a relocation referencing a jump table.
|
||||
fn reloc_constant(&mut self, _: Reloc, _: ConstantOffset);
|
||||
|
||||
/// Add a relocation referencing a jump table.
|
||||
fn reloc_jt(&mut self, _: Reloc, _: JumpTable);
|
||||
|
||||
|
@ -192,7 +195,13 @@ where
|
|||
}
|
||||
|
||||
sink.begin_rodata();
|
||||
// TODO: No read-only data (constant pools) at this time.
|
||||
|
||||
// output constants
|
||||
for (_, constant_data) in func.dfg.constants.iter() {
|
||||
for byte in constant_data.iter() {
|
||||
sink.put1(*byte)
|
||||
}
|
||||
}
|
||||
|
||||
sink.end_codegen();
|
||||
}
|
||||
|
|
|
@ -37,6 +37,7 @@ use crate::iterators::IteratorExtras;
|
|||
use crate::regalloc::RegDiversions;
|
||||
use crate::timing;
|
||||
use crate::CodegenResult;
|
||||
use core::convert::TryFrom;
|
||||
use log::debug;
|
||||
|
||||
#[cfg(feature = "basic-blocks")]
|
||||
|
@ -135,7 +136,11 @@ pub fn relax_branches(
|
|||
let jumptables_size = offset - jumptables;
|
||||
let rodata = offset;
|
||||
|
||||
// TODO: Once we have constant pools we'll do some processing here to update offset.
|
||||
for constant in func.dfg.constants.entries_mut() {
|
||||
constant.set_offset(offset);
|
||||
offset +=
|
||||
u32::try_from(constant.len()).expect("Constants must have a length that fits in a u32")
|
||||
}
|
||||
|
||||
let rodata_size = offset - rodata;
|
||||
|
||||
|
|
|
@ -0,0 +1,220 @@
|
|||
//! Constants
|
||||
//!
|
||||
//! The constant pool defined here allows cranelift to avoid emitting the same constant multiple
|
||||
//! times. As constants are inserted in the pool, a handle is returned; the handle is a cranelift
|
||||
//! Entity. Inserting the same data multiple times will always return the same handle. Future work
|
||||
//! could include: ensuring alignment of constants within the pool, bucketing constants by size.
|
||||
|
||||
use crate::ir::Constant;
|
||||
use cranelift_entity::EntityRef;
|
||||
use std::collections::{BTreeMap, HashMap};
|
||||
use std::vec::Vec;
|
||||
|
||||
/// This type describes the actual constant data.
|
||||
pub type ConstantData = Vec<u8>;
|
||||
|
||||
/// This type describes an offset in bytes within a constant pool.
|
||||
pub type ConstantOffset = u32;
|
||||
|
||||
/// Inner type for storing data and offset together in the constant pool. The offset is optional
|
||||
/// because it must be set relative to the function code size (i.e. constants are emitted after the
|
||||
/// function body); because the function is not yet compiled when constants are inserted,
|
||||
/// [`set_offset`](crate::ir::ConstantPool::set_offset) must be called once a constant's
|
||||
/// offset from the beginning of the function is known (see
|
||||
/// [`relaxation.rs`](crate::binemit::relaxation)).
|
||||
#[derive(Clone)]
|
||||
pub struct ConstantPoolEntry {
|
||||
data: ConstantData,
|
||||
offset: Option<ConstantOffset>,
|
||||
}
|
||||
|
||||
impl ConstantPoolEntry {
|
||||
fn new(data: ConstantData) -> Self {
|
||||
ConstantPoolEntry { data, offset: None }
|
||||
}
|
||||
|
||||
/// Return the size of the constant at this entry.
|
||||
pub fn len(&self) -> usize {
|
||||
self.data.len()
|
||||
}
|
||||
|
||||
/// Assign a new offset to the constant at this entry.
|
||||
pub fn set_offset(&mut self, offset: ConstantOffset) {
|
||||
self.offset = Some(offset)
|
||||
}
|
||||
}
|
||||
|
||||
/// Maintains the mapping between a constant handle (i.e.
|
||||
/// [`Constant`](crate::ir::Constant)) and its constant data (i.e.
|
||||
/// [`ConstantData`](crate::ir::ConstantData)).
|
||||
#[derive(Clone)]
|
||||
pub struct ConstantPool {
|
||||
/// This mapping maintains the insertion order as long as Constants are created with sequentially increasing integers.
|
||||
handles_to_values: BTreeMap<Constant, ConstantPoolEntry>,
|
||||
/// This mapping is unordered (no need for lexicographic ordering) but allows us to map constant data back to handles.
|
||||
values_to_handles: HashMap<ConstantData, Constant>,
|
||||
}
|
||||
|
||||
impl ConstantPool {
|
||||
/// Create a new constant pool instance.
|
||||
pub fn new() -> Self {
|
||||
ConstantPool {
|
||||
handles_to_values: BTreeMap::new(),
|
||||
values_to_handles: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Empty the constant pool of all data.
|
||||
pub fn clear(&mut self) {
|
||||
self.handles_to_values.clear();
|
||||
self.values_to_handles.clear();
|
||||
}
|
||||
|
||||
/// Insert constant data into the pool, returning a handle for later referencing; when constant
|
||||
/// data is inserted that is a duplicate of previous constant data, the existing handle will be
|
||||
/// returned.
|
||||
pub fn insert(&mut self, constant_value: ConstantData) -> Constant {
|
||||
if self.values_to_handles.contains_key(&constant_value) {
|
||||
self.values_to_handles
|
||||
.get(&constant_value)
|
||||
.expect("A constant handle must have a corresponding constant value; this is an implementation error in ConstantPool")
|
||||
.clone()
|
||||
} else {
|
||||
let constant_handle = Constant::new(self.len());
|
||||
self.values_to_handles
|
||||
.insert(constant_value.clone(), constant_handle.clone());
|
||||
self.handles_to_values.insert(
|
||||
constant_handle.clone(),
|
||||
ConstantPoolEntry::new(constant_value),
|
||||
);
|
||||
constant_handle
|
||||
}
|
||||
}
|
||||
|
||||
/// Retrieve the constant data given a handle.
|
||||
pub fn get(&self, constant_handle: Constant) -> &ConstantData {
|
||||
assert!(self.handles_to_values.contains_key(&constant_handle));
|
||||
&self.handles_to_values
|
||||
.get(&constant_handle)
|
||||
.expect("A constant handle must have a corresponding constant value; was a constant handle created outside of the pool?")
|
||||
.data
|
||||
}
|
||||
|
||||
/// Assign an offset to a given constant, where the offset is the number of bytes from the
|
||||
/// beginning of the function to the beginning of the constant data inside the pool.
|
||||
pub fn set_offset(&mut self, constant_handle: Constant, constant_offset: ConstantOffset) {
|
||||
assert!(self.handles_to_values.contains_key(&constant_handle), "A constant handle must have already been inserted into the pool; perhaps a constant pool was created outside of the pool?");
|
||||
self.handles_to_values
|
||||
.entry(constant_handle)
|
||||
.and_modify(|e| e.offset = Some(constant_offset));
|
||||
}
|
||||
|
||||
/// Retrieve the offset of a given constant, where the offset is the number of bytes from the
|
||||
/// beginning of the function to the beginning of the constant data inside the pool.
|
||||
pub fn get_offset(&self, constant_handle: Constant) -> ConstantOffset {
|
||||
self.handles_to_values.get(&constant_handle)
|
||||
.expect("A constant handle must have a corresponding constant value; was a constant handle created outside of the pool?")
|
||||
.offset
|
||||
.expect("A constant offset has not yet been set; verify that `set_offset` has been called before this point")
|
||||
}
|
||||
|
||||
/// Iterate over the constants in insertion order.
|
||||
pub fn iter(&self) -> impl Iterator<Item = (&Constant, &ConstantData)> {
|
||||
self.handles_to_values.iter().map(|(h, e)| (h, &e.data))
|
||||
}
|
||||
|
||||
/// Iterate over mutable entries in the constant pool in insertion order.
|
||||
pub fn entries_mut(&mut self) -> impl Iterator<Item = &mut ConstantPoolEntry> {
|
||||
self.handles_to_values.values_mut()
|
||||
}
|
||||
|
||||
/// Return the number of constants in the pool.
|
||||
pub fn len(&self) -> usize {
|
||||
self.handles_to_values.len()
|
||||
}
|
||||
|
||||
/// Return the combined size of all of the constant values in the pool.
|
||||
pub fn byte_size(&self) -> usize {
|
||||
self.values_to_handles.keys().map(|c| c.len()).sum()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn empty() {
|
||||
let sut = ConstantPool::new();
|
||||
assert_eq!(sut.len(), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn insert() {
|
||||
let mut sut = ConstantPool::new();
|
||||
sut.insert(vec![1, 2, 3]);
|
||||
sut.insert(vec![4, 5, 6]);
|
||||
assert_eq!(sut.len(), 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn insert_duplicate() {
|
||||
let mut sut = ConstantPool::new();
|
||||
let a = sut.insert(vec![1, 2, 3]);
|
||||
sut.insert(vec![4, 5, 6]);
|
||||
let b = sut.insert(vec![1, 2, 3]);
|
||||
assert_eq!(a, b);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn clear() {
|
||||
let mut sut = ConstantPool::new();
|
||||
sut.insert(vec![1, 2, 3]);
|
||||
assert_eq!(sut.len(), 1);
|
||||
|
||||
sut.clear();
|
||||
assert_eq!(sut.len(), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn iteration_order() {
|
||||
let mut sut = ConstantPool::new();
|
||||
sut.insert(vec![1, 2, 3]);
|
||||
sut.insert(vec![4, 5, 6]);
|
||||
sut.insert(vec![1, 2, 3]);
|
||||
let data = sut.iter().map(|(_, v)| v).collect::<Vec<&ConstantData>>();
|
||||
assert_eq!(data, vec![&vec![1, 2, 3], &vec![4, 5, 6]]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn get() {
|
||||
let mut sut = ConstantPool::new();
|
||||
let data = vec![1, 2, 3];
|
||||
let handle = sut.insert(data.clone());
|
||||
assert_eq!(sut.get(handle), &data);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn get_nonexistent_constant() {
|
||||
let sut = ConstantPool::new();
|
||||
let a = Constant::with_number(42).unwrap();
|
||||
sut.get(a); // panics, only use constants returned by ConstantPool
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn get_offset() {
|
||||
let mut sut = ConstantPool::new();
|
||||
let a = sut.insert(vec![1]);
|
||||
sut.set_offset(a, 42);
|
||||
assert_eq!(sut.get_offset(a), 42)
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn get_nonexistent_offset() {
|
||||
let mut sut = ConstantPool::new();
|
||||
let a = sut.insert(vec![1]);
|
||||
sut.get_offset(a); // panics, set_offset should have been called
|
||||
}
|
||||
}
|
|
@ -5,7 +5,7 @@ use crate::ir;
|
|||
use crate::ir::builder::ReplaceBuilder;
|
||||
use crate::ir::extfunc::ExtFuncData;
|
||||
use crate::ir::instructions::{BranchInfo, CallInfo, InstructionData};
|
||||
use crate::ir::types;
|
||||
use crate::ir::{types, ConstantPool};
|
||||
use crate::ir::{
|
||||
Ebb, FuncRef, Inst, SigRef, Signature, Type, Value, ValueLabelAssignments, ValueList,
|
||||
ValueListPool,
|
||||
|
@ -67,6 +67,9 @@ pub struct DataFlowGraph {
|
|||
|
||||
/// Saves Value labels.
|
||||
pub values_labels: Option<HashMap<Value, ValueLabelAssignments>>,
|
||||
|
||||
/// Constants used within the function
|
||||
pub constants: ConstantPool,
|
||||
}
|
||||
|
||||
impl DataFlowGraph {
|
||||
|
@ -81,6 +84,7 @@ impl DataFlowGraph {
|
|||
signatures: PrimaryMap::new(),
|
||||
ext_funcs: PrimaryMap::new(),
|
||||
values_labels: None,
|
||||
constants: ConstantPool::new(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -94,6 +98,7 @@ impl DataFlowGraph {
|
|||
self.signatures.clear();
|
||||
self.ext_funcs.clear();
|
||||
self.values_labels = None;
|
||||
self.constants.clear()
|
||||
}
|
||||
|
||||
/// Get the total number of instructions created in this function, whether they are currently
|
||||
|
|
|
@ -104,6 +104,24 @@ impl GlobalValue {
|
|||
}
|
||||
}
|
||||
|
||||
/// An opaque reference to a constant
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, Ord, PartialOrd)]
|
||||
pub struct Constant(u32);
|
||||
entity_impl!(Constant, "const");
|
||||
|
||||
impl Constant {
|
||||
/// Create a const reference from its number.
|
||||
///
|
||||
/// This method is for use by the parser.
|
||||
pub fn with_number(n: u32) -> Option<Self> {
|
||||
if n < u32::MAX {
|
||||
Some(Constant(n))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// An opaque reference to a jump table.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
|
||||
#[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
|
||||
|
@ -195,7 +213,7 @@ impl Table {
|
|||
}
|
||||
}
|
||||
|
||||
/// A reference to any of the entities defined in this module.
|
||||
/// A reference to any of the entities defined in this module that can appear in CLIF IR.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub enum AnyEntity {
|
||||
/// The whole function.
|
||||
|
@ -331,4 +349,10 @@ mod tests {
|
|||
mem::size_of::<PackedOption<Value>>()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn constant_with_number() {
|
||||
assert_eq!(Constant::with_number(0).unwrap().to_string(), "const0");
|
||||
assert_eq!(Constant::with_number(1).unwrap().to_string(), "const1");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -113,6 +113,7 @@ impl Function {
|
|||
self.encodings.clear();
|
||||
self.locations.clear();
|
||||
self.offsets.clear();
|
||||
self.jt_offsets.clear();
|
||||
self.srclocs.clear();
|
||||
}
|
||||
|
||||
|
|
|
@ -264,6 +264,74 @@ impl FromStr for Uimm32 {
|
|||
}
|
||||
}
|
||||
|
||||
/// A 128-bit unsigned integer immediate operand.
|
||||
///
|
||||
/// This is used as an immediate value in SIMD instructions
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
|
||||
pub struct Uimm128(pub [u8; 16]);
|
||||
|
||||
impl Display for Uimm128 {
|
||||
// print a 128-bit vector in hexadecimal, e.g. 0x000102030405060708090a0b0c0d0e0f
|
||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||
write!(f, "0x")?;
|
||||
let mut anything_written = false;
|
||||
for &b in self.0.iter().rev() {
|
||||
if b == 0 && !anything_written {
|
||||
continue;
|
||||
} else {
|
||||
anything_written = true;
|
||||
write!(f, "{:02x}", b)?;
|
||||
}
|
||||
}
|
||||
if !anything_written {
|
||||
write!(f, "00")?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<u64> for Uimm128 {
|
||||
fn from(x: u64) -> Self {
|
||||
let mut buffer: [u8; 16] = [0; 16]; // zero-fill
|
||||
(0..8).for_each(|byte| buffer[byte] = (x >> (byte as u64 * 8) & 0xff) as u8); // insert each byte from the u64 into v in little-endian order
|
||||
Uimm128(buffer)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&[u8]> for Uimm128 {
|
||||
fn from(slice: &[u8]) -> Self {
|
||||
assert_eq!(slice.len(), 16);
|
||||
let mut buffer = [0; 16];
|
||||
buffer.copy_from_slice(slice);
|
||||
Uimm128(buffer)
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for Uimm128 {
|
||||
type Err = &'static str;
|
||||
|
||||
// parse a 128-bit vector from a hexadecimal string, formatted as above
|
||||
fn from_str(s: &str) -> Result<Self, &'static str> {
|
||||
if s.len() <= 2 || &s[0..2] != "0x" {
|
||||
Err("Expected a hexadecimal string, e.g. 0x1234")
|
||||
} else if s.len() % 2 != 0 {
|
||||
Err("Hexadecimal string must have an even number of digits")
|
||||
} else if s.len() > 34 {
|
||||
Err("Hexadecimal string has too many digits to fit in a 128-bit vector")
|
||||
} else {
|
||||
let mut buffer = [0; 16]; // zero-fill
|
||||
let start_at = s.len() / 2 - 1;
|
||||
for i in (2..s.len()).step_by(2) {
|
||||
let byte = u8::from_str_radix(&s[i..i + 2], 16)
|
||||
.or_else(|_| Err("Unable to parse as hexadecimal"))?;
|
||||
let position = start_at - (i / 2);
|
||||
buffer[position] = byte;
|
||||
}
|
||||
Ok(Uimm128(buffer))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 32-bit signed immediate offset.
|
||||
///
|
||||
/// This is used to encode an immediate offset for load/store instructions. All supported ISAs have
|
||||
|
@ -884,6 +952,54 @@ mod tests {
|
|||
parse_err::<Uimm64>("0x0_0000_0000_0000_0000", "Too many hexadecimal digits");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn format_uimm128() {
|
||||
assert_eq!(Uimm128::from(0).to_string(), "0x00");
|
||||
assert_eq!(Uimm128::from(42).to_string(), "0x2a");
|
||||
assert_eq!(Uimm128::from(3735928559).to_string(), "0xdeadbeef");
|
||||
assert_eq!(
|
||||
Uimm128::from(0x0102030405060708).to_string(),
|
||||
"0x0102030405060708"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_uimm128() {
|
||||
parse_ok::<Uimm128>("0x00", "0x00");
|
||||
parse_ok::<Uimm128>("0x00000042", "0x42");
|
||||
parse_ok::<Uimm128>(
|
||||
"0x0102030405060708090a0b0c0d0e0f",
|
||||
"0x0102030405060708090a0b0c0d0e0f",
|
||||
);
|
||||
|
||||
parse_err::<Uimm128>("", "Expected a hexadecimal string, e.g. 0x1234");
|
||||
parse_err::<Uimm128>("0x", "Expected a hexadecimal string, e.g. 0x1234");
|
||||
parse_err::<Uimm128>(
|
||||
"0x042",
|
||||
"Hexadecimal string must have an even number of digits",
|
||||
);
|
||||
parse_err::<Uimm128>(
|
||||
"0x00000000000000000000000000000000000000000000000000",
|
||||
"Hexadecimal string has too many digits to fit in a 128-bit vector",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn uimm128_endianness() {
|
||||
assert_eq!(
|
||||
"0x42".parse::<Uimm128>().unwrap().0,
|
||||
[0x42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
|
||||
);
|
||||
assert_eq!(
|
||||
"0x00".parse::<Uimm128>().unwrap().0,
|
||||
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
|
||||
);
|
||||
assert_eq!(
|
||||
"0x12345678".parse::<Uimm128>().unwrap().0,
|
||||
[0x78, 0x56, 0x34, 0x12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn format_offset32() {
|
||||
assert_eq!(Offset32(0).to_string(), "");
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
mod builder;
|
||||
pub mod condcodes;
|
||||
pub mod constant;
|
||||
pub mod dfg;
|
||||
pub mod entities;
|
||||
mod extfunc;
|
||||
|
@ -27,9 +28,10 @@ mod valueloc;
|
|||
use serde::{Deserialize, Serialize};
|
||||
|
||||
pub use crate::ir::builder::{InsertBuilder, InstBuilder, InstBuilderBase, InstInserterBase};
|
||||
pub use crate::ir::constant::{ConstantData, ConstantOffset, ConstantPool};
|
||||
pub use crate::ir::dfg::{DataFlowGraph, ValueDef};
|
||||
pub use crate::ir::entities::{
|
||||
Ebb, FuncRef, GlobalValue, Heap, Inst, JumpTable, SigRef, StackSlot, Table, Value,
|
||||
Constant, Ebb, FuncRef, GlobalValue, Heap, Inst, JumpTable, SigRef, StackSlot, Table, Value,
|
||||
};
|
||||
pub use crate::ir::extfunc::{
|
||||
AbiParam, ArgumentExtension, ArgumentPurpose, ExtFuncData, Signature,
|
||||
|
|
|
@ -4,7 +4,7 @@ use super::enc_tables::{needs_offset, needs_sib_byte};
|
|||
use super::registers::RU;
|
||||
use crate::binemit::{bad_encoding, CodeSink, Reloc};
|
||||
use crate::ir::condcodes::{CondCode, FloatCC, IntCC};
|
||||
use crate::ir::{Ebb, Function, Inst, InstructionData, JumpTable, Opcode, TrapCode};
|
||||
use crate::ir::{Constant, Ebb, Function, Inst, InstructionData, JumpTable, Opcode, TrapCode};
|
||||
use crate::isa::{RegUnit, StackBase, StackBaseMask, StackRef, TargetIsa};
|
||||
use crate::regalloc::RegDiversions;
|
||||
|
||||
|
@ -341,3 +341,11 @@ fn jt_disp4<CS: CodeSink + ?Sized>(jt: JumpTable, func: &Function, sink: &mut CS
|
|||
sink.put4(delta);
|
||||
sink.reloc_jt(Reloc::X86PCRelRodata4, jt);
|
||||
}
|
||||
|
||||
/// Emit a four-byte displacement to `constant`
|
||||
fn const_disp4<CS: CodeSink + ?Sized>(constant: Constant, func: &Function, sink: &mut CS) {
|
||||
let offset = func.dfg.constants.get_offset(constant);
|
||||
let delta = offset.wrapping_sub(sink.offset() + 4);
|
||||
sink.put4(delta);
|
||||
sink.reloc_constant(Reloc::X86PCRelRodata4, offset);
|
||||
}
|
||||
|
|
|
@ -679,6 +679,7 @@ impl<'a> Verifier<'a> {
|
|||
// Exhaustive list so we can't forget to add new formats
|
||||
Unary { .. }
|
||||
| UnaryImm { .. }
|
||||
| UnaryImm128 { .. }
|
||||
| UnaryIeee32 { .. }
|
||||
| UnaryIeee64 { .. }
|
||||
| UnaryBool { .. }
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
use crate::entity::SecondaryMap;
|
||||
use crate::ir::entities::AnyEntity;
|
||||
use crate::ir::immediates::Uimm128;
|
||||
use crate::ir::{
|
||||
DataFlowGraph, DisplayFunctionAnnotations, Ebb, Function, Inst, SigRef, Type, Value, ValueDef,
|
||||
ValueLoc,
|
||||
|
@ -487,6 +488,11 @@ pub fn write_operands(
|
|||
match dfg[inst] {
|
||||
Unary { arg, .. } => write!(w, " {}", arg),
|
||||
UnaryImm { imm, .. } => write!(w, " {}", imm),
|
||||
UnaryImm128 { imm, .. } => {
|
||||
let data = dfg.constants.get(imm);
|
||||
let uimm128 = Uimm128::from(&data[..]);
|
||||
write!(w, " {}", uimm128)
|
||||
}
|
||||
UnaryIeee32 { imm, .. } => write!(w, " {}", imm),
|
||||
UnaryIeee64 { imm, .. } => write!(w, " {}", imm),
|
||||
UnaryBool { imm, .. } => write!(w, " {}", imm),
|
||||
|
|
|
@ -1 +1 @@
|
|||
{"files":{"Cargo.toml":"0acc3911c582b0f38099b4694d7600e6d5bb59a701c0b71144ba4cdd0ee2babf","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"87679cdb53e8cbec3b1aa45afb2124727c1c059f8bd10363d27daf318a9f9a36","src/code_translator.rs":"ec67a88ce22cc456d3bd9c410bcf15982b196688374d06f2c1f633c838cb138d","src/environ/dummy.rs":"cca4a867849e82d3fe6793d306d24e89080198e74a58947085edbc12aab2a4ff","src/environ/mod.rs":"b046f5344a1017357c1ee9d661d2193e0247327df293436fa1381a0f45f80584","src/environ/spec.rs":"5f92d6da837267f85543f2700b658b4fb80052816f77d9fbfaa6e511d1ca3116","src/func_translator.rs":"2f1a80ede583cb14cfc2714c1d96855d6d0fdc5e044e092b0257179cd118d876","src/lib.rs":"4664114c8f4c174bea6c0385d36f29198fc9b01a8503308c7d75ea094987744b","src/module_translator.rs":"8f23a0e17c512b6fcb19fc3f19b41aebce6bde51923e812ddd326409ac967efd","src/sections_translator.rs":"cab0e57e173cf752a8ada6cff74abb364c3191a9c3341e5c686d750f51c83995","src/state.rs":"fc2a8d468b4b681d9262fdb8762f3300ffce709cb0b2e48f3835a5b9164e7c93","src/translation_utils.rs":"134ab514ba2a21cca88d603419cf233ffa00f671c8552fd3262a8cd85d3bb97d","tests/wasm_testsuite.rs":"9b4e008587c61377cf38f9d0e4635418ee38e32a865db8da5dfc6e0fae047436"},"package":null}
|
||||
{"files":{"Cargo.toml":"0acc3911c582b0f38099b4694d7600e6d5bb59a701c0b71144ba4cdd0ee2babf","LICENSE":"268872b9816f90fd8e85db5a28d33f8150ebb8dd016653fb39ef1f94f2686bc5","README.md":"87679cdb53e8cbec3b1aa45afb2124727c1c059f8bd10363d27daf318a9f9a36","src/code_translator.rs":"1a830b7a75c868246ee6a648187da60fd60b3620bc47c3dfaa716c2712765def","src/environ/dummy.rs":"cca4a867849e82d3fe6793d306d24e89080198e74a58947085edbc12aab2a4ff","src/environ/mod.rs":"b046f5344a1017357c1ee9d661d2193e0247327df293436fa1381a0f45f80584","src/environ/spec.rs":"5f92d6da837267f85543f2700b658b4fb80052816f77d9fbfaa6e511d1ca3116","src/func_translator.rs":"2f1a80ede583cb14cfc2714c1d96855d6d0fdc5e044e092b0257179cd118d876","src/lib.rs":"4664114c8f4c174bea6c0385d36f29198fc9b01a8503308c7d75ea094987744b","src/module_translator.rs":"8f23a0e17c512b6fcb19fc3f19b41aebce6bde51923e812ddd326409ac967efd","src/sections_translator.rs":"cab0e57e173cf752a8ada6cff74abb364c3191a9c3341e5c686d750f51c83995","src/state.rs":"fc2a8d468b4b681d9262fdb8762f3300ffce709cb0b2e48f3835a5b9164e7c93","src/translation_utils.rs":"134ab514ba2a21cca88d603419cf233ffa00f671c8552fd3262a8cd85d3bb97d","tests/wasm_testsuite.rs":"9e01f9053516ce6a411449aaf41438867fc83c83d45cdbe5e84a9a34d4a1ca02"},"package":null}
|
|
@ -33,7 +33,7 @@ use crate::wasm_unsupported;
|
|||
use core::{i32, u32};
|
||||
use cranelift_codegen::ir::condcodes::{FloatCC, IntCC};
|
||||
use cranelift_codegen::ir::types::*;
|
||||
use cranelift_codegen::ir::{self, InstBuilder, JumpTableData, MemFlags, ValueLabel};
|
||||
use cranelift_codegen::ir::{self, InstBuilder, JumpTableData, MemFlags, Value, ValueLabel};
|
||||
use cranelift_codegen::packed_option::ReservedValue;
|
||||
use cranelift_frontend::{FunctionBuilder, Variable};
|
||||
use wasmparser::{MemoryImmediate, Operator};
|
||||
|
@ -922,30 +922,55 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
|
|||
| Operator::TableSize { .. } => {
|
||||
wasm_unsupported!("proposed bulk memory operator {:?}", op);
|
||||
}
|
||||
Operator::V128Const { value } => {
|
||||
let handle = builder.func.dfg.constants.insert(value.bytes().to_vec());
|
||||
let value = builder.ins().vconst(I8X16, handle);
|
||||
// the v128.const is typed in CLIF as a I8x16 but raw_bitcast to a different type before use
|
||||
state.push1(value)
|
||||
}
|
||||
Operator::I8x16Splat
|
||||
| Operator::I16x8Splat
|
||||
| Operator::I32x4Splat
|
||||
| Operator::I64x2Splat
|
||||
| Operator::F32x4Splat
|
||||
| Operator::F64x2Splat => {
|
||||
let value_to_splat = state.pop1();
|
||||
let ty = type_of(op);
|
||||
let splatted = builder.ins().splat(ty, value_to_splat);
|
||||
state.push1(splatted)
|
||||
}
|
||||
Operator::I32x4ExtractLane { lane }
|
||||
| Operator::I64x2ExtractLane { lane }
|
||||
| Operator::F32x4ExtractLane { lane }
|
||||
| Operator::F64x2ExtractLane { lane } => {
|
||||
let vector = optionally_bitcast_vector(state.pop1(), type_of(op), builder);
|
||||
state.push1(builder.ins().extractlane(vector, lane.clone()))
|
||||
}
|
||||
Operator::I8x16ReplaceLane { lane }
|
||||
| Operator::I16x8ReplaceLane { lane }
|
||||
| Operator::I32x4ReplaceLane { lane }
|
||||
| Operator::I64x2ReplaceLane { lane }
|
||||
| Operator::F32x4ReplaceLane { lane }
|
||||
| Operator::F64x2ReplaceLane { lane } => {
|
||||
let (vector, replacement_value) = state.pop2();
|
||||
let original_vector_type = builder.func.dfg.value_type(vector);
|
||||
let vector = optionally_bitcast_vector(vector, type_of(op), builder);
|
||||
let replaced_vector = builder
|
||||
.ins()
|
||||
.insertlane(vector, lane.clone(), replacement_value);
|
||||
state.push1(optionally_bitcast_vector(
|
||||
replaced_vector,
|
||||
original_vector_type,
|
||||
builder,
|
||||
))
|
||||
}
|
||||
Operator::V128Load { .. }
|
||||
| Operator::V128Store { .. }
|
||||
| Operator::V128Const { .. }
|
||||
| Operator::V8x16Shuffle { .. }
|
||||
| Operator::I8x16Splat
|
||||
| Operator::I8x16ExtractLaneS { .. }
|
||||
| Operator::I8x16ExtractLaneU { .. }
|
||||
| Operator::I8x16ReplaceLane { .. }
|
||||
| Operator::I16x8Splat
|
||||
| Operator::I16x8ExtractLaneS { .. }
|
||||
| Operator::I16x8ExtractLaneU { .. }
|
||||
| Operator::I16x8ReplaceLane { .. }
|
||||
| Operator::I32x4Splat
|
||||
| Operator::I32x4ExtractLane { .. }
|
||||
| Operator::I32x4ReplaceLane { .. }
|
||||
| Operator::I64x2Splat
|
||||
| Operator::I64x2ExtractLane { .. }
|
||||
| Operator::I64x2ReplaceLane { .. }
|
||||
| Operator::F32x4Splat
|
||||
| Operator::F32x4ExtractLane { .. }
|
||||
| Operator::F32x4ReplaceLane { .. }
|
||||
| Operator::F64x2Splat
|
||||
| Operator::F64x2ExtractLane { .. }
|
||||
| Operator::F64x2ReplaceLane { .. }
|
||||
| Operator::V8x16Shuffle { .. }
|
||||
| Operator::I8x16Eq
|
||||
| Operator::I8x16Ne
|
||||
| Operator::I8x16LtS
|
||||
|
@ -1291,3 +1316,174 @@ fn translate_br_if_args(
|
|||
let inputs = state.peekn(return_count);
|
||||
(br_destination, inputs)
|
||||
}
|
||||
|
||||
/// Determine the returned value type of a WebAssembly operator
|
||||
fn type_of(operator: &Operator) -> Type {
|
||||
match operator {
|
||||
Operator::V128Load { .. }
|
||||
| Operator::V128Store { .. }
|
||||
| Operator::V128Const { .. }
|
||||
| Operator::V128Not
|
||||
| Operator::V128And
|
||||
| Operator::V128Or
|
||||
| Operator::V128Xor
|
||||
| Operator::V128Bitselect => I8X16, // default type representing V128
|
||||
|
||||
Operator::V8x16Shuffle { .. }
|
||||
| Operator::I8x16Splat
|
||||
| Operator::I8x16ExtractLaneS { .. }
|
||||
| Operator::I8x16ExtractLaneU { .. }
|
||||
| Operator::I8x16ReplaceLane { .. }
|
||||
| Operator::I8x16Eq
|
||||
| Operator::I8x16Ne
|
||||
| Operator::I8x16LtS
|
||||
| Operator::I8x16LtU
|
||||
| Operator::I8x16GtS
|
||||
| Operator::I8x16GtU
|
||||
| Operator::I8x16LeS
|
||||
| Operator::I8x16LeU
|
||||
| Operator::I8x16GeS
|
||||
| Operator::I8x16GeU
|
||||
| Operator::I8x16Neg
|
||||
| Operator::I8x16AnyTrue
|
||||
| Operator::I8x16AllTrue
|
||||
| Operator::I8x16Shl
|
||||
| Operator::I8x16ShrS
|
||||
| Operator::I8x16ShrU
|
||||
| Operator::I8x16Add
|
||||
| Operator::I8x16AddSaturateS
|
||||
| Operator::I8x16AddSaturateU
|
||||
| Operator::I8x16Sub
|
||||
| Operator::I8x16SubSaturateS
|
||||
| Operator::I8x16SubSaturateU
|
||||
| Operator::I8x16Mul => I8X16,
|
||||
|
||||
Operator::I16x8Splat
|
||||
| Operator::I16x8ExtractLaneS { .. }
|
||||
| Operator::I16x8ExtractLaneU { .. }
|
||||
| Operator::I16x8ReplaceLane { .. }
|
||||
| Operator::I16x8Eq
|
||||
| Operator::I16x8Ne
|
||||
| Operator::I16x8LtS
|
||||
| Operator::I16x8LtU
|
||||
| Operator::I16x8GtS
|
||||
| Operator::I16x8GtU
|
||||
| Operator::I16x8LeS
|
||||
| Operator::I16x8LeU
|
||||
| Operator::I16x8GeS
|
||||
| Operator::I16x8GeU
|
||||
| Operator::I16x8Neg
|
||||
| Operator::I16x8AnyTrue
|
||||
| Operator::I16x8AllTrue
|
||||
| Operator::I16x8Shl
|
||||
| Operator::I16x8ShrS
|
||||
| Operator::I16x8ShrU
|
||||
| Operator::I16x8Add
|
||||
| Operator::I16x8AddSaturateS
|
||||
| Operator::I16x8AddSaturateU
|
||||
| Operator::I16x8Sub
|
||||
| Operator::I16x8SubSaturateS
|
||||
| Operator::I16x8SubSaturateU
|
||||
| Operator::I16x8Mul => I16X8,
|
||||
|
||||
Operator::I32x4Splat
|
||||
| Operator::I32x4ExtractLane { .. }
|
||||
| Operator::I32x4ReplaceLane { .. }
|
||||
| Operator::I32x4Eq
|
||||
| Operator::I32x4Ne
|
||||
| Operator::I32x4LtS
|
||||
| Operator::I32x4LtU
|
||||
| Operator::I32x4GtS
|
||||
| Operator::I32x4GtU
|
||||
| Operator::I32x4LeS
|
||||
| Operator::I32x4LeU
|
||||
| Operator::I32x4GeS
|
||||
| Operator::I32x4GeU
|
||||
| Operator::I32x4Neg
|
||||
| Operator::I32x4AnyTrue
|
||||
| Operator::I32x4AllTrue
|
||||
| Operator::I32x4Shl
|
||||
| Operator::I32x4ShrS
|
||||
| Operator::I32x4ShrU
|
||||
| Operator::I32x4Add
|
||||
| Operator::I32x4Sub
|
||||
| Operator::I32x4Mul
|
||||
| Operator::F32x4ConvertSI32x4
|
||||
| Operator::F32x4ConvertUI32x4 => I32X4,
|
||||
|
||||
Operator::I64x2Splat
|
||||
| Operator::I64x2ExtractLane { .. }
|
||||
| Operator::I64x2ReplaceLane { .. }
|
||||
| Operator::I64x2Neg
|
||||
| Operator::I64x2AnyTrue
|
||||
| Operator::I64x2AllTrue
|
||||
| Operator::I64x2Shl
|
||||
| Operator::I64x2ShrS
|
||||
| Operator::I64x2ShrU
|
||||
| Operator::I64x2Add
|
||||
| Operator::I64x2Sub
|
||||
| Operator::F64x2ConvertSI64x2
|
||||
| Operator::F64x2ConvertUI64x2 => I64X2,
|
||||
|
||||
Operator::F32x4Splat
|
||||
| Operator::F32x4ExtractLane { .. }
|
||||
| Operator::F32x4ReplaceLane { .. }
|
||||
| Operator::F32x4Eq
|
||||
| Operator::F32x4Ne
|
||||
| Operator::F32x4Lt
|
||||
| Operator::F32x4Gt
|
||||
| Operator::F32x4Le
|
||||
| Operator::F32x4Ge
|
||||
| Operator::F32x4Abs
|
||||
| Operator::F32x4Neg
|
||||
| Operator::F32x4Sqrt
|
||||
| Operator::F32x4Add
|
||||
| Operator::F32x4Sub
|
||||
| Operator::F32x4Mul
|
||||
| Operator::F32x4Div
|
||||
| Operator::F32x4Min
|
||||
| Operator::F32x4Max
|
||||
| Operator::I32x4TruncSF32x4Sat
|
||||
| Operator::I32x4TruncUF32x4Sat => F32X4,
|
||||
|
||||
Operator::F64x2Splat
|
||||
| Operator::F64x2ExtractLane { .. }
|
||||
| Operator::F64x2ReplaceLane { .. }
|
||||
| Operator::F64x2Eq
|
||||
| Operator::F64x2Ne
|
||||
| Operator::F64x2Lt
|
||||
| Operator::F64x2Gt
|
||||
| Operator::F64x2Le
|
||||
| Operator::F64x2Ge
|
||||
| Operator::F64x2Abs
|
||||
| Operator::F64x2Neg
|
||||
| Operator::F64x2Sqrt
|
||||
| Operator::F64x2Add
|
||||
| Operator::F64x2Sub
|
||||
| Operator::F64x2Mul
|
||||
| Operator::F64x2Div
|
||||
| Operator::F64x2Min
|
||||
| Operator::F64x2Max
|
||||
| Operator::I64x2TruncSF64x2Sat
|
||||
| Operator::I64x2TruncUF64x2Sat => F64X2,
|
||||
|
||||
_ => unimplemented!(
|
||||
"Currently only the SIMD instructions are translated to their return type: {:?}",
|
||||
operator
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
/// Some SIMD operations only operate on I8X16 in CLIF; this will convert them to that type by
|
||||
/// adding a raw_bitcast if necessary
|
||||
fn optionally_bitcast_vector(
|
||||
value: Value,
|
||||
needed_type: Type,
|
||||
builder: &mut FunctionBuilder,
|
||||
) -> Value {
|
||||
if builder.func.dfg.value_type(value) != needed_type {
|
||||
builder.ins().raw_bitcast(needed_type, value)
|
||||
} else {
|
||||
value
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ use std::io::prelude::*;
|
|||
use std::path::Path;
|
||||
use std::str::FromStr;
|
||||
use target_lexicon::triple;
|
||||
use wabt::wat2wasm;
|
||||
use wabt::{wat2wasm_with_features, Features};
|
||||
|
||||
#[test]
|
||||
fn testsuite() {
|
||||
|
@ -53,6 +53,8 @@ fn read_file(path: &Path) -> io::Result<Vec<u8>> {
|
|||
}
|
||||
|
||||
fn handle_module(path: &Path, flags: &Flags, return_mode: ReturnMode) {
|
||||
let mut features = Features::new();
|
||||
features.enable_all();
|
||||
let data = match path.extension() {
|
||||
None => {
|
||||
panic!("the file extension is not wasm or wat");
|
||||
|
@ -61,7 +63,7 @@ fn handle_module(path: &Path, flags: &Flags, return_mode: ReturnMode) {
|
|||
Some("wasm") => read_file(path).expect("error reading wasm file"),
|
||||
Some("wat") => {
|
||||
let wat = read_file(path).expect("error reading wat file");
|
||||
match wat2wasm(&wat) {
|
||||
match wat2wasm_with_features(&wat, features) {
|
||||
Ok(wasm) => wasm,
|
||||
Err(e) => {
|
||||
panic!("error converting wat to wasm: {:?}", e);
|
||||
|
|
Загрузка…
Ссылка в новой задаче