diff --git a/Cargo.lock b/Cargo.lock index 4ef8b80..ebd9a67 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,13 +2,19 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "anyhow" +version = "1.0.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ad32ce52e4161730f7098c077cd2ed6229b5804ccf99e5366be1ab72a98b4e1" + [[package]] name = "atty" version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ - "hermit-abi", + "hermit-abi 0.1.19", "libc", "winapi", ] @@ -19,100 +25,72 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" -[[package]] -name = "bincode" -version = "1.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" -dependencies = [ - "serde", -] - [[package]] name = "bitflags" version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - [[package]] name = "clap" -version = "3.1.8" +version = "3.2.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71c47df61d9e16dc010b55dba1952a57d8c215dbb533fd13cdd13369aac73b1c" +checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123" dependencies = [ "atty", "bitflags", - "indexmap", - "os_str_bytes", + "clap_lex", + "indexmap 1.9.3", "strsim", "termcolor", "textwrap", ] [[package]] -name = "ctor" -version = "0.1.22" +name = "clap_lex" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f877be4f7c9f246b183111634f75baa039715e3f46ce860677d3b19a69fb229c" +checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" dependencies = [ - "quote", - "syn", + "os_str_bytes", ] [[package]] -name = "dol" -version = "0.1.0" +name = "colored" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbf2150cce219b664a8a70df7a1f933836724b503f8a413af9365b4dcc4d90b8" dependencies = [ - "bincode", - "serde", - "thiserror", + "lazy_static", + "windows-sys", ] [[package]] -name = "either" -version = "1.6.1" +name = "deranged" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" - -[[package]] -name = "fixedbitset" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "279fb028e20b3c4c320317955b77c5e0c9701f05a1d309905d6fc702cdc5053e" - -[[package]] -name = "getrandom" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" dependencies = [ - "cfg-if", - "libc", - "wasi", + "powerfmt", ] [[package]] -name = "ghost" -version = "0.1.2" +name = "equivalent" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a5bcf1bbeab73aa4cf2fde60a846858dc036163c7c33bec309f8d17de785479" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "hashbrown" -version = "0.11.2" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "hashbrown" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" [[package]] name = "hermit-abi" @@ -124,181 +102,153 @@ dependencies = [ ] [[package]] -name = "indexmap" -version = "1.8.1" +name = "hermit-abi" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f647032dfaa1f8b6dc29bd3edb7bbef4861b8b8007ebb118d6db284fd59f6ee" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ "autocfg", - "hashbrown", + "hashbrown 0.12.3", ] [[package]] -name = "indoc" -version = "1.0.4" +name = "indexmap" +version = "2.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7906a9fababaeacb774f72410e497a1d18de916322e33797bb2cd29baa23c9e" +checksum = "7b0b929d511467233429c45a44ac1dcaa21ba0f5ba11e4879e6ed28ddb4f9df4" dependencies = [ - "unindent", + "equivalent", + "hashbrown 0.14.3", ] [[package]] -name = "instant" -version = "0.1.12" +name = "itoa" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" -dependencies = [ - "cfg-if", -] +checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" [[package]] -name = "inventory" -version = "0.2.2" +name = "lazy_static" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce6b5d8c669bfbad811d95ddd7a1c6cf9cfdbf2777e59928b6f3fa8ff54f72a0" -dependencies = [ - "ctor", - "ghost", -] - -[[package]] -name = "itertools" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3" -dependencies = [ - "either", -] +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.122" +version = "0.2.153" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec647867e2bf0772e28c8bcde4f0d19a9216916e890543b5a03ed8ef27b8f259" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" [[package]] -name = "linked-hash-map" -version = "0.5.4" +name = "log" +version = "0.4.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3" +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" [[package]] -name = "lock_api" -version = "0.4.7" +name = "num-conv" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53" -dependencies = [ - "autocfg", - "scopeguard", -] - -[[package]] -name = "memchr" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" [[package]] name = "num-traits" -version = "0.2.14" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" +checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" dependencies = [ "autocfg", ] [[package]] name = "num_cpus" -version = "1.13.1" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi", + "hermit-abi 0.3.9", "libc", ] [[package]] -name = "once_cell" -version = "1.10.0" +name = "num_threads" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9" +checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9" +dependencies = [ + "libc", +] [[package]] name = "os_str_bytes" -version = "6.0.0" +version = "6.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e22443d1643a904602595ba1cd8f7d896afe56d26712531c5ff73a15b2fbf64" -dependencies = [ - "memchr", -] +checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1" [[package]] -name = "parking_lot" +name = "phf" version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" +checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" dependencies = [ - "instant", - "lock_api", - "parking_lot_core", + "phf_shared", ] [[package]] -name = "parking_lot_core" -version = "0.8.5" +name = "phf_codegen" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216" +checksum = "e8d39688d359e6b34654d328e262234662d16cc0f60ec8dcbe5e718709342a5a" dependencies = [ - "cfg-if", - "instant", - "libc", - "redox_syscall", - "smallvec", - "winapi", + "phf_generator", + "phf_shared", ] [[package]] -name = "parse_int" -version = "0.6.0" +name = "phf_generator" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d695b79916a2c08bcff7be7647ab60d1402885265005a6658ffe6d763553c5a" +checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" dependencies = [ - "num-traits", + "phf_shared", + "rand", ] [[package]] -name = "petgraph" -version = "0.6.0" +name = "phf_shared" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a13a2fa9d0b63e5f22328828741e523766fff0ee9e779316902290dff3f824f" +checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" dependencies = [ - "fixedbitset", - "indexmap", + "siphasher", ] +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + [[package]] name = "ppc750cl" -version = "0.2.0" -dependencies = [ - "num-traits", - "serde", -] +version = "0.3.0" [[package]] -name = "ppc750cl-flow-graph" -version = "0.2.0" +name = "ppc750cl-asm" +version = "0.3.0" dependencies = [ - "clap", - "dol", - "itertools", - "parse_int", - "petgraph", - "ppc750cl", + "phf", ] [[package]] name = "ppc750cl-fuzz" -version = "0.2.0" +version = "0.3.0" dependencies = [ "clap", "num_cpus", @@ -307,113 +257,46 @@ dependencies = [ [[package]] name = "ppc750cl-genisa" -version = "0.2.0" +version = "0.3.0" dependencies = [ - "itertools", + "anyhow", + "log", + "num-traits", + "phf", + "phf_codegen", + "prettyplease", "proc-macro2", "quote", "serde", "serde_yaml", + "simple_logger", "syn", ] [[package]] -name = "ppc750cl-py" -version = "0.2.0" -dependencies = [ - "ppc750cl", - "pyo3", -] - -[[package]] -name = "ppc750cl-rand" -version = "0.2.0" -dependencies = [ - "ppc750cl", - "rand_core", - "sfmt", -] - -[[package]] -name = "ppv-lite86" +name = "prettyplease" version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" +checksum = "a41cf62165e97c7f814d2221421dbb9afcbcdb0a88068e5ea206e19951c2cbb5" +dependencies = [ + "proc-macro2", + "syn", +] [[package]] name = "proc-macro2" -version = "1.0.37" +version = "1.0.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec757218438d5fda206afc041538b2f6d889286160d649a86a24d37e1235afd1" +checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" dependencies = [ - "unicode-xid", -] - -[[package]] -name = "pyo3" -version = "0.16.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b3e99c4c3e790e4fc365b42b70c1f7801f42eadc4ea648fa327e6f5ca29f215" -dependencies = [ - "cfg-if", - "indoc", - "inventory", - "libc", - "parking_lot", - "pyo3-build-config", - "pyo3-ffi", - "pyo3-macros", - "unindent", -] - -[[package]] -name = "pyo3-build-config" -version = "0.16.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2486b96281859ff0a3929ba6467b13751627b974f7137362db38e2bed14b2094" -dependencies = [ - "once_cell", - "target-lexicon", -] - -[[package]] -name = "pyo3-ffi" -version = "0.16.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd9de1d94557751599f8bd321f10e6c1ef2801067acb58c91138deef2ae83a17" -dependencies = [ - "libc", - "pyo3-build-config", -] - -[[package]] -name = "pyo3-macros" -version = "0.16.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b9584049129b1cfb615243391a6345c726690271ae195ffd6aa3766177296aa" -dependencies = [ - "proc-macro2", - "pyo3-macros-backend", - "quote", - "syn", -] - -[[package]] -name = "pyo3-macros-backend" -version = "0.16.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c4717e6a55c51a9958eda1f5481ff7f62cccd21f45309c10e4731cb7198dbc" -dependencies = [ - "proc-macro2", - "quote", - "syn", + "unicode-ident", ] [[package]] name = "quote" -version = "1.0.17" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "632d02bff7f874a36f33ea8bb416cd484b90cc66c1194b1a1110d067a7013f58" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" dependencies = [ "proc-macro2", ] @@ -424,65 +307,35 @@ version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ - "libc", - "rand_chacha", - "rand_core", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", "rand_core", ] [[package]] name = "rand_core" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" -dependencies = [ - "getrandom", -] - -[[package]] -name = "redox_syscall" -version = "0.2.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42" -dependencies = [ - "bitflags", -] +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" [[package]] name = "ryu" -version = "1.0.9" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" - -[[package]] -name = "scopeguard" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" [[package]] name = "serde" -version = "1.0.136" +version = "1.0.197" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789" +checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.136" +version = "1.0.197" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9" +checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" dependencies = [ "proc-macro2", "quote", @@ -491,31 +344,34 @@ dependencies = [ [[package]] name = "serde_yaml" -version = "0.8.23" +version = "0.9.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a521f2940385c165a24ee286aa8599633d162077a54bdcae2a6fd5a7bfa7a0" +checksum = "8fd075d994154d4a774f95b51fb96bdc2832b0ea48425c92546073816cda1f2f" dependencies = [ - "indexmap", + "indexmap 2.2.5", + "itoa", "ryu", "serde", - "yaml-rust", + "unsafe-libyaml", ] [[package]] -name = "sfmt" -version = "0.7.0" +name = "simple_logger" +version = "4.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e389a3c1536438f85612667cd992dfb7169f60784252342278458e90d37c7565" +checksum = "8e7e46c8c90251d47d08b28b8a419ffb4aede0f87c2eea95e17d1d5bacbf3ef1" dependencies = [ - "rand", - "rand_core", + "colored", + "log", + "time", + "windows-sys", ] [[package]] -name = "smallvec" -version = "1.8.0" +name = "siphasher" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" [[package]] name = "strsim" @@ -525,73 +381,74 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" -version = "1.0.91" +version = "2.0.52" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b683b2b825c8eef438b77c36a06dc262294da3d5a5813fac20da149241dcd44d" +checksum = "b699d15b36d1f02c3e7c69f8ffef53de37aefae075d8488d4ba1a7788d574a07" dependencies = [ "proc-macro2", "quote", - "unicode-xid", + "unicode-ident", ] -[[package]] -name = "target-lexicon" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7fa7e55043acb85fca6b3c01485a2eeb6b69c5d21002e273c79e465f43b7ac1" - [[package]] name = "termcolor" -version = "1.1.3" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" dependencies = [ "winapi-util", ] [[package]] name = "textwrap" -version = "0.15.0" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb" +checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9" [[package]] -name = "thiserror" -version = "1.0.30" +name = "time" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417" +checksum = "c8248b6521bb14bc45b4067159b9b6ad792e2d6d754d6c41fb50e29fefe38749" dependencies = [ - "thiserror-impl", + "deranged", + "itoa", + "libc", + "num-conv", + "num_threads", + "powerfmt", + "serde", + "time-core", + "time-macros", ] [[package]] -name = "thiserror-impl" -version = "1.0.30" +name = "time-core" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" + +[[package]] +name = "time-macros" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ba3a3ef41e6672a2f0f001392bb5dcd3ff0a9992d618ca761a11c3121547774" dependencies = [ - "proc-macro2", - "quote", - "syn", + "num-conv", + "time-core", ] [[package]] -name = "unicode-xid" -version = "0.2.2" +name = "unicode-ident" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "unindent" -version = "0.1.8" +name = "unsafe-libyaml" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "514672a55d7380da379785a4d70ca8386c8883ff7eaae877be4d2081cebe73d8" - -[[package]] -name = "wasi" -version = "0.10.2+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" +checksum = "ab4c90930b95a82d00dc9e9ac071b4991924390d46cbd0dfe566148667605e4b" [[package]] name = "winapi" @@ -611,9 +468,9 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" dependencies = [ "winapi", ] @@ -625,10 +482,67 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] -name = "yaml-rust" -version = "0.4.5" +name = "windows-sys" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "linked-hash-map", + "windows-targets", ] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" diff --git a/Cargo.toml b/Cargo.toml index 92a14d8..3d0b3a8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,11 +1,11 @@ [workspace] +members = ["asm", "disasm", "fuzz", "genisa"] resolver = "2" -members = [ - "disasm", - "disasm-py", - "dol", - "fuzz", - "genisa", - "flow-graph", - "rand", -] + +[profile.release] +panic = "abort" +opt-level = "z" + +[profile.release-lto] +inherits = "release" +lto = "thin" diff --git a/LICENSE b/LICENSE deleted file mode 100644 index f288702..0000000 --- a/LICENSE +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. diff --git a/LICENSE-APACHE b/LICENSE-APACHE new file mode 100644 index 0000000..927b079 --- /dev/null +++ b/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 2024 Luke Street. + + 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. diff --git a/LICENSE-MIT b/LICENSE-MIT new file mode 100644 index 0000000..5a318fa --- /dev/null +++ b/LICENSE-MIT @@ -0,0 +1,21 @@ +MIT License + +Copyright 2024 Luke Street. + +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. diff --git a/README.md b/README.md index a56495c..af13a20 100644 --- a/README.md +++ b/README.md @@ -5,35 +5,10 @@ Rust tools for working with the PowerPC 750CL family of processors. ### Rust crates ```shell -rustup components add rustfmt cargo run --package ppc750cl-genisa cargo build --release ``` -### Python module - -```shell -python -m venv env -source ./env/bin/activate -pip install maturin -maturin build -m ./disasm-py/Cargo.toml -``` - -Install module in dev env - -``` -maturin develop -m ./disasm-py/Cargo.toml -python ->>> import ppc750cl ->>> ins = ppc750cl.Ins(addr=0x80006969, code=0x10400420) ->>> str(ins) -'ps_merge00 f2, f0, f0' ->>> ins.fields() -[('frD', 2), ('frA', 0), ('frB', 0)] ->>> ins.frD -2 -``` - ### Instruction Set For those unfamiliar with PowerPC, here are some basics. @@ -48,7 +23,7 @@ For those unfamiliar with PowerPC, here are some basics. The file [isa.yaml](./isa.yaml) contains a full definition of the PowerPC 750CL instruction set. -It powers the disassembler, assembler, and Rust/Python bindings code analysis tools. +It powers the disassembler and assembler. Similarly to LLVM TableGen, the program `ppc750cl-genisa` generates a Rust file implementing an instruction decoder. @@ -57,10 +32,11 @@ Similarly to LLVM TableGen, the program `ppc750cl-genisa` generates a Rust file - This project does not use `unsafe` Rust code outside of testing utils. - The disassembler has been fuzzed over all ~4.29 billion possible instructions (via `ppc750cl-fuzz`). - It is safe to run the disassembler over untrusted byte arrays. -- However no guarantees on correctness are made (yet). Expect bugs. +- However, no guarantees on correctness are made (yet). Expect bugs. ### Performance -- Performance isn't great but acceptable. -- Disassembling & printing: 600k insn/s (2.4 MB/s) -- Disassembling only: 6M insn/s (24 MB/s) +With a single thread on Ryzen 9 3900X: + +- Disassembling & printing: ~5M insn/s (~20 MB/s) +- Disassembling only: ~50M insn/s (~200 MB/s) diff --git a/analysis/cfa.md b/analysis/cfa.md deleted file mode 100644 index b0f4741..0000000 --- a/analysis/cfa.md +++ /dev/null @@ -1,174 +0,0 @@ ---- -date: 2022-04-10 -status: draft ---- - -# Control-flow analysis - -CFA analyses the entire `.text` section with linear complexity. - -It has the following goals: -- Detect function boundaries -- Create the control-flow graph of each function - -## Pass 1: Find control-flow intrinsics - -Input: -- `.text` section - -Output: -- Locations of compiler intrinsics - -Rules - -*savegpr/restgpr detection* (CodeWarrior only) - -Find the following instructions in `.text` - -```asm -_save_gpr: -stw r14, -0x48(r11) -stw r15, -0x44(r11) -stw r16, -0x40(r11) -stw r17, -0x3c(r11) -stw r18, -0x38(r11) -stw r19, -0x34(r11) -stw r20, -0x30(r11) -stw r21, -0x2c(r11) -stw r22, -0x28(r11) -stw r23, -0x24(r11) -stw r24, -0x20(r11) -stw r25, -0x1c(r11) -stw r26, -0x18(r11) -stw r27, -0x14(r11) -stw r28, -0x10(r11) -stw r29, -0xc(r11) -stw r30, -0x8(r11) -stw r31, -0x4(r11) -blr - -_load_gpr: -lwz r14, -0x48(r11) -lwz r15, -0x44(r11) -lwz r16, -0x40(r11) -lwz r17, -0x3c(r11) -lwz r18, -0x38(r11) -lwz r19, -0x34(r11) -lwz r20, -0x30(r11) -lwz r21, -0x2c(r11) -lwz r22, -0x28(r11) -lwz r23, -0x24(r11) -lwz r24, -0x20(r11) -lwz r25, -0x1c(r11) -lwz r26, -0x18(r11) -lwz r27, -0x14(r11) -lwz r28, -0x10(r11) -lwz r29, -0xc(r11) -lwz r30, -0x8(r11) -lwz r31, -0x4(r11) -blr -``` - -## Pass 2: Branch analysis - -Input: -- `.text` section - -Output: -- Slices (cuts) from which basic blocks can be derived -- Forward edges between basic blocks -- Initial set of function boundaries - -#### Branch instruction hints - -- Iterate over all branch opcodes (b, bc, bcctr, bclr) -- Assume that branches with link register save … - - point to the start of another function; - - eventually return back to the call site. -- Assume that branches without link register save are … - - tail calls if their target precedes the function start of the call site; - - probably jumps to basic blocks within the function otherwise (might be wrong) -- Skip indirect local branches (bcctr, bclr) for now. - -#### Stack frame detection (CodeWarrior only) - -Detect patterns matching stack frames. They might be reordered due to instruction scheduling. - -Since CodeWarrior will only emit one function epilogue and prologue per function, -we can use this hint (if present) to reliably detect function bounds. - -- On function entry point: - - Execute instructions up to next branch - - Derive stack frame from changes in machine state - - If the stack changed, we found an epilog -- When a `blr` (function return) is encountered: - - Execute instructions in basic block of `blr` - - If stack-related machine state got reverted, assume this BB to contain the prolog - -Example 0x80045de0 from RMCP01 (savegpr/restgpr sled): - -```asm -# Stack -# +0x04..+0x08: ret addr to caller -# 0x00..+0x04: caller backchain <- caller r1 -# -0x30.. 0x00: callee saved gprs <- callee r11 -# -0x68..-0x30: callee stack -# -0x6c..-0x68: ret addr to callee -# -0x70..-0x6c: callee backchain <- callee r1 - -_alloc_stack_frame: -stwu r1, -0x70(r1) # store callee backchain & alloc stack frame -mflr r0 -… -stw r0, 0x74(r1) # store ret addr to caller -… -la r11, 0x40(r1) # load ptr to callee saved gprs -bl _savegpr_22 # save gprs -mr r31, r1 - -… - -_free_stack_frame: -mr r10, r31 -la r11, 0x40(r10) # load ptr to callee saved gprs -bl _restgpr_22 # restore gprs -lwz r10, 0x0(r1) # load ptr to caller stack frame -lwz r0, 0x4(r10) # load ret addr to caller -mr r1, r10 # free stack frame -mtlr r0 -blr # return to caller -``` - -Example 0x80228490 from RMCP01 (stmw/lmw): - -```asm -# Stack -# +0x04..+0x08: ret addr to caller -# 0x00..+0x04: caller backchain <- caller r1 -# -0x30.. 0x00: callee saved gprs <- callee r11 -# -0x38..-0x30: callee stack -# -0x3c..-0x38: ret addr to callee -# -0x40..-0x3c: callee backchain <- callee r1 - -_alloc_stack_frame: -stwu r1, -0x40(r1) # store callee backchain & alloc stack frame -mflr r0 -stw r0, 0x44(r1) # store ret addr to caller -stmw r20, -0x30(r1) # save gprs - -… - -_free_stack_frame: -lmw r20, -0x30(r1) # restore gprs -lwz r0, 0x44(r1) # load ret addr to caller -mtlr r0 -la r1, 0x40(r1) # free stack frame -blr # return to caller -``` - -## TODO - -Add the following rules: -- follow indirect local branches -- destructor detection -- vtable detection diff --git a/asm/Cargo.toml b/asm/Cargo.toml new file mode 100644 index 0000000..6425aea --- /dev/null +++ b/asm/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "ppc750cl-asm" +version = "0.3.0" +edition = "2021" +authors = ["Luke Street "] +license = "MIT OR Apache-2.0" +description = "Assembler for PowerPC 750CL" +keywords = ["powerpc", "wii", "gamecube"] +repository = "https://github.com/encounter/ppc750cl" + +[features] +default = ["std"] +std = [] + +[dependencies] +phf = "0.11" diff --git a/asm/src/generated.rs b/asm/src/generated.rs new file mode 100644 index 0000000..61a4303 --- /dev/null +++ b/asm/src/generated.rs @@ -0,0 +1,4618 @@ +#![allow(unused)] +#![cfg_attr(rustfmt, rustfmt_skip)] +use crate::types::*; +pub type Arguments = [Argument; 5]; +fn gen_add(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x7c000214 | modifiers; + // rD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // rA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // rB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_addc(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x7c000014 | modifiers; + // rD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // rA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // rB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_adde(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x7c000114 | modifiers; + // rD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // rA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // rB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_addi(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x38000000 | modifiers; + // rD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // rA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // simm + code |= parse_signed(args, 2, -0x8000, 0x8000)? as u32 & 0xffff; + Ok(code) +} +fn gen_addic(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x30000000 | modifiers; + // rD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // rA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // simm + code |= parse_signed(args, 2, -0x8000, 0x8000)? as u32 & 0xffff; + Ok(code) +} +fn gen_addic_(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x34000000 | modifiers; + // rD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // rA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // simm + code |= parse_signed(args, 2, -0x8000, 0x8000)? as u32 & 0xffff; + Ok(code) +} +fn gen_addis(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x3c000000 | modifiers; + // rD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // rA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // uimm + code |= parse_unsigned(args, 2, 0x0, 0xffff)? & 0xffff; + Ok(code) +} +fn gen_addme(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 2)?; + let mut code = 0x7c0001d4 | modifiers; + // rD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // rA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + Ok(code) +} +fn gen_addze(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 2)?; + let mut code = 0x7c000194 | modifiers; + // rD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // rA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + Ok(code) +} +fn gen_and(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x7c000038 | modifiers; + // rA + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 16; + // rS + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 21; + // rB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_andc(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x7c000078 | modifiers; + // rA + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 16; + // rS + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 21; + // rB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_andi_(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x70000000 | modifiers; + // rA + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 16; + // rS + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 21; + // uimm + code |= parse_unsigned(args, 2, 0x0, 0xffff)? & 0xffff; + Ok(code) +} +fn gen_andis_(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x74000000 | modifiers; + // rA + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 16; + // rS + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 21; + // uimm + code |= parse_unsigned(args, 2, 0x0, 0xffff)? & 0xffff; + Ok(code) +} +fn gen_b(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 1)?; + let mut code = 0x48000000 | modifiers; + // LI + code |= parse_signed(args, 0, -0x2000000, 0x2000000)? as u32 & 0x3fffffc; + Ok(code) +} +fn gen_bc(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x40000000 | modifiers; + // BO + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // BI + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // BD + code |= parse_signed(args, 2, -0x8000, 0x8000)? as u32 & 0xfffc; + Ok(code) +} +fn gen_bcctr(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 2)?; + let mut code = 0x4c000420 | modifiers; + // BO + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // BI + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + Ok(code) +} +fn gen_bclr(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 2)?; + let mut code = 0x4c000020 | modifiers; + // BO + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // BI + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + Ok(code) +} +fn gen_cmp(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 4)?; + let mut code = 0x7c000000 | modifiers; + // crfD + code |= (parse_unsigned(args, 0, 0x0, 0x7)? & 0x7) << 23; + // L + code |= (parse_unsigned(args, 1, 0x0, 0x1)? & 0x1) << 21; + // rA + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 16; + // rB + code |= (parse_unsigned(args, 3, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_cmpi(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 4)?; + let mut code = 0x2c000000 | modifiers; + // crfD + code |= (parse_unsigned(args, 0, 0x0, 0x7)? & 0x7) << 23; + // L + code |= (parse_unsigned(args, 1, 0x0, 0x1)? & 0x1) << 21; + // rA + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 16; + // simm + code |= parse_signed(args, 3, -0x8000, 0x8000)? as u32 & 0xffff; + Ok(code) +} +fn gen_cmpl(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 4)?; + let mut code = 0x7c000040 | modifiers; + // crfD + code |= (parse_unsigned(args, 0, 0x0, 0x7)? & 0x7) << 23; + // L + code |= (parse_unsigned(args, 1, 0x0, 0x1)? & 0x1) << 21; + // rA + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 16; + // rB + code |= (parse_unsigned(args, 3, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_cmpli(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 4)?; + let mut code = 0x28000000 | modifiers; + // crfD + code |= (parse_unsigned(args, 0, 0x0, 0x7)? & 0x7) << 23; + // L + code |= (parse_unsigned(args, 1, 0x0, 0x1)? & 0x1) << 21; + // rA + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 16; + // uimm + code |= parse_unsigned(args, 3, 0x0, 0xffff)? & 0xffff; + Ok(code) +} +fn gen_cntlzw(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 2)?; + let mut code = 0x7c000034 | modifiers; + // rA + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 16; + // rS + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 21; + Ok(code) +} +fn gen_crand(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x4c000202 | modifiers; + // crbD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // crbA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // crbB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_crandc(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x4c000102 | modifiers; + // crbD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // crbA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // crbB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_creqv(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x4c000242 | modifiers; + // crbD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // crbA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // crbB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_crnand(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x4c0001c2 | modifiers; + // crbD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // crbA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // crbB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_crnor(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x4c000042 | modifiers; + // crbD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // crbA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // crbB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_cror(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x4c000382 | modifiers; + // crbD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // crbA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // crbB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_crorc(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x4c000342 | modifiers; + // crbD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // crbA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // crbB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_crxor(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x4c000182 | modifiers; + // crbD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // crbA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // crbB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_dcbf(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 2)?; + let mut code = 0x7c0000ac | modifiers; + // rA + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 16; + // rB + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_dcbi(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 2)?; + let mut code = 0x7c0003ac | modifiers; + // rA + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 16; + // rB + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_dcbst(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 2)?; + let mut code = 0x7c00006c | modifiers; + // rA + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 16; + // rB + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_dcbt(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 2)?; + let mut code = 0x7c00022c | modifiers; + // rA + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 16; + // rB + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_dcbtst(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 2)?; + let mut code = 0x7c0001ec | modifiers; + // rA + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 16; + // rB + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_dcbz(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 2)?; + let mut code = 0x7c0007ec | modifiers; + // rA + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 16; + // rB + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_dcbz_l(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 2)?; + let mut code = 0x100007ec | modifiers; + // rA + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 16; + // rB + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_divw(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x7c0003d6 | modifiers; + // rD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // rA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // rB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_divwu(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x7c000396 | modifiers; + // rD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // rA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // rB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_eciwx(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x7c00026c | modifiers; + // rD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // rA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // rB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_ecowx(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x7c00036c | modifiers; + // rS + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // rA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // rB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_eieio(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 0)?; + let mut code = 0x7c0006ac | modifiers; + Ok(code) +} +fn gen_eqv(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x7c000238 | modifiers; + // rA + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 16; + // rS + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 21; + // rB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_extsb(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 2)?; + let mut code = 0x7c000774 | modifiers; + // rA + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 16; + // rS + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 21; + Ok(code) +} +fn gen_extsh(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 2)?; + let mut code = 0x7c000734 | modifiers; + // rA + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 16; + // rS + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 21; + Ok(code) +} +fn gen_fabs(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 2)?; + let mut code = 0xfc000210 | modifiers; + // frD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // frB + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_fadd(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0xfc00002a | modifiers; + // frD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // frA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // frB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_fadds(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0xec00002a | modifiers; + // frD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // frA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // frB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_fcmpo(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0xfc000040 | modifiers; + // crfD + code |= (parse_unsigned(args, 0, 0x0, 0x7)? & 0x7) << 23; + // frA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // frB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_fcmpu(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0xfc000000 | modifiers; + // crfD + code |= (parse_unsigned(args, 0, 0x0, 0x7)? & 0x7) << 23; + // frA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // frB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_fctiw(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 2)?; + let mut code = 0xfc00001c | modifiers; + // frD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // frB + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_fctiwz(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 2)?; + let mut code = 0xfc00001e | modifiers; + // frD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // frB + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_fdiv(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0xfc000024 | modifiers; + // frD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // frA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // frB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_fdivs(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0xec000024 | modifiers; + // frD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // frA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // frB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_fmadd(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 4)?; + let mut code = 0xfc00003a | modifiers; + // frD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // frA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // frC + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 6; + // frB + code |= (parse_unsigned(args, 3, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_fmadds(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 4)?; + let mut code = 0xec00003a | modifiers; + // frD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // frA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // frC + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 6; + // frB + code |= (parse_unsigned(args, 3, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_fmr(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 2)?; + let mut code = 0xfc000090 | modifiers; + // frD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // frB + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_fmsub(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 4)?; + let mut code = 0xfc000038 | modifiers; + // frD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // frA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // frC + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 6; + // frB + code |= (parse_unsigned(args, 3, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_fmsubs(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 4)?; + let mut code = 0xec000038 | modifiers; + // frD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // frA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // frC + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 6; + // frB + code |= (parse_unsigned(args, 3, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_fmul(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0xfc000032 | modifiers; + // frD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // frA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // frC + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 6; + Ok(code) +} +fn gen_fmuls(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0xec000032 | modifiers; + // frD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // frA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // frC + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 6; + Ok(code) +} +fn gen_fnabs(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 2)?; + let mut code = 0xfc000110 | modifiers; + // frD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // frB + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_fneg(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 2)?; + let mut code = 0xfc000050 | modifiers; + // frD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // frB + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_fnmadd(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 4)?; + let mut code = 0xfc00003e | modifiers; + // frD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // frA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // frC + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 6; + // frB + code |= (parse_unsigned(args, 3, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_fnmadds(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 4)?; + let mut code = 0xec00003e | modifiers; + // frD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // frA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // frC + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 6; + // frB + code |= (parse_unsigned(args, 3, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_fnmsub(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 4)?; + let mut code = 0xfc00003c | modifiers; + // frD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // frA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // frC + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 6; + // frB + code |= (parse_unsigned(args, 3, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_fnmsubs(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 4)?; + let mut code = 0xec00003c | modifiers; + // frD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // frA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // frC + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 6; + // frB + code |= (parse_unsigned(args, 3, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_fres(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 2)?; + let mut code = 0xec000030 | modifiers; + // frD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // frB + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_frsp(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 2)?; + let mut code = 0xfc000018 | modifiers; + // frD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // frB + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_frsqrte(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 2)?; + let mut code = 0xfc000034 | modifiers; + // frD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // frB + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_fsel(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 4)?; + let mut code = 0xfc00002e | modifiers; + // frD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // frA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // frC + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 6; + // frB + code |= (parse_unsigned(args, 3, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_fsub(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0xfc000028 | modifiers; + // frD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // frA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // frB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_fsubs(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0xec000028 | modifiers; + // frD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // frA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // frB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_icbi(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 2)?; + let mut code = 0x7c0007ac | modifiers; + // rA + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 16; + // rB + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_isync(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 0)?; + let mut code = 0x4c00012c | modifiers; + Ok(code) +} +fn gen_lbz(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x88000000 | modifiers; + // rD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // offset + code |= parse_signed(args, 1, -0x8000, 0x8000)? as u32 & 0xffff; + // rA + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 16; + Ok(code) +} +fn gen_lbzu(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x8c000000 | modifiers; + // rD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // offset + code |= parse_signed(args, 1, -0x8000, 0x8000)? as u32 & 0xffff; + // rA + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 16; + Ok(code) +} +fn gen_lbzux(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x7c0000ee | modifiers; + // rD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // rA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // rB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_lbzx(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x7c0000ae | modifiers; + // rD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // rA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // rB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_lfd(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0xc8000000 | modifiers; + // frD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // offset + code |= parse_signed(args, 1, -0x8000, 0x8000)? as u32 & 0xffff; + // rA + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 16; + Ok(code) +} +fn gen_lfdu(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0xcc000000 | modifiers; + // frD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // offset + code |= parse_signed(args, 1, -0x8000, 0x8000)? as u32 & 0xffff; + // rA + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 16; + Ok(code) +} +fn gen_lfdux(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x7c0004ee | modifiers; + // frD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // rA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // rB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_lfdx(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x7c0004ae | modifiers; + // frD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // rA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // rB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_lfs(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0xc0000000 | modifiers; + // frD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // offset + code |= parse_signed(args, 1, -0x8000, 0x8000)? as u32 & 0xffff; + // rA + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 16; + Ok(code) +} +fn gen_lfsu(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0xc4000000 | modifiers; + // frD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // offset + code |= parse_signed(args, 1, -0x8000, 0x8000)? as u32 & 0xffff; + // rA + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 16; + Ok(code) +} +fn gen_lfsux(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x7c00046e | modifiers; + // frD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // rA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // rB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_lfsx(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x7c00042e | modifiers; + // frD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // rA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // rB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_lha(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0xa8000000 | modifiers; + // rD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // offset + code |= parse_signed(args, 1, -0x8000, 0x8000)? as u32 & 0xffff; + // rA + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 16; + Ok(code) +} +fn gen_lhau(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0xac000000 | modifiers; + // rD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // offset + code |= parse_signed(args, 1, -0x8000, 0x8000)? as u32 & 0xffff; + // rA + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 16; + Ok(code) +} +fn gen_lhaux(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x7c0002ee | modifiers; + // rD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // rA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // rB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_lhax(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x7c0002ae | modifiers; + // rD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // rA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // rB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_lhbrx(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x7c00062c | modifiers; + // rD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // rA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // rB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_lhz(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0xa0000000 | modifiers; + // rD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // offset + code |= parse_signed(args, 1, -0x8000, 0x8000)? as u32 & 0xffff; + // rA + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 16; + Ok(code) +} +fn gen_lhzu(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0xa4000000 | modifiers; + // rD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // offset + code |= parse_signed(args, 1, -0x8000, 0x8000)? as u32 & 0xffff; + // rA + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 16; + Ok(code) +} +fn gen_lhzux(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x7c00026e | modifiers; + // rD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // rA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // rB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_lhzx(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x7c00022e | modifiers; + // rD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // rA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // rB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_lmw(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0xb8000000 | modifiers; + // rD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // offset + code |= parse_signed(args, 1, -0x8000, 0x8000)? as u32 & 0xffff; + // rA + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 16; + Ok(code) +} +fn gen_lswi(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x7c0004aa | modifiers; + // rD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // rA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // NB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_lswx(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x7c00042a | modifiers; + // rD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // rA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // rB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_lwarx(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x7c000028 | modifiers; + // rD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // rA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // rB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_lwbrx(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x7c00042c | modifiers; + // rD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // rA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // rB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_lwz(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x80000000 | modifiers; + // rD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // offset + code |= parse_signed(args, 1, -0x8000, 0x8000)? as u32 & 0xffff; + // rA + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 16; + Ok(code) +} +fn gen_lwzu(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x84000000 | modifiers; + // rD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // offset + code |= parse_signed(args, 1, -0x8000, 0x8000)? as u32 & 0xffff; + // rA + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 16; + Ok(code) +} +fn gen_lwzux(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x7c00006e | modifiers; + // rD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // rA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // rB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_lwzx(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x7c00002e | modifiers; + // rD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // rA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // rB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_mcrf(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 2)?; + let mut code = 0x4c000000 | modifiers; + // crfD + code |= (parse_unsigned(args, 0, 0x0, 0x7)? & 0x7) << 23; + // crfS + code |= (parse_unsigned(args, 1, 0x0, 0x7)? & 0x7) << 18; + Ok(code) +} +fn gen_mcrfs(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 2)?; + let mut code = 0xfc000080 | modifiers; + // crfD + code |= (parse_unsigned(args, 0, 0x0, 0x7)? & 0x7) << 23; + // crfS + code |= (parse_unsigned(args, 1, 0x0, 0x7)? & 0x7) << 18; + Ok(code) +} +fn gen_mcrxr(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 1)?; + let mut code = 0x7c000400 | modifiers; + // crfD + code |= (parse_unsigned(args, 0, 0x0, 0x7)? & 0x7) << 23; + Ok(code) +} +fn gen_mfcr(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 1)?; + let mut code = 0x7c000026 | modifiers; + // rD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + Ok(code) +} +fn gen_mffs(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 1)?; + let mut code = 0xfc00048e | modifiers; + // frD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + Ok(code) +} +fn gen_mfmsr(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 1)?; + let mut code = 0x7c0000a6 | modifiers; + // rD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + Ok(code) +} +fn gen_mfspr(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 2)?; + let mut code = 0x7c0002a6 | modifiers; + // rD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // spr + code + |= { + let mut value = parse_unsigned(args, 1, 0x0, 0x3ff)?; + value = ((value & 0b11111_00000) >> 5) | ((value & 0b00000_11111) << 5); + (value & 0x3ff) << 11 + }; + Ok(code) +} +fn gen_mfsr(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 2)?; + let mut code = 0x7c0004a6 | modifiers; + // rD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // sr + code |= (parse_unsigned(args, 1, 0x0, 0xf)? & 0xf) << 16; + Ok(code) +} +fn gen_mfsrin(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 2)?; + let mut code = 0x7c000526 | modifiers; + // rD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // rB + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_mftb(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 2)?; + let mut code = 0x7c0002e6 | modifiers; + // rD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // tbr + code + |= { + let mut value = parse_unsigned(args, 1, 0x0, 0x3ff)?; + value = ((value & 0b11111_00000) >> 5) | ((value & 0b00000_11111) << 5); + (value & 0x3ff) << 11 + }; + Ok(code) +} +fn gen_mtcrf(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 2)?; + let mut code = 0x7c000120 | modifiers; + // crm + code |= (parse_unsigned(args, 0, 0x0, 0xff)? & 0xff) << 12; + // rS + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 21; + Ok(code) +} +fn gen_mtfsb0(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 1)?; + let mut code = 0xfc00008c | modifiers; + // crbD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + Ok(code) +} +fn gen_mtfsb1(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 1)?; + let mut code = 0xfc00004c | modifiers; + // crbD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + Ok(code) +} +fn gen_mtfsf(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 2)?; + let mut code = 0xfc00058e | modifiers; + // mtfsf_FM + code |= (parse_unsigned(args, 0, 0x0, 0xff)? & 0xff) << 17; + // frB + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_mtfsfi(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 2)?; + let mut code = 0xfc00010c | modifiers; + // crfD + code |= (parse_unsigned(args, 0, 0x0, 0x7)? & 0x7) << 23; + // mtfsf_IMM + code |= (parse_unsigned(args, 1, 0x0, 0xf)? & 0xf) << 12; + Ok(code) +} +fn gen_mtmsr(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 1)?; + let mut code = 0x7c000124 | modifiers; + // rS + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + Ok(code) +} +fn gen_mtspr(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 2)?; + let mut code = 0x7c0003a6 | modifiers; + // spr + code + |= { + let mut value = parse_unsigned(args, 0, 0x0, 0x3ff)?; + value = ((value & 0b11111_00000) >> 5) | ((value & 0b00000_11111) << 5); + (value & 0x3ff) << 11 + }; + // rS + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 21; + Ok(code) +} +fn gen_mtsr(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 2)?; + let mut code = 0x7c0001a4 | modifiers; + // sr + code |= (parse_unsigned(args, 0, 0x0, 0xf)? & 0xf) << 16; + // rS + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 21; + Ok(code) +} +fn gen_mtsrin(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 2)?; + let mut code = 0x7c0001e4 | modifiers; + // rS + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // rB + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_mulhw(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x7c000096 | modifiers; + // rD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // rA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // rB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_mulhwu(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x7c000016 | modifiers; + // rD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // rA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // rB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_mulli(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x1c000000 | modifiers; + // rD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // rA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // simm + code |= parse_signed(args, 2, -0x8000, 0x8000)? as u32 & 0xffff; + Ok(code) +} +fn gen_mullw(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x7c0001d6 | modifiers; + // rD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // rA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // rB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_nand(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x7c0003b8 | modifiers; + // rA + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 16; + // rS + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 21; + // rB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_neg(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 2)?; + let mut code = 0x7c0000d0 | modifiers; + // rD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // rA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + Ok(code) +} +fn gen_nor(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x7c0000f8 | modifiers; + // rA + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 16; + // rS + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 21; + // rB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_or(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x7c000378 | modifiers; + // rA + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 16; + // rS + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 21; + // rB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_orc(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x7c000338 | modifiers; + // rA + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 16; + // rS + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 21; + // rB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_ori(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x60000000 | modifiers; + // rA + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 16; + // rS + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 21; + // uimm + code |= parse_unsigned(args, 2, 0x0, 0xffff)? & 0xffff; + Ok(code) +} +fn gen_oris(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x64000000 | modifiers; + // rA + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 16; + // rS + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 21; + // uimm + code |= parse_unsigned(args, 2, 0x0, 0xffff)? & 0xffff; + Ok(code) +} +fn gen_psq_l(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 5)?; + let mut code = 0xe0000000 | modifiers; + // frD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // ps_offset + code |= parse_signed(args, 1, -0x800, 0x800)? as u32 & 0xfff; + // rA + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 16; + // ps_W + code |= (parse_unsigned(args, 3, 0x0, 0x1)? & 0x1) << 15; + // ps_I + code |= (parse_unsigned(args, 4, 0x0, 0x7)? & 0x7) << 12; + Ok(code) +} +fn gen_psq_lu(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 5)?; + let mut code = 0xe4000000 | modifiers; + // frD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // ps_offset + code |= parse_signed(args, 1, -0x800, 0x800)? as u32 & 0xfff; + // rA + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 16; + // ps_W + code |= (parse_unsigned(args, 3, 0x0, 0x1)? & 0x1) << 15; + // ps_I + code |= (parse_unsigned(args, 4, 0x0, 0x7)? & 0x7) << 12; + Ok(code) +} +fn gen_psq_lux(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 5)?; + let mut code = 0x1000004c | modifiers; + // frD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // rA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // rB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + // ps_WX + code |= (parse_unsigned(args, 3, 0x0, 0x1)? & 0x1) << 10; + // ps_IX + code |= (parse_unsigned(args, 4, 0x0, 0x7)? & 0x7) << 7; + Ok(code) +} +fn gen_psq_lx(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 5)?; + let mut code = 0x1000000c | modifiers; + // frD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // rA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // rB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + // ps_WX + code |= (parse_unsigned(args, 3, 0x0, 0x1)? & 0x1) << 10; + // ps_IX + code |= (parse_unsigned(args, 4, 0x0, 0x7)? & 0x7) << 7; + Ok(code) +} +fn gen_psq_st(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 5)?; + let mut code = 0xf0000000 | modifiers; + // frS + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // ps_offset + code |= parse_signed(args, 1, -0x800, 0x800)? as u32 & 0xfff; + // rA + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 16; + // ps_W + code |= (parse_unsigned(args, 3, 0x0, 0x1)? & 0x1) << 15; + // ps_I + code |= (parse_unsigned(args, 4, 0x0, 0x7)? & 0x7) << 12; + Ok(code) +} +fn gen_psq_stu(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 5)?; + let mut code = 0xf4000000 | modifiers; + // frS + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // ps_offset + code |= parse_signed(args, 1, -0x800, 0x800)? as u32 & 0xfff; + // rA + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 16; + // ps_W + code |= (parse_unsigned(args, 3, 0x0, 0x1)? & 0x1) << 15; + // ps_I + code |= (parse_unsigned(args, 4, 0x0, 0x7)? & 0x7) << 12; + Ok(code) +} +fn gen_psq_stux(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 5)?; + let mut code = 0x1000004e | modifiers; + // frS + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // rA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // rB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + // ps_WX + code |= (parse_unsigned(args, 3, 0x0, 0x1)? & 0x1) << 10; + // ps_IX + code |= (parse_unsigned(args, 4, 0x0, 0x7)? & 0x7) << 7; + Ok(code) +} +fn gen_psq_stx(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 5)?; + let mut code = 0x1000000e | modifiers; + // frS + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // rA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // rB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + // ps_WX + code |= (parse_unsigned(args, 3, 0x0, 0x1)? & 0x1) << 10; + // ps_IX + code |= (parse_unsigned(args, 4, 0x0, 0x7)? & 0x7) << 7; + Ok(code) +} +fn gen_ps_abs(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 2)?; + let mut code = 0x10000210 | modifiers; + // frD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // frB + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_ps_add(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x1000002a | modifiers; + // frD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // frA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // frB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_ps_cmpo0(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x10000040 | modifiers; + // crfD + code |= (parse_unsigned(args, 0, 0x0, 0x7)? & 0x7) << 23; + // frA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // frB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_ps_cmpo1(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x100000c0 | modifiers; + // crfD + code |= (parse_unsigned(args, 0, 0x0, 0x7)? & 0x7) << 23; + // frA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // frB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_ps_cmpu0(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x10000000 | modifiers; + // crfD + code |= (parse_unsigned(args, 0, 0x0, 0x7)? & 0x7) << 23; + // frA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // frB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_ps_cmpu1(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x10000080 | modifiers; + // crfD + code |= (parse_unsigned(args, 0, 0x0, 0x7)? & 0x7) << 23; + // frA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // frB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_ps_div(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x10000024 | modifiers; + // frD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // frA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // frB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_ps_madd(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 4)?; + let mut code = 0x1000003a | modifiers; + // frD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // frA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // frC + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 6; + // frB + code |= (parse_unsigned(args, 3, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_ps_madds0(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 4)?; + let mut code = 0x1000001c | modifiers; + // frD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // frA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // frC + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 6; + // frB + code |= (parse_unsigned(args, 3, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_ps_madds1(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 4)?; + let mut code = 0x1000001e | modifiers; + // frD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // frA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // frC + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 6; + // frB + code |= (parse_unsigned(args, 3, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_ps_merge00(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x10000420 | modifiers; + // frD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // frA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // frB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_ps_merge01(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x10000460 | modifiers; + // frD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // frA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // frB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_ps_merge10(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x100004a0 | modifiers; + // frD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // frA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // frB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_ps_merge11(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x100004e0 | modifiers; + // frD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // frA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // frB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_ps_mr(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 2)?; + let mut code = 0x10000090 | modifiers; + // frD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // frB + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_ps_msub(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 4)?; + let mut code = 0x10000038 | modifiers; + // frD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // frA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // frC + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 6; + // frB + code |= (parse_unsigned(args, 3, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_ps_mul(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x10000032 | modifiers; + // frD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // frA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // frC + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 6; + Ok(code) +} +fn gen_ps_muls0(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x10000018 | modifiers; + // frD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // frA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // frC + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 6; + Ok(code) +} +fn gen_ps_muls1(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x1000001a | modifiers; + // frD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // frA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // frC + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 6; + Ok(code) +} +fn gen_ps_nabs(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 2)?; + let mut code = 0x10000110 | modifiers; + // frD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // frB + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_ps_neg(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 2)?; + let mut code = 0x10000050 | modifiers; + // frD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // frB + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_ps_nmadd(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 4)?; + let mut code = 0x1000003e | modifiers; + // frD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // frA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // frC + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 6; + // frB + code |= (parse_unsigned(args, 3, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_ps_nmsub(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 4)?; + let mut code = 0x1000003c | modifiers; + // frD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // frA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // frC + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 6; + // frB + code |= (parse_unsigned(args, 3, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_ps_res(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 2)?; + let mut code = 0x10000030 | modifiers; + // frD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // frB + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_ps_rsqrte(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 2)?; + let mut code = 0x10000034 | modifiers; + // frD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // frB + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_ps_sel(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 4)?; + let mut code = 0x1000002e | modifiers; + // frD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // frA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // frC + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 6; + // frB + code |= (parse_unsigned(args, 3, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_ps_sub(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x10000028 | modifiers; + // frD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // frA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // frB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_ps_sum0(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 4)?; + let mut code = 0x10000014 | modifiers; + // frD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // frA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // frC + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 6; + // frB + code |= (parse_unsigned(args, 3, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_ps_sum1(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 4)?; + let mut code = 0x10000016 | modifiers; + // frD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // frA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // frC + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 6; + // frB + code |= (parse_unsigned(args, 3, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_rfi(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 0)?; + let mut code = 0x4c000064 | modifiers; + Ok(code) +} +fn gen_rlwimi(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 5)?; + let mut code = 0x50000000 | modifiers; + // rA + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 16; + // rS + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 21; + // SH + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + // MB + code |= (parse_unsigned(args, 3, 0x0, 0x1f)? & 0x1f) << 6; + // ME + code |= (parse_unsigned(args, 4, 0x0, 0x1f)? & 0x1f) << 1; + Ok(code) +} +fn gen_rlwinm(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 5)?; + let mut code = 0x54000000 | modifiers; + // rA + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 16; + // rS + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 21; + // SH + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + // MB + code |= (parse_unsigned(args, 3, 0x0, 0x1f)? & 0x1f) << 6; + // ME + code |= (parse_unsigned(args, 4, 0x0, 0x1f)? & 0x1f) << 1; + Ok(code) +} +fn gen_rlwnm(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 5)?; + let mut code = 0x5c000000 | modifiers; + // rA + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 16; + // rS + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 21; + // rB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + // MB + code |= (parse_unsigned(args, 3, 0x0, 0x1f)? & 0x1f) << 6; + // ME + code |= (parse_unsigned(args, 4, 0x0, 0x1f)? & 0x1f) << 1; + Ok(code) +} +fn gen_sc(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 0)?; + let mut code = 0x44000002 | modifiers; + Ok(code) +} +fn gen_slw(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x7c000030 | modifiers; + // rA + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 16; + // rS + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 21; + // rB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_sraw(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x7c000630 | modifiers; + // rA + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 16; + // rS + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 21; + // rB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_srawi(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x7c000670 | modifiers; + // rA + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 16; + // rS + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 21; + // SH + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_srw(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x7c000430 | modifiers; + // rA + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 16; + // rS + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 21; + // rB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_stb(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x98000000 | modifiers; + // rS + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // offset + code |= parse_signed(args, 1, -0x8000, 0x8000)? as u32 & 0xffff; + // rA + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 16; + Ok(code) +} +fn gen_stbu(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x9c000000 | modifiers; + // rS + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // offset + code |= parse_signed(args, 1, -0x8000, 0x8000)? as u32 & 0xffff; + // rA + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 16; + Ok(code) +} +fn gen_stbux(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x7c0001ee | modifiers; + // rS + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // rA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // rB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_stbx(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x7c0001ae | modifiers; + // rS + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // rA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // rB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_stfd(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0xd8000000 | modifiers; + // frS + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // offset + code |= parse_signed(args, 1, -0x8000, 0x8000)? as u32 & 0xffff; + // rA + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 16; + Ok(code) +} +fn gen_stfdu(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0xdc000000 | modifiers; + // frS + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // offset + code |= parse_signed(args, 1, -0x8000, 0x8000)? as u32 & 0xffff; + // rA + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 16; + Ok(code) +} +fn gen_stfdux(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x7c0005ee | modifiers; + // frS + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // rA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // rB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_stfdx(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x7c0005ae | modifiers; + // frS + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // rA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // rB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_stfiwx(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x7c0007ae | modifiers; + // frS + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // rA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // rB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_stfs(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0xd0000000 | modifiers; + // frS + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // offset + code |= parse_signed(args, 1, -0x8000, 0x8000)? as u32 & 0xffff; + // rA + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 16; + Ok(code) +} +fn gen_stfsu(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0xd4000000 | modifiers; + // frS + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // offset + code |= parse_signed(args, 1, -0x8000, 0x8000)? as u32 & 0xffff; + // rA + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 16; + Ok(code) +} +fn gen_stfsux(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x7c00056e | modifiers; + // frS + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // rA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // rB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_stfsx(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x7c00052e | modifiers; + // frS + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // rA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // rB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_sth(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0xb0000000 | modifiers; + // rS + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // offset + code |= parse_signed(args, 1, -0x8000, 0x8000)? as u32 & 0xffff; + // rA + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 16; + Ok(code) +} +fn gen_sthbrx(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x7c00072c | modifiers; + // rS + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // rA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // rB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_sthu(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0xb4000000 | modifiers; + // rS + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // offset + code |= parse_signed(args, 1, -0x8000, 0x8000)? as u32 & 0xffff; + // rA + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 16; + Ok(code) +} +fn gen_sthux(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x7c00036e | modifiers; + // rS + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // rA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // rB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_sthx(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x7c00032e | modifiers; + // rS + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // rA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // rB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_stmw(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0xbc000000 | modifiers; + // rS + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // offset + code |= parse_signed(args, 1, -0x8000, 0x8000)? as u32 & 0xffff; + // rA + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 16; + Ok(code) +} +fn gen_stswi(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x7c0005aa | modifiers; + // rS + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // rA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // NB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_stswx(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x7c00052a | modifiers; + // rS + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // rA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // rB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_stw(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x90000000 | modifiers; + // rS + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // offset + code |= parse_signed(args, 1, -0x8000, 0x8000)? as u32 & 0xffff; + // rA + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 16; + Ok(code) +} +fn gen_stwbrx(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x7c00052c | modifiers; + // rS + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // rA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // rB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_stwcx_(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x7c00012d | modifiers; + // rS + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // rA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // rB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_stwu(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x94000000 | modifiers; + // rS + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // offset + code |= parse_signed(args, 1, -0x8000, 0x8000)? as u32 & 0xffff; + // rA + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 16; + Ok(code) +} +fn gen_stwux(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x7c00016e | modifiers; + // rS + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // rA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // rB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_stwx(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x7c00012e | modifiers; + // rS + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // rA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // rB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_subf(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x7c000050 | modifiers; + // rD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // rA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // rB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_subfc(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x7c000010 | modifiers; + // rD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // rA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // rB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_subfe(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x7c000110 | modifiers; + // rD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // rA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // rB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_subfic(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x20000000 | modifiers; + // rD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // rA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // simm + code |= parse_signed(args, 2, -0x8000, 0x8000)? as u32 & 0xffff; + Ok(code) +} +fn gen_subfme(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 2)?; + let mut code = 0x7c0001d0 | modifiers; + // rD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // rA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + Ok(code) +} +fn gen_subfze(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 2)?; + let mut code = 0x7c000190 | modifiers; + // rD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // rA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + Ok(code) +} +fn gen_sync(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 0)?; + let mut code = 0x7c0004ac | modifiers; + Ok(code) +} +fn gen_tlbie(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 1)?; + let mut code = 0x7c000264 | modifiers; + // rB + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_tlbsync(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 0)?; + let mut code = 0x7c00046c | modifiers; + Ok(code) +} +fn gen_tw(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x7c000008 | modifiers; + // TO + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // rA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // rB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_twi(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0xc000000 | modifiers; + // TO + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // rA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // simm + code |= parse_signed(args, 2, -0x8000, 0x8000)? as u32 & 0xffff; + Ok(code) +} +fn gen_xor(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x7c000278 | modifiers; + // rA + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 16; + // rS + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 21; + // rB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_xori(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x68000000 | modifiers; + // rA + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 16; + // rS + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 21; + // uimm + code |= parse_unsigned(args, 2, 0x0, 0xffff)? & 0xffff; + Ok(code) +} +fn gen_xoris(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x6c000000 | modifiers; + // rA + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 16; + // rS + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 21; + // uimm + code |= parse_unsigned(args, 2, 0x0, 0xffff)? & 0xffff; + Ok(code) +} +fn gen_bdnzlr(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 0)?; + let mut code = 0x4e000020 | modifiers; + Ok(code) +} +fn gen_mfxer(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 1)?; + let mut code = 0x7c0102a6 | modifiers; + // rD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + Ok(code) +} +fn gen_mfsdr1(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 1)?; + let mut code = 0x7c1902a6 | modifiers; + // rD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + Ok(code) +} +fn gen_mfdbatu(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 2)?; + let mut code = 0x7c1882a6 | modifiers; + // rD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // spr_BAT + code |= (parse_unsigned(args, 1, 0x0, 0x3)? & 0x3) << 17; + Ok(code) +} +fn gen_mfsrr0(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 1)?; + let mut code = 0x7c1a02a6 | modifiers; + // rD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + Ok(code) +} +fn gen_bltlr(args: &Arguments, modifiers: u32) -> Result { + match arg_count(args) { + 0 => { + let mut code = 0x4d800020 | modifiers; + Ok(code) + } + 1 => { + let mut code = 0x4d800020 | modifiers; + // crfS + code |= (parse_unsigned(args, 0, 0x0, 0x7)? & 0x7) << 18; + Ok(code) + } + value => { + Err(ArgumentError::ArgCount { + value, + expected: 1, + }) + } + } +} +fn gen_mtear(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 1)?; + let mut code = 0x7c1a43a6 | modifiers; + // rS + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + Ok(code) +} +fn gen_extrwi(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 4)?; + let mut code = 0x5400003e | modifiers; + // rA + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 16; + // rS + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 21; + // MB + code |= ((32 - parse_unsigned(args, 2, 0x0, 0x1f)?) & 0x1f) << 6; + // SH + code + |= ((parse_unsigned(args, 3, 0x0, 0x1f)? + parse_unsigned(args, 2, 0x0, 0x1f)?) + & 0x1f) << 11; + Ok(code) +} +fn gen_mtdar(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 1)?; + let mut code = 0x7c1303a6 | modifiers; + // rS + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + Ok(code) +} +fn gen_rotlw(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x5c00003e | modifiers; + // rA + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 16; + // rS + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 21; + // rB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_mtsrr1(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 1)?; + let mut code = 0x7c1b03a6 | modifiers; + // rS + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + Ok(code) +} +fn gen_mfsrr1(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 1)?; + let mut code = 0x7c1b02a6 | modifiers; + // rD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + Ok(code) +} +fn gen_blectr(args: &Arguments, modifiers: u32) -> Result { + match arg_count(args) { + 0 => { + let mut code = 0x4c810420 | modifiers; + Ok(code) + } + 1 => { + let mut code = 0x4c810420 | modifiers; + // crfS + code |= (parse_unsigned(args, 0, 0x0, 0x7)? & 0x7) << 18; + Ok(code) + } + value => { + Err(ArgumentError::ArgCount { + value, + expected: 1, + }) + } + } +} +fn gen_bnslr(args: &Arguments, modifiers: u32) -> Result { + match arg_count(args) { + 0 => { + let mut code = 0x4c830020 | modifiers; + Ok(code) + } + 1 => { + let mut code = 0x4c830020 | modifiers; + // crfS + code |= (parse_unsigned(args, 0, 0x0, 0x7)? & 0x7) << 18; + Ok(code) + } + value => { + Err(ArgumentError::ArgCount { + value, + expected: 1, + }) + } + } +} +fn gen_crnot(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 2)?; + let mut code = 0x4c000042 | modifiers; + // crbD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // crbA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // crbB + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_mfdsisr(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 1)?; + let mut code = 0x7c1202a6 | modifiers; + // rD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + Ok(code) +} +fn gen_slwi(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x54000000 | modifiers; + // rA + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 16; + // rS + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 21; + // SH + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + // ME + code |= ((31 - parse_unsigned(args, 2, 0x0, 0x1f)?) & 0x1f) << 1; + Ok(code) +} +fn gen_twlge(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 2)?; + let mut code = 0x7ca00008 | modifiers; + // rA + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 16; + // rB + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_mttbu(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 1)?; + let mut code = 0x7c1d43a6 | modifiers; + // rS + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + Ok(code) +} +fn gen_mfibatl(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 2)?; + let mut code = 0x7c1182a6 | modifiers; + // rD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // spr_BAT + code |= (parse_unsigned(args, 1, 0x0, 0x3)? & 0x3) << 17; + Ok(code) +} +fn gen_beqctr(args: &Arguments, modifiers: u32) -> Result { + match arg_count(args) { + 0 => { + let mut code = 0x4d820420 | modifiers; + Ok(code) + } + 1 => { + let mut code = 0x4d820420 | modifiers; + // crfS + code |= (parse_unsigned(args, 0, 0x0, 0x7)? & 0x7) << 18; + Ok(code) + } + value => { + Err(ArgumentError::ArgCount { + value, + expected: 1, + }) + } + } +} +fn gen_bgtlr(args: &Arguments, modifiers: u32) -> Result { + match arg_count(args) { + 0 => { + let mut code = 0x4d810020 | modifiers; + Ok(code) + } + 1 => { + let mut code = 0x4d810020 | modifiers; + // crfS + code |= (parse_unsigned(args, 0, 0x0, 0x7)? & 0x7) << 18; + Ok(code) + } + value => { + Err(ArgumentError::ArgCount { + value, + expected: 1, + }) + } + } +} +fn gen_cmplw(args: &Arguments, modifiers: u32) -> Result { + match arg_count(args) { + 2 => { + let mut code = 0x7c000040 | modifiers; + // rA + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 16; + // rB + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) + } + 3 => { + let mut code = 0x7c000040 | modifiers; + // crfD + code |= (parse_unsigned(args, 0, 0x0, 0x7)? & 0x7) << 23; + // rA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // rB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) + } + value => { + Err(ArgumentError::ArgCount { + value, + expected: 3, + }) + } + } +} +fn gen_mtlr(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 1)?; + let mut code = 0x7c0803a6 | modifiers; + // rS + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + Ok(code) +} +fn gen_mtsdr1(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 1)?; + let mut code = 0x7c1903a6 | modifiers; + // rS + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + Ok(code) +} +fn gen_mr(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 2)?; + let mut code = 0x7c000378 | modifiers; + // rA + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 16; + // rS + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 21; + // rB + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_twgti(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 2)?; + let mut code = 0xd000000 | modifiers; + // rA + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 16; + // simm + code |= parse_signed(args, 1, -0x8000, 0x8000)? as u32 & 0xffff; + Ok(code) +} +fn gen_bge(args: &Arguments, modifiers: u32) -> Result { + match arg_count(args) { + 1 => { + let mut code = 0x40800000 | modifiers; + // BD + code |= parse_signed(args, 0, -0x8000, 0x8000)? as u32 & 0xfffc; + Ok(code) + } + 2 => { + let mut code = 0x40800000 | modifiers; + // crfS + code |= (parse_unsigned(args, 0, 0x0, 0x7)? & 0x7) << 18; + // BD + code |= parse_signed(args, 1, -0x8000, 0x8000)? as u32 & 0xfffc; + Ok(code) + } + value => { + Err(ArgumentError::ArgCount { + value, + expected: 2, + }) + } + } +} +fn gen_bltctr(args: &Arguments, modifiers: u32) -> Result { + match arg_count(args) { + 0 => { + let mut code = 0x4d800420 | modifiers; + Ok(code) + } + 1 => { + let mut code = 0x4d800420 | modifiers; + // crfS + code |= (parse_unsigned(args, 0, 0x0, 0x7)? & 0x7) << 18; + Ok(code) + } + value => { + Err(ArgumentError::ArgCount { + value, + expected: 1, + }) + } + } +} +fn gen_mtibatu(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 2)?; + let mut code = 0x7c1083a6 | modifiers; + // spr_BAT + code |= (parse_unsigned(args, 0, 0x0, 0x3)? & 0x3) << 17; + // rS + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 21; + Ok(code) +} +fn gen_subi(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x38000000 | modifiers; + // rD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // rA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // simm + code |= (-parse_signed(args, 2, -0x8000, 0x8000)?) as u32 & 0xffff; + Ok(code) +} +fn gen_nop(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 0)?; + let mut code = 0x60000000 | modifiers; + Ok(code) +} +fn gen_mttbl(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 1)?; + let mut code = 0x7c1c43a6 | modifiers; + // rS + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + Ok(code) +} +fn gen_blelr(args: &Arguments, modifiers: u32) -> Result { + match arg_count(args) { + 0 => { + let mut code = 0x4c810020 | modifiers; + Ok(code) + } + 1 => { + let mut code = 0x4c810020 | modifiers; + // crfS + code |= (parse_unsigned(args, 0, 0x0, 0x7)? & 0x7) << 18; + Ok(code) + } + value => { + Err(ArgumentError::ArgCount { + value, + expected: 1, + }) + } + } +} +fn gen_crmove(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 2)?; + let mut code = 0x4c000382 | modifiers; + // crbD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // crbA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // crbB + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_mfdbatl(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 2)?; + let mut code = 0x7c1982a6 | modifiers; + // rD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // spr_BAT + code |= (parse_unsigned(args, 1, 0x0, 0x3)? & 0x3) << 17; + Ok(code) +} +fn gen_mfibatu(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 2)?; + let mut code = 0x7c1082a6 | modifiers; + // rD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // spr_BAT + code |= (parse_unsigned(args, 1, 0x0, 0x3)? & 0x3) << 17; + Ok(code) +} +fn gen_cmpd(args: &Arguments, modifiers: u32) -> Result { + match arg_count(args) { + 2 => { + let mut code = 0x7c200000 | modifiers; + // rA + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 16; + // rB + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) + } + 3 => { + let mut code = 0x7c200000 | modifiers; + // crfD + code |= (parse_unsigned(args, 0, 0x0, 0x7)? & 0x7) << 23; + // rA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // rB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) + } + value => { + Err(ArgumentError::ArgCount { + value, + expected: 3, + }) + } + } +} +fn gen_clrlwi(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x5400003e | modifiers; + // rA + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 16; + // rS + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 21; + // MB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 6; + Ok(code) +} +fn gen_cmpw(args: &Arguments, modifiers: u32) -> Result { + match arg_count(args) { + 2 => { + let mut code = 0x7c000000 | modifiers; + // rA + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 16; + // rB + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) + } + 3 => { + let mut code = 0x7c000000 | modifiers; + // crfD + code |= (parse_unsigned(args, 0, 0x0, 0x7)? & 0x7) << 23; + // rA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // rB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) + } + value => { + Err(ArgumentError::ArgCount { + value, + expected: 3, + }) + } + } +} +fn gen_bdzf(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 2)?; + let mut code = 0x40400000 | modifiers; + // BI + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 16; + // BD + code |= parse_signed(args, 1, -0x8000, 0x8000)? as u32 & 0xfffc; + Ok(code) +} +fn gen_subic(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x30000000 | modifiers; + // rD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // rA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // simm + code |= (-parse_signed(args, 2, -0x8000, 0x8000)?) as u32 & 0xffff; + Ok(code) +} +fn gen_mtdsisr(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 1)?; + let mut code = 0x7c1203a6 | modifiers; + // rS + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + Ok(code) +} +fn gen_beq(args: &Arguments, modifiers: u32) -> Result { + match arg_count(args) { + 1 => { + let mut code = 0x41820000 | modifiers; + // BD + code |= parse_signed(args, 0, -0x8000, 0x8000)? as u32 & 0xfffc; + Ok(code) + } + 2 => { + let mut code = 0x41820000 | modifiers; + // crfS + code |= (parse_unsigned(args, 0, 0x0, 0x7)? & 0x7) << 18; + // BD + code |= parse_signed(args, 1, -0x8000, 0x8000)? as u32 & 0xfffc; + Ok(code) + } + value => { + Err(ArgumentError::ArgCount { + value, + expected: 2, + }) + } + } +} +fn gen_mflr(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 1)?; + let mut code = 0x7c0802a6 | modifiers; + // rD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + Ok(code) +} +fn gen_clrrwi(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x54000000 | modifiers; + // rA + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 16; + // rS + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 21; + // ME + code |= ((31 - parse_unsigned(args, 2, 0x0, 0x1f)?) & 0x1f) << 1; + Ok(code) +} +fn gen_bns(args: &Arguments, modifiers: u32) -> Result { + match arg_count(args) { + 1 => { + let mut code = 0x40830000 | modifiers; + // BD + code |= parse_signed(args, 0, -0x8000, 0x8000)? as u32 & 0xfffc; + Ok(code) + } + 2 => { + let mut code = 0x40830000 | modifiers; + // crfS + code |= (parse_unsigned(args, 0, 0x0, 0x7)? & 0x7) << 18; + // BD + code |= parse_signed(args, 1, -0x8000, 0x8000)? as u32 & 0xfffc; + Ok(code) + } + value => { + Err(ArgumentError::ArgCount { + value, + expected: 2, + }) + } + } +} +fn gen_mfear(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 1)?; + let mut code = 0x7c1a42a6 | modifiers; + // rD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + Ok(code) +} +fn gen_bdz(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 1)?; + let mut code = 0x42400000 | modifiers; + // BD + code |= parse_signed(args, 0, -0x8000, 0x8000)? as u32 & 0xfffc; + Ok(code) +} +fn gen_subis(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x3c000000 | modifiers; + // rD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // rA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // simm + code |= (-parse_signed(args, 2, -0x8000, 0x8000)?) as u32 & 0xffff; + Ok(code) +} +fn gen_bctr(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 0)?; + let mut code = 0x4e800420 | modifiers; + Ok(code) +} +fn gen_bnsctr(args: &Arguments, modifiers: u32) -> Result { + match arg_count(args) { + 0 => { + let mut code = 0x4c830420 | modifiers; + Ok(code) + } + 1 => { + let mut code = 0x4c830420 | modifiers; + // crfS + code |= (parse_unsigned(args, 0, 0x0, 0x7)? & 0x7) << 18; + Ok(code) + } + value => { + Err(ArgumentError::ArgCount { + value, + expected: 1, + }) + } + } +} +fn gen_mtdbatl(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 2)?; + let mut code = 0x7c1983a6 | modifiers; + // spr_BAT + code |= (parse_unsigned(args, 0, 0x0, 0x3)? & 0x3) << 17; + // rS + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 21; + Ok(code) +} +fn gen_mtsprg(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 2)?; + let mut code = 0x7c1043a6 | modifiers; + // spr_SPRG + code |= (parse_unsigned(args, 0, 0x0, 0x3)? & 0x3) << 16; + // rS + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 21; + Ok(code) +} +fn gen_mfctr(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 1)?; + let mut code = 0x7c0902a6 | modifiers; + // rD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + Ok(code) +} +fn gen_clrlslwi(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 4)?; + let mut code = 0x54000000 | modifiers; + // rA + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 16; + // rS + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 21; + // MB + code + |= ((parse_unsigned(args, 2, 0x0, 0x1f)? - parse_unsigned(args, 3, 0x0, 0x1f)?) + & 0x1f) << 6; + // SH + code |= (parse_unsigned(args, 3, 0x0, 0x1f)? & 0x1f) << 11; + // ME + code |= ((31 - parse_unsigned(args, 3, 0x0, 0x1f)?) & 0x1f) << 1; + Ok(code) +} +fn gen_bgt(args: &Arguments, modifiers: u32) -> Result { + match arg_count(args) { + 1 => { + let mut code = 0x41810000 | modifiers; + // BD + code |= parse_signed(args, 0, -0x8000, 0x8000)? as u32 & 0xfffc; + Ok(code) + } + 2 => { + let mut code = 0x41810000 | modifiers; + // crfS + code |= (parse_unsigned(args, 0, 0x0, 0x7)? & 0x7) << 18; + // BD + code |= parse_signed(args, 1, -0x8000, 0x8000)? as u32 & 0xfffc; + Ok(code) + } + value => { + Err(ArgumentError::ArgCount { + value, + expected: 2, + }) + } + } +} +fn gen_cmplwi(args: &Arguments, modifiers: u32) -> Result { + match arg_count(args) { + 2 => { + let mut code = 0x28000000 | modifiers; + // rA + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 16; + // uimm + code |= parse_unsigned(args, 1, 0x0, 0xffff)? & 0xffff; + Ok(code) + } + 3 => { + let mut code = 0x28000000 | modifiers; + // crfD + code |= (parse_unsigned(args, 0, 0x0, 0x7)? & 0x7) << 23; + // rA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // uimm + code |= parse_unsigned(args, 2, 0x0, 0xffff)? & 0xffff; + Ok(code) + } + value => { + Err(ArgumentError::ArgCount { + value, + expected: 3, + }) + } + } +} +fn gen_bne(args: &Arguments, modifiers: u32) -> Result { + match arg_count(args) { + 1 => { + let mut code = 0x40820000 | modifiers; + // BD + code |= parse_signed(args, 0, -0x8000, 0x8000)? as u32 & 0xfffc; + Ok(code) + } + 2 => { + let mut code = 0x40820000 | modifiers; + // crfS + code |= (parse_unsigned(args, 0, 0x0, 0x7)? & 0x7) << 18; + // BD + code |= parse_signed(args, 1, -0x8000, 0x8000)? as u32 & 0xfffc; + Ok(code) + } + value => { + Err(ArgumentError::ArgCount { + value, + expected: 2, + }) + } + } +} +fn gen_cmpldi(args: &Arguments, modifiers: u32) -> Result { + match arg_count(args) { + 2 => { + let mut code = 0x28200000 | modifiers; + // rA + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 16; + // uimm + code |= parse_unsigned(args, 1, 0x0, 0xffff)? & 0xffff; + Ok(code) + } + 3 => { + let mut code = 0x28200000 | modifiers; + // crfD + code |= (parse_unsigned(args, 0, 0x0, 0x7)? & 0x7) << 23; + // rA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // uimm + code |= parse_unsigned(args, 2, 0x0, 0xffff)? & 0xffff; + Ok(code) + } + value => { + Err(ArgumentError::ArgCount { + value, + expected: 3, + }) + } + } +} +fn gen_mtibatl(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 2)?; + let mut code = 0x7c1183a6 | modifiers; + // spr_BAT + code |= (parse_unsigned(args, 0, 0x0, 0x3)? & 0x3) << 17; + // rS + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 21; + Ok(code) +} +fn gen_blt(args: &Arguments, modifiers: u32) -> Result { + match arg_count(args) { + 1 => { + let mut code = 0x41800000 | modifiers; + // BD + code |= parse_signed(args, 0, -0x8000, 0x8000)? as u32 & 0xfffc; + Ok(code) + } + 2 => { + let mut code = 0x41800000 | modifiers; + // crfS + code |= (parse_unsigned(args, 0, 0x0, 0x7)? & 0x7) << 18; + // BD + code |= parse_signed(args, 1, -0x8000, 0x8000)? as u32 & 0xfffc; + Ok(code) + } + value => { + Err(ArgumentError::ArgCount { + value, + expected: 2, + }) + } + } +} +fn gen_bdzt(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 2)?; + let mut code = 0x41400000 | modifiers; + // BI + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 16; + // BD + code |= parse_signed(args, 1, -0x8000, 0x8000)? as u32 & 0xfffc; + Ok(code) +} +fn gen_blr(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 0)?; + let mut code = 0x4e800020 | modifiers; + Ok(code) +} +fn gen_beqlr(args: &Arguments, modifiers: u32) -> Result { + match arg_count(args) { + 0 => { + let mut code = 0x4d820020 | modifiers; + Ok(code) + } + 1 => { + let mut code = 0x4d820020 | modifiers; + // crfS + code |= (parse_unsigned(args, 0, 0x0, 0x7)? & 0x7) << 18; + Ok(code) + } + value => { + Err(ArgumentError::ArgCount { + value, + expected: 1, + }) + } + } +} +fn gen_twui(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 2)?; + let mut code = 0xfe00000 | modifiers; + // rA + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 16; + // simm + code |= parse_signed(args, 1, -0x8000, 0x8000)? as u32 & 0xffff; + Ok(code) +} +fn gen_bdnzt(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 2)?; + let mut code = 0x41000000 | modifiers; + // BI + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 16; + // BD + code |= parse_signed(args, 1, -0x8000, 0x8000)? as u32 & 0xfffc; + Ok(code) +} +fn gen_mtdbatu(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 2)?; + let mut code = 0x7c1883a6 | modifiers; + // spr_BAT + code |= (parse_unsigned(args, 0, 0x0, 0x3)? & 0x3) << 17; + // rS + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 21; + Ok(code) +} +fn gen_cmpld(args: &Arguments, modifiers: u32) -> Result { + match arg_count(args) { + 2 => { + let mut code = 0x7c200040 | modifiers; + // rA + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 16; + // rB + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) + } + 3 => { + let mut code = 0x7c200040 | modifiers; + // crfD + code |= (parse_unsigned(args, 0, 0x0, 0x7)? & 0x7) << 23; + // rA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // rB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) + } + value => { + Err(ArgumentError::ArgCount { + value, + expected: 3, + }) + } + } +} +fn gen_srwi(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x5400003e | modifiers; + // rA + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 16; + // rS + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 21; + // MB + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 6; + // SH + code |= ((32 - parse_unsigned(args, 2, 0x0, 0x1f)?) & 0x1f) << 11; + Ok(code) +} +fn gen_cmpdi(args: &Arguments, modifiers: u32) -> Result { + match arg_count(args) { + 2 => { + let mut code = 0x2c200000 | modifiers; + // rA + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 16; + // simm + code |= parse_signed(args, 1, -0x8000, 0x8000)? as u32 & 0xffff; + Ok(code) + } + 3 => { + let mut code = 0x2c200000 | modifiers; + // crfD + code |= (parse_unsigned(args, 0, 0x0, 0x7)? & 0x7) << 23; + // rA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // simm + code |= parse_signed(args, 2, -0x8000, 0x8000)? as u32 & 0xffff; + Ok(code) + } + value => { + Err(ArgumentError::ArgCount { + value, + expected: 3, + }) + } + } +} +fn gen_rotrwi(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x5400003e | modifiers; + // rA + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 16; + // rS + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 21; + // SH + code |= ((32 - parse_unsigned(args, 2, 0x0, 0x1f)?) & 0x1f) << 11; + Ok(code) +} +fn gen_bgectr(args: &Arguments, modifiers: u32) -> Result { + match arg_count(args) { + 0 => { + let mut code = 0x4c800420 | modifiers; + Ok(code) + } + 1 => { + let mut code = 0x4c800420 | modifiers; + // crfS + code |= (parse_unsigned(args, 0, 0x0, 0x7)? & 0x7) << 18; + Ok(code) + } + value => { + Err(ArgumentError::ArgCount { + value, + expected: 1, + }) + } + } +} +fn gen_bdnz(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 1)?; + let mut code = 0x42000000 | modifiers; + // BD + code |= parse_signed(args, 0, -0x8000, 0x8000)? as u32 & 0xfffc; + Ok(code) +} +fn gen_bsoctr(args: &Arguments, modifiers: u32) -> Result { + match arg_count(args) { + 0 => { + let mut code = 0x4d830420 | modifiers; + Ok(code) + } + 1 => { + let mut code = 0x4d830420 | modifiers; + // crfS + code |= (parse_unsigned(args, 0, 0x0, 0x7)? & 0x7) << 18; + Ok(code) + } + value => { + Err(ArgumentError::ArgCount { + value, + expected: 1, + }) + } + } +} +fn gen_subic_(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x34000000 | modifiers; + // rD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // rA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // simm + code |= (-parse_signed(args, 2, -0x8000, 0x8000)?) as u32 & 0xffff; + Ok(code) +} +fn gen_bnelr(args: &Arguments, modifiers: u32) -> Result { + match arg_count(args) { + 0 => { + let mut code = 0x4c820020 | modifiers; + Ok(code) + } + 1 => { + let mut code = 0x4c820020 | modifiers; + // crfS + code |= (parse_unsigned(args, 0, 0x0, 0x7)? & 0x7) << 18; + Ok(code) + } + value => { + Err(ArgumentError::ArgCount { + value, + expected: 1, + }) + } + } +} +fn gen_bdzlr(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 0)?; + let mut code = 0x4e400020 | modifiers; + Ok(code) +} +fn gen_bdzflr(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 1)?; + let mut code = 0x4c000020 | modifiers; + // BI + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 16; + Ok(code) +} +fn gen_rotlwi(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 3)?; + let mut code = 0x5400003e | modifiers; + // rA + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 16; + // rS + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 21; + // SH + code |= (parse_unsigned(args, 2, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_lis(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 2)?; + let mut code = 0x3c000000 | modifiers; + // rD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // uimm + code |= parse_unsigned(args, 1, 0x0, 0xffff)? & 0xffff; + Ok(code) +} +fn gen_ble(args: &Arguments, modifiers: u32) -> Result { + match arg_count(args) { + 1 => { + let mut code = 0x40810000 | modifiers; + // BD + code |= parse_signed(args, 0, -0x8000, 0x8000)? as u32 & 0xfffc; + Ok(code) + } + 2 => { + let mut code = 0x40810000 | modifiers; + // crfS + code |= (parse_unsigned(args, 0, 0x0, 0x7)? & 0x7) << 18; + // BD + code |= parse_signed(args, 1, -0x8000, 0x8000)? as u32 & 0xfffc; + Ok(code) + } + value => { + Err(ArgumentError::ArgCount { + value, + expected: 2, + }) + } + } +} +fn gen_bso(args: &Arguments, modifiers: u32) -> Result { + match arg_count(args) { + 1 => { + let mut code = 0x41830000 | modifiers; + // BD + code |= parse_signed(args, 0, -0x8000, 0x8000)? as u32 & 0xfffc; + Ok(code) + } + 2 => { + let mut code = 0x41830000 | modifiers; + // crfS + code |= (parse_unsigned(args, 0, 0x0, 0x7)? & 0x7) << 18; + // BD + code |= parse_signed(args, 1, -0x8000, 0x8000)? as u32 & 0xfffc; + Ok(code) + } + value => { + Err(ArgumentError::ArgCount { + value, + expected: 2, + }) + } + } +} +fn gen_bdnzf(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 2)?; + let mut code = 0x40000000 | modifiers; + // BI + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 16; + // BD + code |= parse_signed(args, 1, -0x8000, 0x8000)? as u32 & 0xfffc; + Ok(code) +} +fn gen_cmpwi(args: &Arguments, modifiers: u32) -> Result { + match arg_count(args) { + 2 => { + let mut code = 0x2c000000 | modifiers; + // rA + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 16; + // simm + code |= parse_signed(args, 1, -0x8000, 0x8000)? as u32 & 0xffff; + Ok(code) + } + 3 => { + let mut code = 0x2c000000 | modifiers; + // crfD + code |= (parse_unsigned(args, 0, 0x0, 0x7)? & 0x7) << 23; + // rA + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 16; + // simm + code |= parse_signed(args, 2, -0x8000, 0x8000)? as u32 & 0xffff; + Ok(code) + } + value => { + Err(ArgumentError::ArgCount { + value, + expected: 3, + }) + } + } +} +fn gen_bdztlr(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 1)?; + let mut code = 0x4d400020 | modifiers; + // BI + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 16; + Ok(code) +} +fn gen_mtxer(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 1)?; + let mut code = 0x7c0103a6 | modifiers; + // rS + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + Ok(code) +} +fn gen_mfsprg(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 2)?; + let mut code = 0x7c1042a6 | modifiers; + // rD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // spr_SPRG + code |= (parse_unsigned(args, 1, 0x0, 0x3)? & 0x3) << 16; + Ok(code) +} +fn gen_bgtctr(args: &Arguments, modifiers: u32) -> Result { + match arg_count(args) { + 0 => { + let mut code = 0x4d810420 | modifiers; + Ok(code) + } + 1 => { + let mut code = 0x4d810420 | modifiers; + // crfS + code |= (parse_unsigned(args, 0, 0x0, 0x7)? & 0x7) << 18; + Ok(code) + } + value => { + Err(ArgumentError::ArgCount { + value, + expected: 1, + }) + } + } +} +fn gen_bsolr(args: &Arguments, modifiers: u32) -> Result { + match arg_count(args) { + 0 => { + let mut code = 0x4d830020 | modifiers; + Ok(code) + } + 1 => { + let mut code = 0x4d830020 | modifiers; + // crfS + code |= (parse_unsigned(args, 0, 0x0, 0x7)? & 0x7) << 18; + Ok(code) + } + value => { + Err(ArgumentError::ArgCount { + value, + expected: 1, + }) + } + } +} +fn gen_tweq(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 2)?; + let mut code = 0x7c800008 | modifiers; + // rA + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 16; + // rB + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_crclr(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 1)?; + let mut code = 0x4c000182 | modifiers; + // crbD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // crbA + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 16; + // crbB + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_mtdec(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 1)?; + let mut code = 0x7c1603a6 | modifiers; + // rS + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + Ok(code) +} +fn gen_crset(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 1)?; + let mut code = 0x4c000242 | modifiers; + // crbD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // crbA + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 16; + // crbB + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_mfdar(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 1)?; + let mut code = 0x7c1302a6 | modifiers; + // rD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + Ok(code) +} +fn gen_mfdec(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 1)?; + let mut code = 0x7c1602a6 | modifiers; + // rD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + Ok(code) +} +fn gen_bnectr(args: &Arguments, modifiers: u32) -> Result { + match arg_count(args) { + 0 => { + let mut code = 0x4c820420 | modifiers; + Ok(code) + } + 1 => { + let mut code = 0x4c820420 | modifiers; + // crfS + code |= (parse_unsigned(args, 0, 0x0, 0x7)? & 0x7) << 18; + Ok(code) + } + value => { + Err(ArgumentError::ArgCount { + value, + expected: 1, + }) + } + } +} +fn gen_mtctr(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 1)?; + let mut code = 0x7c0903a6 | modifiers; + // rS + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + Ok(code) +} +fn gen_extlwi(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 4)?; + let mut code = 0x54000000 | modifiers; + // rA + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 16; + // rS + code |= (parse_unsigned(args, 1, 0x0, 0x1f)? & 0x1f) << 21; + // ME + code |= ((parse_unsigned(args, 2, 0x0, 0x1f)? - 1) & 0x1f) << 1; + // SH + code |= (parse_unsigned(args, 3, 0x0, 0x1f)? & 0x1f) << 11; + Ok(code) +} +fn gen_li(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 2)?; + let mut code = 0x38000000 | modifiers; + // rD + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + // simm + code |= parse_signed(args, 1, -0x8000, 0x8000)? as u32 & 0xffff; + Ok(code) +} +fn gen_mtsrr0(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 1)?; + let mut code = 0x7c1a03a6 | modifiers; + // rS + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 21; + Ok(code) +} +fn gen_bdnztlr(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 1)?; + let mut code = 0x4d000020 | modifiers; + // BI + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 16; + Ok(code) +} +fn gen_trap(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 0)?; + let mut code = 0x7fe00008 | modifiers; + Ok(code) +} +fn gen_bgelr(args: &Arguments, modifiers: u32) -> Result { + match arg_count(args) { + 0 => { + let mut code = 0x4c800020 | modifiers; + Ok(code) + } + 1 => { + let mut code = 0x4c800020 | modifiers; + // crfS + code |= (parse_unsigned(args, 0, 0x0, 0x7)? & 0x7) << 18; + Ok(code) + } + value => { + Err(ArgumentError::ArgCount { + value, + expected: 1, + }) + } + } +} +fn gen_twllei(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 2)?; + let mut code = 0xcc00000 | modifiers; + // rA + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 16; + // simm + code |= parse_signed(args, 1, -0x8000, 0x8000)? as u32 & 0xffff; + Ok(code) +} +fn gen_bdnzflr(args: &Arguments, modifiers: u32) -> Result { + check_arg_count(args, 1)?; + let mut code = 0x4c000020 | modifiers; + // BI + code |= (parse_unsigned(args, 0, 0x0, 0x1f)? & 0x1f) << 16; + Ok(code) +} +type MnemonicFn = fn(&Arguments, u32) -> Result; +const MNEMONIC_MAP: phf::Map<&'static str, (MnemonicFn, u32)> = ::phf::Map { + key: 12913932095322966823, + disps: &[ + (0, 8), + (0, 241), + (0, 25), + (0, 34), + (0, 0), + (0, 9), + (0, 36), + (0, 0), + (1, 466), + (0, 36), + (0, 137), + (0, 27), + (0, 39), + (0, 1), + (0, 115), + (0, 44), + (0, 54), + (0, 242), + (0, 172), + (1, 477), + (2, 186), + (0, 217), + (0, 81), + (0, 293), + (0, 548), + (0, 0), + (0, 4), + (19, 476), + (0, 4), + (0, 0), + (0, 0), + (0, 610), + (0, 20), + (1, 100), + (0, 66), + (0, 10), + (0, 0), + (0, 0), + (0, 22), + (0, 35), + (1, 329), + (0, 28), + (2, 141), + (0, 0), + (0, 0), + (0, 23), + (1, 34), + (0, 23), + (0, 1), + (0, 35), + (1, 169), + (0, 23), + (0, 3), + (0, 6), + (0, 34), + (0, 0), + (2, 465), + (0, 53), + (0, 502), + (1, 22), + (5, 67), + (0, 335), + (7, 423), + (0, 2), + (0, 6), + (0, 0), + (0, 24), + (0, 43), + (0, 42), + (3, 566), + (0, 298), + (1, 36), + (1, 262), + (0, 130), + (0, 80), + (0, 29), + (0, 0), + (0, 45), + (0, 14), + (0, 3), + (0, 5), + (0, 31), + (3, 165), + (8, 649), + (0, 95), + (0, 426), + (0, 121), + (0, 59), + (0, 27), + (0, 0), + (0, 16), + (2, 105), + (0, 441), + (2, 155), + (1, 362), + (0, 352), + (3, 181), + (33, 126), + (5, 693), + (0, 16), + (2, 356), + (4, 98), + (5, 227), + (0, 12), + (48, 629), + (0, 62), + (1, 455), + (0, 4), + (0, 0), + (6, 587), + (0, 121), + (1, 8), + (3, 590), + (0, 376), + (0, 0), + (0, 233), + (30, 339), + (0, 95), + (0, 2), + (0, 3), + (5, 286), + (0, 172), + (0, 23), + (3, 114), + (2, 644), + (0, 262), + (0, 30), + (0, 290), + (19, 621), + (0, 517), + (17, 110), + (0, 18), + (1, 390), + (24, 77), + (0, 1), + (0, 0), + (0, 1), + (0, 3), + (0, 155), + (0, 40), + ], + entries: &[ + ("mfdbatu", (gen_mfdbatu, 0x0)), + ("bdnztlr", (gen_bdnztlr, 0x0)), + ("ps_mr", (gen_ps_mr, 0x0)), + ("rotlwi", (gen_rotlwi, 0x0)), + ("addc.", (gen_addc, 0x1)), + ("fmr", (gen_fmr, 0x0)), + ("mtdec", (gen_mtdec, 0x0)), + ("fmadds.", (gen_fmadds, 0x1)), + ("beq+", (gen_beq, 0x200000)), + ("bgt+", (gen_bgt, 0x200000)), + ("li", (gen_li, 0x0)), + ("tlbie", (gen_tlbie, 0x0)), + ("bsol-", (gen_bso, 0x200001)), + ("lfsux", (gen_lfsux, 0x0)), + ("crset", (gen_crset, 0x0)), + ("icbi", (gen_icbi, 0x0)), + ("bgtctrl+", (gen_bgtctr, 0x200001)), + ("ps_msub.", (gen_ps_msub, 0x1)), + ("bgtlr", (gen_bgtlr, 0x0)), + ("fmsub.", (gen_fmsub, 0x1)), + ("crxor", (gen_crxor, 0x0)), + ("blt-", (gen_blt, 0x200000)), + ("frsqrte.", (gen_frsqrte, 0x1)), + ("fctiwz", (gen_fctiwz, 0x0)), + ("fctiwz.", (gen_fctiwz, 0x1)), + ("bsol", (gen_bso, 0x1)), + ("bdzl-", (gen_bdz, 0x200001)), + ("ps_sub.", (gen_ps_sub, 0x1)), + ("fnmadds", (gen_fnmadds, 0x0)), + ("neg", (gen_neg, 0x0)), + ("bnela+", (gen_bne, 0x200003)), + ("sth", (gen_sth, 0x0)), + ("creqv", (gen_creqv, 0x0)), + ("mtfsf", (gen_mtfsf, 0x0)), + ("mullw.", (gen_mullw, 0x1)), + ("mfdbatl", (gen_mfdbatl, 0x0)), + ("stwu", (gen_stwu, 0x0)), + ("dcbz_l", (gen_dcbz_l, 0x0)), + ("beqla-", (gen_beq, 0x200003)), + ("ps_cmpu0", (gen_ps_cmpu0, 0x0)), + ("bnel+", (gen_bne, 0x200001)), + ("and", (gen_and, 0x0)), + ("slw.", (gen_slw, 0x1)), + ("bdztla-", (gen_bdzt, 0x200003)), + ("bgtl", (gen_bgt, 0x1)), + ("cror", (gen_cror, 0x0)), + ("beqa+", (gen_beq, 0x200002)), + ("mfcr", (gen_mfcr, 0x0)), + ("mcrxr", (gen_mcrxr, 0x0)), + ("eqv.", (gen_eqv, 0x1)), + ("bc", (gen_bc, 0x0)), + ("bdnztlrl", (gen_bdnztlr, 0x1)), + ("ps_nabs.", (gen_ps_nabs, 0x1)), + ("ps_merge01.", (gen_ps_merge01, 0x1)), + ("tw", (gen_tw, 0x0)), + ("subfme", (gen_subfme, 0x0)), + ("fneg.", (gen_fneg, 0x1)), + ("fneg", (gen_fneg, 0x0)), + ("bsolr+", (gen_bsolr, 0x200000)), + ("subf.", (gen_subf, 0x1)), + ("bdnzfla-", (gen_bdnzf, 0x200003)), + ("mtctr", (gen_mtctr, 0x0)), + ("ble", (gen_ble, 0x0)), + ("extlwi", (gen_extlwi, 0x0)), + ("bgtctr+", (gen_bgtctr, 0x200000)), + ("cmpdi", (gen_cmpdi, 0x0)), + ("andis.", (gen_andis_, 0x0)), + ("bdnzfla+", (gen_bdnzf, 0x200003)), + ("bdnza-", (gen_bdnz, 0x200002)), + ("ps_sum0.", (gen_ps_sum0, 0x1)), + ("fcmpu", (gen_fcmpu, 0x0)), + ("subfo.", (gen_subf, 0x401)), + ("andc.", (gen_andc, 0x1)), + ("subic.", (gen_subic_, 0x0)), + ("frsqrte", (gen_frsqrte, 0x0)), + ("trap", (gen_trap, 0x0)), + ("bnsa-", (gen_bns, 0x200002)), + ("crclr", (gen_crclr, 0x0)), + ("bdzlr", (gen_bdzlr, 0x0)), + ("bcla-", (gen_bc, 0x200003)), + ("mtibatu", (gen_mtibatu, 0x0)), + ("extsh.", (gen_extsh, 0x1)), + ("blrl", (gen_blr, 0x1)), + ("mulhwu", (gen_mulhwu, 0x0)), + ("bclr+", (gen_bclr, 0x200000)), + ("cmpl", (gen_cmpl, 0x0)), + ("bgectrl+", (gen_bgectr, 0x200001)), + ("blela", (gen_ble, 0x3)), + ("lfdu", (gen_lfdu, 0x0)), + ("divwo.", (gen_divw, 0x401)), + ("bdnzflrl+", (gen_bdnzflr, 0x200001)), + ("addeo.", (gen_adde, 0x401)), + ("blelr", (gen_blelr, 0x0)), + ("ps_madd", (gen_ps_madd, 0x0)), + ("lwzu", (gen_lwzu, 0x0)), + ("bltl+", (gen_blt, 0x200001)), + ("clrlwi", (gen_clrlwi, 0x0)), + ("mtlr", (gen_mtlr, 0x0)), + ("lfd", (gen_lfd, 0x0)), + ("mtfsb0", (gen_mtfsb0, 0x0)), + ("bdz", (gen_bdz, 0x0)), + ("bcctr", (gen_bcctr, 0x0)), + ("sthu", (gen_sthu, 0x0)), + ("mtsprg", (gen_mtsprg, 0x0)), + ("subfze", (gen_subfze, 0x0)), + ("bdzflr+", (gen_bdzflr, 0x200000)), + ("psq_stx", (gen_psq_stx, 0x0)), + ("lbz", (gen_lbz, 0x0)), + ("fctiw.", (gen_fctiw, 0x1)), + ("bdz+", (gen_bdz, 0x200000)), + ("bdz-", (gen_bdz, 0x200000)), + ("mfdec", (gen_mfdec, 0x0)), + ("bso-", (gen_bso, 0x200000)), + ("addis", (gen_addis, 0x0)), + ("bdnza+", (gen_bdnz, 0x200002)), + ("ps_cmpo0", (gen_ps_cmpo0, 0x0)), + ("bdzfl", (gen_bdzf, 0x1)), + ("bnsl-", (gen_bns, 0x200001)), + ("fnmsub.", (gen_fnmsub, 0x1)), + ("blelr+", (gen_blelr, 0x200000)), + ("bdzta-", (gen_bdzt, 0x200002)), + ("bgta", (gen_bgt, 0x2)), + ("lswi", (gen_lswi, 0x0)), + ("bltlrl", (gen_bltlr, 0x1)), + ("mfxer", (gen_mfxer, 0x0)), + ("bdnzfa-", (gen_bdnzf, 0x200002)), + ("srw", (gen_srw, 0x0)), + ("bdnzt", (gen_bdnzt, 0x0)), + ("bge-", (gen_bge, 0x200000)), + ("mtear", (gen_mtear, 0x0)), + ("slwi", (gen_slwi, 0x0)), + ("fres.", (gen_fres, 0x1)), + ("crnand", (gen_crnand, 0x0)), + ("fsub", (gen_fsub, 0x0)), + ("bdzfl+", (gen_bdzf, 0x200001)), + ("beqlr", (gen_beqlr, 0x0)), + ("bsoctrl", (gen_bsoctr, 0x1)), + ("bltctrl+", (gen_bltctr, 0x200001)), + ("mtfsf.", (gen_mtfsf, 0x1)), + ("blela-", (gen_ble, 0x200003)), + ("twui", (gen_twui, 0x0)), + ("bsolrl", (gen_bsolr, 0x1)), + ("stb", (gen_stb, 0x0)), + ("bso+", (gen_bso, 0x200000)), + ("bgtl-", (gen_bgt, 0x200001)), + ("sraw", (gen_sraw, 0x0)), + ("beqlrl", (gen_beqlr, 0x1)), + ("fabs.", (gen_fabs, 0x1)), + ("bsola-", (gen_bso, 0x200003)), + ("stfdu", (gen_stfdu, 0x0)), + ("bdnzfa+", (gen_bdnzf, 0x200002)), + ("cntlzw", (gen_cntlzw, 0x0)), + ("stwux", (gen_stwux, 0x0)), + ("xoris", (gen_xoris, 0x0)), + ("fnmadd.", (gen_fnmadd, 0x1)), + ("bsoa+", (gen_bso, 0x200002)), + ("addi", (gen_addi, 0x0)), + ("fnmadd", (gen_fnmadd, 0x0)), + ("subfmeo.", (gen_subfme, 0x401)), + ("bsolr", (gen_bsolr, 0x0)), + ("bdnzflr+", (gen_bdnzflr, 0x200000)), + ("fadd.", (gen_fadd, 0x1)), + ("bsoctr", (gen_bsoctr, 0x0)), + ("blta+", (gen_blt, 0x200002)), + ("ps_sub", (gen_ps_sub, 0x0)), + ("subfco.", (gen_subfc, 0x401)), + ("sc", (gen_sc, 0x0)), + ("sthbrx", (gen_sthbrx, 0x0)), + ("ps_rsqrte", (gen_ps_rsqrte, 0x0)), + ("bdztlrl+", (gen_bdztlr, 0x200001)), + ("beqa-", (gen_beq, 0x200002)), + ("ps_mul", (gen_ps_mul, 0x0)), + ("bdzlrl+", (gen_bdzlr, 0x200001)), + ("cmpw", (gen_cmpw, 0x0)), + ("mtfsb1.", (gen_mtfsb1, 0x1)), + ("bgtlr+", (gen_bgtlr, 0x200000)), + ("blela+", (gen_ble, 0x200003)), + ("addmeo", (gen_addme, 0x400)), + ("fmr.", (gen_fmr, 0x1)), + ("blectr", (gen_blectr, 0x0)), + ("cmp", (gen_cmp, 0x0)), + ("bdzta", (gen_bdzt, 0x2)), + ("bdnztlr+", (gen_bdnztlr, 0x200000)), + ("divwu.", (gen_divwu, 0x1)), + ("blea-", (gen_ble, 0x200002)), + ("stswx", (gen_stswx, 0x0)), + ("addc", (gen_addc, 0x0)), + ("mulhw.", (gen_mulhw, 0x1)), + ("subic", (gen_subic, 0x0)), + ("clrlslwi", (gen_clrlslwi, 0x0)), + ("bgelrl", (gen_bgelr, 0x1)), + ("add.", (gen_add, 0x1)), + ("subfzeo", (gen_subfze, 0x400)), + ("bltlr+", (gen_bltlr, 0x200000)), + ("extsh", (gen_extsh, 0x0)), + ("mfdar", (gen_mfdar, 0x0)), + ("mtdbatu", (gen_mtdbatu, 0x0)), + ("mtibatl", (gen_mtibatl, 0x0)), + ("fnabs", (gen_fnabs, 0x0)), + ("extlwi.", (gen_extlwi, 0x1)), + ("stswi", (gen_stswi, 0x0)), + ("bltlrl+", (gen_bltlr, 0x200001)), + ("lhax", (gen_lhax, 0x0)), + ("ps_merge00.", (gen_ps_merge00, 0x1)), + ("ps_madds0", (gen_ps_madds0, 0x0)), + ("extrwi", (gen_extrwi, 0x0)), + ("bsoctrl+", (gen_bsoctr, 0x200001)), + ("eieio", (gen_eieio, 0x0)), + ("mfibatl", (gen_mfibatl, 0x0)), + ("bltl", (gen_blt, 0x1)), + ("blt", (gen_blt, 0x0)), + ("mulhw", (gen_mulhw, 0x0)), + ("blta-", (gen_blt, 0x200002)), + ("rfi", (gen_rfi, 0x0)), + ("bdnzfa", (gen_bdnzf, 0x2)), + ("ps_neg", (gen_ps_neg, 0x0)), + ("lfsu", (gen_lfsu, 0x0)), + ("bgectr", (gen_bgectr, 0x0)), + ("ps_rsqrte.", (gen_ps_rsqrte, 0x1)), + ("mfsr", (gen_mfsr, 0x0)), + ("ori", (gen_ori, 0x0)), + ("bdnzf+", (gen_bdnzf, 0x200000)), + ("bca+", (gen_bc, 0x200002)), + ("psq_stux", (gen_psq_stux, 0x0)), + ("ps_res", (gen_ps_res, 0x0)), + ("bgtla+", (gen_bgt, 0x200003)), + ("subfmeo", (gen_subfme, 0x400)), + ("bnsa+", (gen_bns, 0x200002)), + ("bgelrl+", (gen_bgelr, 0x200001)), + ("bcctrl+", (gen_bcctr, 0x200001)), + ("fnmsubs", (gen_fnmsubs, 0x0)), + ("cmplw", (gen_cmplw, 0x0)), + ("bgt", (gen_bgt, 0x0)), + ("srw.", (gen_srw, 0x1)), + ("blectrl", (gen_blectr, 0x1)), + ("mfmsr", (gen_mfmsr, 0x0)), + ("bsol+", (gen_bso, 0x200001)), + ("beq-", (gen_beq, 0x200000)), + ("beqa", (gen_beq, 0x2)), + ("fmadds", (gen_fmadds, 0x0)), + ("bdzfla+", (gen_bdzf, 0x200003)), + ("beqctr+", (gen_beqctr, 0x200000)), + ("lfsx", (gen_lfsx, 0x0)), + ("bsoa", (gen_bso, 0x2)), + ("bdza-", (gen_bdz, 0x200002)), + ("ps_neg.", (gen_ps_neg, 0x1)), + ("addme", (gen_addme, 0x0)), + ("bdnz-", (gen_bdnz, 0x200000)), + ("bnsla-", (gen_bns, 0x200003)), + ("ps_muls0.", (gen_ps_muls0, 0x1)), + ("clrlwi.", (gen_clrlwi, 0x1)), + ("fmul", (gen_fmul, 0x0)), + ("andc", (gen_andc, 0x0)), + ("clrrwi.", (gen_clrrwi, 0x1)), + ("addco", (gen_addc, 0x400)), + ("addo", (gen_add, 0x400)), + ("beqlrl+", (gen_beqlr, 0x200001)), + ("bgela+", (gen_bge, 0x200003)), + ("srawi.", (gen_srawi, 0x1)), + ("srawi", (gen_srawi, 0x0)), + ("bl", (gen_b, 0x1)), + ("fmadd.", (gen_fmadd, 0x1)), + ("mr.", (gen_mr, 0x1)), + ("bdzt+", (gen_bdzt, 0x200000)), + ("rlwnm.", (gen_rlwnm, 0x1)), + ("blectr+", (gen_blectr, 0x200000)), + ("bdztl-", (gen_bdzt, 0x200001)), + ("addzeo", (gen_addze, 0x400)), + ("isync", (gen_isync, 0x0)), + ("fsel", (gen_fsel, 0x0)), + ("bnectrl+", (gen_bnectr, 0x200001)), + ("ps_res.", (gen_ps_res, 0x1)), + ("bne-", (gen_bne, 0x200000)), + ("bla", (gen_b, 0x3)), + ("bnea-", (gen_bne, 0x200002)), + ("ps_merge10", (gen_ps_merge10, 0x0)), + ("mfear", (gen_mfear, 0x0)), + ("srwi", (gen_srwi, 0x0)), + ("lfdux", (gen_lfdux, 0x0)), + ("nop", (gen_nop, 0x0)), + ("mtmsr", (gen_mtmsr, 0x0)), + ("bcl-", (gen_bc, 0x200001)), + ("dcbt", (gen_dcbt, 0x0)), + ("cmpi", (gen_cmpi, 0x0)), + ("ecowx", (gen_ecowx, 0x0)), + ("fnabs.", (gen_fnabs, 0x1)), + ("ps_merge11.", (gen_ps_merge11, 0x1)), + ("bnectr+", (gen_bnectr, 0x200000)), + ("bcla+", (gen_bc, 0x200003)), + ("blr", (gen_blr, 0x0)), + ("clrrwi", (gen_clrrwi, 0x0)), + ("bns", (gen_bns, 0x0)), + ("ps_muls1.", (gen_ps_muls1, 0x1)), + ("fadds.", (gen_fadds, 0x1)), + ("bdnzt+", (gen_bdnzt, 0x200000)), + ("lfdx", (gen_lfdx, 0x0)), + ("psq_stu", (gen_psq_stu, 0x0)), + ("bnectr", (gen_bnectr, 0x0)), + ("bsoa-", (gen_bso, 0x200002)), + ("mtspr", (gen_mtspr, 0x0)), + ("bdnztla+", (gen_bdnzt, 0x200003)), + ("mflr", (gen_mflr, 0x0)), + ("nand.", (gen_nand, 0x1)), + ("bgtctrl", (gen_bgtctr, 0x1)), + ("addme.", (gen_addme, 0x1)), + ("xor", (gen_xor, 0x0)), + ("mullwo", (gen_mullw, 0x400)), + ("crandc", (gen_crandc, 0x0)), + ("bltla-", (gen_blt, 0x200003)), + ("mfctr", (gen_mfctr, 0x0)), + ("ps_div", (gen_ps_div, 0x0)), + ("bgel+", (gen_bge, 0x200001)), + ("blelrl", (gen_blelr, 0x1)), + ("stwx", (gen_stwx, 0x0)), + ("lwarx", (gen_lwarx, 0x0)), + ("bdnztla-", (gen_bdnzt, 0x200003)), + ("lwz", (gen_lwz, 0x0)), + ("bdnzl", (gen_bdnz, 0x1)), + ("ps_nabs", (gen_ps_nabs, 0x0)), + ("bge", (gen_bge, 0x0)), + ("dcbi", (gen_dcbi, 0x0)), + ("divwo", (gen_divw, 0x400)), + ("ps_merge01", (gen_ps_merge01, 0x0)), + ("bdzt-", (gen_bdzt, 0x200000)), + ("cmplwi", (gen_cmplwi, 0x0)), + ("subfic", (gen_subfic, 0x0)), + ("bdnzfl-", (gen_bdnzf, 0x200001)), + ("sthux", (gen_sthux, 0x0)), + ("bdzta+", (gen_bdzt, 0x200002)), + ("eciwx", (gen_eciwx, 0x0)), + ("ps_mul.", (gen_ps_mul, 0x1)), + ("mttbu", (gen_mttbu, 0x0)), + ("mr", (gen_mr, 0x0)), + ("bnea+", (gen_bne, 0x200002)), + ("bgea-", (gen_bge, 0x200002)), + ("beqlr+", (gen_beqlr, 0x200000)), + ("bdzfla", (gen_bdzf, 0x3)), + ("bdnzfl+", (gen_bdnzf, 0x200001)), + ("subfo", (gen_subf, 0x400)), + ("mtfsb0.", (gen_mtfsb0, 0x1)), + ("lwzx", (gen_lwzx, 0x0)), + ("bns-", (gen_bns, 0x200000)), + ("lhzu", (gen_lhzu, 0x0)), + ("and.", (gen_and, 0x1)), + ("fctiw", (gen_fctiw, 0x0)), + ("ps_nmadd.", (gen_ps_nmadd, 0x1)), + ("subfe", (gen_subfe, 0x0)), + ("addzeo.", (gen_addze, 0x401)), + ("bdnzlrl", (gen_bdnzlr, 0x1)), + ("bdzfla-", (gen_bdzf, 0x200003)), + ("mtdbatl", (gen_mtdbatl, 0x0)), + ("bc-", (gen_bc, 0x200000)), + ("bdnztlrl+", (gen_bdnztlr, 0x200001)), + ("divw.", (gen_divw, 0x1)), + ("subfe.", (gen_subfe, 0x1)), + ("bnel", (gen_bne, 0x1)), + ("fres", (gen_fres, 0x0)), + ("bnsla+", (gen_bns, 0x200003)), + ("bdzlrl", (gen_bdzlr, 0x1)), + ("mtsr", (gen_mtsr, 0x0)), + ("sthx", (gen_sthx, 0x0)), + ("stbux", (gen_stbux, 0x0)), + ("fdivs.", (gen_fdivs, 0x1)), + ("lhaux", (gen_lhaux, 0x0)), + ("ps_add", (gen_ps_add, 0x0)), + ("xor.", (gen_xor, 0x1)), + ("cmpli", (gen_cmpli, 0x0)), + ("orc", (gen_orc, 0x0)), + ("stmw", (gen_stmw, 0x0)), + ("dcbtst", (gen_dcbtst, 0x0)), + ("bdnzt-", (gen_bdnzt, 0x200000)), + ("bdnzlr+", (gen_bdnzlr, 0x200000)), + ("addmeo.", (gen_addme, 0x401)), + ("lwbrx", (gen_lwbrx, 0x0)), + ("subfc", (gen_subfc, 0x0)), + ("subfc.", (gen_subfc, 0x1)), + ("stfsu", (gen_stfsu, 0x0)), + ("crnot", (gen_crnot, 0x0)), + ("bgea+", (gen_bge, 0x200002)), + ("bdnzla+", (gen_bdnz, 0x200003)), + ("bdzl+", (gen_bdz, 0x200001)), + ("bdzfa+", (gen_bdzf, 0x200002)), + ("stfdx", (gen_stfdx, 0x0)), + ("bnslrl+", (gen_bnslr, 0x200001)), + ("twgti", (gen_twgti, 0x0)), + ("slw", (gen_slw, 0x0)), + ("bdnzfla", (gen_bdnzf, 0x3)), + ("bdzla+", (gen_bdz, 0x200003)), + ("bgel-", (gen_bge, 0x200001)), + ("beqctrl+", (gen_beqctr, 0x200001)), + ("lmw", (gen_lmw, 0x0)), + ("mfdsisr", (gen_mfdsisr, 0x0)), + ("bge+", (gen_bge, 0x200000)), + ("cntlzw.", (gen_cntlzw, 0x1)), + ("blel+", (gen_ble, 0x200001)), + ("dcbz", (gen_dcbz, 0x0)), + ("ps_nmadd", (gen_ps_nmadd, 0x0)), + ("lha", (gen_lha, 0x0)), + ("bdnzl+", (gen_bdnz, 0x200001)), + ("fsubs.", (gen_fsubs, 0x1)), + ("dcbf", (gen_dcbf, 0x0)), + ("blt+", (gen_blt, 0x200000)), + ("lwzux", (gen_lwzux, 0x0)), + ("ps_add.", (gen_ps_add, 0x1)), + ("bdztla+", (gen_bdzt, 0x200003)), + ("stfiwx", (gen_stfiwx, 0x0)), + ("subi", (gen_subi, 0x0)), + ("ble+", (gen_ble, 0x200000)), + ("subfeo.", (gen_subfe, 0x401)), + ("ps_madds1.", (gen_ps_madds1, 0x1)), + ("bclr", (gen_bclr, 0x0)), + ("or", (gen_or, 0x0)), + ("rotlw.", (gen_rotlw, 0x1)), + ("ps_sel", (gen_ps_sel, 0x0)), + ("bnelrl+", (gen_bnelr, 0x200001)), + ("bnectrl", (gen_bnectr, 0x1)), + ("blelrl+", (gen_blelr, 0x200001)), + ("bdzfa", (gen_bdzf, 0x2)), + ("bdnzla-", (gen_bdnz, 0x200003)), + ("mtfsfi", (gen_mtfsfi, 0x0)), + ("dcbst", (gen_dcbst, 0x0)), + ("beql+", (gen_beq, 0x200001)), + ("bdnzlr", (gen_bdnzlr, 0x0)), + ("bltctr+", (gen_bltctr, 0x200000)), + ("bdnztl", (gen_bdnzt, 0x1)), + ("psq_l", (gen_psq_l, 0x0)), + ("lhau", (gen_lhau, 0x0)), + ("bnelr", (gen_bnelr, 0x0)), + ("bnslr+", (gen_bnslr, 0x200000)), + ("bclrl", (gen_bclr, 0x1)), + ("bdzla-", (gen_bdz, 0x200003)), + ("cmpldi", (gen_cmpldi, 0x0)), + ("psq_st", (gen_psq_st, 0x0)), + ("bnsl", (gen_bns, 0x1)), + ("ps_sel.", (gen_ps_sel, 0x1)), + ("rlwimi", (gen_rlwimi, 0x0)), + ("adde", (gen_adde, 0x0)), + ("ps_sum1.", (gen_ps_sum1, 0x1)), + ("bdztlr+", (gen_bdztlr, 0x200000)), + ("divwuo", (gen_divwu, 0x400)), + ("stfs", (gen_stfs, 0x0)), + ("bdzflr", (gen_bdzflr, 0x0)), + ("bgtl+", (gen_bgt, 0x200001)), + ("mfsdr1", (gen_mfsdr1, 0x0)), + ("stfdux", (gen_stfdux, 0x0)), + ("or.", (gen_or, 0x1)), + ("stbu", (gen_stbu, 0x0)), + ("mtfsb1", (gen_mtfsb1, 0x0)), + ("nor.", (gen_nor, 0x1)), + ("bnslr", (gen_bnslr, 0x0)), + ("rlwimi.", (gen_rlwimi, 0x1)), + ("beqctrl", (gen_beqctr, 0x1)), + ("bdztl", (gen_bdzt, 0x1)), + ("bctr", (gen_bctr, 0x0)), + ("crorc", (gen_crorc, 0x0)), + ("bgta-", (gen_bgt, 0x200002)), + ("ps_nmsub.", (gen_ps_nmsub, 0x1)), + ("divwuo.", (gen_divwu, 0x401)), + ("icbi.", (gen_icbi, 0x1)), + ("ps_sum1", (gen_ps_sum1, 0x0)), + ("bnsctr+", (gen_bnsctr, 0x200000)), + ("blea+", (gen_ble, 0x200002)), + ("bgtctr", (gen_bgtctr, 0x0)), + ("mfspr", (gen_mfspr, 0x0)), + ("blectrl+", (gen_blectr, 0x200001)), + ("bns+", (gen_bns, 0x200000)), + ("nego", (gen_neg, 0x400)), + ("mtsrin", (gen_mtsrin, 0x0)), + ("subfeo", (gen_subfe, 0x400)), + ("ps_abs.", (gen_ps_abs, 0x1)), + ("fdivs", (gen_fdivs, 0x0)), + ("bsolrl+", (gen_bsolr, 0x200001)), + ("fmul.", (gen_fmul, 0x1)), + ("rotlw", (gen_rotlw, 0x0)), + ("bcla", (gen_bc, 0x3)), + ("fmuls", (gen_fmuls, 0x0)), + ("bdzt", (gen_bdzt, 0x0)), + ("bdza+", (gen_bdz, 0x200002)), + ("fnmadds.", (gen_fnmadds, 0x1)), + ("twlge", (gen_twlge, 0x0)), + ("ps_madd.", (gen_ps_madd, 0x1)), + ("bne+", (gen_bne, 0x200000)), + ("beql", (gen_beq, 0x1)), + ("cmpd", (gen_cmpd, 0x0)), + ("mtfsfi.", (gen_mtfsfi, 0x1)), + ("bnela-", (gen_bne, 0x200003)), + ("stfsux", (gen_stfsux, 0x0)), + ("rotlwi.", (gen_rotlwi, 0x1)), + ("extrwi.", (gen_extrwi, 0x1)), + ("bgelr+", (gen_bgelr, 0x200000)), + ("lfs", (gen_lfs, 0x0)), + ("bdzf-", (gen_bdzf, 0x200000)), + ("bltla", (gen_blt, 0x3)), + ("divwu", (gen_divwu, 0x0)), + ("fnmsubs.", (gen_fnmsubs, 0x1)), + ("bnel-", (gen_bne, 0x200001)), + ("subfme.", (gen_subfme, 0x1)), + ("mcrf", (gen_mcrf, 0x0)), + ("frsp.", (gen_frsp, 0x1)), + ("bcctr+", (gen_bcctr, 0x200000)), + ("extsb", (gen_extsb, 0x0)), + ("clrlslwi.", (gen_clrlslwi, 0x1)), + ("bso", (gen_bso, 0x0)), + ("bdza", (gen_bdz, 0x2)), + ("bdnzlrl+", (gen_bdnzlr, 0x200001)), + ("bdnz", (gen_bdnz, 0x0)), + ("mullw", (gen_mullw, 0x0)), + ("sraw.", (gen_sraw, 0x1)), + ("bgea", (gen_bge, 0x2)), + ("bgtla-", (gen_bgt, 0x200003)), + ("frsp", (gen_frsp, 0x0)), + ("blea", (gen_ble, 0x2)), + ("bdztla", (gen_bdzt, 0x3)), + ("ps_merge11", (gen_ps_merge11, 0x0)), + ("twllei", (gen_twllei, 0x0)), + ("ps_mr.", (gen_ps_mr, 0x1)), + ("mttbl", (gen_mttbl, 0x0)), + ("bltla+", (gen_blt, 0x200003)), + ("mcrfs", (gen_mcrfs, 0x0)), + ("bdzla", (gen_bdz, 0x3)), + ("rlwinm", (gen_rlwinm, 0x0)), + ("bne", (gen_bne, 0x0)), + ("sync", (gen_sync, 0x0)), + ("bca-", (gen_bc, 0x200002)), + ("orc.", (gen_orc, 0x1)), + ("eqv", (gen_eqv, 0x0)), + ("andi.", (gen_andi_, 0x0)), + ("mfsrr1", (gen_mfsrr1, 0x0)), + ("fsel.", (gen_fsel, 0x1)), + ("stfd", (gen_stfd, 0x0)), + ("bnslrl", (gen_bnslr, 0x1)), + ("subfco", (gen_subfc, 0x400)), + ("mfsrr0", (gen_mfsrr0, 0x0)), + ("subfze.", (gen_subfze, 0x1)), + ("mffs", (gen_mffs, 0x0)), + ("fdiv.", (gen_fdiv, 0x1)), + ("bdnzta-", (gen_bdnzt, 0x200002)), + ("blta", (gen_blt, 0x2)), + ("ps_muls1", (gen_ps_muls1, 0x0)), + ("bsola", (gen_bso, 0x3)), + ("b", (gen_b, 0x0)), + ("bltl-", (gen_blt, 0x200001)), + ("bcl+", (gen_bc, 0x200001)), + ("nego.", (gen_neg, 0x401)), + ("bgel", (gen_bge, 0x1)), + ("ps_merge00", (gen_ps_merge00, 0x0)), + ("stwcx.", (gen_stwcx_, 0x0)), + ("add", (gen_add, 0x0)), + ("fsubs", (gen_fsubs, 0x0)), + ("bcl", (gen_bc, 0x1)), + ("ba", (gen_b, 0x2)), + ("bdnzflrl", (gen_bdnzflr, 0x1)), + ("bltctr", (gen_bltctr, 0x0)), + ("bnsctrl+", (gen_bnsctr, 0x200001)), + ("lhz", (gen_lhz, 0x0)), + ("lhzux", (gen_lhzux, 0x0)), + ("bgtlrl", (gen_bgtlr, 0x1)), + ("bdnztl+", (gen_bdnzt, 0x200001)), + ("fadd", (gen_fadd, 0x0)), + ("fadds", (gen_fadds, 0x0)), + ("ps_madds1", (gen_ps_madds1, 0x0)), + ("mfibatu", (gen_mfibatu, 0x0)), + ("addze.", (gen_addze, 0x1)), + ("mftb", (gen_mftb, 0x0)), + ("bcctrl", (gen_bcctr, 0x1)), + ("bgta+", (gen_bgt, 0x200002)), + ("bdzl", (gen_bdz, 0x1)), + ("mtxer", (gen_mtxer, 0x0)), + ("beql-", (gen_beq, 0x200001)), + ("beq", (gen_beq, 0x0)), + ("mffs.", (gen_mffs, 0x1)), + ("bltctrl", (gen_bltctr, 0x1)), + ("mtsrr1", (gen_mtsrr1, 0x0)), + ("stw", (gen_stw, 0x0)), + ("subf", (gen_subf, 0x0)), + ("lis", (gen_lis, 0x0)), + ("bca", (gen_bc, 0x2)), + ("bdnzla", (gen_bdnz, 0x3)), + ("bnsla", (gen_bns, 0x3)), + ("lswx", (gen_lswx, 0x0)), + ("bdzfa-", (gen_bdzf, 0x200002)), + ("bdnzta", (gen_bdnzt, 0x2)), + ("bdnztl-", (gen_bdnzt, 0x200001)), + ("bdzf+", (gen_bdzf, 0x200000)), + ("bdnzta+", (gen_bdnzt, 0x200002)), + ("rlwinm.", (gen_rlwinm, 0x1)), + ("mtdar", (gen_mtdar, 0x0)), + ("bdztlr", (gen_bdztlr, 0x0)), + ("nor", (gen_nor, 0x0)), + ("srwi.", (gen_srwi, 0x1)), + ("bsoctr+", (gen_bsoctr, 0x200000)), + ("xori", (gen_xori, 0x0)), + ("cmpld", (gen_cmpld, 0x0)), + ("crand", (gen_crand, 0x0)), + ("bnsctrl", (gen_bnsctr, 0x1)), + ("bdztl+", (gen_bdzt, 0x200001)), + ("bgtla", (gen_bgt, 0x3)), + ("bdnzf-", (gen_bdnzf, 0x200000)), + ("extsb.", (gen_extsb, 0x1)), + ("ps_div.", (gen_ps_div, 0x1)), + ("fsub.", (gen_fsub, 0x1)), + ("bclrl+", (gen_bclr, 0x200001)), + ("lbzux", (gen_lbzux, 0x0)), + ("beqla+", (gen_beq, 0x200003)), + ("rlwnm", (gen_rlwnm, 0x0)), + ("lhbrx", (gen_lhbrx, 0x0)), + ("crmove", (gen_crmove, 0x0)), + ("bdnztla", (gen_bdnzt, 0x3)), + ("fnmsub", (gen_fnmsub, 0x0)), + ("subis", (gen_subis, 0x0)), + ("ps_cmpo1", (gen_ps_cmpo1, 0x0)), + ("ps_msub", (gen_ps_msub, 0x0)), + ("bdnz+", (gen_bdnz, 0x200000)), + ("bdnzl-", (gen_bdnz, 0x200001)), + ("bnela", (gen_bne, 0x3)), + ("fmuls.", (gen_fmuls, 0x1)), + ("ps_merge10.", (gen_ps_merge10, 0x1)), + ("lhzx", (gen_lhzx, 0x0)), + ("psq_lux", (gen_psq_lux, 0x0)), + ("bdnzfl", (gen_bdnzf, 0x1)), + ("tlbsync", (gen_tlbsync, 0x0)), + ("ps_sum0", (gen_ps_sum0, 0x0)), + ("bc+", (gen_bc, 0x200000)), + ("mfsprg", (gen_mfsprg, 0x0)), + ("fabs", (gen_fabs, 0x0)), + ("mullwo.", (gen_mullw, 0x401)), + ("mulhwu.", (gen_mulhwu, 0x1)), + ("mtsdr1", (gen_mtsdr1, 0x0)), + ("bnsl+", (gen_bns, 0x200001)), + ("divw", (gen_divw, 0x0)), + ("addic.", (gen_addic_, 0x0)), + ("bctrl", (gen_bctr, 0x1)), + ("mtsrr0", (gen_mtsrr0, 0x0)), + ("bgela", (gen_bge, 0x3)), + ("ble-", (gen_ble, 0x200000)), + ("bdztlrl", (gen_bdztlr, 0x1)), + ("mfsrin", (gen_mfsrin, 0x0)), + ("bgectrl", (gen_bgectr, 0x1)), + ("fmsubs.", (gen_fmsubs, 0x1)), + ("lbzx", (gen_lbzx, 0x0)), + ("bgt-", (gen_bgt, 0x200000)), + ("bdnza", (gen_bdnz, 0x2)), + ("addo.", (gen_add, 0x401)), + ("bdzf", (gen_bdzf, 0x0)), + ("crnor", (gen_crnor, 0x0)), + ("ps_muls0", (gen_ps_muls0, 0x0)), + ("neg.", (gen_neg, 0x1)), + ("ps_nmsub", (gen_ps_nmsub, 0x0)), + ("ps_cmpu1", (gen_ps_cmpu1, 0x0)), + ("bdzflrl+", (gen_bdzflr, 0x200001)), + ("blel-", (gen_ble, 0x200001)), + ("bnea", (gen_bne, 0x2)), + ("twi", (gen_twi, 0x0)), + ("rotrwi.", (gen_rotrwi, 0x1)), + ("bnelr+", (gen_bnelr, 0x200000)), + ("addze", (gen_addze, 0x0)), + ("blel", (gen_ble, 0x1)), + ("fmsub", (gen_fmsub, 0x0)), + ("bsola+", (gen_bso, 0x200003)), + ("addeo", (gen_adde, 0x400)), + ("beqctr", (gen_beqctr, 0x0)), + ("adde.", (gen_adde, 0x1)), + ("fmsubs", (gen_fmsubs, 0x0)), + ("bdzflrl", (gen_bdzflr, 0x1)), + ("bdnzf", (gen_bdnzf, 0x0)), + ("fdiv", (gen_fdiv, 0x0)), + ("bltlr", (gen_bltlr, 0x0)), + ("bdnzflr", (gen_bdnzflr, 0x0)), + ("mtdsisr", (gen_mtdsisr, 0x0)), + ("fcmpo", (gen_fcmpo, 0x0)), + ("mulli", (gen_mulli, 0x0)), + ("cmpwi", (gen_cmpwi, 0x0)), + ("addco.", (gen_addc, 0x401)), + ("ps_abs", (gen_ps_abs, 0x0)), + ("psq_lu", (gen_psq_lu, 0x0)), + ("oris", (gen_oris, 0x0)), + ("bnsa", (gen_bns, 0x2)), + ("ps_madds0.", (gen_ps_madds0, 0x1)), + ("fmadd", (gen_fmadd, 0x0)), + ("psq_lx", (gen_psq_lx, 0x0)), + ("bdzfl-", (gen_bdzf, 0x200001)), + ("bgela-", (gen_bge, 0x200003)), + ("bnelrl", (gen_bnelr, 0x1)), + ("subfzeo.", (gen_subfze, 0x401)), + ("nand", (gen_nand, 0x0)), + ("mtcrf", (gen_mtcrf, 0x0)), + ("lbzu", (gen_lbzu, 0x0)), + ("tweq", (gen_tweq, 0x0)), + ("stwbrx", (gen_stwbrx, 0x0)), + ("slwi.", (gen_slwi, 0x1)), + ("bnsctr", (gen_bnsctr, 0x0)), + ("bdzlr+", (gen_bdzlr, 0x200000)), + ("stfsx", (gen_stfsx, 0x0)), + ("bgtlrl+", (gen_bgtlr, 0x200001)), + ("stbx", (gen_stbx, 0x0)), + ("addic", (gen_addic, 0x0)), + ("rotrwi", (gen_rotrwi, 0x0)), + ("bgectr+", (gen_bgectr, 0x200000)), + ("beqla", (gen_beq, 0x3)), + ("bgelr", (gen_bgelr, 0x0)), + ], +}; +pub fn assemble(mnemonic: &str, args: &Arguments) -> Result { + if let Some(&(fn_ptr, modifiers)) = MNEMONIC_MAP.get(mnemonic) { + fn_ptr(args, modifiers) + } else { + Err(ArgumentError::UnknownMnemonic) + } +} diff --git a/asm/src/lib.rs b/asm/src/lib.rs new file mode 100644 index 0000000..d7d42a4 --- /dev/null +++ b/asm/src/lib.rs @@ -0,0 +1,6 @@ +#![cfg_attr(not(feature = "std"), no_std)] +mod generated; +mod types; + +pub use generated::*; +pub use types::{Argument, ArgumentError}; diff --git a/asm/src/types.rs b/asm/src/types.rs new file mode 100644 index 0000000..1abd493 --- /dev/null +++ b/asm/src/types.rs @@ -0,0 +1,94 @@ +use crate::Arguments; +use core::fmt::Formatter; + +#[derive(Debug)] +pub enum ArgumentError { + ArgOutOfRangeUnsigned { index: usize, value: u32, start: u32, end: u32 }, + ArgOutOfRangeSigned { index: usize, value: i32, start: i32, end: i32 }, + ArgCount { value: usize, expected: usize }, + UnknownMnemonic, +} + +impl core::fmt::Display for ArgumentError { + fn fmt(&self, _f: &mut Formatter<'_>) -> core::fmt::Result { + todo!() + } +} + +#[cfg(feature = "std")] +impl std::error::Error for ArgumentError {} + +#[derive(Debug, Default, Clone, Copy, Eq, PartialEq)] +pub enum Argument { + #[default] + None, + Unsigned(u32), + Signed(i32), +} + +pub const fn parse_unsigned( + args: &Arguments, + index: usize, + start: u32, + end: u32, +) -> Result { + match args[index] { + Argument::Unsigned(value) => { + if value >= start && value <= end { + Ok(value) + } else { + Err(ArgumentError::ArgOutOfRangeUnsigned { index, value, start, end }) + } + } + Argument::Signed(value) => { + if value >= start as i32 && value <= end as i32 { + Ok(value as u32) + } else { + Err(ArgumentError::ArgOutOfRangeUnsigned { index, value: value as u32, start, end }) + } + } + Argument::None => Err(ArgumentError::ArgCount { value: index, expected: index + 1 }), + } +} + +pub const fn parse_signed( + args: &Arguments, + index: usize, + start: i32, + end: i32, +) -> Result { + match args[index] { + Argument::Unsigned(value) => { + if (start < 0 || value >= start as u32) && value <= end as u32 { + Ok(value as i32) + } else { + Err(ArgumentError::ArgOutOfRangeSigned { index, value: value as i32, start, end }) + } + } + Argument::Signed(value) => { + if value >= start && value <= end { + Ok(value) + } else { + Err(ArgumentError::ArgOutOfRangeSigned { index, value, start, end }) + } + } + Argument::None => Err(ArgumentError::ArgCount { value: index, expected: index + 1 }), + } +} + +pub const fn arg_count(args: &Arguments) -> usize { + let mut i = 0; + while i < args.len() && !matches!(args[i], Argument::None) { + i += 1; + } + i +} + +pub const fn check_arg_count(args: &Arguments, expected: usize) -> Result<(), ArgumentError> { + let value = arg_count(args); + if value == expected { + Ok(()) + } else { + Err(ArgumentError::ArgCount { value, expected }) + } +} diff --git a/asm/tests/test_asm.rs b/asm/tests/test_asm.rs new file mode 100644 index 0000000..0f2c586 --- /dev/null +++ b/asm/tests/test_asm.rs @@ -0,0 +1,182 @@ +use ppc750cl_asm::*; +use Argument::{None, Signed as S, Unsigned as U}; + +macro_rules! assert_asm { + ($mnemonic:literal, $arg1:expr, $arg2:expr, $arg3:expr, $arg4:expr, $arg5: expr, $code:literal) => {{ + assert_eq!(assemble($mnemonic, &[$arg1, $arg2, $arg3, $arg4, $arg5]).unwrap(), $code) + }}; + ($mnemonic:literal, $arg1:expr, $arg2:expr, $arg3:expr, $arg4:expr, $code:literal) => {{ + assert_eq!(assemble($mnemonic, &[$arg1, $arg2, $arg3, $arg4, None]).unwrap(), $code) + }}; + ($mnemonic:literal, $arg1:expr, $arg2:expr, $arg3:expr, $code:literal) => {{ + assert_eq!(assemble($mnemonic, &[$arg1, $arg2, $arg3, None, None]).unwrap(), $code) + }}; + ($mnemonic:literal, $arg1:expr, $arg2:expr, $code:literal) => {{ + assert_eq!(assemble($mnemonic, &[$arg1, $arg2, None, None, None]).unwrap(), $code) + }}; + ($mnemonic:literal, $arg1:expr, $code:literal) => {{ + assert_eq!(assemble($mnemonic, &[$arg1, None, None, None, None]).unwrap(), $code) + }}; + ($mnemonic:literal, $code:literal) => {{ + assert_eq!(assemble($mnemonic, &[None, None, None, None, None]).unwrap(), $code) + }}; +} + +#[test] +fn test_ins_add() { + assert_asm!("add", U(2), U(3), U(4), 0x7C432214); // add r2, r3, r4 + assert_asm!("add.", U(7), U(6), U(5), 0x7CE62A15); // add. r7, r6, r5 + assert_asm!("addo", U(31), U(31), U(31), 0x7FFFFE14); // addo r31, r31, r31 + assert_asm!("addo.", U(28), U(29), U(30), 0x7F9DF615); // addo. r28, r29, r30 +} + +#[test] +fn test_ins_addc() { + assert_asm!("addc", U(2), U(3), U(4), 0x7C432014); // addc r2, r3, r4 + assert_asm!("addc.", U(7), U(6), U(5), 0x7CE62815); // addc. r7, r6, r5 + assert_asm!("addco", U(31), U(31), U(31), 0x7FFFFC14); // addco r31, r31, r31 + assert_asm!("addco.", U(28), U(29), U(30), 0x7F9DF415); // addco. r28, r29, r30 +} + +#[test] +fn test_ins_addi() { + assert_asm!("addi", U(0), U(1), U(0x140), 0x38010140); // addi r0, r1, 0x140 + assert_asm!("addi", U(0), U(4), S(-0x7000), 0x38049000); // addi r0, r4, -0x7000 + assert_asm!("subi", U(0), U(4), S(0x7000), 0x38049000); // subi r0, r4, 0x7000 + assert_asm!("li", U(5), U(0), 0x38A00000); // li r5, 0 +} + +#[test] +fn test_ins_b() { + assert_asm!("b", U(0), 0x48000000); // b 0x0 + assert_asm!("b", U(4), 0x48000004); // b 0x4 + assert_asm!("bl", U(0xA5C8), 0x4800A5C9); // bl 0xa5c8 + assert_asm!("bl", U(0x23B4D8), 0x4823B4D9); // bl 0x23b4d8 + assert_asm!("bl", S(-0x1FC368), 0x4BE03C99); // bl -0x1fc368 + assert_asm!("bl", S(-0x23E5A8), 0x4BDC1A59); // bl -0x23e5a8 + assert_asm!("bla", U(0x60), 0x48000063); // bla 0x60 + assert_asm!("ba", U(0), 0x48000002); // ba 0x0 +} + +#[test] +fn test_ins_bc() { + assert_asm!("bge", U(0x8), 0x40800008); // bge 0x8 + assert_asm!("bge", U(0x2350), 0x40802350); // bge 0x2350 + assert_asm!("bge", S(-0x384), 0x4080FC7C); // bge -0x384 + assert_asm!("ble", U(0xac), 0x408100AC); // ble 0xac + assert_asm!("ble", S(-0x878), 0x4081F788); // ble -0x878 + assert_asm!("bne", U(0x1ba0), 0x40821BA0); // bne 0x1ba0 + assert_asm!("bne", S(-0x1c3c), 0x4082E3C4); // bne -0x1c3c + assert_asm!("bne", U(1), U(0xd8), 0x408600D8); // bne cr1, 0xd8 + assert_asm!("bne", U(1), S(-0x134), 0x4086FECC); // bne cr1, -0x134 + assert_asm!("bge", U(7), U(0xc), 0x409C000C); // bge cr7, 0xc + assert_asm!("blt", U(0xc), 0x4180000C); // blt 0xc + assert_asm!("blt", S(-0x640), 0x4180F9C0); // blt -0x640 + assert_asm!("bgt", U(0x21c), 0x4181021C); // bgt 0x21c + assert_asm!("bgt", S(-0x280), 0x4181FD80); // bgt -0x280 + assert_asm!("beq", U(0x2304), 0x41822304); // beq 0x2304 + assert_asm!("beq", S(-0x1c4), 0x4182FE3C); // beq -0x1c4 + assert_asm!("blt", U(1), U(0x1ac), 0x418401AC); // blt cr1, 0x1ac + assert_asm!("blt", U(1), S(-0x31c), 0x4184FCE4); // blt cr1, -0x31c + assert_asm!("bgt", U(1), U(0xc0), 0x418500C0); // bgt cr1, 0xc0 + assert_asm!("bgt", U(1), U(0x2e4), 0x418502E4); // bgt cr1, 0x2e4 + assert_asm!("beq", U(6), U(0x138), 0x419A0138); // beq cr6, 0x138 + assert_asm!("blt", U(7), U(0x8), 0x419C0008); // blt cr7, 0x8 + assert_asm!("bdz", S(-0x10), 0x4240FFF0); // bdz -0x10 + assert_asm!("bdnz", S(-0xaa0), 0x4200F560); // bdnz -0xaa0 + assert_asm!("bdnzf", U(1), U(0x14), 0x40010014); // bdnzf gt, 0x14 + assert_asm!("bdzfl", U(1), U(0x34), 0x40410035); // bdzfl gt, 0x34 + assert_asm!("bdztla", U(3), U(0x20), 0x41430023); // bdztla un, 0x20 + assert_asm!("bdnztla", U(8), S(-0x20), 0x4108FFE3); // bdnztla cr2lt, -0x20 + assert_asm!("bne+", U(0x8), 0x40A20008); // bne+ 0x8 +} + +#[test] +fn test_ins_bcctr() { + assert_asm!("bctr", 0x4E800420); // bctr + assert_asm!("bctrl", 0x4E800421); // bctrl + assert_asm!("beqctr", 0x4D820420); // beqctr + assert_asm!("bgtctrl", U(3), 0x4D8D0421); // bgtctrl cr3 + assert_asm!("beqctr+", 0x4DA20420); // beqctr+ + assert_asm!("bgtctrl+", U(6), 0x4DB90421); // bgtctrl+ cr6 +} + +#[test] +fn test_ins_bclr() { + assert_asm!("bgelr", 0x4C800020); // bgelr + assert_asm!("bgelr+", 0x4CA00020); // bgelr+ + assert_asm!("blelr", 0x4C810020); // blelr + assert_asm!("bnelr", 0x4C820020); // bnelr + assert_asm!("bnelr", U(7), 0x4C9E0020); // bnelr cr7 + assert_asm!("bltlr", 0x4D800020); // bltlr + assert_asm!("bgtlr", 0x4D810020); // bgtlr + assert_asm!("beqlr", 0x4D820020); // beqlr + assert_asm!("beqlr", U(1), 0x4D860020); // beqlr cr1 + assert_asm!("blr", 0x4E800020); // blr + assert_asm!("blrl", 0x4E800021); // blrl + assert_asm!("bdnztlr", U(0), 0x4D000020); // bdnztlr lt + assert_asm!("bdnzflrl", U(31), 0x4C1F0021); // bdnzflrl cr7un +} + +#[test] +fn test_ins_cmpi() { + assert_asm!("cmpi", U(6), U(0), U(31), U(0), 0x2F1F0000); // cmpi r6, 0, 31, 0 + assert_asm!("cmpwi", U(5), U(0xd00), 0x2C050D00); // cmpwi r5, 0xd00 + assert_asm!("cmpwi", U(6), U(31), U(0), 0x2F1F0000); // cmpwi r6, 0 +} + +#[test] +fn test_ins_mfspr() { + assert_asm!("mfsrr0", U(16), 0x7E1A02A6); // mfsrr0 r16 + assert_asm!("mfspr", U(3), U(1008), 0x7C70FAA6); // mfspr r3, HID0 + assert_asm!("mfibatu", U(3), U(2), 0x7C7482A6); // mfibatu r3, 2 + assert_asm!("mfibatl", U(3), U(3), 0x7C7782A6); // mfibatl r3, 3 +} + +#[test] +fn test_ins_rlwimi() { + assert_asm!("rlwimi", U(3), U(0), U(0), U(27), U(31), 0x500306FE); // rlwimi r3, r0, 0, 27, 31 + assert_asm!("rlwimi", U(3), U(0), U(5), U(21), U(26), 0x50032D74); // rlwimi r3, r0, 5, 21, 26 + assert_asm!("clrrwi.", U(0), U(0), U(0), 0x5400003F); // clrrwi. r0, r0, 0 +} + +#[test] +fn test_ins_rlwinm() { + assert_asm!("rlwinm", U(0), U(0), U(0), U(16), U(25), 0x54000432); // rlwinm r0, r0, 0, 16, 25 + assert_asm!("rlwinm", U(9), U(0), U(12), U(8), U(19), 0x54096226); // rlwinm r9, r0, 12, 8, 19 + assert_asm!("rlwinm.", U(0), U(0), U(0), U(16), U(17), 0x54000423); // rlwinm. r0, r0, 0, 16, 17 + assert_asm!("slwi", U(5), U(31), U(2), 0x57E5103A); // slwi r5, r31, 2 + assert_asm!("extlwi", U(3), U(4), U(20), U(4), 0x54832026); // extlwi r3, r4, 20, 4 + assert_asm!("extrwi", U(3), U(4), U(20), U(1), 0x5483AB3E); // extrwi r3, r4, 20, 1 + assert_asm!("extrwi", U(0), U(0), U(2), U(2), 0x540027BE); // extrwi r0, r0, 2, 2 + assert_asm!("rlwinm", U(3), U(4), U(19), U(12), U(31), 0x54839B3E); // rlwinm r3, r4, 19, 12, 31 + assert_asm!("rotlwi", U(3), U(4), U(4), 0x5483203E); // rotlwi r3, r4, 4 + assert_asm!("rotrwi", U(3), U(4), U(4), 0x5483E03E); // rotrwi r3, r4, 4 + assert_asm!("clrlwi", U(4), U(3), U(16), 0x5464043E); // clrlwi r4, r3, 16 + assert_asm!("clrrwi", U(3), U(4), U(4), 0x54830036); // clrrwi r3, r4, 4 + assert_asm!("clrlslwi", U(4), U(3), U(31), U(1), 0x54640FBC); // clrlslwi r4, r3, 31, 1 + assert_asm!("clrlslwi", U(9), U(0), U(27), U(5), 0x54092DB4); // clrlslwi r9, r0, 27, 5 + assert_asm!("clrlslwi", U(9), U(0), U(20), U(12), 0x54096226); // clrlslwi r9, r0, 20, 12 +} + +#[test] +fn test_tw() { + assert_asm!("tw", U(0), U(6), U(7), 0x7C063808); // tw 0, r6, r7 + assert_asm!("tweq", U(4), U(5), 0x7C842808); // tweq r4, r5 + assert_asm!("twlge", U(4), U(5), 0x7CA42808); // twlge r4, r5 + assert_asm!("trap", 0x7FE00008); // trap +} + +#[test] +fn test_twi() { + assert_asm!("twi", U(0), U(0), U(0), 0x0C000000); // twi 0, r0, 0x0 + assert_asm!("twgti", U(7), S(-0x1), 0x0D07FFFF); // twgti r7, -0x1 + assert_asm!("twllei", U(4), S(-0xff), 0x0CC4FF01); // twllei r4, -0xff + assert_asm!("twui", U(4), U(0x3), 0x0FE40003); // twui r4, 0x3 +} + +#[test] +fn test_ins_xor() { + assert_asm!("xor", U(5), U(0), U(5), 0x7C052A78); // xor r5, r0, r5 + assert_asm!("xor.", U(7), U(9), U(10), 0x7D275279); // xor. r7, r9, r10 +} diff --git a/disasm-py/Cargo.toml b/disasm-py/Cargo.toml deleted file mode 100644 index a924bc7..0000000 --- a/disasm-py/Cargo.toml +++ /dev/null @@ -1,20 +0,0 @@ -[package] -name = "ppc750cl-py" -version = "0.2.0" -edition = "2021" -authors = ["Richard Patel "] -license = "GPL-3.0-or-later" -description = "Python bindings for PowerPC 750CL Disassembler" -repository = "https://github.com/terorie/ppc750cl" - -[lib] -name = "ppc750cl" -crate-type = ["cdylib"] - -[features] -extension-module = ["pyo3/extension-module"] -default = ["extension-module"] - -[dependencies] -pyo3 = { version = "0.16", features = ["multiple-pymethods"] } -ppc750cl = { version = "0.2.0", path = "../disasm" } diff --git a/disasm-py/src/lib.rs b/disasm-py/src/lib.rs deleted file mode 100644 index e9a14dd..0000000 --- a/disasm-py/src/lib.rs +++ /dev/null @@ -1,257 +0,0 @@ -use pyo3::prelude::*; -use pyo3::types::PyBytes; - -use ppc750cl::formatter::FormattedIns; - -#[pyclass] -struct Ins(ppc750cl::Ins); - -#[pymethods] -impl Ins { - #[new] - fn new(code: u32, addr: u32) -> Self { - Ins(ppc750cl::Ins::new(code, addr)) - } - - #[getter] - fn code(&self) -> u32 { - self.0.code - } - - #[getter] - fn addr(&self) -> u32 { - self.0.addr - } - - #[getter] - fn opcode(&self) -> &'static str { - self.0.op.mnemonic() - } - - fn __str__(&self) -> String { - FormattedIns(self.0.clone()).to_string() - } - - fn fields(&self) -> Vec<(&'static str, i64)> { - self.0 - .fields() - .iter() - .flat_map(|field| field.argument().map(|arg| (field.name(), arg.into()))) - .collect() - } -} - -#[allow(non_snake_case)] -#[pymethods] -impl Ins { - #[getter] - fn simm(&self) -> i64 { - self.0.field_simm() as i64 - } - #[getter] - fn uimm(&self) -> i64 { - self.0.field_uimm() as i64 - } - #[getter] - fn offset(&self) -> i64 { - self.0.field_offset() as i64 - } - #[getter] - fn ps_offset(&self) -> i64 { - self.0.field_ps_offset() as i64 - } - #[getter] - fn BO(&self) -> i64 { - self.0.field_BO() as i64 - } - #[getter] - fn BI(&self) -> i64 { - self.0.field_BI() as i64 - } - #[getter] - fn BD(&self) -> i64 { - self.0.field_BD() as i64 - } - #[getter] - fn LI(&self) -> i64 { - self.0.field_LI() as i64 - } - #[getter] - fn SH(&self) -> i64 { - self.0.field_SH() as i64 - } - #[getter] - fn MB(&self) -> i64 { - self.0.field_SH() as i64 - } - #[getter] - fn ME(&self) -> i64 { - self.0.field_SH() as i64 - } - #[getter] - fn rS(&self) -> i64 { - self.0.field_rS() as i64 - } - #[getter] - fn rD(&self) -> i64 { - self.0.field_rD() as i64 - } - #[getter] - fn rA(&self) -> i64 { - self.0.field_rA() as i64 - } - #[getter] - fn rB(&self) -> i64 { - self.0.field_rB() as i64 - } - #[getter] - fn sr(&self) -> i64 { - self.0.field_sr() as i64 - } - #[getter] - fn spr(&self) -> i64 { - self.0.field_spr() as i64 - } - #[getter] - fn frS(&self) -> i64 { - self.0.field_frS() as i64 - } - #[getter] - fn frD(&self) -> i64 { - self.0.field_frD() as i64 - } - #[getter] - fn frA(&self) -> i64 { - self.0.field_frA() as i64 - } - #[getter] - fn frB(&self) -> i64 { - self.0.field_frB() as i64 - } - #[getter] - fn frC(&self) -> i64 { - self.0.field_frC() as i64 - } - #[getter] - fn crbD(&self) -> i64 { - self.0.field_crbD() as i64 - } - #[getter] - fn crbA(&self) -> i64 { - self.0.field_crbA() as i64 - } - #[getter] - fn crbB(&self) -> i64 { - self.0.field_crbB() as i64 - } - #[getter] - fn crfD(&self) -> i64 { - self.0.field_crfD() as i64 - } - #[getter] - fn crfS(&self) -> i64 { - self.0.field_crfS() as i64 - } - #[getter] - fn crm(&self) -> i64 { - self.0.field_crm() as i64 - } - #[getter] - fn ps_I(&self) -> i64 { - self.0.field_ps_I() as i64 - } - #[getter] - fn ps_IX(&self) -> i64 { - self.0.field_ps_IX() as i64 - } - #[getter] - fn ps_W(&self) -> i64 { - self.0.field_ps_W() as i64 - } - #[getter] - fn ps_WX(&self) -> i64 { - self.0.field_ps_WX() as i64 - } - #[getter] - fn ps_NB(&self) -> i64 { - self.0.field_NB() as i64 - } - #[getter] - fn tbr(&self) -> i64 { - self.0.field_tbr() as i64 - } - #[getter] - fn mtfsf_FM(&self) -> i64 { - self.0.field_mtfsf_FM() as i64 - } - #[getter] - fn mtfsf_IMM(&self) -> i64 { - self.0.field_mtfsf_IMM() as i64 - } - #[getter] - fn TO(&self) -> i64 { - self.0.field_TO() as i64 - } -} - -impl From for Ins { - fn from(ins: ppc750cl::Ins) -> Self { - Self(ins) - } -} - -#[pyclass] -struct DisasmIterator { - bytes: Py, - addr: u32, - offset: u32, - left: usize, -} - -#[pymethods] -impl DisasmIterator { - fn __iter__(slf: PyRef) -> PyRef { - slf - } - fn __next__(mut slf: PyRefMut) -> PyResult> { - if slf.left < 4 { - return Ok(None); - } - let bytes = slf.bytes.as_ref(slf.py()); - let code = ((bytes[(slf.offset) as usize] as u32) << 24) - | ((bytes[(slf.offset + 1) as usize] as u32) << 16) - | ((bytes[(slf.offset + 2) as usize] as u32) << 8) - | (bytes[(slf.offset + 3) as usize] as u32); - slf.offset += 4; - slf.left -= 4; - let ins = Ins::new(code, slf.addr); - slf.addr += 4; - Ok(Some(ins)) - } -} - -#[pyfunction(code, addr, offset = "0", size = "None")] -fn disasm_iter( - code: &PyBytes, - addr: u32, - offset: u32, - size: Option, -) -> PyResult { - let left = match size { - None => code.as_bytes().len().saturating_sub(offset as usize), - Some(v) => v as usize, - }; - Ok(DisasmIterator { - bytes: code.into(), - addr, - offset, - left, - }) -} - -#[pymodule] -fn ppc750cl(_: Python, m: &PyModule) -> PyResult<()> { - m.add_class::()?; - m.add_wrapped(wrap_pyfunction!(disasm_iter))?; - Ok(()) -} diff --git a/disasm/Cargo.toml b/disasm/Cargo.toml index a8030fa..2124ea1 100644 --- a/disasm/Cargo.toml +++ b/disasm/Cargo.toml @@ -1,13 +1,12 @@ [package] name = "ppc750cl" -version = "0.2.0" +version = "0.3.0" edition = "2021" -authors = ["Richard Patel "] -license = "GPL-3.0-or-later" +authors = ["Luke Street "] +license = "MIT OR Apache-2.0" description = "Disassembler for PowerPC 750CL" keywords = ["powerpc", "wii", "gamecube"] -repository = "https://github.com/terorie/ppc750cl" +repository = "https://github.com/encounter/ppc750cl" [dependencies] -num-traits = "0.2" -serde = "1.0" +# Intentionally left blank. diff --git a/disasm/src/disasm.rs b/disasm/src/disasm.rs new file mode 100644 index 0000000..bffb298 --- /dev/null +++ b/disasm/src/disasm.rs @@ -0,0 +1,368 @@ +use core::{ + fmt, + fmt::{Display, Formatter, LowerHex}, +}; + +use crate::generated::{ + Arguments, Opcode, BASE_MNEMONICS, DEFS_FUNCTIONS, SIMPLIFIED_MNEMONICS, USES_FUNCTIONS, +}; + +/// A PowerPC 750CL instruction. +#[derive(Default, Clone, Debug, Eq, PartialEq)] +pub struct Ins { + pub code: u32, + pub op: Opcode, +} + +impl Ins { + /// Create a new instruction from its raw code. + pub fn new(code: u32) -> Self { + Self { code, op: Opcode::_detect(code) } + } + + /// Parse the instruction into a simplified mnemonic, if any match. + pub fn simplified(self) -> SimplifiedIns { + SimplifiedIns::new(self) + } + + /// Parse the instruction into its basic form. + pub fn basic_form(self) -> SimplifiedIns { + SimplifiedIns::basic_form(self) + } + + /// Returns all registers defined by the instruction. + pub fn defs(&self) -> Arguments { + DEFS_FUNCTIONS[self.op as usize](self) + } + + /// Returns all registers used by the instruction. + pub fn uses(&self) -> Arguments { + USES_FUNCTIONS[self.op as usize](self) + } + + /// Returns the relative branch offset of the instruction, if any. + pub fn branch_offset(&self) -> Option { + match self.op { + Opcode::B => Some(self.field_li()), + Opcode::Bc => Some(self.field_bd() as i32), + _ => None, + } + } + + /// Returns the absolute branch destination of the instruction, if any. + pub fn branch_dest(&self, addr: u32) -> Option { + self.branch_offset().and_then(|offset| { + if self.field_aa() { + Some(offset as u32) + } else { + addr.checked_add_signed(offset) + } + }) + } + + /// Whether the instruction is any kind of branch. + pub fn is_branch(&self) -> bool { + matches!(self.op, Opcode::B | Opcode::Bc | Opcode::Bcctr | Opcode::Bclr) + } + + /// Whether the instruction is a direct branch. + pub fn is_direct_branch(&self) -> bool { + matches!(self.op, Opcode::B | Opcode::Bc) + } + + /// Whether the instruction is an unconditional branch. + pub fn is_unconditional_branch(&self) -> bool { + match self.op { + Opcode::B => true, + Opcode::Bc | Opcode::Bcctr | Opcode::Bclr => { + self.field_bo() == 20 && self.field_bi() == 0 + } + _ => false, + } + } + + /// Whether the instruction is a conditional branch. + pub fn is_conditional_branch(&self) -> bool { + self.is_branch() && !self.is_unconditional_branch() + } + + /// Whether the instruction is a branch with link. (blr) + #[inline] + pub fn is_blr(&self) -> bool { + self.code == 0x4e800020 + } +} + +macro_rules! field_arg_no_display { + ($name:ident, $typ:ident) => { + #[derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq)] + pub struct $name(pub $typ); + impl From<$name> for Argument { + fn from(x: $name) -> Argument { + Argument::$name(x) + } + } + impl From<$typ> for $name { + fn from(x: $typ) -> $name { + $name(x) + } + } + }; +} + +macro_rules! field_arg { + ($name:ident, $typ:ident) => { + field_arg_no_display!($name, $typ); + impl Display for $name { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + write!(f, "{}", self.0) + } + } + }; + ($name:ident, $typ:ident, $format:literal) => { + field_arg_no_display!($name, $typ); + impl Display for $name { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + write!(f, $format, self.0) + } + } + }; + ($name:ident, $typ:ident, $format:literal, $format_arg:expr) => { + field_arg_no_display!($name, $typ); + impl Display for $name { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + write!(f, $format, $format_arg(self.0)) + } + } + }; +} + +// General-purpose register. +field_arg!(GPR, u8, "r{}"); +// Floating-point register (direct or paired-singles mode). +field_arg!(FPR, u8, "f{}"); +// Segment register. +field_arg!(SR, u8); +// Special-purpose register. +field_arg_no_display!(SPR, u16); +impl Display for SPR { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str(match self.0 { + 1 => "XER", + 8 => "LR", + 9 => "CTR", + 18 => "DSISR", + 19 => "DAR", + 22 => "DEC", + 25 => "SDR1", + 26 => "SRR0", + 27 => "SRR1", + 272 => "SPRG0", + 273 => "SPRG1", + 274 => "SPRG2", + 275 => "SPRG3", + 282 => "EAR", + 287 => "PVR", + 528 => "IBAT0U", + 529 => "IBAT0L", + 530 => "IBAT1U", + 531 => "IBAT1L", + 532 => "IBAT2U", + 533 => "IBAT2L", + 534 => "IBAT3U", + 535 => "IBAT3L", + 536 => "DBAT0U", + 537 => "DBAT0L", + 538 => "DBAT1U", + 539 => "DBAT1L", + 540 => "DBAT2U", + 541 => "DBAT2L", + 542 => "DBAT3U", + 543 => "DBAT3L", + 912 => "GQR0", + 913 => "GQR1", + 914 => "GQR2", + 915 => "GQR3", + 916 => "GQR4", + 917 => "GQR5", + 918 => "GQR6", + 919 => "GQR7", + 920 => "HID2", + 921 => "WPAR", + 922 => "DMA_U", + 923 => "DMA_L", + 936 => "UMMCR0", + 937 => "UPMC1", + 938 => "UPMC2", + 939 => "USIA", + 940 => "UMMCR1", + 941 => "UPMC3", + 942 => "UPMC4", + 943 => "USDA", + 952 => "MMCR0", + 953 => "PMC1", + 954 => "PMC2", + 955 => "SIA", + 956 => "MMCR1", + 957 => "PMC3", + 958 => "PMC4", + 959 => "SDA", + 1008 => "HID0", + 1009 => "HID1", + 1010 => "IABR", + 1013 => "DABR", + 1017 => "L2CR", + 1019 => "ICTC", + 1020 => "THRM1", + 1021 => "THRM2", + 1022 => "THRM3", + _ => return write!(f, "{}", self.0), + }) + } +} +// Condition register field. +field_arg!(CRField, u8, "cr{}"); +// Condition register bit (index + condition case). +field_arg_no_display!(CRBit, u8); +impl Display for CRBit { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + let cr = self.0 >> 2; + let cc = self.0 & 3; + if cr != 0 { + write!(f, "{}", CRField(cr))?; + } + const CR_NAMES: [&str; 4] = ["lt", "gt", "eq", "un"]; + f.write_str(CR_NAMES[cc as usize]) + } +} +// Paired-single graphics quantization register +field_arg!(GQR, u8, "qr{}"); +// Unsigned immediate. +field_arg!(Uimm, u16, "{:#x}"); +// Signed immediate. +field_arg!(Simm, i16, "{:#x}", SignedHexLiteral); +// Offset for indirect memory reference. +field_arg!(Offset, i16, "{:#x}", SignedHexLiteral); +// Branch destination. +field_arg!(BranchDest, i32, "{:#x}", SignedHexLiteral); +impl From for BranchDest { + fn from(x: i16) -> BranchDest { + BranchDest(x as i32) + } +} +// Unsigned opaque argument. +field_arg!(OpaqueU, u16); +impl From for OpaqueU { + fn from(x: u8) -> OpaqueU { + OpaqueU(x as u16) + } +} + +#[derive(Debug, Default, Clone, Eq, PartialEq)] +pub enum Argument { + #[default] + None, + GPR(GPR), + FPR(FPR), + SR(SR), + SPR(SPR), + CRField(CRField), + CRBit(CRBit), + GQR(GQR), + Uimm(Uimm), + Simm(Simm), + Offset(Offset), + BranchDest(BranchDest), + OpaqueU(OpaqueU), +} + +impl Display for Argument { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + match self { + Argument::None => Ok(()), + Argument::GPR(x) => x.fmt(f), + Argument::FPR(x) => x.fmt(f), + Argument::SR(x) => x.fmt(f), + Argument::SPR(x) => x.fmt(f), + Argument::CRField(x) => x.fmt(f), + Argument::CRBit(x) => x.fmt(f), + Argument::GQR(x) => x.fmt(f), + Argument::Uimm(x) => x.fmt(f), + Argument::Simm(x) => x.fmt(f), + Argument::Offset(x) => x.fmt(f), + Argument::BranchDest(x) => x.fmt(f), + Argument::OpaqueU(x) => x.fmt(f), + } + } +} + +/// A simplified PowerPC 750CL instruction. +pub struct SimplifiedIns { + pub ins: Ins, + pub mnemonic: &'static str, + pub args: Arguments, +} + +impl SimplifiedIns { + pub fn new(ins: Ins) -> Self { + let (mnemonic, args) = SIMPLIFIED_MNEMONICS[ins.op as usize](&ins); + Self { ins, mnemonic, args } + } + + pub fn basic_form(ins: Ins) -> Self { + let (mnemonic, args) = BASE_MNEMONICS[ins.op as usize](&ins); + Self { ins, mnemonic, args } + } +} + +impl Display for SimplifiedIns { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + write!(f, "{}", self.mnemonic)?; + let mut writing_offset = false; + for (i, argument) in self.args.iter().enumerate() { + if matches!(argument, Argument::None) { + break; + } + if i == 0 { + write!(f, " ")?; + } else if !writing_offset { + write!(f, ", ")?; + } + write!(f, "{}", argument)?; + if let Argument::Offset(_) = argument { + write!(f, "(")?; + writing_offset = true; + continue; + } + if writing_offset { + write!(f, ")")?; + writing_offset = false; + } + } + Ok(()) + } +} + +pub struct SignedHexLiteral(pub T); + +impl LowerHex for SignedHexLiteral { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + if self.0 < 0 { + write!(f, "-")?; + LowerHex::fmt(&-(self.0 as i32), f) + } else { + LowerHex::fmt(&self.0, f) + } + } +} + +impl LowerHex for SignedHexLiteral { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + if self.0 < 0 { + write!(f, "-")?; + LowerHex::fmt(&-(self.0 as i64), f) + } else { + LowerHex::fmt(&self.0, f) + } + } +} diff --git a/disasm/src/formatter.rs b/disasm/src/formatter.rs deleted file mode 100644 index d1322c5..0000000 --- a/disasm/src/formatter.rs +++ /dev/null @@ -1,33 +0,0 @@ -use std::fmt::{Display, Formatter}; - -use crate::prelude::*; - -pub struct FormattedIns(pub Ins); - -impl Display for FormattedIns { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - let simple = self.0.clone().simplified(); - write!(f, "{}{}", simple.mnemonic, simple.suffix)?; - let mut writing_offset = false; - for (i, arg) in simple.args.iter().enumerate() { - if i == 0 { - write!(f, " ")?; - } - if i > 0 && !writing_offset { - write!(f, ", ")?; - } - if let Argument::Offset(val) = arg { - write!(f, "{}(", val)?; - writing_offset = true; - continue; - } else { - write!(f, "{}", arg)?; - } - if writing_offset { - write!(f, ")")?; - writing_offset = false; - } - } - Ok(()) - } -} diff --git a/disasm/src/generated.rs b/disasm/src/generated.rs index c66997f..eaa9639 100644 --- a/disasm/src/generated.rs +++ b/disasm/src/generated.rs @@ -1,8095 +1,11225 @@ -use crate::prelude::*; -#[derive(Debug, Copy, Clone, Eq, PartialEq)] +#![allow(unused)] +#![cfg_attr(rustfmt, rustfmt_skip)] +use crate::disasm::*; +/// The entry table allows us to quickly find the range of possible opcodes for a +/// given 6-bit prefix. 2*64 bytes should fit in a cache line (or two). +const OPCODE_ENTRIES: [(u8, u8); 64] = [ + (0, 0), + (0, 0), + (0, 0), + (0, 1), + (1, 35), + (0, 0), + (0, 0), + (35, 36), + (36, 37), + (0, 0), + (37, 38), + (38, 39), + (39, 40), + (40, 41), + (41, 42), + (42, 43), + (43, 44), + (44, 45), + (45, 46), + (46, 59), + (59, 60), + (60, 61), + (0, 0), + (61, 62), + (62, 63), + (63, 64), + (64, 65), + (65, 66), + (66, 67), + (67, 68), + (0, 0), + (68, 160), + (160, 161), + (161, 162), + (162, 163), + (163, 164), + (164, 165), + (165, 166), + (166, 167), + (167, 168), + (168, 169), + (169, 170), + (170, 171), + (171, 172), + (172, 173), + (173, 174), + (174, 175), + (175, 176), + (176, 177), + (177, 178), + (178, 179), + (179, 180), + (180, 181), + (181, 182), + (182, 183), + (183, 184), + (184, 185), + (185, 186), + (0, 0), + (186, 195), + (195, 196), + (196, 197), + (0, 0), + (197, 222), +]; +/// The bitmask and pattern for each opcode. +const OPCODE_PATTERNS: [(u32, u32); 256] = [ + (0xfc000000, 0xc000000), + (0xffe007ff, 0x100007ec), + (0xfc00007f, 0x1000004c), + (0xfc00007f, 0x1000000c), + (0xfc00007f, 0x1000004e), + (0xfc00007f, 0x1000000e), + (0xfc1f07fe, 0x10000210), + (0xfc0007fe, 0x1000002a), + (0xfc6007ff, 0x10000040), + (0xfc6007ff, 0x100000c0), + (0xfc6007ff, 0x10000000), + (0xfc6007ff, 0x10000080), + (0xfc0007fe, 0x10000024), + (0xfc00003e, 0x1000003a), + (0xfc00003e, 0x1000001c), + (0xfc00003e, 0x1000001e), + (0xfc0007fe, 0x10000420), + (0xfc0007fe, 0x10000460), + (0xfc0007fe, 0x100004a0), + (0xfc0007fe, 0x100004e0), + (0xfc1f07fe, 0x10000090), + (0xfc00003e, 0x10000038), + (0xfc00f83e, 0x10000032), + (0xfc00f83e, 0x10000018), + (0xfc00f83e, 0x1000001a), + (0xfc1f07fe, 0x10000110), + (0xfc1f07fe, 0x10000050), + (0xfc00003e, 0x1000003e), + (0xfc00003e, 0x1000003c), + (0xfc1f07fe, 0x10000030), + (0xfc1f07fe, 0x10000034), + (0xfc00003e, 0x1000002e), + (0xfc0007fe, 0x10000028), + (0xfc00003e, 0x10000014), + (0xfc00003e, 0x10000016), + (0xfc000000, 0x1c000000), + (0xfc000000, 0x20000000), + (0xfc400000, 0x28000000), + (0xfc400000, 0x2c000000), + (0xfc000000, 0x30000000), + (0xfc000000, 0x34000000), + (0xfc000000, 0x38000000), + (0xfc000000, 0x3c000000), + (0xfc000000, 0x40000000), + (0xffffffff, 0x44000002), + (0xfc000000, 0x48000000), + (0xfc00fffe, 0x4c000420), + (0xfc00fffe, 0x4c000020), + (0xfc0007ff, 0x4c000202), + (0xfc0007ff, 0x4c000102), + (0xfc0007ff, 0x4c000242), + (0xfc0007ff, 0x4c0001c2), + (0xfc0007ff, 0x4c000042), + (0xfc0007ff, 0x4c000382), + (0xfc0007ff, 0x4c000342), + (0xfc0007ff, 0x4c000182), + (0xffffffff, 0x4c00012c), + (0xfc63ffff, 0x4c000000), + (0xffffffff, 0x4c000064), + (0xfc000000, 0x50000000), + (0xfc000000, 0x54000000), + (0xfc000000, 0x5c000000), + (0xfc000000, 0x60000000), + (0xfc000000, 0x64000000), + (0xfc000000, 0x68000000), + (0xfc000000, 0x6c000000), + (0xfc000000, 0x70000000), + (0xfc000000, 0x74000000), + (0xfc0003fe, 0x7c000214), + (0xfc0003fe, 0x7c000014), + (0xfc0003fe, 0x7c000114), + (0xfc00fbfe, 0x7c0001d4), + (0xfc00fbfe, 0x7c000194), + (0xfc0007fe, 0x7c000038), + (0xfc0007fe, 0x7c000078), + (0xfc4007ff, 0x7c000000), + (0xfc4007ff, 0x7c000040), + (0xfc00fffe, 0x7c000034), + (0xffe007ff, 0x7c0000ac), + (0xffe007ff, 0x7c0003ac), + (0xffe007ff, 0x7c00006c), + (0xffe007ff, 0x7c00022c), + (0xffe007ff, 0x7c0001ec), + (0xffe007ff, 0x7c0007ec), + (0xfc0003fe, 0x7c0003d6), + (0xfc0003fe, 0x7c000396), + (0xfc0007ff, 0x7c00026c), + (0xfc0007ff, 0x7c00036c), + (0xffffffff, 0x7c0006ac), + (0xfc0007fe, 0x7c000238), + (0xfc00fffe, 0x7c000774), + (0xfc00fffe, 0x7c000734), + (0xffe007fe, 0x7c0007ac), + (0xfc0007ff, 0x7c0000ee), + (0xfc0007ff, 0x7c0000ae), + (0xfc0007ff, 0x7c0004ee), + (0xfc0007ff, 0x7c0004ae), + (0xfc0007ff, 0x7c00046e), + (0xfc0007ff, 0x7c00042e), + (0xfc0007ff, 0x7c0002ee), + (0xfc0007ff, 0x7c0002ae), + (0xfc0007ff, 0x7c00062c), + (0xfc0007ff, 0x7c00026e), + (0xfc0007ff, 0x7c00022e), + (0xfc0007ff, 0x7c0004aa), + (0xfc0007ff, 0x7c00042a), + (0xfc0007ff, 0x7c000028), + (0xfc0007ff, 0x7c00042c), + (0xfc0007ff, 0x7c00006e), + (0xfc0007ff, 0x7c00002e), + (0xfc7fffff, 0x7c000400), + (0xfc1fffff, 0x7c000026), + (0xfc1fffff, 0x7c0000a6), + (0xfc0007ff, 0x7c0002a6), + (0xfc10ffff, 0x7c0004a6), + (0xfc1f07ff, 0x7c000526), + (0xfc0007ff, 0x7c0002e6), + (0xfc100fff, 0x7c000120), + (0xfc1fffff, 0x7c000124), + (0xfc0007ff, 0x7c0003a6), + (0xfc10ffff, 0x7c0001a4), + (0xfc1f07ff, 0x7c0001e4), + (0xfc0007fe, 0x7c000096), + (0xfc0007fe, 0x7c000016), + (0xfc0003fe, 0x7c0001d6), + (0xfc0007fe, 0x7c0003b8), + (0xfc00fbfe, 0x7c0000d0), + (0xfc0007fe, 0x7c0000f8), + (0xfc0007fe, 0x7c000378), + (0xfc0007fe, 0x7c000338), + (0xfc0007fe, 0x7c000030), + (0xfc0007fe, 0x7c000630), + (0xfc0007fe, 0x7c000670), + (0xfc0007fe, 0x7c000430), + (0xfc0007ff, 0x7c0001ee), + (0xfc0007ff, 0x7c0001ae), + (0xfc0007ff, 0x7c0005ee), + (0xfc0007ff, 0x7c0005ae), + (0xfc0007ff, 0x7c0007ae), + (0xfc0007ff, 0x7c00056e), + (0xfc0007ff, 0x7c00052e), + (0xfc0007ff, 0x7c00072c), + (0xfc0007ff, 0x7c00036e), + (0xfc0007ff, 0x7c00032e), + (0xfc0007ff, 0x7c0005aa), + (0xfc0007ff, 0x7c00052a), + (0xfc0007ff, 0x7c00052c), + (0xfc0007ff, 0x7c00012d), + (0xfc0007ff, 0x7c00016e), + (0xfc0007ff, 0x7c00012e), + (0xfc0003fe, 0x7c000050), + (0xfc0003fe, 0x7c000010), + (0xfc0003fe, 0x7c000110), + (0xfc00fbfe, 0x7c0001d0), + (0xfc00fbfe, 0x7c000190), + (0xffffffff, 0x7c0004ac), + (0xffff07ff, 0x7c000264), + (0xffffffff, 0x7c00046c), + (0xfc0007ff, 0x7c000008), + (0xfc0007fe, 0x7c000278), + (0xfc000000, 0x80000000), + (0xfc000000, 0x84000000), + (0xfc000000, 0x88000000), + (0xfc000000, 0x8c000000), + (0xfc000000, 0x90000000), + (0xfc000000, 0x94000000), + (0xfc000000, 0x98000000), + (0xfc000000, 0x9c000000), + (0xfc000000, 0xa0000000), + (0xfc000000, 0xa4000000), + (0xfc000000, 0xa8000000), + (0xfc000000, 0xac000000), + (0xfc000000, 0xb0000000), + (0xfc000000, 0xb4000000), + (0xfc000000, 0xb8000000), + (0xfc000000, 0xbc000000), + (0xfc000000, 0xc0000000), + (0xfc000000, 0xc4000000), + (0xfc000000, 0xc8000000), + (0xfc000000, 0xcc000000), + (0xfc000000, 0xd0000000), + (0xfc000000, 0xd4000000), + (0xfc000000, 0xd8000000), + (0xfc000000, 0xdc000000), + (0xfc000000, 0xe0000000), + (0xfc000000, 0xe4000000), + (0xfc0007fe, 0xec00002a), + (0xfc0007fe, 0xec000024), + (0xfc00003e, 0xec00003a), + (0xfc00003e, 0xec000038), + (0xfc00f83e, 0xec000032), + (0xfc00003e, 0xec00003e), + (0xfc00003e, 0xec00003c), + (0xfc1f07fe, 0xec000030), + (0xfc0007fe, 0xec000028), + (0xfc000000, 0xf0000000), + (0xfc000000, 0xf4000000), + (0xfc1f07fe, 0xfc000210), + (0xfc0007fe, 0xfc00002a), + (0xfc6007ff, 0xfc000040), + (0xfc6007ff, 0xfc000000), + (0xfc1f07fe, 0xfc00001c), + (0xfc1f07fe, 0xfc00001e), + (0xfc0007fe, 0xfc000024), + (0xfc00003e, 0xfc00003a), + (0xfc1f07fe, 0xfc000090), + (0xfc00003e, 0xfc000038), + (0xfc00f83e, 0xfc000032), + (0xfc1f07fe, 0xfc000110), + (0xfc1f07fe, 0xfc000050), + (0xfc00003e, 0xfc00003e), + (0xfc00003e, 0xfc00003c), + (0xfc1f07fe, 0xfc000018), + (0xfc1f07fe, 0xfc000034), + (0xfc00003e, 0xfc00002e), + (0xfc0007fe, 0xfc000028), + (0xfc63ffff, 0xfc000080), + (0xfc1ffffe, 0xfc00048e), + (0xfc1ffffe, 0xfc00008c), + (0xfc1ffffe, 0xfc00004c), + (0xfe0107fe, 0xfc00058e), + (0xfc7f0ffe, 0xfc00010c), + (0, 0), + (0, 0), + (0, 0), + (0, 0), + (0, 0), + (0, 0), + (0, 0), + (0, 0), + (0, 0), + (0, 0), + (0, 0), + (0, 0), + (0, 0), + (0, 0), + (0, 0), + (0, 0), + (0, 0), + (0, 0), + (0, 0), + (0, 0), + (0, 0), + (0, 0), + (0, 0), + (0, 0), + (0, 0), + (0, 0), + (0, 0), + (0, 0), + (0, 0), + (0, 0), + (0, 0), + (0, 0), + (0, 0), + (0, 0), +]; +/// The name of each opcode. +const OPCODE_NAMES: [&str; 256] = [ + "twi", + "dcbz_l", + "psq_lux", + "psq_lx", + "psq_stux", + "psq_stx", + "ps_abs", + "ps_add", + "ps_cmpo0", + "ps_cmpo1", + "ps_cmpu0", + "ps_cmpu1", + "ps_div", + "ps_madd", + "ps_madds0", + "ps_madds1", + "ps_merge00", + "ps_merge01", + "ps_merge10", + "ps_merge11", + "ps_mr", + "ps_msub", + "ps_mul", + "ps_muls0", + "ps_muls1", + "ps_nabs", + "ps_neg", + "ps_nmadd", + "ps_nmsub", + "ps_res", + "ps_rsqrte", + "ps_sel", + "ps_sub", + "ps_sum0", + "ps_sum1", + "mulli", + "subfic", + "cmpli", + "cmpi", + "addic", + "addic.", + "addi", + "addis", + "bc", + "sc", + "b", + "bcctr", + "bclr", + "crand", + "crandc", + "creqv", + "crnand", + "crnor", + "cror", + "crorc", + "crxor", + "isync", + "mcrf", + "rfi", + "rlwimi", + "rlwinm", + "rlwnm", + "ori", + "oris", + "xori", + "xoris", + "andi.", + "andis.", + "add", + "addc", + "adde", + "addme", + "addze", + "and", + "andc", + "cmp", + "cmpl", + "cntlzw", + "dcbf", + "dcbi", + "dcbst", + "dcbt", + "dcbtst", + "dcbz", + "divw", + "divwu", + "eciwx", + "ecowx", + "eieio", + "eqv", + "extsb", + "extsh", + "icbi", + "lbzux", + "lbzx", + "lfdux", + "lfdx", + "lfsux", + "lfsx", + "lhaux", + "lhax", + "lhbrx", + "lhzux", + "lhzx", + "lswi", + "lswx", + "lwarx", + "lwbrx", + "lwzux", + "lwzx", + "mcrxr", + "mfcr", + "mfmsr", + "mfspr", + "mfsr", + "mfsrin", + "mftb", + "mtcrf", + "mtmsr", + "mtspr", + "mtsr", + "mtsrin", + "mulhw", + "mulhwu", + "mullw", + "nand", + "neg", + "nor", + "or", + "orc", + "slw", + "sraw", + "srawi", + "srw", + "stbux", + "stbx", + "stfdux", + "stfdx", + "stfiwx", + "stfsux", + "stfsx", + "sthbrx", + "sthux", + "sthx", + "stswi", + "stswx", + "stwbrx", + "stwcx.", + "stwux", + "stwx", + "subf", + "subfc", + "subfe", + "subfme", + "subfze", + "sync", + "tlbie", + "tlbsync", + "tw", + "xor", + "lwz", + "lwzu", + "lbz", + "lbzu", + "stw", + "stwu", + "stb", + "stbu", + "lhz", + "lhzu", + "lha", + "lhau", + "sth", + "sthu", + "lmw", + "stmw", + "lfs", + "lfsu", + "lfd", + "lfdu", + "stfs", + "stfsu", + "stfd", + "stfdu", + "psq_l", + "psq_lu", + "fadds", + "fdivs", + "fmadds", + "fmsubs", + "fmuls", + "fnmadds", + "fnmsubs", + "fres", + "fsubs", + "psq_st", + "psq_stu", + "fabs", + "fadd", + "fcmpo", + "fcmpu", + "fctiw", + "fctiwz", + "fdiv", + "fmadd", + "fmr", + "fmsub", + "fmul", + "fnabs", + "fneg", + "fnmadd", + "fnmsub", + "frsp", + "frsqrte", + "fsel", + "fsub", + "mcrfs", + "mffs", + "mtfsb0", + "mtfsb1", + "mtfsf", + "mtfsfi", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", +]; +#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)] +#[repr(u8)] +#[non_exhaustive] pub enum Opcode { - Illegal = -1, - Add, - Addc, - Adde, - Addi, - Addic, - Addic_, - Addis, - Addme, - Addze, - And, - Andc, - Andi_, - Andis_, - B, - Bc, - Bcctr, - Bclr, - Cmp, - Cmpi, - Cmpl, - Cmpli, - Cntlzw, - Crand, - Crandc, - Creqv, - Crnand, - Crnor, - Cror, - Crorc, - Crxor, - Dcbf, - Dcbi, - Dcbst, - Dcbt, - Dcbtst, - Dcbz, - DcbzL, - Divw, - Divwu, - Eciwx, - Ecowx, - Eieio, - Eqv, - Extsb, - Extsh, - Fabs, - Fadd, - Fadds, - Fcmpo, - Fcmpu, - Fctiw, - Fctiwz, - Fdiv, - Fdivs, - Fmadd, - Fmadds, - Fmr, - Fmsub, - Fmsubs, - Fmul, - Fmuls, - Fnabs, - Fneg, - Fnmadd, - Fnmadds, - Fnmsub, - Fnmsubs, - Fres, - Frsp, - Frsqrte, - Fsel, - Fsub, - Fsubs, - Icbi, - Isync, - Lbz, - Lbzu, - Lbzux, - Lbzx, - Lfd, - Lfdu, - Lfdux, - Lfdx, - Lfs, - Lfsu, - Lfsux, - Lfsx, - Lha, - Lhau, - Lhaux, - Lhax, - Lhbrx, - Lhz, - Lhzu, - Lhzux, - Lhzx, - Lmw, - Lswi, - Lswx, - Lwarx, - Lwbrx, - Lwz, - Lwzu, - Lwzux, - Lwzx, - Mcrf, - Mcrfs, - Mcrxr, - Mfcr, - Mffs, - Mfmsr, - Mfspr, - Mfsr, - Mfsrin, - Mftb, - Mtcrf, - Mtfsb0, - Mtfsb1, - Mtfsf, - Mtfsfi, - Mtmsr, - Mtspr, - Mtsr, - Mtsrin, - Mulhw, - Mulhwu, - Mulli, - Mullw, - Nand, - Neg, - Nor, - Or, - Orc, - Ori, - Oris, - PsqL, - PsqLu, - PsqLux, - PsqLx, - PsqSt, - PsqStu, - PsqStux, - PsqStx, - PsAbs, - PsAdd, - PsCmpo0, - PsCmpo1, - PsCmpu0, - PsCmpu1, - PsDiv, - PsMadd, - PsMadds0, - PsMadds1, - PsMerge00, - PsMerge01, - PsMerge10, - PsMerge11, - PsMr, - PsMsub, - PsMul, - PsMuls0, - PsMuls1, - PsNabs, - PsNeg, - PsNmadd, - PsNmsub, - PsRes, - PsRsqrte, - PsSel, - PsSub, - PsSum0, - PsSum1, - Rfi, - Rlwimi, - Rlwinm, - Rlwnm, - Sc, - Slw, - Sraw, - Srawi, - Srw, - Stb, - Stbu, - Stbux, - Stbx, - Stfd, - Stfdu, - Stfdux, - Stfdx, - Stfiwx, - Stfs, - Stfsu, - Stfsux, - Stfsx, - Sth, - Sthbrx, - Sthu, - Sthux, - Sthx, - Stmw, - Stswi, - Stswx, - Stw, - Stwbrx, - Stwcx_, - Stwu, - Stwux, - Stwx, - Subf, - Subfc, - Subfe, - Subfic, - Subfme, - Subfze, - Sync, - Tlbie, - Tlbsync, - Tw, - Twi, - Xor, - Xori, - Xoris, + /// An illegal or unknown opcode + #[default] + Illegal = u8::MAX, + /// twi: Trap Word Immediate + Twi = 0, + /// dcbz_l: Data Cache Block Set to Zero Locked + DcbzL = 1, + /// psq_lux: Paired Single Quantized Load with Update Indexed + PsqLux = 2, + /// psq_lx: Paired Single Quantized Load Indexed + PsqLx = 3, + /// psq_stux: Paired Single Quantized Store with Update Indexed + PsqStux = 4, + /// psq_stx: Paired Single Quantized Store Indexed + PsqStx = 5, + /// ps_abs: Paired Single Absolute Value + PsAbs = 6, + /// ps_add: Paired Single Add + PsAdd = 7, + /// ps_cmpo0: Paired Singles Compare Ordered High + PsCmpo0 = 8, + /// ps_cmpo1: Paired Singles Compare Ordered Low + PsCmpo1 = 9, + /// ps_cmpu0: Paired Singles Compare Unordered High + PsCmpu0 = 10, + /// ps_cmpu1: Paired Singles Compare Unordered Low + PsCmpu1 = 11, + /// ps_div: Paired Single Divide + PsDiv = 12, + /// ps_madd: Paired Single Multiply-Add + PsMadd = 13, + /// ps_madds0: Paired Single Multiply-Add Scalar high + PsMadds0 = 14, + /// ps_madds1: Paired Single Multiply-Add Scalar low + PsMadds1 = 15, + /// ps_merge00: Paired Single MERGE high + PsMerge00 = 16, + /// ps_merge01: Paired Single MERGE direct + PsMerge01 = 17, + /// ps_merge10: Paired Single MERGE swapped + PsMerge10 = 18, + /// ps_merge11: Paired Single MERGE low + PsMerge11 = 19, + /// ps_mr: Paired Single Move Register + PsMr = 20, + /// ps_msub: Paired Single Multiply-Subtract + PsMsub = 21, + /// ps_mul: Paired Single Multiply + PsMul = 22, + /// ps_muls0: Paired Single Multiply Scalar high + PsMuls0 = 23, + /// ps_muls1: Paired Single Multiply Scalar low + PsMuls1 = 24, + /// ps_nabs: Paired Single Negative Absolute Value + PsNabs = 25, + /// ps_neg: Paired Single Negate + PsNeg = 26, + /// ps_nmadd: Paired Single Negative Multiply-Add + PsNmadd = 27, + /// ps_nmsub: Paired Single Negative Multiply-Subtract + PsNmsub = 28, + /// ps_res: Paired Single Reciprocal Estimate + PsRes = 29, + /// ps_rsqrte: Paired Single Reciprocal Square Root Estimate + PsRsqrte = 30, + /// ps_sel: Paired Single Select + PsSel = 31, + /// ps_sub: Paired Single Subtract + PsSub = 32, + /// ps_sum0: Paired Single vector SUM high + PsSum0 = 33, + /// ps_sum1: Paired Single vector SUM low + PsSum1 = 34, + /// mulli: Multiply Low Immediate + Mulli = 35, + /// subfic: Subtract from Immediate Carrying + Subfic = 36, + /// cmpli: Compare Logical Immediate + Cmpli = 37, + /// cmpi: Compare Immediate + Cmpi = 38, + /// addic: Add Immediate Carrying + Addic = 39, + /// addic.: Add Immediate Carrying and Record + Addic_ = 40, + /// addi: Add Immediate + Addi = 41, + /// addis: Add Immediate Shifted + Addis = 42, + /// bc: Branch Conditional + Bc = 43, + /// sc: System Call + Sc = 44, + /// b: Branch + B = 45, + /// bcctr: Branch Conditional to Count Register + Bcctr = 46, + /// bclr: Branch Conditional to Link Register + Bclr = 47, + /// crand: Condition Register AND + Crand = 48, + /// crandc: Condition Register AND with Complement + Crandc = 49, + /// creqv: Condition Register Equivalent + Creqv = 50, + /// crnand: Condition Register NAND + Crnand = 51, + /// crnor: Condition Register NOR + Crnor = 52, + /// cror: Condition Register OR + Cror = 53, + /// crorc: Condition Register OR with Complement + Crorc = 54, + /// crxor: Condition Register XOR + Crxor = 55, + /// isync: Instruction Synchronize + Isync = 56, + /// mcrf: Move Condition Register Field + Mcrf = 57, + /// rfi: Return from Interrupt + Rfi = 58, + /// rlwimi: Rotate Left Word Immediate then Mask Insert + Rlwimi = 59, + /// rlwinm: Rotate Left Word Immediate then AND with Mask + Rlwinm = 60, + /// rlwnm: Rotate Left Word then AND with Mask + Rlwnm = 61, + /// ori: OR Immediate + Ori = 62, + /// oris: OR Immediate Shifted + Oris = 63, + /// xori: XOR Immediate + Xori = 64, + /// xoris: XOR Immediate Shifted + Xoris = 65, + /// andi.: AND Immediate + Andi_ = 66, + /// andis.: AND Immediate Shifted + Andis_ = 67, + /// add: Add + Add = 68, + /// addc: Add Carrying + Addc = 69, + /// adde: Add Extended + Adde = 70, + /// addme: Add to Minus One Extended + Addme = 71, + /// addze: Add to Zero Extended + Addze = 72, + /// and: AND + And = 73, + /// andc: AND with Complement + Andc = 74, + /// cmp: Compare + Cmp = 75, + /// cmpl: Compare Logical + Cmpl = 76, + /// cntlzw: Count Leading Zeros Word + Cntlzw = 77, + /// dcbf: Data Cache Block Flush + Dcbf = 78, + /// dcbi: Data Cache Block Invalidate + Dcbi = 79, + /// dcbst: Data Cache Block Store + Dcbst = 80, + /// dcbt: Data Cache Block Touch + Dcbt = 81, + /// dcbtst: Data Cache Block Touch for Store + Dcbtst = 82, + /// dcbz: Data Cache Block Clear to Zero + Dcbz = 83, + /// divw: Divide Word + Divw = 84, + /// divwu: Divide Word Unsigned + Divwu = 85, + /// eciwx: External Control In Word Indexed + Eciwx = 86, + /// ecowx: External Control Out Word Indexed + Ecowx = 87, + /// eieio: Enforce In-Order Execution of I/O + Eieio = 88, + /// eqv: Equivalent + Eqv = 89, + /// extsb: Extend Sign Byte + Extsb = 90, + /// extsh: Extend Sign Half Word + Extsh = 91, + /// icbi: Instruction Cache Block Invalidate + Icbi = 92, + /// lbzux: Load Byte and Zero with Update Indexed + Lbzux = 93, + /// lbzx: Load Byte and Zero Indexed + Lbzx = 94, + /// lfdux: Load Floating-Point Double with Update Indexed + Lfdux = 95, + /// lfdx: Load Floating-Point Double Indexed + Lfdx = 96, + /// lfsux: Load Floating-Point Single with Update Indexed + Lfsux = 97, + /// lfsx: Load Floating-Point Single Indexed + Lfsx = 98, + /// lhaux: Load Half Word Algebraic with Update Indexed + Lhaux = 99, + /// lhax: Load Half Word Algebraic Indexed + Lhax = 100, + /// lhbrx: Load Half Word Byte-Reverse Indexed + Lhbrx = 101, + /// lhzux: Load Half Word and Zero with Update Indexed + Lhzux = 102, + /// lhzx: Load Half Word and Zero Indexed + Lhzx = 103, + /// lswi: Load String Word Immediate + Lswi = 104, + /// lswx: Load String Word Indexed + Lswx = 105, + /// lwarx: Load String Word and Reverse Indexed + Lwarx = 106, + /// lwbrx: Load String Word and Byte-Reverse Indexed + Lwbrx = 107, + /// lwzux: Load Word and Zero with Update Indexed + Lwzux = 108, + /// lwzx: Load Word and Zero Indexed + Lwzx = 109, + /// mcrxr: Move to Condition Register from XER + Mcrxr = 110, + /// mfcr: Move from Condition Register + Mfcr = 111, + /// mfmsr: Move from Machine State Register + Mfmsr = 112, + /// mfspr: Move from Special-Purpose Register + Mfspr = 113, + /// mfsr: Move from Segment Register + Mfsr = 114, + /// mfsrin: Move from Segment Register Indirect + Mfsrin = 115, + /// mftb: Move from Time Base + Mftb = 116, + /// mtcrf: Move to Condition Register Fields + Mtcrf = 117, + /// mtmsr: Move to Machine State Register + Mtmsr = 118, + /// mtspr: Move to Special-Purpose Register + Mtspr = 119, + /// mtsr: Move to Segment Register + Mtsr = 120, + /// mtsrin: Move to Segment Register Indirect + Mtsrin = 121, + /// mulhw: Multiply High Word + Mulhw = 122, + /// mulhwu: Multiply High Word Unsigned + Mulhwu = 123, + /// mullw: Multiply Low Word + Mullw = 124, + /// nand: NAND + Nand = 125, + /// neg: Negate + Neg = 126, + /// nor: NOR + Nor = 127, + /// or: OR + Or = 128, + /// orc: OR with Complement + Orc = 129, + /// slw: Shift Left Word + Slw = 130, + /// sraw: Shift Right Algebraic Word + Sraw = 131, + /// srawi: Shift Right Algebraic Word Immediate + Srawi = 132, + /// srw: Shift Right Word + Srw = 133, + /// stbux: Store Byte with Update Indexed + Stbux = 134, + /// stbx: Store Byte Indexed + Stbx = 135, + /// stfdux: Store Floating-Point Double with Update Indexed + Stfdux = 136, + /// stfdx: Store Floating-Point Double Indexed + Stfdx = 137, + /// stfiwx: Store Floating-Point as Integer Word Indexed + Stfiwx = 138, + /// stfsux: Store Floating-Point Single with Update Indexed + Stfsux = 139, + /// stfsx: Store Floating-Point Single Indexed + Stfsx = 140, + /// sthbrx: Store Half Word Byte-Reverse Indexed + Sthbrx = 141, + /// sthux: Store Half Word with Update Indexed + Sthux = 142, + /// sthx: Store Half Word Indexed + Sthx = 143, + /// stswi: Store String Word Immediate + Stswi = 144, + /// stswx: Store String Word Indexed + Stswx = 145, + /// stwbrx: Store Word Byte-Reverse Indexed + Stwbrx = 146, + /// stwcx.: Store Word Conditional Indexed + Stwcx_ = 147, + /// stwux: Store Word Indexed + Stwux = 148, + /// stwx: Store Word Indexed + Stwx = 149, + /// subf: Subtract From Carrying + Subf = 150, + /// subfc: Subtract from Carrying + Subfc = 151, + /// subfe: Subtract from Extended + Subfe = 152, + /// subfme: Subtract from Minus One Extended + Subfme = 153, + /// subfze: Subtract from Zero Extended + Subfze = 154, + /// sync: Synchronize + Sync = 155, + /// tlbie: Translation Lookaside Buffer Invalidate Entry + Tlbie = 156, + /// tlbsync: TLB Synchronize + Tlbsync = 157, + /// tw: Trap Word + Tw = 158, + /// xor: XOR + Xor = 159, + /// lwz: Load Word and Zero + Lwz = 160, + /// lwzu: Load Word and Zero with Update + Lwzu = 161, + /// lbz: Load Byte and Zero + Lbz = 162, + /// lbzu: Load Byte and Zero with Update + Lbzu = 163, + /// stw: Store Word + Stw = 164, + /// stwu: Store Word with Update + Stwu = 165, + /// stb: Store Byte + Stb = 166, + /// stbu: Store Byte with Update + Stbu = 167, + /// lhz: Load Half Word and Zero + Lhz = 168, + /// lhzu: Load Half Word and Zero with Update + Lhzu = 169, + /// lha: Load Half Word Algebraic + Lha = 170, + /// lhau: Load Half Word Algebraic with Update + Lhau = 171, + /// sth: Store Half Word + Sth = 172, + /// sthu: Store Half Word with Update + Sthu = 173, + /// lmw: Load Multiple Word + Lmw = 174, + /// stmw: Store Multiple Word + Stmw = 175, + /// lfs: Load Floating-Point Single + Lfs = 176, + /// lfsu: Load Floating-Point Single with Update + Lfsu = 177, + /// lfd: Load Floating-Point Double + Lfd = 178, + /// lfdu: Load Floating-Point Double with Update + Lfdu = 179, + /// stfs: Store Floating-Point Single + Stfs = 180, + /// stfsu: Store Floating-Point Single with Update + Stfsu = 181, + /// stfd: Store Floating-Point Double + Stfd = 182, + /// stfdu: Store Floating-Point Double with Update + Stfdu = 183, + /// psq_l: Paired Single Quantized Load + PsqL = 184, + /// psq_lu: Paired Single Quantized Load with Update + PsqLu = 185, + /// fadds: Floating Add (Single-Precision) + Fadds = 186, + /// fdivs: Floating Divide (Single-Precision) + Fdivs = 187, + /// fmadds: Floating Multiply-Add (Single-Precision) + Fmadds = 188, + /// fmsubs: Floating Multiply-Subtract (Single-Precision) + Fmsubs = 189, + /// fmuls: Floating Multiply (Single-Precision) + Fmuls = 190, + /// fnmadds: Floating Negative Multiply-Add (Single-Precision) + Fnmadds = 191, + /// fnmsubs: Floating Negative Multiply-Subtract (Single-Precision) + Fnmsubs = 192, + /// fres: Floating Reciprocal Estimate Single + Fres = 193, + /// fsubs: Floating Subtract (Single-Precision) + Fsubs = 194, + /// psq_st: Paired Single Quantized Store + PsqSt = 195, + /// psq_stu: Paired Single Quantized Store with Update + PsqStu = 196, + /// fabs: Floating Absolute Value + Fabs = 197, + /// fadd: Floating Add (Double-Precision) + Fadd = 198, + /// fcmpo: Floating Compare Ordered + Fcmpo = 199, + /// fcmpu: Floating Compare Unordered + Fcmpu = 200, + /// fctiw: Floating Convert to Integer Word + Fctiw = 201, + /// fctiwz: Floating Convert to Integer Word with Round toward Zero + Fctiwz = 202, + /// fdiv: Floating Divide (Double-Precision) + Fdiv = 203, + /// fmadd: Floating Multiply-Add (Double-Precision) + Fmadd = 204, + /// fmr: Floating Move Register (Double-Precision) + Fmr = 205, + /// fmsub: Floating Multiply-Subtract (Double-Precision) + Fmsub = 206, + /// fmul: Floating Multiply (Double-Precision) + Fmul = 207, + /// fnabs: Floating Negative Absolute Value + Fnabs = 208, + /// fneg: Floating Negate + Fneg = 209, + /// fnmadd: Floating Negative Multiply-Add (Double-Precision) + Fnmadd = 210, + /// fnmsub: Floating Negative Multiply-Subtract (Double-Precision) + Fnmsub = 211, + /// frsp: Floating Round to Single + Frsp = 212, + /// frsqrte: Floating Reciprocal Square Root Estimate + Frsqrte = 213, + /// fsel: Floating Select + Fsel = 214, + /// fsub: Floating Subtract (Double-Precision) + Fsub = 215, + /// mcrfs: Move to Condition Register from FPSCR + Mcrfs = 216, + /// mffs: Move from FPSCR + Mffs = 217, + /// mtfsb0: Move to FPSCR Bit 0 + Mtfsb0 = 218, + /// mtfsb1: Move to FPSCR Bit 1 + Mtfsb1 = 219, + /// mtfsf: Move to FPSCR Fields + Mtfsf = 220, + /// mtfsfi: Move to FPSCR Field Immediate + Mtfsfi = 221, } -#[allow(clippy::all)] impl Opcode { - pub(crate) fn _mnemonic(self) -> &'static str { - match self { - Opcode::Illegal => "", - Opcode::Add => "add", - Opcode::Addc => "addc", - Opcode::Adde => "adde", - Opcode::Addi => "addi", - Opcode::Addic => "addic", - Opcode::Addic_ => "addic.", - Opcode::Addis => "addis", - Opcode::Addme => "addme", - Opcode::Addze => "addze", - Opcode::And => "and", - Opcode::Andc => "andc", - Opcode::Andi_ => "andi.", - Opcode::Andis_ => "andis.", - Opcode::B => "b", - Opcode::Bc => "bc", - Opcode::Bcctr => "bcctr", - Opcode::Bclr => "bclr", - Opcode::Cmp => "cmp", - Opcode::Cmpi => "cmpi", - Opcode::Cmpl => "cmpl", - Opcode::Cmpli => "cmpli", - Opcode::Cntlzw => "cntlzw", - Opcode::Crand => "crand", - Opcode::Crandc => "crandc", - Opcode::Creqv => "creqv", - Opcode::Crnand => "crnand", - Opcode::Crnor => "crnor", - Opcode::Cror => "cror", - Opcode::Crorc => "crorc", - Opcode::Crxor => "crxor", - Opcode::Dcbf => "dcbf", - Opcode::Dcbi => "dcbi", - Opcode::Dcbst => "dcbst", - Opcode::Dcbt => "dcbt", - Opcode::Dcbtst => "dcbtst", - Opcode::Dcbz => "dcbz", - Opcode::DcbzL => "dcbz_l", - Opcode::Divw => "divw", - Opcode::Divwu => "divwu", - Opcode::Eciwx => "eciwx", - Opcode::Ecowx => "ecowx", - Opcode::Eieio => "eieio", - Opcode::Eqv => "eqv", - Opcode::Extsb => "extsb", - Opcode::Extsh => "extsh", - Opcode::Fabs => "fabs", - Opcode::Fadd => "fadd", - Opcode::Fadds => "fadds", - Opcode::Fcmpo => "fcmpo", - Opcode::Fcmpu => "fcmpu", - Opcode::Fctiw => "fctiw", - Opcode::Fctiwz => "fctiwz", - Opcode::Fdiv => "fdiv", - Opcode::Fdivs => "fdivs", - Opcode::Fmadd => "fmadd", - Opcode::Fmadds => "fmadds", - Opcode::Fmr => "fmr", - Opcode::Fmsub => "fmsub", - Opcode::Fmsubs => "fmsubs", - Opcode::Fmul => "fmul", - Opcode::Fmuls => "fmuls", - Opcode::Fnabs => "fnabs", - Opcode::Fneg => "fneg", - Opcode::Fnmadd => "fnmadd", - Opcode::Fnmadds => "fnmadds", - Opcode::Fnmsub => "fnmsub", - Opcode::Fnmsubs => "fnmsubs", - Opcode::Fres => "fres", - Opcode::Frsp => "frsp", - Opcode::Frsqrte => "frsqrte", - Opcode::Fsel => "fsel", - Opcode::Fsub => "fsub", - Opcode::Fsubs => "fsubs", - Opcode::Icbi => "icbi", - Opcode::Isync => "isync", - Opcode::Lbz => "lbz", - Opcode::Lbzu => "lbzu", - Opcode::Lbzux => "lbzux", - Opcode::Lbzx => "lbzx", - Opcode::Lfd => "lfd", - Opcode::Lfdu => "lfdu", - Opcode::Lfdux => "lfdux", - Opcode::Lfdx => "lfdx", - Opcode::Lfs => "lfs", - Opcode::Lfsu => "lfsu", - Opcode::Lfsux => "lfsux", - Opcode::Lfsx => "lfsx", - Opcode::Lha => "lha", - Opcode::Lhau => "lhau", - Opcode::Lhaux => "lhaux", - Opcode::Lhax => "lhax", - Opcode::Lhbrx => "lhbrx", - Opcode::Lhz => "lhz", - Opcode::Lhzu => "lhzu", - Opcode::Lhzux => "lhzux", - Opcode::Lhzx => "lhzx", - Opcode::Lmw => "lmw", - Opcode::Lswi => "lswi", - Opcode::Lswx => "lswx", - Opcode::Lwarx => "lwarx", - Opcode::Lwbrx => "lwbrx", - Opcode::Lwz => "lwz", - Opcode::Lwzu => "lwzu", - Opcode::Lwzux => "lwzux", - Opcode::Lwzx => "lwzx", - Opcode::Mcrf => "mcrf", - Opcode::Mcrfs => "mcrfs", - Opcode::Mcrxr => "mcrxr", - Opcode::Mfcr => "mfcr", - Opcode::Mffs => "mffs", - Opcode::Mfmsr => "mfmsr", - Opcode::Mfspr => "mfspr", - Opcode::Mfsr => "mfsr", - Opcode::Mfsrin => "mfsrin", - Opcode::Mftb => "mftb", - Opcode::Mtcrf => "mtcrf", - Opcode::Mtfsb0 => "mtfsb0", - Opcode::Mtfsb1 => "mtfsb1", - Opcode::Mtfsf => "mtfsf", - Opcode::Mtfsfi => "mtfsfi", - Opcode::Mtmsr => "mtmsr", - Opcode::Mtspr => "mtspr", - Opcode::Mtsr => "mtsr", - Opcode::Mtsrin => "mtsrin", - Opcode::Mulhw => "mulhw", - Opcode::Mulhwu => "mulhwu", - Opcode::Mulli => "mulli", - Opcode::Mullw => "mullw", - Opcode::Nand => "nand", - Opcode::Neg => "neg", - Opcode::Nor => "nor", - Opcode::Or => "or", - Opcode::Orc => "orc", - Opcode::Ori => "ori", - Opcode::Oris => "oris", - Opcode::PsqL => "psq_l", - Opcode::PsqLu => "psq_lu", - Opcode::PsqLux => "psq_lux", - Opcode::PsqLx => "psq_lx", - Opcode::PsqSt => "psq_st", - Opcode::PsqStu => "psq_stu", - Opcode::PsqStux => "psq_stux", - Opcode::PsqStx => "psq_stx", - Opcode::PsAbs => "ps_abs", - Opcode::PsAdd => "ps_add", - Opcode::PsCmpo0 => "ps_cmpo0", - Opcode::PsCmpo1 => "ps_cmpo1", - Opcode::PsCmpu0 => "ps_cmpu0", - Opcode::PsCmpu1 => "ps_cmpu1", - Opcode::PsDiv => "ps_div", - Opcode::PsMadd => "ps_madd", - Opcode::PsMadds0 => "ps_madds0", - Opcode::PsMadds1 => "ps_madds1", - Opcode::PsMerge00 => "ps_merge00", - Opcode::PsMerge01 => "ps_merge01", - Opcode::PsMerge10 => "ps_merge10", - Opcode::PsMerge11 => "ps_merge11", - Opcode::PsMr => "ps_mr", - Opcode::PsMsub => "ps_msub", - Opcode::PsMul => "ps_mul", - Opcode::PsMuls0 => "ps_muls0", - Opcode::PsMuls1 => "ps_muls1", - Opcode::PsNabs => "ps_nabs", - Opcode::PsNeg => "ps_neg", - Opcode::PsNmadd => "ps_nmadd", - Opcode::PsNmsub => "ps_nmsub", - Opcode::PsRes => "ps_res", - Opcode::PsRsqrte => "ps_rsqrte", - Opcode::PsSel => "ps_sel", - Opcode::PsSub => "ps_sub", - Opcode::PsSum0 => "ps_sum0", - Opcode::PsSum1 => "ps_sum1", - Opcode::Rfi => "rfi", - Opcode::Rlwimi => "rlwimi", - Opcode::Rlwinm => "rlwinm", - Opcode::Rlwnm => "rlwnm", - Opcode::Sc => "sc", - Opcode::Slw => "slw", - Opcode::Sraw => "sraw", - Opcode::Srawi => "srawi", - Opcode::Srw => "srw", - Opcode::Stb => "stb", - Opcode::Stbu => "stbu", - Opcode::Stbux => "stbux", - Opcode::Stbx => "stbx", - Opcode::Stfd => "stfd", - Opcode::Stfdu => "stfdu", - Opcode::Stfdux => "stfdux", - Opcode::Stfdx => "stfdx", - Opcode::Stfiwx => "stfiwx", - Opcode::Stfs => "stfs", - Opcode::Stfsu => "stfsu", - Opcode::Stfsux => "stfsux", - Opcode::Stfsx => "stfsx", - Opcode::Sth => "sth", - Opcode::Sthbrx => "sthbrx", - Opcode::Sthu => "sthu", - Opcode::Sthux => "sthux", - Opcode::Sthx => "sthx", - Opcode::Stmw => "stmw", - Opcode::Stswi => "stswi", - Opcode::Stswx => "stswx", - Opcode::Stw => "stw", - Opcode::Stwbrx => "stwbrx", - Opcode::Stwcx_ => "stwcx.", - Opcode::Stwu => "stwu", - Opcode::Stwux => "stwux", - Opcode::Stwx => "stwx", - Opcode::Subf => "subf", - Opcode::Subfc => "subfc", - Opcode::Subfe => "subfe", - Opcode::Subfic => "subfic", - Opcode::Subfme => "subfme", - Opcode::Subfze => "subfze", - Opcode::Sync => "sync", - Opcode::Tlbie => "tlbie", - Opcode::Tlbsync => "tlbsync", - Opcode::Tw => "tw", - Opcode::Twi => "twi", - Opcode::Xor => "xor", - Opcode::Xori => "xori", - Opcode::Xoris => "xoris", - } + #[inline] + pub const fn _mnemonic(self) -> &'static str { + OPCODE_NAMES[self as usize] } - pub(crate) fn _detect(code: u32) -> Self { - if code & 0xfc0003fe == 0x7c000214 { - return Opcode::Add; - } - if code & 0xfc0003fe == 0x7c000014 { - return Opcode::Addc; - } - if code & 0xfc0003fe == 0x7c000114 { - return Opcode::Adde; - } - if code & 0xfc000000 == 0x38000000 { - return Opcode::Addi; - } - if code & 0xfc000000 == 0x30000000 { - return Opcode::Addic; - } - if code & 0xfc000000 == 0x34000000 { - return Opcode::Addic_; - } - if code & 0xfc000000 == 0x3c000000 { - return Opcode::Addis; - } - if code & 0xfc00fbfe == 0x7c0001d4 { - return Opcode::Addme; - } - if code & 0xfc00fbfe == 0x7c000194 { - return Opcode::Addze; - } - if code & 0xfc0007fe == 0x7c000038 { - return Opcode::And; - } - if code & 0xfc0007fe == 0x7c000078 { - return Opcode::Andc; - } - if code & 0xfc000000 == 0x70000000 { - return Opcode::Andi_; - } - if code & 0xfc000000 == 0x74000000 { - return Opcode::Andis_; - } - if code & 0xfc000000 == 0x48000000 { - return Opcode::B; - } - if code & 0xfc000000 == 0x40000000 { - return Opcode::Bc; - } - if code & 0xfc00fffe == 0x4c000420 { - return Opcode::Bcctr; - } - if code & 0xfc00fffe == 0x4c000020 { - return Opcode::Bclr; - } - if code & 0xfc4007ff == 0x7c000000 { - return Opcode::Cmp; - } - if code & 0xfc400000 == 0x2c000000 { - return Opcode::Cmpi; - } - if code & 0xfc4007ff == 0x7c000040 { - return Opcode::Cmpl; - } - if code & 0xfc400000 == 0x28000000 { - return Opcode::Cmpli; - } - if code & 0xfc00fffe == 0x7c000034 { - return Opcode::Cntlzw; - } - if code & 0xfc0007ff == 0x4c000202 { - return Opcode::Crand; - } - if code & 0xfc0007ff == 0x4c000102 { - return Opcode::Crandc; - } - if code & 0xfc0007ff == 0x4c000242 { - return Opcode::Creqv; - } - if code & 0xfc0007ff == 0x4c0001c2 { - return Opcode::Crnand; - } - if code & 0xfc0007ff == 0x4c000042 { - return Opcode::Crnor; - } - if code & 0xfc0007ff == 0x4c000382 { - return Opcode::Cror; - } - if code & 0xfc0007ff == 0x4c000342 { - return Opcode::Crorc; - } - if code & 0xfc0007ff == 0x4c000182 { - return Opcode::Crxor; - } - if code & 0xffe007ff == 0x7c0000ac { - return Opcode::Dcbf; - } - if code & 0xffe007ff == 0x7c0003ac { - return Opcode::Dcbi; - } - if code & 0xffe007ff == 0x7c00006c { - return Opcode::Dcbst; - } - if code & 0xffe007ff == 0x7c00022c { - return Opcode::Dcbt; - } - if code & 0xffe007ff == 0x7c0001ec { - return Opcode::Dcbtst; - } - if code & 0xffe007ff == 0x7c0007ec { - return Opcode::Dcbz; - } - if code & 0xffe007ff == 0x100007ec { - return Opcode::DcbzL; - } - if code & 0xfc0003fe == 0x7c0003d6 { - return Opcode::Divw; - } - if code & 0xfc0003fe == 0x7c000396 { - return Opcode::Divwu; - } - if code & 0xfc0007ff == 0x7c00026c { - return Opcode::Eciwx; - } - if code & 0xfc0007ff == 0x7c00036c { - return Opcode::Ecowx; - } - if code & 0xffffffff == 0x7c0006ac { - return Opcode::Eieio; - } - if code & 0xfc0007fe == 0x7c000238 { - return Opcode::Eqv; - } - if code & 0xfc00fffe == 0x7c000774 { - return Opcode::Extsb; - } - if code & 0xfc00fffe == 0x7c000734 { - return Opcode::Extsh; - } - if code & 0xfc1f07fe == 0xfc000210 { - return Opcode::Fabs; - } - if code & 0xfc0007fe == 0xfc00002a { - return Opcode::Fadd; - } - if code & 0xfc0007fe == 0xec00002a { - return Opcode::Fadds; - } - if code & 0xfc6007ff == 0xfc000040 { - return Opcode::Fcmpo; - } - if code & 0xfc6007ff == 0xfc000000 { - return Opcode::Fcmpu; - } - if code & 0xfc1f07fe == 0xfc00001c { - return Opcode::Fctiw; - } - if code & 0xfc1f07fe == 0xfc00001e { - return Opcode::Fctiwz; - } - if code & 0xfc0007fe == 0xfc000024 { - return Opcode::Fdiv; - } - if code & 0xfc0007fe == 0xec000024 { - return Opcode::Fdivs; - } - if code & 0xfc00003e == 0xfc00003a { - return Opcode::Fmadd; - } - if code & 0xfc00003e == 0xec00003a { - return Opcode::Fmadds; - } - if code & 0xfc1f07fe == 0xfc000090 { - return Opcode::Fmr; - } - if code & 0xfc00003e == 0xfc000038 { - return Opcode::Fmsub; - } - if code & 0xfc00003e == 0xec000038 { - return Opcode::Fmsubs; - } - if code & 0xfc00f83e == 0xfc000032 { - return Opcode::Fmul; - } - if code & 0xfc00f83e == 0xec000032 { - return Opcode::Fmuls; - } - if code & 0xfc1f07fe == 0xfc000110 { - return Opcode::Fnabs; - } - if code & 0xfc1f07fe == 0xfc000050 { - return Opcode::Fneg; - } - if code & 0xfc00003e == 0xfc00003e { - return Opcode::Fnmadd; - } - if code & 0xfc00003e == 0xec00003e { - return Opcode::Fnmadds; - } - if code & 0xfc00003e == 0xfc00003c { - return Opcode::Fnmsub; - } - if code & 0xfc00003e == 0xec00003c { - return Opcode::Fnmsubs; - } - if code & 0xfc1f07fe == 0xec000030 { - return Opcode::Fres; - } - if code & 0xfc1f07fe == 0xfc000018 { - return Opcode::Frsp; - } - if code & 0xfc1f07fe == 0xfc000034 { - return Opcode::Frsqrte; - } - if code & 0xfc00003e == 0xfc00002e { - return Opcode::Fsel; - } - if code & 0xfc0007fe == 0xfc000028 { - return Opcode::Fsub; - } - if code & 0xfc0007fe == 0xec000028 { - return Opcode::Fsubs; - } - if code & 0xffe007fe == 0x7c0007ac { - return Opcode::Icbi; - } - if code & 0xffffffff == 0x4c00012c { - return Opcode::Isync; - } - if code & 0xfc000000 == 0x88000000 { - return Opcode::Lbz; - } - if code & 0xfc000000 == 0x8c000000 { - return Opcode::Lbzu; - } - if code & 0xfc0007ff == 0x7c0000ee { - return Opcode::Lbzux; - } - if code & 0xfc0007ff == 0x7c0000ae { - return Opcode::Lbzx; - } - if code & 0xfc000000 == 0xc8000000 { - return Opcode::Lfd; - } - if code & 0xfc000000 == 0xcc000000 { - return Opcode::Lfdu; - } - if code & 0xfc0007ff == 0x7c0004ee { - return Opcode::Lfdux; - } - if code & 0xfc0007ff == 0x7c0004ae { - return Opcode::Lfdx; - } - if code & 0xfc000000 == 0xc0000000 { - return Opcode::Lfs; - } - if code & 0xfc000000 == 0xc4000000 { - return Opcode::Lfsu; - } - if code & 0xfc0007ff == 0x7c00046e { - return Opcode::Lfsux; - } - if code & 0xfc0007ff == 0x7c00042e { - return Opcode::Lfsx; - } - if code & 0xfc000000 == 0xa8000000 { - return Opcode::Lha; - } - if code & 0xfc000000 == 0xac000000 { - return Opcode::Lhau; - } - if code & 0xfc0007ff == 0x7c0002ee { - return Opcode::Lhaux; - } - if code & 0xfc0007ff == 0x7c0002ae { - return Opcode::Lhax; - } - if code & 0xfc0007ff == 0x7c00062c { - return Opcode::Lhbrx; - } - if code & 0xfc000000 == 0xa0000000 { - return Opcode::Lhz; - } - if code & 0xfc000000 == 0xa4000000 { - return Opcode::Lhzu; - } - if code & 0xfc0007ff == 0x7c00026e { - return Opcode::Lhzux; - } - if code & 0xfc0007ff == 0x7c00022e { - return Opcode::Lhzx; - } - if code & 0xfc000000 == 0xb8000000 { - return Opcode::Lmw; - } - if code & 0xfc0007ff == 0x7c0004aa { - return Opcode::Lswi; - } - if code & 0xfc0007ff == 0x7c00042a { - return Opcode::Lswx; - } - if code & 0xfc0007ff == 0x7c000028 { - return Opcode::Lwarx; - } - if code & 0xfc0007ff == 0x7c00042c { - return Opcode::Lwbrx; - } - if code & 0xfc000000 == 0x80000000 { - return Opcode::Lwz; - } - if code & 0xfc000000 == 0x84000000 { - return Opcode::Lwzu; - } - if code & 0xfc0007ff == 0x7c00006e { - return Opcode::Lwzux; - } - if code & 0xfc0007ff == 0x7c00002e { - return Opcode::Lwzx; - } - if code & 0xfc63ffff == 0x4c000000 { - return Opcode::Mcrf; - } - if code & 0xfc63ffff == 0xfc000080 { - return Opcode::Mcrfs; - } - if code & 0xfc7fffff == 0x7c000400 { - return Opcode::Mcrxr; - } - if code & 0xfc1fffff == 0x7c000026 { - return Opcode::Mfcr; - } - if code & 0xfc1ffffe == 0xfc00048e { - return Opcode::Mffs; - } - if code & 0xfc1fffff == 0x7c0000a6 { - return Opcode::Mfmsr; - } - if code & 0xfc0007ff == 0x7c0002a6 { - return Opcode::Mfspr; - } - if code & 0xfc10ffff == 0x7c0004a6 { - return Opcode::Mfsr; - } - if code & 0xfc1f07ff == 0x7c000526 { - return Opcode::Mfsrin; - } - if code & 0xfc0007ff == 0x7c0002e6 { - return Opcode::Mftb; - } - if code & 0xfc100fff == 0x7c000120 { - return Opcode::Mtcrf; - } - if code & 0xfc1ffffe == 0xfc00008c { - return Opcode::Mtfsb0; - } - if code & 0xfc1ffffe == 0xfc00004c { - return Opcode::Mtfsb1; - } - if code & 0xfe0107fe == 0xfc00058e { - return Opcode::Mtfsf; - } - if code & 0xfc7f0ffe == 0xfc00010c { - return Opcode::Mtfsfi; - } - if code & 0xfc1fffff == 0x7c000124 { - return Opcode::Mtmsr; - } - if code & 0xfc0007ff == 0x7c0003a6 { - return Opcode::Mtspr; - } - if code & 0xfc10ffff == 0x7c0001a4 { - return Opcode::Mtsr; - } - if code & 0xfc1f07ff == 0x7c0001e4 { - return Opcode::Mtsrin; - } - if code & 0xfc0007fe == 0x7c000096 { - return Opcode::Mulhw; - } - if code & 0xfc0007fe == 0x7c000016 { - return Opcode::Mulhwu; - } - if code & 0xfc000000 == 0x1c000000 { - return Opcode::Mulli; - } - if code & 0xfc0003fe == 0x7c0001d6 { - return Opcode::Mullw; - } - if code & 0xfc0007fe == 0x7c0003b8 { - return Opcode::Nand; - } - if code & 0xfc00fbfe == 0x7c0000d0 { - return Opcode::Neg; - } - if code & 0xfc0007fe == 0x7c0000f8 { - return Opcode::Nor; - } - if code & 0xfc0007fe == 0x7c000378 { - return Opcode::Or; - } - if code & 0xfc0007fe == 0x7c000338 { - return Opcode::Orc; - } - if code & 0xfc000000 == 0x60000000 { - return Opcode::Ori; - } - if code & 0xfc000000 == 0x64000000 { - return Opcode::Oris; - } - if code & 0xfc000000 == 0xe0000000 { - return Opcode::PsqL; - } - if code & 0xfc000000 == 0xe4000000 { - return Opcode::PsqLu; - } - if code & 0xfc00007f == 0x1000004c { - return Opcode::PsqLux; - } - if code & 0xfc00007f == 0x1000000c { - return Opcode::PsqLx; - } - if code & 0xfc000000 == 0xf0000000 { - return Opcode::PsqSt; - } - if code & 0xfc000000 == 0xf4000000 { - return Opcode::PsqStu; - } - if code & 0xfc00007f == 0x1000004e { - return Opcode::PsqStux; - } - if code & 0xfc00007f == 0x1000000e { - return Opcode::PsqStx; - } - if code & 0xfc1f07fe == 0x10000210 { - return Opcode::PsAbs; - } - if code & 0xfc0007fe == 0x1000002a { - return Opcode::PsAdd; - } - if code & 0xfc6007ff == 0x10000040 { - return Opcode::PsCmpo0; - } - if code & 0xfc6007ff == 0x100000c0 { - return Opcode::PsCmpo1; - } - if code & 0xfc6007ff == 0x10000000 { - return Opcode::PsCmpu0; - } - if code & 0xfc6007ff == 0x10000080 { - return Opcode::PsCmpu1; - } - if code & 0xfc0007fe == 0x10000024 { - return Opcode::PsDiv; - } - if code & 0xfc00003e == 0x1000003a { - return Opcode::PsMadd; - } - if code & 0xfc00003e == 0x1000001c { - return Opcode::PsMadds0; - } - if code & 0xfc00003e == 0x1000001e { - return Opcode::PsMadds1; - } - if code & 0xfc0007fe == 0x10000420 { - return Opcode::PsMerge00; - } - if code & 0xfc0007fe == 0x10000460 { - return Opcode::PsMerge01; - } - if code & 0xfc0007fe == 0x100004a0 { - return Opcode::PsMerge10; - } - if code & 0xfc0007fe == 0x100004e0 { - return Opcode::PsMerge11; - } - if code & 0xfc1f07fe == 0x10000090 { - return Opcode::PsMr; - } - if code & 0xfc00003e == 0x10000038 { - return Opcode::PsMsub; - } - if code & 0xfc00f83e == 0x10000032 { - return Opcode::PsMul; - } - if code & 0xfc00f83e == 0x10000018 { - return Opcode::PsMuls0; - } - if code & 0xfc00f83e == 0x1000001a { - return Opcode::PsMuls1; - } - if code & 0xfc1f07fe == 0x10000110 { - return Opcode::PsNabs; - } - if code & 0xfc1f07fe == 0x10000050 { - return Opcode::PsNeg; - } - if code & 0xfc00003e == 0x1000003e { - return Opcode::PsNmadd; - } - if code & 0xfc00003e == 0x1000003c { - return Opcode::PsNmsub; - } - if code & 0xfc1f07fe == 0x10000030 { - return Opcode::PsRes; - } - if code & 0xfc1f07fe == 0x10000034 { - return Opcode::PsRsqrte; - } - if code & 0xfc00003e == 0x1000002e { - return Opcode::PsSel; - } - if code & 0xfc0007fe == 0x10000028 { - return Opcode::PsSub; - } - if code & 0xfc00003e == 0x10000014 { - return Opcode::PsSum0; - } - if code & 0xfc00003e == 0x10000016 { - return Opcode::PsSum1; - } - if code & 0xffffffff == 0x4c000064 { - return Opcode::Rfi; - } - if code & 0xfc000000 == 0x50000000 { - return Opcode::Rlwimi; - } - if code & 0xfc000000 == 0x54000000 { - return Opcode::Rlwinm; - } - if code & 0xfc000000 == 0x5c000000 { - return Opcode::Rlwnm; - } - if code & 0xffffffff == 0x44000002 { - return Opcode::Sc; - } - if code & 0xfc0007fe == 0x7c000030 { - return Opcode::Slw; - } - if code & 0xfc0007fe == 0x7c000630 { - return Opcode::Sraw; - } - if code & 0xfc0007fe == 0x7c000670 { - return Opcode::Srawi; - } - if code & 0xfc0007fe == 0x7c000430 { - return Opcode::Srw; - } - if code & 0xfc000000 == 0x98000000 { - return Opcode::Stb; - } - if code & 0xfc000000 == 0x9c000000 { - return Opcode::Stbu; - } - if code & 0xfc0007ff == 0x7c0001ee { - return Opcode::Stbux; - } - if code & 0xfc0007ff == 0x7c0001ae { - return Opcode::Stbx; - } - if code & 0xfc000000 == 0xd8000000 { - return Opcode::Stfd; - } - if code & 0xfc000000 == 0xdc000000 { - return Opcode::Stfdu; - } - if code & 0xfc0007ff == 0x7c0005ee { - return Opcode::Stfdux; - } - if code & 0xfc0007ff == 0x7c0005ae { - return Opcode::Stfdx; - } - if code & 0xfc0007ff == 0x7c0007ae { - return Opcode::Stfiwx; - } - if code & 0xfc000000 == 0xd0000000 { - return Opcode::Stfs; - } - if code & 0xfc000000 == 0xd4000000 { - return Opcode::Stfsu; - } - if code & 0xfc0007ff == 0x7c00056e { - return Opcode::Stfsux; - } - if code & 0xfc0007ff == 0x7c00052e { - return Opcode::Stfsx; - } - if code & 0xfc000000 == 0xb0000000 { - return Opcode::Sth; - } - if code & 0xfc0007ff == 0x7c00072c { - return Opcode::Sthbrx; - } - if code & 0xfc000000 == 0xb4000000 { - return Opcode::Sthu; - } - if code & 0xfc0007ff == 0x7c00036e { - return Opcode::Sthux; - } - if code & 0xfc0007ff == 0x7c00032e { - return Opcode::Sthx; - } - if code & 0xfc000000 == 0xbc000000 { - return Opcode::Stmw; - } - if code & 0xfc0007ff == 0x7c0005aa { - return Opcode::Stswi; - } - if code & 0xfc0007ff == 0x7c00052a { - return Opcode::Stswx; - } - if code & 0xfc000000 == 0x90000000 { - return Opcode::Stw; - } - if code & 0xfc0007ff == 0x7c00052c { - return Opcode::Stwbrx; - } - if code & 0xfc0007ff == 0x7c00012d { - return Opcode::Stwcx_; - } - if code & 0xfc000000 == 0x94000000 { - return Opcode::Stwu; - } - if code & 0xfc0007ff == 0x7c00016e { - return Opcode::Stwux; - } - if code & 0xfc0007ff == 0x7c00012e { - return Opcode::Stwx; - } - if code & 0xfc0003fe == 0x7c000050 { - return Opcode::Subf; - } - if code & 0xfc0003fe == 0x7c000010 { - return Opcode::Subfc; - } - if code & 0xfc0003fe == 0x7c000110 { - return Opcode::Subfe; - } - if code & 0xfc000000 == 0x20000000 { - return Opcode::Subfic; - } - if code & 0xfc00fbfe == 0x7c0001d0 { - return Opcode::Subfme; - } - if code & 0xfc00fbfe == 0x7c000190 { - return Opcode::Subfze; - } - if code & 0xffffffff == 0x7c0004ac { - return Opcode::Sync; - } - if code & 0xffff07ff == 0x7c000264 { - return Opcode::Tlbie; - } - if code & 0xffffffff == 0x7c00046c { - return Opcode::Tlbsync; - } - if code & 0xfc0007ff == 0x7c000008 { - return Opcode::Tw; - } - if code & 0xfc000000 == 0xc000000 { - return Opcode::Twi; - } - if code & 0xfc0007fe == 0x7c000278 { - return Opcode::Xor; - } - if code & 0xfc000000 == 0x68000000 { - return Opcode::Xori; - } - if code & 0xfc000000 == 0x6c000000 { - return Opcode::Xoris; - } - Opcode::Illegal + #[inline] + pub const fn _detect(code: u32) -> Self { + let entry = OPCODE_ENTRIES[(code >> 26) as usize]; + let mut i = entry.0; + while i < entry.1 { + let pattern = OPCODE_PATTERNS[i as usize]; + if (code & pattern.0) == pattern.1 { + // Safety: The enum is repr(u8) and marked non_exhaustive + return unsafe { core::mem::transmute(i) }; + } + i += 1; + } + Self::Illegal } } -#[allow(non_camel_case_types)] -#[derive(Debug, Copy, Clone, Eq, PartialEq)] -pub enum Field { - simm(Simm), - uimm(Uimm), - offset(Offset), - ps_offset(Offset), - BO(OpaqueU), - BI(CRBit), - BD(BranchDest), - LI(BranchDest), - SH(OpaqueU), - MB(OpaqueU), - ME(OpaqueU), - rS(GPR), - rD(GPR), - rA(GPR), - rB(GPR), - sr(SR), - spr(SPR), - frS(FPR), - frD(FPR), - frA(FPR), - frB(FPR), - frC(FPR), - crbD(CRBit), - crbA(CRBit), - crbB(CRBit), - crfD(CRField), - crfS(CRField), - crm(OpaqueU), - ps_I(GQR), - ps_IX(GQR), - ps_W(OpaqueU), - ps_WX(OpaqueU), - NB(OpaqueU), - tbr(OpaqueU), - mtfsf_FM(OpaqueU), - mtfsf_IMM(OpaqueU), - spr_SPRG(OpaqueU), - spr_BAT(OpaqueU), - TO(OpaqueU), - L(OpaqueU), - xer, - ctr, - lr, -} -impl Field { - pub fn argument(&self) -> Option { - match self { - Field::simm(x) => Some(Argument::Simm(*x)), - Field::uimm(x) => Some(Argument::Uimm(*x)), - Field::offset(x) => Some(Argument::Offset(*x)), - Field::ps_offset(x) => Some(Argument::Offset(*x)), - Field::BO(x) => Some(Argument::OpaqueU(*x)), - Field::BI(x) => Some(Argument::CRBit(*x)), - Field::BD(x) => Some(Argument::BranchDest(*x)), - Field::LI(x) => Some(Argument::BranchDest(*x)), - Field::SH(x) => Some(Argument::OpaqueU(*x)), - Field::MB(x) => Some(Argument::OpaqueU(*x)), - Field::ME(x) => Some(Argument::OpaqueU(*x)), - Field::rS(x) => Some(Argument::GPR(*x)), - Field::rD(x) => Some(Argument::GPR(*x)), - Field::rA(x) => Some(Argument::GPR(*x)), - Field::rB(x) => Some(Argument::GPR(*x)), - Field::sr(x) => Some(Argument::SR(*x)), - Field::spr(x) => Some(Argument::SPR(*x)), - Field::frS(x) => Some(Argument::FPR(*x)), - Field::frD(x) => Some(Argument::FPR(*x)), - Field::frA(x) => Some(Argument::FPR(*x)), - Field::frB(x) => Some(Argument::FPR(*x)), - Field::frC(x) => Some(Argument::FPR(*x)), - Field::crbD(x) => Some(Argument::CRBit(*x)), - Field::crbA(x) => Some(Argument::CRBit(*x)), - Field::crbB(x) => Some(Argument::CRBit(*x)), - Field::crfD(x) => Some(Argument::CRField(*x)), - Field::crfS(x) => Some(Argument::CRField(*x)), - Field::crm(x) => Some(Argument::OpaqueU(*x)), - Field::ps_I(x) => Some(Argument::GQR(*x)), - Field::ps_IX(x) => Some(Argument::GQR(*x)), - Field::ps_W(x) => Some(Argument::OpaqueU(*x)), - Field::ps_WX(x) => Some(Argument::OpaqueU(*x)), - Field::NB(x) => Some(Argument::OpaqueU(*x)), - Field::tbr(x) => Some(Argument::OpaqueU(*x)), - Field::mtfsf_FM(x) => Some(Argument::OpaqueU(*x)), - Field::mtfsf_IMM(x) => Some(Argument::OpaqueU(*x)), - Field::spr_SPRG(x) => Some(Argument::OpaqueU(*x)), - Field::spr_BAT(x) => Some(Argument::OpaqueU(*x)), - Field::TO(x) => Some(Argument::OpaqueU(*x)), - Field::L(x) => Some(Argument::OpaqueU(*x)), - _ => None, - } - } - pub fn name(&self) -> &'static str { - match self { - Field::simm(_) => "simm", - Field::uimm(_) => "uimm", - Field::offset(_) => "offset", - Field::ps_offset(_) => "ps_offset", - Field::BO(_) => "BO", - Field::BI(_) => "BI", - Field::BD(_) => "BD", - Field::LI(_) => "LI", - Field::SH(_) => "SH", - Field::MB(_) => "MB", - Field::ME(_) => "ME", - Field::rS(_) => "rS", - Field::rD(_) => "rD", - Field::rA(_) => "rA", - Field::rB(_) => "rB", - Field::sr(_) => "sr", - Field::spr(_) => "spr", - Field::frS(_) => "frS", - Field::frD(_) => "frD", - Field::frA(_) => "frA", - Field::frB(_) => "frB", - Field::frC(_) => "frC", - Field::crbD(_) => "crbD", - Field::crbA(_) => "crbA", - Field::crbB(_) => "crbB", - Field::crfD(_) => "crfD", - Field::crfS(_) => "crfS", - Field::crm(_) => "crm", - Field::ps_I(_) => "ps_I", - Field::ps_IX(_) => "ps_IX", - Field::ps_W(_) => "ps_W", - Field::ps_WX(_) => "ps_WX", - Field::NB(_) => "NB", - Field::tbr(_) => "tbr", - Field::mtfsf_FM(_) => "mtfsf_FM", - Field::mtfsf_IMM(_) => "mtfsf_IMM", - Field::spr_SPRG(_) => "spr_SPRG", - Field::spr_BAT(_) => "spr_BAT", - Field::TO(_) => "TO", - Field::L(_) => "L", - Field::xer => "xer", - Field::ctr => "ctr", - Field::lr => "lr", - } - } -} -#[allow(clippy::all, unused_mut)] impl Ins { - pub(crate) fn _fields(&self) -> Vec { - match self.op { - Opcode::Illegal => vec![], - Opcode::Add => vec![ - Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Addc => vec![ - Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Adde => vec![ - Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Addi => vec![ - Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::simm(Simm( - ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _, - )), - ], - Opcode::Addic => vec![ - Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::simm(Simm( - ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _, - )), - ], - Opcode::Addic_ => vec![ - Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::simm(Simm( - ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _, - )), - ], - Opcode::Addis => vec![ - Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::uimm(Uimm((self.code & 0xffff) as _)), - ], - Opcode::Addme => vec![ - Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - ], - Opcode::Addze => vec![ - Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - ], - Opcode::And => vec![ - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Andc => vec![ - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Andi_ => vec![ - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::uimm(Uimm((self.code & 0xffff) as _)), - ], - Opcode::Andis_ => vec![ - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::uimm(Uimm((self.code & 0xffff) as _)), - ], - Opcode::B => vec![Field::LI(BranchDest( - ((((((self.code >> 2u8) & 0xffffff) ^ 0x800000).wrapping_sub(0x800000)) as i32) - << 2u8) as _, - ))], - Opcode::Bc => vec![ - Field::BO(OpaqueU(((self.code >> 21u8) & 0x1f) as _)), - Field::BI(CRBit(((self.code >> 16u8) & 0x1f) as _)), - Field::BD(BranchDest( - ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) as i32) - << 2u8) as _, - )), - ], - Opcode::Bcctr => vec![ - Field::BO(OpaqueU(((self.code >> 21u8) & 0x1f) as _)), - Field::BI(CRBit(((self.code >> 16u8) & 0x1f) as _)), - ], - Opcode::Bclr => vec![ - Field::BO(OpaqueU(((self.code >> 21u8) & 0x1f) as _)), - Field::BI(CRBit(((self.code >> 16u8) & 0x1f) as _)), - ], - Opcode::Cmp => vec![ - Field::crfD(CRField(((self.code >> 23u8) & 0x7) as _)), - Field::L(OpaqueU(((self.code >> 21u8) & 0x1) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Cmpi => vec![ - Field::crfD(CRField(((self.code >> 23u8) & 0x7) as _)), - Field::L(OpaqueU(((self.code >> 21u8) & 0x1) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::simm(Simm( - ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _, - )), - ], - Opcode::Cmpl => vec![ - Field::crfD(CRField(((self.code >> 23u8) & 0x7) as _)), - Field::L(OpaqueU(((self.code >> 21u8) & 0x1) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Cmpli => vec![ - Field::crfD(CRField(((self.code >> 23u8) & 0x7) as _)), - Field::L(OpaqueU(((self.code >> 21u8) & 0x1) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::uimm(Uimm((self.code & 0xffff) as _)), - ], - Opcode::Cntlzw => vec![ - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - ], - Opcode::Crand => vec![ - Field::crbD(CRBit(((self.code >> 21u8) & 0x1f) as _)), - Field::crbA(CRBit(((self.code >> 16u8) & 0x1f) as _)), - Field::crbB(CRBit(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Crandc => vec![ - Field::crbD(CRBit(((self.code >> 21u8) & 0x1f) as _)), - Field::crbA(CRBit(((self.code >> 16u8) & 0x1f) as _)), - Field::crbB(CRBit(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Creqv => vec![ - Field::crbD(CRBit(((self.code >> 21u8) & 0x1f) as _)), - Field::crbA(CRBit(((self.code >> 16u8) & 0x1f) as _)), - Field::crbB(CRBit(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Crnand => vec![ - Field::crbD(CRBit(((self.code >> 21u8) & 0x1f) as _)), - Field::crbA(CRBit(((self.code >> 16u8) & 0x1f) as _)), - Field::crbB(CRBit(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Crnor => vec![ - Field::crbD(CRBit(((self.code >> 21u8) & 0x1f) as _)), - Field::crbA(CRBit(((self.code >> 16u8) & 0x1f) as _)), - Field::crbB(CRBit(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Cror => vec![ - Field::crbD(CRBit(((self.code >> 21u8) & 0x1f) as _)), - Field::crbA(CRBit(((self.code >> 16u8) & 0x1f) as _)), - Field::crbB(CRBit(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Crorc => vec![ - Field::crbD(CRBit(((self.code >> 21u8) & 0x1f) as _)), - Field::crbA(CRBit(((self.code >> 16u8) & 0x1f) as _)), - Field::crbB(CRBit(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Crxor => vec![ - Field::crbD(CRBit(((self.code >> 21u8) & 0x1f) as _)), - Field::crbA(CRBit(((self.code >> 16u8) & 0x1f) as _)), - Field::crbB(CRBit(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Dcbf => vec![ - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Dcbi => vec![ - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Dcbst => vec![ - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Dcbt => vec![ - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Dcbtst => vec![ - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Dcbz => vec![ - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::DcbzL => vec![ - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Divw => vec![ - Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Divwu => vec![ - Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Eciwx => vec![ - Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Ecowx => vec![ - Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Eieio => vec![], - Opcode::Eqv => vec![ - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Extsb => vec![ - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - ], - Opcode::Extsh => vec![ - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - ], - Opcode::Fabs => vec![ - Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Fadd => vec![ - Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Fadds => vec![ - Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Fcmpo => vec![ - Field::crfD(CRField(((self.code >> 23u8) & 0x7) as _)), - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Fcmpu => vec![ - Field::crfD(CRField(((self.code >> 23u8) & 0x7) as _)), - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Fctiw => vec![ - Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Fctiwz => vec![ - Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Fdiv => vec![ - Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Fdivs => vec![ - Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Fmadd => vec![ - Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), - Field::frC(FPR(((self.code >> 6u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Fmadds => vec![ - Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), - Field::frC(FPR(((self.code >> 6u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Fmr => vec![ - Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Fmsub => vec![ - Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), - Field::frC(FPR(((self.code >> 6u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Fmsubs => vec![ - Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), - Field::frC(FPR(((self.code >> 6u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Fmul => vec![ - Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), - Field::frC(FPR(((self.code >> 6u8) & 0x1f) as _)), - ], - Opcode::Fmuls => vec![ - Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), - Field::frC(FPR(((self.code >> 6u8) & 0x1f) as _)), - ], - Opcode::Fnabs => vec![ - Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Fneg => vec![ - Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Fnmadd => vec![ - Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), - Field::frC(FPR(((self.code >> 6u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Fnmadds => vec![ - Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), - Field::frC(FPR(((self.code >> 6u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Fnmsub => vec![ - Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), - Field::frC(FPR(((self.code >> 6u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Fnmsubs => vec![ - Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), - Field::frC(FPR(((self.code >> 6u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Fres => vec![ - Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Frsp => vec![ - Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Frsqrte => vec![ - Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Fsel => vec![ - Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), - Field::frC(FPR(((self.code >> 6u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Fsub => vec![ - Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Fsubs => vec![ - Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Icbi => vec![ - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Isync => vec![], - Opcode::Lbz => vec![ - Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::offset(Offset( - ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _, - )), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - ], - Opcode::Lbzu => vec![ - Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::offset(Offset( - ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _, - )), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - ], - Opcode::Lbzux => vec![ - Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Lbzx => vec![ - Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Lfd => vec![ - Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::offset(Offset( - ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _, - )), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - ], - Opcode::Lfdu => vec![ - Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::offset(Offset( - ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _, - )), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - ], - Opcode::Lfdux => vec![ - Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Lfdx => vec![ - Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Lfs => vec![ - Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::offset(Offset( - ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _, - )), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - ], - Opcode::Lfsu => vec![ - Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::offset(Offset( - ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _, - )), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - ], - Opcode::Lfsux => vec![ - Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Lfsx => vec![ - Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Lha => vec![ - Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::offset(Offset( - ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _, - )), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - ], - Opcode::Lhau => vec![ - Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::offset(Offset( - ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _, - )), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - ], - Opcode::Lhaux => vec![ - Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Lhax => vec![ - Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Lhbrx => vec![ - Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Lhz => vec![ - Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::offset(Offset( - ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _, - )), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - ], - Opcode::Lhzu => vec![ - Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::offset(Offset( - ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _, - )), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - ], - Opcode::Lhzux => vec![ - Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Lhzx => vec![ - Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Lmw => vec![ - Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::offset(Offset( - ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _, - )), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - ], - Opcode::Lswi => vec![ - Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::NB(OpaqueU(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Lswx => vec![ - Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Lwarx => vec![ - Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Lwbrx => vec![ - Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Lwz => vec![ - Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::offset(Offset( - ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _, - )), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - ], - Opcode::Lwzu => vec![ - Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::offset(Offset( - ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _, - )), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - ], - Opcode::Lwzux => vec![ - Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Lwzx => vec![ - Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Mcrf => vec![ - Field::crfD(CRField(((self.code >> 23u8) & 0x7) as _)), - Field::crfS(CRField(((self.code >> 18u8) & 0x7) as _)), - ], - Opcode::Mcrfs => vec![ - Field::crfD(CRField(((self.code >> 23u8) & 0x7) as _)), - Field::crfS(CRField(((self.code >> 18u8) & 0x7) as _)), - ], - Opcode::Mcrxr => vec![Field::crfD(CRField(((self.code >> 23u8) & 0x7) as _))], - Opcode::Mfcr => vec![Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Mffs => vec![Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Mfmsr => vec![Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Mfspr => vec![ - Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::spr(SPR( - (((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32) - | ((((self.code >> 11u8) & 0x3ff) & 0b00000_11111u32) << 5u32)) - as u32 as _, - )), - ], - Opcode::Mfsr => vec![ - Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::sr(SR(((self.code >> 16u8) & 0xf) as _)), - ], - Opcode::Mfsrin => vec![ - Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Mftb => vec![ - Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::tbr(OpaqueU( - (((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32) - | ((((self.code >> 11u8) & 0x3ff) & 0b00000_11111u32) << 5u32)) - as u32 as _, - )), - ], - Opcode::Mtcrf => vec![ - Field::crm(OpaqueU(((self.code >> 12u8) & 0xff) as _)), - Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - ], - Opcode::Mtfsb0 => vec![Field::crbD(CRBit(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Mtfsb1 => vec![Field::crbD(CRBit(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Mtfsf => vec![ - Field::mtfsf_FM(OpaqueU(((self.code >> 17u8) & 0xff) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Mtfsfi => vec![ - Field::crfD(CRField(((self.code >> 23u8) & 0x7) as _)), - Field::mtfsf_IMM(OpaqueU(((self.code >> 12u8) & 0xf) as _)), - ], - Opcode::Mtmsr => vec![Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Mtspr => vec![ - Field::spr(SPR( - (((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32) - | ((((self.code >> 11u8) & 0x3ff) & 0b00000_11111u32) << 5u32)) - as u32 as _, - )), - Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - ], - Opcode::Mtsr => vec![ - Field::sr(SR(((self.code >> 16u8) & 0xf) as _)), - Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - ], - Opcode::Mtsrin => vec![ - Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Mulhw => vec![ - Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Mulhwu => vec![ - Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Mulli => vec![ - Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::simm(Simm( - ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _, - )), - ], - Opcode::Mullw => vec![ - Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Nand => vec![ - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Neg => vec![ - Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - ], - Opcode::Nor => vec![ - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Or => vec![ - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Orc => vec![ - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Ori => vec![ - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::uimm(Uimm((self.code & 0xffff) as _)), - ], - Opcode::Oris => vec![ - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::uimm(Uimm((self.code & 0xffff) as _)), - ], - Opcode::PsqL => vec![ - Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::ps_offset(Offset( - ((((self.code & 0xfff) ^ 0x800).wrapping_sub(0x800)) as i32) as _, - )), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::ps_W(OpaqueU(((self.code >> 15u8) & 0x1) as _)), - Field::ps_I(GQR(((self.code >> 12u8) & 0x7) as _)), - ], - Opcode::PsqLu => vec![ - Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::ps_offset(Offset( - ((((self.code & 0xfff) ^ 0x800).wrapping_sub(0x800)) as i32) as _, - )), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::ps_W(OpaqueU(((self.code >> 15u8) & 0x1) as _)), - Field::ps_I(GQR(((self.code >> 12u8) & 0x7) as _)), - ], - Opcode::PsqLux => vec![ - Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - Field::ps_WX(OpaqueU(((self.code >> 10u8) & 0x1) as _)), - Field::ps_IX(GQR(((self.code >> 7u8) & 0x7) as _)), - ], - Opcode::PsqLx => vec![ - Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - Field::ps_WX(OpaqueU(((self.code >> 10u8) & 0x1) as _)), - Field::ps_IX(GQR(((self.code >> 7u8) & 0x7) as _)), - ], - Opcode::PsqSt => vec![ - Field::frS(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::ps_offset(Offset( - ((((self.code & 0xfff) ^ 0x800).wrapping_sub(0x800)) as i32) as _, - )), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::ps_W(OpaqueU(((self.code >> 15u8) & 0x1) as _)), - Field::ps_I(GQR(((self.code >> 12u8) & 0x7) as _)), - ], - Opcode::PsqStu => vec![ - Field::frS(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::ps_offset(Offset( - ((((self.code & 0xfff) ^ 0x800).wrapping_sub(0x800)) as i32) as _, - )), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::ps_W(OpaqueU(((self.code >> 15u8) & 0x1) as _)), - Field::ps_I(GQR(((self.code >> 12u8) & 0x7) as _)), - ], - Opcode::PsqStux => vec![ - Field::frS(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - Field::ps_WX(OpaqueU(((self.code >> 10u8) & 0x1) as _)), - Field::ps_IX(GQR(((self.code >> 7u8) & 0x7) as _)), - ], - Opcode::PsqStx => vec![ - Field::frS(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - Field::ps_WX(OpaqueU(((self.code >> 10u8) & 0x1) as _)), - Field::ps_IX(GQR(((self.code >> 7u8) & 0x7) as _)), - ], - Opcode::PsAbs => vec![ - Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::PsAdd => vec![ - Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::PsCmpo0 => vec![ - Field::crfD(CRField(((self.code >> 23u8) & 0x7) as _)), - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::PsCmpo1 => vec![ - Field::crfD(CRField(((self.code >> 23u8) & 0x7) as _)), - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::PsCmpu0 => vec![ - Field::crfD(CRField(((self.code >> 23u8) & 0x7) as _)), - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::PsCmpu1 => vec![ - Field::crfD(CRField(((self.code >> 23u8) & 0x7) as _)), - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::PsDiv => vec![ - Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::PsMadd => vec![ - Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), - Field::frC(FPR(((self.code >> 6u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::PsMadds0 => vec![ - Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), - Field::frC(FPR(((self.code >> 6u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::PsMadds1 => vec![ - Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), - Field::frC(FPR(((self.code >> 6u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::PsMerge00 => vec![ - Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::PsMerge01 => vec![ - Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::PsMerge10 => vec![ - Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::PsMerge11 => vec![ - Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::PsMr => vec![ - Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::PsMsub => vec![ - Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), - Field::frC(FPR(((self.code >> 6u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::PsMul => vec![ - Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), - Field::frC(FPR(((self.code >> 6u8) & 0x1f) as _)), - ], - Opcode::PsMuls0 => vec![ - Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), - Field::frC(FPR(((self.code >> 6u8) & 0x1f) as _)), - ], - Opcode::PsMuls1 => vec![ - Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), - Field::frC(FPR(((self.code >> 6u8) & 0x1f) as _)), - ], - Opcode::PsNabs => vec![ - Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::PsNeg => vec![ - Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::PsNmadd => vec![ - Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), - Field::frC(FPR(((self.code >> 6u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::PsNmsub => vec![ - Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), - Field::frC(FPR(((self.code >> 6u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::PsRes => vec![ - Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::PsRsqrte => vec![ - Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::PsSel => vec![ - Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), - Field::frC(FPR(((self.code >> 6u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::PsSub => vec![ - Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::PsSum0 => vec![ - Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), - Field::frC(FPR(((self.code >> 6u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::PsSum1 => vec![ - Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), - Field::frC(FPR(((self.code >> 6u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Rfi => vec![], - Opcode::Rlwimi => vec![ - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::SH(OpaqueU(((self.code >> 11u8) & 0x1f) as _)), - Field::MB(OpaqueU(((self.code >> 6u8) & 0x1f) as _)), - Field::ME(OpaqueU(((self.code >> 1u8) & 0x1f) as _)), - ], - Opcode::Rlwinm => vec![ - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::SH(OpaqueU(((self.code >> 11u8) & 0x1f) as _)), - Field::MB(OpaqueU(((self.code >> 6u8) & 0x1f) as _)), - Field::ME(OpaqueU(((self.code >> 1u8) & 0x1f) as _)), - ], - Opcode::Rlwnm => vec![ - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - Field::MB(OpaqueU(((self.code >> 6u8) & 0x1f) as _)), - Field::ME(OpaqueU(((self.code >> 1u8) & 0x1f) as _)), - ], - Opcode::Sc => vec![], - Opcode::Slw => vec![ - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Sraw => vec![ - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Srawi => vec![ - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::SH(OpaqueU(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Srw => vec![ - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Stb => vec![ - Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::offset(Offset( - ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _, - )), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - ], - Opcode::Stbu => vec![ - Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::offset(Offset( - ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _, - )), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - ], - Opcode::Stbux => vec![ - Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Stbx => vec![ - Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Stfd => vec![ - Field::frS(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::offset(Offset( - ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _, - )), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - ], - Opcode::Stfdu => vec![ - Field::frS(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::offset(Offset( - ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _, - )), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - ], - Opcode::Stfdux => vec![ - Field::frS(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Stfdx => vec![ - Field::frS(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Stfiwx => vec![ - Field::frS(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Stfs => vec![ - Field::frS(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::offset(Offset( - ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _, - )), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - ], - Opcode::Stfsu => vec![ - Field::frS(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::offset(Offset( - ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _, - )), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - ], - Opcode::Stfsux => vec![ - Field::frS(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Stfsx => vec![ - Field::frS(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Sth => vec![ - Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::offset(Offset( - ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _, - )), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - ], - Opcode::Sthbrx => vec![ - Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Sthu => vec![ - Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::offset(Offset( - ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _, - )), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - ], - Opcode::Sthux => vec![ - Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Sthx => vec![ - Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Stmw => vec![ - Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::offset(Offset( - ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _, - )), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - ], - Opcode::Stswi => vec![ - Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::NB(OpaqueU(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Stswx => vec![ - Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Stw => vec![ - Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::offset(Offset( - ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _, - )), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - ], - Opcode::Stwbrx => vec![ - Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Stwcx_ => vec![ - Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Stwu => vec![ - Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::offset(Offset( - ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _, - )), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - ], - Opcode::Stwux => vec![ - Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Stwx => vec![ - Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Subf => vec![ - Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Subfc => vec![ - Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Subfe => vec![ - Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Subfic => vec![ - Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::simm(Simm( - ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _, - )), - ], - Opcode::Subfme => vec![ - Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - ], - Opcode::Subfze => vec![ - Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - ], - Opcode::Sync => vec![], - Opcode::Tlbie => vec![Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _))], - Opcode::Tlbsync => vec![], - Opcode::Tw => vec![ - Field::TO(OpaqueU(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Twi => vec![ - Field::TO(OpaqueU(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::simm(Simm( - ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _, - )), - ], - Opcode::Xor => vec![ - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ], - Opcode::Xori => vec![ - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::uimm(Uimm((self.code & 0xffff) as _)), - ], - Opcode::Xoris => vec![ - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::uimm(Uimm((self.code & 0xffff) as _)), - ], - } + /// simm: Signed Immediate + #[inline(always)] + pub const fn field_simm(&self) -> i16 { + ((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000) as i16 } - pub(crate) fn _defs(&self) -> Vec { - match self.op { - Opcode::Illegal => vec![], - Opcode::Add => vec![Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Addc => vec![Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Adde => vec![Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Addi => vec![Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Addic => vec![Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Addic_ => vec![Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Addis => vec![Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Addme => vec![Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Addze => vec![Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::And => vec![Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))], - Opcode::Andc => vec![Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))], - Opcode::Andi_ => vec![Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))], - Opcode::Andis_ => vec![Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))], - Opcode::B => vec![], - Opcode::Bc => vec![], - Opcode::Bcctr => vec![], - Opcode::Bclr => vec![], - Opcode::Cmp => vec![Field::crfD(CRField(((self.code >> 23u8) & 0x7) as _))], - Opcode::Cmpi => vec![Field::crfD(CRField(((self.code >> 23u8) & 0x7) as _))], - Opcode::Cmpl => vec![Field::crfD(CRField(((self.code >> 23u8) & 0x7) as _))], - Opcode::Cmpli => vec![Field::crfD(CRField(((self.code >> 23u8) & 0x7) as _))], - Opcode::Cntlzw => vec![Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))], - Opcode::Crand => vec![Field::crbD(CRBit(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Crandc => vec![Field::crbD(CRBit(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Creqv => vec![Field::crbD(CRBit(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Crnand => vec![Field::crbD(CRBit(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Crnor => vec![Field::crbD(CRBit(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Cror => vec![Field::crbD(CRBit(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Crorc => vec![Field::crbD(CRBit(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Crxor => vec![Field::crbD(CRBit(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Dcbf => vec![], - Opcode::Dcbi => vec![], - Opcode::Dcbst => vec![], - Opcode::Dcbt => vec![], - Opcode::Dcbtst => vec![], - Opcode::Dcbz => vec![], - Opcode::DcbzL => vec![], - Opcode::Divw => vec![Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Divwu => vec![Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Eciwx => vec![Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Ecowx => vec![], - Opcode::Eieio => vec![], - Opcode::Eqv => vec![Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))], - Opcode::Extsb => vec![Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))], - Opcode::Extsh => vec![Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))], - Opcode::Fabs => vec![Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Fadd => vec![Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Fadds => vec![Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Fcmpo => vec![Field::crfD(CRField(((self.code >> 23u8) & 0x7) as _))], - Opcode::Fcmpu => vec![Field::crfD(CRField(((self.code >> 23u8) & 0x7) as _))], - Opcode::Fctiw => vec![Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Fctiwz => vec![Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Fdiv => vec![Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Fdivs => vec![Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Fmadd => vec![Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Fmadds => vec![Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Fmr => vec![Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Fmsub => vec![Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Fmsubs => vec![Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Fmul => vec![Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Fmuls => vec![Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Fnabs => vec![Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Fneg => vec![Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Fnmadd => vec![Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Fnmadds => vec![Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Fnmsub => vec![Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Fnmsubs => vec![Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Fres => vec![Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Frsp => vec![Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Frsqrte => vec![Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Fsel => vec![Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Fsub => vec![Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Fsubs => vec![Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Icbi => vec![], - Opcode::Isync => vec![], - Opcode::Lbz => vec![Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Lbzu => vec![ - Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - ], - Opcode::Lbzux => vec![ - Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - ], - Opcode::Lbzx => vec![Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Lfd => vec![Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Lfdu => vec![ - Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - ], - Opcode::Lfdux => vec![ - Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - ], - Opcode::Lfdx => vec![Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Lfs => vec![Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Lfsu => vec![ - Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - ], - Opcode::Lfsux => vec![ - Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - ], - Opcode::Lfsx => vec![Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Lha => vec![Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Lhau => vec![ - Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - ], - Opcode::Lhaux => vec![ - Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - ], - Opcode::Lhax => vec![Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Lhbrx => vec![Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Lhz => vec![Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Lhzu => vec![ - Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - ], - Opcode::Lhzux => vec![ - Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - ], - Opcode::Lhzx => vec![Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Lmw => vec![Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Lswi => vec![Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Lswx => vec![Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Lwarx => vec![Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Lwbrx => vec![Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Lwz => vec![Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Lwzu => vec![ - Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - ], - Opcode::Lwzux => vec![ - Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - ], - Opcode::Lwzx => vec![Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Mcrf => vec![Field::crfD(CRField(((self.code >> 23u8) & 0x7) as _))], - Opcode::Mcrfs => vec![Field::crfD(CRField(((self.code >> 23u8) & 0x7) as _))], - Opcode::Mcrxr => vec![ - Field::crfD(CRField(((self.code >> 23u8) & 0x7) as _)), - Field::xer, - ], - Opcode::Mfcr => vec![Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Mffs => vec![Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Mfmsr => vec![Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Mfspr => vec![Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Mfsr => vec![Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Mfsrin => vec![Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Mftb => vec![Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Mtcrf => vec![], - Opcode::Mtfsb0 => vec![Field::crbD(CRBit(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Mtfsb1 => vec![Field::crbD(CRBit(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Mtfsf => vec![], - Opcode::Mtfsfi => vec![Field::crfD(CRField(((self.code >> 23u8) & 0x7) as _))], - Opcode::Mtmsr => vec![], - Opcode::Mtspr => vec![], - Opcode::Mtsr => vec![], - Opcode::Mtsrin => vec![], - Opcode::Mulhw => vec![Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Mulhwu => vec![Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Mulli => vec![Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Mullw => vec![Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Nand => vec![Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))], - Opcode::Neg => vec![Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Nor => vec![Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))], - Opcode::Or => vec![Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))], - Opcode::Orc => vec![Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))], - Opcode::Ori => vec![Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))], - Opcode::Oris => vec![Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))], - Opcode::PsqL => vec![Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::PsqLu => vec![ - Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - ], - Opcode::PsqLux => vec![ - Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - ], - Opcode::PsqLx => vec![Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::PsqSt => vec![], - Opcode::PsqStu => vec![Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))], - Opcode::PsqStux => vec![Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))], - Opcode::PsqStx => vec![], - Opcode::PsAbs => vec![Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::PsAdd => vec![Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::PsCmpo0 => vec![Field::crfD(CRField(((self.code >> 23u8) & 0x7) as _))], - Opcode::PsCmpo1 => vec![Field::crfD(CRField(((self.code >> 23u8) & 0x7) as _))], - Opcode::PsCmpu0 => vec![Field::crfD(CRField(((self.code >> 23u8) & 0x7) as _))], - Opcode::PsCmpu1 => vec![Field::crfD(CRField(((self.code >> 23u8) & 0x7) as _))], - Opcode::PsDiv => vec![Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::PsMadd => vec![Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::PsMadds0 => vec![Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::PsMadds1 => vec![Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::PsMerge00 => vec![Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::PsMerge01 => vec![Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::PsMerge10 => vec![Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::PsMerge11 => vec![Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::PsMr => vec![Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::PsMsub => vec![Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::PsMul => vec![Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::PsMuls0 => vec![Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::PsMuls1 => vec![Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::PsNabs => vec![Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::PsNeg => vec![Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::PsNmadd => vec![Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::PsNmsub => vec![Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::PsRes => vec![Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::PsRsqrte => vec![Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::PsSel => vec![Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::PsSub => vec![Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::PsSum0 => vec![Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::PsSum1 => vec![Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Rfi => vec![], - Opcode::Rlwimi => vec![Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))], - Opcode::Rlwinm => vec![Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))], - Opcode::Rlwnm => vec![Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))], - Opcode::Sc => vec![], - Opcode::Slw => vec![Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))], - Opcode::Sraw => vec![Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))], - Opcode::Srawi => vec![Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))], - Opcode::Srw => vec![Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))], - Opcode::Stb => vec![], - Opcode::Stbu => vec![Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))], - Opcode::Stbux => vec![Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))], - Opcode::Stbx => vec![], - Opcode::Stfd => vec![], - Opcode::Stfdu => vec![Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))], - Opcode::Stfdux => vec![Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))], - Opcode::Stfdx => vec![], - Opcode::Stfiwx => vec![], - Opcode::Stfs => vec![], - Opcode::Stfsu => vec![Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))], - Opcode::Stfsux => vec![Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))], - Opcode::Stfsx => vec![], - Opcode::Sth => vec![], - Opcode::Sthbrx => vec![], - Opcode::Sthu => vec![Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))], - Opcode::Sthux => vec![Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))], - Opcode::Sthx => vec![], - Opcode::Stmw => vec![], - Opcode::Stswi => vec![], - Opcode::Stswx => vec![], - Opcode::Stw => vec![], - Opcode::Stwbrx => vec![], - Opcode::Stwcx_ => vec![], - Opcode::Stwu => vec![Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))], - Opcode::Stwux => vec![Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))], - Opcode::Stwx => vec![], - Opcode::Subf => vec![Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Subfc => vec![Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Subfe => vec![Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Subfic => vec![Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Subfme => vec![Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Subfze => vec![Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _))], - Opcode::Sync => vec![], - Opcode::Tlbie => vec![], - Opcode::Tlbsync => vec![], - Opcode::Tw => vec![], - Opcode::Twi => vec![], - Opcode::Xor => vec![Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))], - Opcode::Xori => vec![Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))], - Opcode::Xoris => vec![Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))], - } + /// uimm: Unsigned Immediate + #[inline(always)] + pub const fn field_uimm(&self) -> u16 { + (self.code & 0xffff) as u16 } - pub(crate) fn _uses(&self) -> Vec { - match self.op { - Opcode::Illegal => vec![], - Opcode::Add => { - let mut uses = vec![ - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::Addc => { - let mut uses = vec![ - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::Adde => { - let mut uses = vec![ - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::Addi => { - let mut uses = vec![]; - if ((self.code >> 16u8) & 0x1f) != 0 { - uses.push(Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))); - } - uses - } - Opcode::Addic => { - let mut uses = vec![Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))]; - uses - } - Opcode::Addic_ => { - let mut uses = vec![Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))]; - uses - } - Opcode::Addis => { - let mut uses = vec![]; - if ((self.code >> 16u8) & 0x1f) != 0 { - uses.push(Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))); - } - uses - } - Opcode::Addme => { - let mut uses = vec![Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))]; - uses - } - Opcode::Addze => { - let mut uses = vec![Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))]; - uses - } - Opcode::And => { - let mut uses = vec![ - Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::Andc => { - let mut uses = vec![ - Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::Andi_ => { - let mut uses = vec![Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _))]; - uses - } - Opcode::Andis_ => { - let mut uses = vec![Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _))]; - uses - } - Opcode::B => { - let mut uses = vec![]; - uses - } - Opcode::Bc => { - let mut uses = vec![]; - uses - } - Opcode::Bcctr => { - let mut uses = vec![Field::ctr]; - uses - } - Opcode::Bclr => { - let mut uses = vec![Field::lr]; - uses - } - Opcode::Cmp => { - let mut uses = vec![ - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::Cmpi => { - let mut uses = vec![Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))]; - uses - } - Opcode::Cmpl => { - let mut uses = vec![ - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::Cmpli => { - let mut uses = vec![Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))]; - uses - } - Opcode::Cntlzw => { - let mut uses = vec![Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _))]; - uses - } - Opcode::Crand => { - let mut uses = vec![ - Field::crbA(CRBit(((self.code >> 16u8) & 0x1f) as _)), - Field::crbB(CRBit(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::Crandc => { - let mut uses = vec![ - Field::crbA(CRBit(((self.code >> 16u8) & 0x1f) as _)), - Field::crbB(CRBit(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::Creqv => { - let mut uses = vec![ - Field::crbA(CRBit(((self.code >> 16u8) & 0x1f) as _)), - Field::crbB(CRBit(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::Crnand => { - let mut uses = vec![ - Field::crbA(CRBit(((self.code >> 16u8) & 0x1f) as _)), - Field::crbB(CRBit(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::Crnor => { - let mut uses = vec![ - Field::crbA(CRBit(((self.code >> 16u8) & 0x1f) as _)), - Field::crbB(CRBit(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::Cror => { - let mut uses = vec![ - Field::crbA(CRBit(((self.code >> 16u8) & 0x1f) as _)), - Field::crbB(CRBit(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::Crorc => { - let mut uses = vec![ - Field::crbA(CRBit(((self.code >> 16u8) & 0x1f) as _)), - Field::crbB(CRBit(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::Crxor => { - let mut uses = vec![ - Field::crbA(CRBit(((self.code >> 16u8) & 0x1f) as _)), - Field::crbB(CRBit(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::Dcbf => { - let mut uses = vec![Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _))]; - if ((self.code >> 16u8) & 0x1f) != 0 { - uses.push(Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))); - } - uses - } - Opcode::Dcbi => { - let mut uses = vec![Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _))]; - if ((self.code >> 16u8) & 0x1f) != 0 { - uses.push(Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))); - } - uses - } - Opcode::Dcbst => { - let mut uses = vec![Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _))]; - if ((self.code >> 16u8) & 0x1f) != 0 { - uses.push(Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))); - } - uses - } - Opcode::Dcbt => { - let mut uses = vec![Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _))]; - if ((self.code >> 16u8) & 0x1f) != 0 { - uses.push(Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))); - } - uses - } - Opcode::Dcbtst => { - let mut uses = vec![Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _))]; - if ((self.code >> 16u8) & 0x1f) != 0 { - uses.push(Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))); - } - uses - } - Opcode::Dcbz => { - let mut uses = vec![Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _))]; - if ((self.code >> 16u8) & 0x1f) != 0 { - uses.push(Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))); - } - uses - } - Opcode::DcbzL => { - let mut uses = vec![Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _))]; - if ((self.code >> 16u8) & 0x1f) != 0 { - uses.push(Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))); - } - uses - } - Opcode::Divw => { - let mut uses = vec![ - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::Divwu => { - let mut uses = vec![ - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::Eciwx => { - let mut uses = vec![Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _))]; - if ((self.code >> 16u8) & 0x1f) != 0 { - uses.push(Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))); - } - uses - } - Opcode::Ecowx => { - let mut uses = vec![ - Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - if ((self.code >> 16u8) & 0x1f) != 0 { - uses.push(Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))); - } - uses - } - Opcode::Eieio => { - let mut uses = vec![]; - uses - } - Opcode::Eqv => { - let mut uses = vec![ - Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::Extsb => { - let mut uses = vec![Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _))]; - uses - } - Opcode::Extsh => { - let mut uses = vec![Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _))]; - uses - } - Opcode::Fabs => { - let mut uses = vec![Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _))]; - uses - } - Opcode::Fadd => { - let mut uses = vec![ - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::Fadds => { - let mut uses = vec![ - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::Fcmpo => { - let mut uses = vec![ - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::Fcmpu => { - let mut uses = vec![ - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::Fctiw => { - let mut uses = vec![Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _))]; - uses - } - Opcode::Fctiwz => { - let mut uses = vec![Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _))]; - uses - } - Opcode::Fdiv => { - let mut uses = vec![ - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::Fdivs => { - let mut uses = vec![ - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::Fmadd => { - let mut uses = vec![ - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), - Field::frC(FPR(((self.code >> 6u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::Fmadds => { - let mut uses = vec![ - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), - Field::frC(FPR(((self.code >> 6u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::Fmr => { - let mut uses = vec![Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _))]; - uses - } - Opcode::Fmsub => { - let mut uses = vec![ - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), - Field::frC(FPR(((self.code >> 6u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::Fmsubs => { - let mut uses = vec![ - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), - Field::frC(FPR(((self.code >> 6u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::Fmul => { - let mut uses = vec![ - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), - Field::frC(FPR(((self.code >> 6u8) & 0x1f) as _)), - ]; - uses - } - Opcode::Fmuls => { - let mut uses = vec![ - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), - Field::frC(FPR(((self.code >> 6u8) & 0x1f) as _)), - ]; - uses - } - Opcode::Fnabs => { - let mut uses = vec![Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _))]; - uses - } - Opcode::Fneg => { - let mut uses = vec![Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _))]; - uses - } - Opcode::Fnmadd => { - let mut uses = vec![ - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), - Field::frC(FPR(((self.code >> 6u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::Fnmadds => { - let mut uses = vec![ - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), - Field::frC(FPR(((self.code >> 6u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::Fnmsub => { - let mut uses = vec![ - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), - Field::frC(FPR(((self.code >> 6u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::Fnmsubs => { - let mut uses = vec![ - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), - Field::frC(FPR(((self.code >> 6u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::Fres => { - let mut uses = vec![Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _))]; - uses - } - Opcode::Frsp => { - let mut uses = vec![Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _))]; - uses - } - Opcode::Frsqrte => { - let mut uses = vec![Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _))]; - uses - } - Opcode::Fsel => { - let mut uses = vec![ - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), - Field::frC(FPR(((self.code >> 6u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::Fsub => { - let mut uses = vec![ - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::Fsubs => { - let mut uses = vec![ - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::Icbi => { - let mut uses = vec![Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _))]; - if ((self.code >> 16u8) & 0x1f) != 0 { - uses.push(Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))); - } - uses - } - Opcode::Isync => { - let mut uses = vec![]; - uses - } - Opcode::Lbz => { - let mut uses = vec![Field::offset(Offset( - ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _, - ))]; - if ((self.code >> 16u8) & 0x1f) != 0 { - uses.push(Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))); - } - uses - } - Opcode::Lbzu => { - let mut uses = vec![ - Field::offset(Offset( - ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _, - )), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - ]; - uses - } - Opcode::Lbzux => { - let mut uses = vec![ - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::Lbzx => { - let mut uses = vec![Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _))]; - if ((self.code >> 16u8) & 0x1f) != 0 { - uses.push(Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))); - } - uses - } - Opcode::Lfd => { - let mut uses = vec![Field::offset(Offset( - ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _, - ))]; - if ((self.code >> 16u8) & 0x1f) != 0 { - uses.push(Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))); - } - uses - } - Opcode::Lfdu => { - let mut uses = vec![ - Field::offset(Offset( - ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _, - )), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - ]; - uses - } - Opcode::Lfdux => { - let mut uses = vec![ - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::Lfdx => { - let mut uses = vec![Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _))]; - if ((self.code >> 16u8) & 0x1f) != 0 { - uses.push(Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))); - } - uses - } - Opcode::Lfs => { - let mut uses = vec![Field::offset(Offset( - ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _, - ))]; - if ((self.code >> 16u8) & 0x1f) != 0 { - uses.push(Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))); - } - uses - } - Opcode::Lfsu => { - let mut uses = vec![ - Field::offset(Offset( - ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _, - )), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - ]; - uses - } - Opcode::Lfsux => { - let mut uses = vec![ - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::Lfsx => { - let mut uses = vec![Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _))]; - if ((self.code >> 16u8) & 0x1f) != 0 { - uses.push(Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))); - } - uses - } - Opcode::Lha => { - let mut uses = vec![Field::offset(Offset( - ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _, - ))]; - if ((self.code >> 16u8) & 0x1f) != 0 { - uses.push(Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))); - } - uses - } - Opcode::Lhau => { - let mut uses = vec![ - Field::offset(Offset( - ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _, - )), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - ]; - uses - } - Opcode::Lhaux => { - let mut uses = vec![ - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::Lhax => { - let mut uses = vec![Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _))]; - if ((self.code >> 16u8) & 0x1f) != 0 { - uses.push(Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))); - } - uses - } - Opcode::Lhbrx => { - let mut uses = vec![Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _))]; - if ((self.code >> 16u8) & 0x1f) != 0 { - uses.push(Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))); - } - uses - } - Opcode::Lhz => { - let mut uses = vec![Field::offset(Offset( - ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _, - ))]; - if ((self.code >> 16u8) & 0x1f) != 0 { - uses.push(Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))); - } - uses - } - Opcode::Lhzu => { - let mut uses = vec![ - Field::offset(Offset( - ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _, - )), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - ]; - uses - } - Opcode::Lhzux => { - let mut uses = vec![ - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::Lhzx => { - let mut uses = vec![Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _))]; - if ((self.code >> 16u8) & 0x1f) != 0 { - uses.push(Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))); - } - uses - } - Opcode::Lmw => { - let mut uses = vec![Field::offset(Offset( - ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _, - ))]; - if ((self.code >> 16u8) & 0x1f) != 0 { - uses.push(Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))); - } - uses - } - Opcode::Lswi => { - let mut uses = vec![]; - if ((self.code >> 16u8) & 0x1f) != 0 { - uses.push(Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))); - } - uses - } - Opcode::Lswx => { - let mut uses = vec![Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _))]; - if ((self.code >> 16u8) & 0x1f) != 0 { - uses.push(Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))); - } - uses - } - Opcode::Lwarx => { - let mut uses = vec![Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _))]; - if ((self.code >> 16u8) & 0x1f) != 0 { - uses.push(Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))); - } - uses - } - Opcode::Lwbrx => { - let mut uses = vec![Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _))]; - if ((self.code >> 16u8) & 0x1f) != 0 { - uses.push(Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))); - } - uses - } - Opcode::Lwz => { - let mut uses = vec![Field::offset(Offset( - ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _, - ))]; - if ((self.code >> 16u8) & 0x1f) != 0 { - uses.push(Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))); - } - uses - } - Opcode::Lwzu => { - let mut uses = vec![ - Field::offset(Offset( - ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _, - )), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - ]; - uses - } - Opcode::Lwzux => { - let mut uses = vec![ - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::Lwzx => { - let mut uses = vec![Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _))]; - if ((self.code >> 16u8) & 0x1f) != 0 { - uses.push(Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))); - } - uses - } - Opcode::Mcrf => { - let mut uses = vec![Field::crfS(CRField(((self.code >> 18u8) & 0x7) as _))]; - uses - } - Opcode::Mcrfs => { - let mut uses = vec![Field::crfS(CRField(((self.code >> 18u8) & 0x7) as _))]; - uses - } - Opcode::Mcrxr => { - let mut uses = vec![]; - uses - } - Opcode::Mfcr => { - let mut uses = vec![]; - uses - } - Opcode::Mffs => { - let mut uses = vec![]; - uses - } - Opcode::Mfmsr => { - let mut uses = vec![]; - uses - } - Opcode::Mfspr => { - let mut uses = vec![]; - uses - } - Opcode::Mfsr => { - let mut uses = vec![]; - uses - } - Opcode::Mfsrin => { - let mut uses = vec![Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _))]; - uses - } - Opcode::Mftb => { - let mut uses = vec![]; - uses - } - Opcode::Mtcrf => { - let mut uses = vec![Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _))]; - uses - } - Opcode::Mtfsb0 => { - let mut uses = vec![]; - uses - } - Opcode::Mtfsb1 => { - let mut uses = vec![]; - uses - } - Opcode::Mtfsf => { - let mut uses = vec![Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _))]; - uses - } - Opcode::Mtfsfi => { - let mut uses = vec![]; - uses - } - Opcode::Mtmsr => { - let mut uses = vec![Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _))]; - uses - } - Opcode::Mtspr => { - let mut uses = vec![Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _))]; - uses - } - Opcode::Mtsr => { - let mut uses = vec![Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _))]; - uses - } - Opcode::Mtsrin => { - let mut uses = vec![ - Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::Mulhw => { - let mut uses = vec![ - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::Mulhwu => { - let mut uses = vec![ - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::Mulli => { - let mut uses = vec![Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))]; - uses - } - Opcode::Mullw => { - let mut uses = vec![ - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::Nand => { - let mut uses = vec![ - Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::Neg => { - let mut uses = vec![Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))]; - uses - } - Opcode::Nor => { - let mut uses = vec![ - Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::Or => { - let mut uses = vec![ - Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::Orc => { - let mut uses = vec![ - Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::Ori => { - let mut uses = vec![Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _))]; - uses - } - Opcode::Oris => { - let mut uses = vec![Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _))]; - uses - } - Opcode::PsqL => { - let mut uses = vec![]; - if ((self.code >> 16u8) & 0x1f) != 0 { - uses.push(Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))); - } - uses - } - Opcode::PsqLu => { - let mut uses = vec![Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))]; - uses - } - Opcode::PsqLux => { - let mut uses = vec![ - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::PsqLx => { - let mut uses = vec![Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _))]; - if ((self.code >> 16u8) & 0x1f) != 0 { - uses.push(Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))); - } - uses - } - Opcode::PsqSt => { - let mut uses = vec![Field::frS(FPR(((self.code >> 21u8) & 0x1f) as _))]; - if ((self.code >> 16u8) & 0x1f) != 0 { - uses.push(Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))); - } - uses - } - Opcode::PsqStu => { - let mut uses = vec![ - Field::frS(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - ]; - uses - } - Opcode::PsqStux => { - let mut uses = vec![ - Field::frS(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::PsqStx => { - let mut uses = vec![ - Field::frS(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - if ((self.code >> 16u8) & 0x1f) != 0 { - uses.push(Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))); - } - uses - } - Opcode::PsAbs => { - let mut uses = vec![Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _))]; - uses - } - Opcode::PsAdd => { - let mut uses = vec![ - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::PsCmpo0 => { - let mut uses = vec![Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _))]; - if ((self.code >> 16u8) & 0x1f) != 0 { - uses.push(Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _))); - } - uses - } - Opcode::PsCmpo1 => { - let mut uses = vec![Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _))]; - if ((self.code >> 16u8) & 0x1f) != 0 { - uses.push(Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _))); - } - uses - } - Opcode::PsCmpu0 => { - let mut uses = vec![Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _))]; - if ((self.code >> 16u8) & 0x1f) != 0 { - uses.push(Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _))); - } - uses - } - Opcode::PsCmpu1 => { - let mut uses = vec![Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _))]; - if ((self.code >> 16u8) & 0x1f) != 0 { - uses.push(Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _))); - } - uses - } - Opcode::PsDiv => { - let mut uses = vec![ - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::PsMadd => { - let mut uses = vec![ - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), - Field::frC(FPR(((self.code >> 6u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::PsMadds0 => { - let mut uses = vec![ - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), - Field::frC(FPR(((self.code >> 6u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::PsMadds1 => { - let mut uses = vec![ - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), - Field::frC(FPR(((self.code >> 6u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::PsMerge00 => { - let mut uses = vec![ - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::PsMerge01 => { - let mut uses = vec![ - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::PsMerge10 => { - let mut uses = vec![ - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::PsMerge11 => { - let mut uses = vec![ - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::PsMr => { - let mut uses = vec![Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _))]; - uses - } - Opcode::PsMsub => { - let mut uses = vec![ - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), - Field::frC(FPR(((self.code >> 6u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::PsMul => { - let mut uses = vec![ - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), - Field::frC(FPR(((self.code >> 6u8) & 0x1f) as _)), - ]; - uses - } - Opcode::PsMuls0 => { - let mut uses = vec![ - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), - Field::frC(FPR(((self.code >> 6u8) & 0x1f) as _)), - ]; - uses - } - Opcode::PsMuls1 => { - let mut uses = vec![ - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), - Field::frC(FPR(((self.code >> 6u8) & 0x1f) as _)), - ]; - uses - } - Opcode::PsNabs => { - let mut uses = vec![Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _))]; - uses - } - Opcode::PsNeg => { - let mut uses = vec![Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _))]; - uses - } - Opcode::PsNmadd => { - let mut uses = vec![ - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), - Field::frC(FPR(((self.code >> 6u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::PsNmsub => { - let mut uses = vec![ - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), - Field::frC(FPR(((self.code >> 6u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::PsRes => { - let mut uses = vec![Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _))]; - uses - } - Opcode::PsRsqrte => { - let mut uses = vec![Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _))]; - uses - } - Opcode::PsSel => { - let mut uses = vec![ - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), - Field::frC(FPR(((self.code >> 6u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::PsSub => { - let mut uses = vec![ - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::PsSum0 => { - let mut uses = vec![ - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), - Field::frC(FPR(((self.code >> 6u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::PsSum1 => { - let mut uses = vec![ - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), - Field::frC(FPR(((self.code >> 6u8) & 0x1f) as _)), - Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::Rfi => { - let mut uses = vec![]; - uses - } - Opcode::Rlwimi => { - let mut uses = vec![ - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::SH(OpaqueU(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::Rlwinm => { - let mut uses = vec![ - Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::SH(OpaqueU(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::Rlwnm => { - let mut uses = vec![ - Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::Sc => { - let mut uses = vec![]; - uses - } - Opcode::Slw => { - let mut uses = vec![ - Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::Sraw => { - let mut uses = vec![ - Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::Srawi => { - let mut uses = vec![Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _))]; - uses - } - Opcode::Srw => { - let mut uses = vec![ - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::Stb => { - let mut uses = vec![Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _))]; - if ((self.code >> 16u8) & 0x1f) != 0 { - uses.push(Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))); - } - uses - } - Opcode::Stbu => { - let mut uses = vec![ - Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - ]; - uses - } - Opcode::Stbux => { - let mut uses = vec![ - Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::Stbx => { - let mut uses = vec![ - Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - if ((self.code >> 16u8) & 0x1f) != 0 { - uses.push(Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))); - } - uses - } - Opcode::Stfd => { - let mut uses = vec![Field::frS(FPR(((self.code >> 21u8) & 0x1f) as _))]; - if ((self.code >> 16u8) & 0x1f) != 0 { - uses.push(Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))); - } - uses - } - Opcode::Stfdu => { - let mut uses = vec![ - Field::frS(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - ]; - uses - } - Opcode::Stfdux => { - let mut uses = vec![ - Field::frS(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::Stfdx => { - let mut uses = vec![ - Field::frS(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - if ((self.code >> 16u8) & 0x1f) != 0 { - uses.push(Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))); - } - uses - } - Opcode::Stfiwx => { - let mut uses = vec![ - Field::frS(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - if ((self.code >> 16u8) & 0x1f) != 0 { - uses.push(Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))); - } - uses - } - Opcode::Stfs => { - let mut uses = vec![Field::frS(FPR(((self.code >> 21u8) & 0x1f) as _))]; - if ((self.code >> 16u8) & 0x1f) != 0 { - uses.push(Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))); - } - uses - } - Opcode::Stfsu => { - let mut uses = vec![ - Field::frS(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - ]; - uses - } - Opcode::Stfsux => { - let mut uses = vec![ - Field::frS(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::Stfsx => { - let mut uses = vec![ - Field::frS(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - if ((self.code >> 16u8) & 0x1f) != 0 { - uses.push(Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))); - } - uses - } - Opcode::Sth => { - let mut uses = vec![Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _))]; - if ((self.code >> 16u8) & 0x1f) != 0 { - uses.push(Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))); - } - uses - } - Opcode::Sthbrx => { - let mut uses = vec![ - Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - if ((self.code >> 16u8) & 0x1f) != 0 { - uses.push(Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))); - } - uses - } - Opcode::Sthu => { - let mut uses = vec![ - Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - ]; - uses - } - Opcode::Sthux => { - let mut uses = vec![ - Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::Sthx => { - let mut uses = vec![ - Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - if ((self.code >> 16u8) & 0x1f) != 0 { - uses.push(Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))); - } - uses - } - Opcode::Stmw => { - let mut uses = vec![Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _))]; - if ((self.code >> 16u8) & 0x1f) != 0 { - uses.push(Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))); - } - uses - } - Opcode::Stswi => { - let mut uses = vec![Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _))]; - if ((self.code >> 16u8) & 0x1f) != 0 { - uses.push(Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))); - } - uses - } - Opcode::Stswx => { - let mut uses = vec![ - Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - if ((self.code >> 16u8) & 0x1f) != 0 { - uses.push(Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))); - } - uses - } - Opcode::Stw => { - let mut uses = vec![Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _))]; - if ((self.code >> 16u8) & 0x1f) != 0 { - uses.push(Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))); - } - uses - } - Opcode::Stwbrx => { - let mut uses = vec![ - Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - if ((self.code >> 16u8) & 0x1f) != 0 { - uses.push(Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))); - } - uses - } - Opcode::Stwcx_ => { - let mut uses = vec![ - Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - if ((self.code >> 16u8) & 0x1f) != 0 { - uses.push(Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))); - } - uses - } - Opcode::Stwu => { - let mut uses = vec![ - Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - ]; - uses - } - Opcode::Stwux => { - let mut uses = vec![ - Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::Stwx => { - let mut uses = vec![ - Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - if ((self.code >> 16u8) & 0x1f) != 0 { - uses.push(Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))); - } - uses - } - Opcode::Subf => { - let mut uses = vec![ - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::Subfc => { - let mut uses = vec![ - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::Subfe => { - let mut uses = vec![ - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::Subfic => { - let mut uses = vec![Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))]; - uses - } - Opcode::Subfme => { - let mut uses = vec![Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))]; - uses - } - Opcode::Subfze => { - let mut uses = vec![Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))]; - uses - } - Opcode::Sync => { - let mut uses = vec![]; - uses - } - Opcode::Tlbie => { - let mut uses = vec![Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _))]; - uses - } - Opcode::Tlbsync => { - let mut uses = vec![]; - uses - } - Opcode::Tw => { - let mut uses = vec![ - Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::Twi => { - let mut uses = vec![Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))]; - uses - } - Opcode::Xor => { - let mut uses = vec![ - Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - ]; - uses - } - Opcode::Xori => { - let mut uses = vec![Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _))]; - uses - } - Opcode::Xoris => { - let mut uses = vec![Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _))]; - uses - } - } + /// offset: Branch Offset + #[inline(always)] + pub const fn field_offset(&self) -> i16 { + ((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000) as i16 } - pub(crate) fn _suffix(&self) -> String { - match self.op { - Opcode::Illegal => String::new(), - Opcode::Add => { - let mut s = String::with_capacity(4); - if self.bit(21usize) { - s.push('o'); - } - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::Addc => { - let mut s = String::with_capacity(4); - if self.bit(21usize) { - s.push('o'); - } - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::Adde => { - let mut s = String::with_capacity(4); - if self.bit(21usize) { - s.push('o'); - } - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::Addi => String::new(), - Opcode::Addic => String::new(), - Opcode::Addic_ => String::new(), - Opcode::Addis => String::new(), - Opcode::Addme => { - let mut s = String::with_capacity(4); - if self.bit(21usize) { - s.push('o'); - } - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::Addze => { - let mut s = String::with_capacity(4); - if self.bit(21usize) { - s.push('o'); - } - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::And => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::Andc => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::Andi_ => String::new(), - Opcode::Andis_ => String::new(), - Opcode::B => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('l'); - } - if self.bit(30usize) { - s.push('a'); - } - s - } - Opcode::Bc => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('l'); - } - if self.bit(30usize) { - s.push('a'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 - && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) as i32) - << 2u8) - >= 0 - { - s.push('+'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 - && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) as i32) - << 2u8) - < 0 - { - s.push('-'); - } - s - } - Opcode::Bcctr => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('l'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 { - s.push('+'); - } - s - } - Opcode::Bclr => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('l'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 { - s.push('+'); - } - s - } - Opcode::Cmp => String::new(), - Opcode::Cmpi => String::new(), - Opcode::Cmpl => String::new(), - Opcode::Cmpli => String::new(), - Opcode::Cntlzw => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::Crand => String::new(), - Opcode::Crandc => String::new(), - Opcode::Creqv => String::new(), - Opcode::Crnand => String::new(), - Opcode::Crnor => String::new(), - Opcode::Cror => String::new(), - Opcode::Crorc => String::new(), - Opcode::Crxor => String::new(), - Opcode::Dcbf => String::new(), - Opcode::Dcbi => String::new(), - Opcode::Dcbst => String::new(), - Opcode::Dcbt => String::new(), - Opcode::Dcbtst => String::new(), - Opcode::Dcbz => String::new(), - Opcode::DcbzL => String::new(), - Opcode::Divw => { - let mut s = String::with_capacity(4); - if self.bit(21usize) { - s.push('o'); - } - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::Divwu => { - let mut s = String::with_capacity(4); - if self.bit(21usize) { - s.push('o'); - } - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::Eciwx => String::new(), - Opcode::Ecowx => String::new(), - Opcode::Eieio => String::new(), - Opcode::Eqv => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::Extsb => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::Extsh => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::Fabs => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::Fadd => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::Fadds => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::Fcmpo => String::new(), - Opcode::Fcmpu => String::new(), - Opcode::Fctiw => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::Fctiwz => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::Fdiv => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::Fdivs => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::Fmadd => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::Fmadds => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::Fmr => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::Fmsub => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::Fmsubs => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::Fmul => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::Fmuls => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::Fnabs => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::Fneg => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::Fnmadd => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::Fnmadds => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::Fnmsub => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::Fnmsubs => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::Fres => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::Frsp => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::Frsqrte => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::Fsel => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::Fsub => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::Fsubs => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::Icbi => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::Isync => String::new(), - Opcode::Lbz => String::new(), - Opcode::Lbzu => String::new(), - Opcode::Lbzux => String::new(), - Opcode::Lbzx => String::new(), - Opcode::Lfd => String::new(), - Opcode::Lfdu => String::new(), - Opcode::Lfdux => String::new(), - Opcode::Lfdx => String::new(), - Opcode::Lfs => String::new(), - Opcode::Lfsu => String::new(), - Opcode::Lfsux => String::new(), - Opcode::Lfsx => String::new(), - Opcode::Lha => String::new(), - Opcode::Lhau => String::new(), - Opcode::Lhaux => String::new(), - Opcode::Lhax => String::new(), - Opcode::Lhbrx => String::new(), - Opcode::Lhz => String::new(), - Opcode::Lhzu => String::new(), - Opcode::Lhzux => String::new(), - Opcode::Lhzx => String::new(), - Opcode::Lmw => String::new(), - Opcode::Lswi => String::new(), - Opcode::Lswx => String::new(), - Opcode::Lwarx => String::new(), - Opcode::Lwbrx => String::new(), - Opcode::Lwz => String::new(), - Opcode::Lwzu => String::new(), - Opcode::Lwzux => String::new(), - Opcode::Lwzx => String::new(), - Opcode::Mcrf => String::new(), - Opcode::Mcrfs => String::new(), - Opcode::Mcrxr => String::new(), - Opcode::Mfcr => String::new(), - Opcode::Mffs => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::Mfmsr => String::new(), - Opcode::Mfspr => String::new(), - Opcode::Mfsr => String::new(), - Opcode::Mfsrin => String::new(), - Opcode::Mftb => String::new(), - Opcode::Mtcrf => String::new(), - Opcode::Mtfsb0 => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::Mtfsb1 => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::Mtfsf => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::Mtfsfi => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::Mtmsr => String::new(), - Opcode::Mtspr => String::new(), - Opcode::Mtsr => String::new(), - Opcode::Mtsrin => String::new(), - Opcode::Mulhw => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::Mulhwu => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::Mulli => String::new(), - Opcode::Mullw => { - let mut s = String::with_capacity(4); - if self.bit(21usize) { - s.push('o'); - } - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::Nand => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::Neg => { - let mut s = String::with_capacity(4); - if self.bit(21usize) { - s.push('o'); - } - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::Nor => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::Or => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::Orc => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::Ori => String::new(), - Opcode::Oris => String::new(), - Opcode::PsqL => String::new(), - Opcode::PsqLu => String::new(), - Opcode::PsqLux => String::new(), - Opcode::PsqLx => String::new(), - Opcode::PsqSt => String::new(), - Opcode::PsqStu => String::new(), - Opcode::PsqStux => String::new(), - Opcode::PsqStx => String::new(), - Opcode::PsAbs => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::PsAdd => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::PsCmpo0 => String::new(), - Opcode::PsCmpo1 => String::new(), - Opcode::PsCmpu0 => String::new(), - Opcode::PsCmpu1 => String::new(), - Opcode::PsDiv => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::PsMadd => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::PsMadds0 => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::PsMadds1 => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::PsMerge00 => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::PsMerge01 => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::PsMerge10 => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::PsMerge11 => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::PsMr => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::PsMsub => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::PsMul => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::PsMuls0 => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::PsMuls1 => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::PsNabs => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::PsNeg => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::PsNmadd => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::PsNmsub => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::PsRes => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::PsRsqrte => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::PsSel => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::PsSub => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::PsSum0 => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::PsSum1 => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::Rfi => String::new(), - Opcode::Rlwimi => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::Rlwinm => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::Rlwnm => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::Sc => String::new(), - Opcode::Slw => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::Sraw => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::Srawi => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::Srw => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::Stb => String::new(), - Opcode::Stbu => String::new(), - Opcode::Stbux => String::new(), - Opcode::Stbx => String::new(), - Opcode::Stfd => String::new(), - Opcode::Stfdu => String::new(), - Opcode::Stfdux => String::new(), - Opcode::Stfdx => String::new(), - Opcode::Stfiwx => String::new(), - Opcode::Stfs => String::new(), - Opcode::Stfsu => String::new(), - Opcode::Stfsux => String::new(), - Opcode::Stfsx => String::new(), - Opcode::Sth => String::new(), - Opcode::Sthbrx => String::new(), - Opcode::Sthu => String::new(), - Opcode::Sthux => String::new(), - Opcode::Sthx => String::new(), - Opcode::Stmw => String::new(), - Opcode::Stswi => String::new(), - Opcode::Stswx => String::new(), - Opcode::Stw => String::new(), - Opcode::Stwbrx => String::new(), - Opcode::Stwcx_ => String::new(), - Opcode::Stwu => String::new(), - Opcode::Stwux => String::new(), - Opcode::Stwx => String::new(), - Opcode::Subf => { - let mut s = String::with_capacity(4); - if self.bit(21usize) { - s.push('o'); - } - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::Subfc => { - let mut s = String::with_capacity(4); - if self.bit(21usize) { - s.push('o'); - } - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::Subfe => { - let mut s = String::with_capacity(4); - if self.bit(21usize) { - s.push('o'); - } - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::Subfic => String::new(), - Opcode::Subfme => { - let mut s = String::with_capacity(4); - if self.bit(21usize) { - s.push('o'); - } - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::Subfze => { - let mut s = String::with_capacity(4); - if self.bit(21usize) { - s.push('o'); - } - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::Sync => String::new(), - Opcode::Tlbie => String::new(), - Opcode::Tlbsync => String::new(), - Opcode::Tw => String::new(), - Opcode::Twi => String::new(), - Opcode::Xor => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::Xori => String::new(), - Opcode::Xoris => String::new(), - } + /// ps_offset: Paired Single Offset + #[inline(always)] + pub const fn field_ps_offset(&self) -> i16 { + ((self.code & 0xfff) ^ 0x800).wrapping_sub(0x800) as i16 } - pub(crate) fn _simplified(self) -> SimplifiedIns { - match self.op { - Opcode::Addi => { - if ((self.code >> 16u8) & 0x1f) == 0 { - return SimplifiedIns { - mnemonic: "li", - suffix: String::new(), - args: vec![ - Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _)), - Argument::Simm(Simm( - ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) - as _, - )), - ], - ins: self, - }; - } - if ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) < 0 - && ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) != -0x8000 - { - return SimplifiedIns { - mnemonic: "subi", - suffix: String::new(), - args: vec![ - Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _)), - Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), - Argument::Simm(Simm( - (-((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32)) - as _, - )), - ], - ins: self, - }; - } - } - Opcode::Addic => { - if ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) < 0 - && ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) != -0x8000 - { - return SimplifiedIns { - mnemonic: "subic", - suffix: String::new(), - args: vec![ - Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _)), - Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), - Argument::Simm(Simm( - (-((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32)) - as _, - )), - ], - ins: self, - }; - } - } - Opcode::Addic_ => { - if ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) < 0 - && ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) != -0x8000 - { - return SimplifiedIns { - mnemonic: "subic.", - suffix: String::new(), - args: vec![ - Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _)), - Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), - Argument::Simm(Simm( - (-((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32)) - as _, - )), - ], - ins: self, - }; - } - } - Opcode::Addis => { - if ((self.code >> 16u8) & 0x1f) == 0 { - return SimplifiedIns { - mnemonic: "lis", - suffix: String::new(), - args: vec![ - Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _)), - Argument::Uimm(Uimm((self.code & 0xffff) as _)), - ], - ins: self, - }; - } - if ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) < 0 - && ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) != -0x8000 - { - return SimplifiedIns { - mnemonic: "subis", - suffix: String::new(), - args: vec![ - Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _)), - Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), - Argument::Simm(Simm( - (-((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32)) - as _, - )), - ], - ins: self, - }; - } - } - Opcode::Bc => { - if ((self.code >> 21u8) & 0x1f) & 0b11110 == 12 && ((self.code >> 16u8) & 0x1f) == 0 - { - return SimplifiedIns { - mnemonic: "blt", - suffix: { - { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('l'); - } - if self.bit(30usize) { - s.push('a'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 - && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) - .wrapping_sub(0x2000)) - as i32) - << 2u8) - >= 0 - { - s.push('+'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 - && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) - .wrapping_sub(0x2000)) - as i32) - << 2u8) - < 0 - { - s.push('-'); - } - s - } - }, - args: vec![Argument::BranchDest(BranchDest( - ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) - as i32) - << 2u8) as _, - ))], - ins: self, - }; - } - if ((self.code >> 21u8) & 0x1f) & 0b11110 == 12 - && ((self.code >> 16u8) & 0x1f) & 0b11 == 0 - { - return SimplifiedIns { - mnemonic: "blt", - suffix: { - { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('l'); - } - if self.bit(30usize) { - s.push('a'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 - && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) - .wrapping_sub(0x2000)) - as i32) - << 2u8) - >= 0 - { - s.push('+'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 - && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) - .wrapping_sub(0x2000)) - as i32) - << 2u8) - < 0 - { - s.push('-'); - } - s - } - }, - args: vec![ - Argument::CRField(CRField(((self.code >> 18u8) & 0x7) as _)), - Argument::BranchDest(BranchDest( - ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) - as i32) - << 2u8) as _, - )), - ], - ins: self, - }; - } - if ((self.code >> 21u8) & 0x1f) & 0b11110 == 4 && ((self.code >> 16u8) & 0x1f) == 1 - { - return SimplifiedIns { - mnemonic: "ble", - suffix: { - { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('l'); - } - if self.bit(30usize) { - s.push('a'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 - && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) - .wrapping_sub(0x2000)) - as i32) - << 2u8) - >= 0 - { - s.push('+'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 - && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) - .wrapping_sub(0x2000)) - as i32) - << 2u8) - < 0 - { - s.push('-'); - } - s - } - }, - args: vec![Argument::BranchDest(BranchDest( - ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) - as i32) - << 2u8) as _, - ))], - ins: self, - }; - } - if ((self.code >> 21u8) & 0x1f) & 0b11110 == 4 - && ((self.code >> 16u8) & 0x1f) & 0b11 == 1 - { - return SimplifiedIns { - mnemonic: "ble", - suffix: { - { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('l'); - } - if self.bit(30usize) { - s.push('a'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 - && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) - .wrapping_sub(0x2000)) - as i32) - << 2u8) - >= 0 - { - s.push('+'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 - && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) - .wrapping_sub(0x2000)) - as i32) - << 2u8) - < 0 - { - s.push('-'); - } - s - } - }, - args: vec![ - Argument::CRField(CRField(((self.code >> 18u8) & 0x7) as _)), - Argument::BranchDest(BranchDest( - ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) - as i32) - << 2u8) as _, - )), - ], - ins: self, - }; - } - if ((self.code >> 21u8) & 0x1f) & 0b11110 == 12 && ((self.code >> 16u8) & 0x1f) == 2 - { - return SimplifiedIns { - mnemonic: "beq", - suffix: { - { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('l'); - } - if self.bit(30usize) { - s.push('a'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 - && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) - .wrapping_sub(0x2000)) - as i32) - << 2u8) - >= 0 - { - s.push('+'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 - && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) - .wrapping_sub(0x2000)) - as i32) - << 2u8) - < 0 - { - s.push('-'); - } - s - } - }, - args: vec![Argument::BranchDest(BranchDest( - ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) - as i32) - << 2u8) as _, - ))], - ins: self, - }; - } - if ((self.code >> 21u8) & 0x1f) & 0b11110 == 12 - && ((self.code >> 16u8) & 0x1f) & 0b11 == 2 - { - return SimplifiedIns { - mnemonic: "beq", - suffix: { - { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('l'); - } - if self.bit(30usize) { - s.push('a'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 - && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) - .wrapping_sub(0x2000)) - as i32) - << 2u8) - >= 0 - { - s.push('+'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 - && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) - .wrapping_sub(0x2000)) - as i32) - << 2u8) - < 0 - { - s.push('-'); - } - s - } - }, - args: vec![ - Argument::CRField(CRField(((self.code >> 18u8) & 0x7) as _)), - Argument::BranchDest(BranchDest( - ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) - as i32) - << 2u8) as _, - )), - ], - ins: self, - }; - } - if ((self.code >> 21u8) & 0x1f) & 0b11110 == 4 && ((self.code >> 16u8) & 0x1f) == 0 - { - return SimplifiedIns { - mnemonic: "bge", - suffix: { - { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('l'); - } - if self.bit(30usize) { - s.push('a'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 - && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) - .wrapping_sub(0x2000)) - as i32) - << 2u8) - >= 0 - { - s.push('+'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 - && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) - .wrapping_sub(0x2000)) - as i32) - << 2u8) - < 0 - { - s.push('-'); - } - s - } - }, - args: vec![Argument::BranchDest(BranchDest( - ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) - as i32) - << 2u8) as _, - ))], - ins: self, - }; - } - if ((self.code >> 21u8) & 0x1f) & 0b11110 == 4 - && ((self.code >> 16u8) & 0x1f) & 0b11 == 0 - { - return SimplifiedIns { - mnemonic: "bge", - suffix: { - { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('l'); - } - if self.bit(30usize) { - s.push('a'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 - && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) - .wrapping_sub(0x2000)) - as i32) - << 2u8) - >= 0 - { - s.push('+'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 - && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) - .wrapping_sub(0x2000)) - as i32) - << 2u8) - < 0 - { - s.push('-'); - } - s - } - }, - args: vec![ - Argument::CRField(CRField(((self.code >> 18u8) & 0x7) as _)), - Argument::BranchDest(BranchDest( - ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) - as i32) - << 2u8) as _, - )), - ], - ins: self, - }; - } - if ((self.code >> 21u8) & 0x1f) & 0b11110 == 12 && ((self.code >> 16u8) & 0x1f) == 1 - { - return SimplifiedIns { - mnemonic: "bgt", - suffix: { - { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('l'); - } - if self.bit(30usize) { - s.push('a'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 - && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) - .wrapping_sub(0x2000)) - as i32) - << 2u8) - >= 0 - { - s.push('+'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 - && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) - .wrapping_sub(0x2000)) - as i32) - << 2u8) - < 0 - { - s.push('-'); - } - s - } - }, - args: vec![Argument::BranchDest(BranchDest( - ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) - as i32) - << 2u8) as _, - ))], - ins: self, - }; - } - if ((self.code >> 21u8) & 0x1f) & 0b11110 == 12 - && ((self.code >> 16u8) & 0x1f) & 0b11 == 1 - { - return SimplifiedIns { - mnemonic: "bgt", - suffix: { - { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('l'); - } - if self.bit(30usize) { - s.push('a'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 - && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) - .wrapping_sub(0x2000)) - as i32) - << 2u8) - >= 0 - { - s.push('+'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 - && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) - .wrapping_sub(0x2000)) - as i32) - << 2u8) - < 0 - { - s.push('-'); - } - s - } - }, - args: vec![ - Argument::CRField(CRField(((self.code >> 18u8) & 0x7) as _)), - Argument::BranchDest(BranchDest( - ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) - as i32) - << 2u8) as _, - )), - ], - ins: self, - }; - } - if ((self.code >> 21u8) & 0x1f) & 0b11110 == 4 && ((self.code >> 16u8) & 0x1f) == 2 - { - return SimplifiedIns { - mnemonic: "bne", - suffix: { - { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('l'); - } - if self.bit(30usize) { - s.push('a'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 - && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) - .wrapping_sub(0x2000)) - as i32) - << 2u8) - >= 0 - { - s.push('+'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 - && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) - .wrapping_sub(0x2000)) - as i32) - << 2u8) - < 0 - { - s.push('-'); - } - s - } - }, - args: vec![Argument::BranchDest(BranchDest( - ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) - as i32) - << 2u8) as _, - ))], - ins: self, - }; - } - if ((self.code >> 21u8) & 0x1f) & 0b11110 == 4 - && ((self.code >> 16u8) & 0x1f) & 0b11 == 2 - { - return SimplifiedIns { - mnemonic: "bne", - suffix: { - { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('l'); - } - if self.bit(30usize) { - s.push('a'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 - && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) - .wrapping_sub(0x2000)) - as i32) - << 2u8) - >= 0 - { - s.push('+'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 - && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) - .wrapping_sub(0x2000)) - as i32) - << 2u8) - < 0 - { - s.push('-'); - } - s - } - }, - args: vec![ - Argument::CRField(CRField(((self.code >> 18u8) & 0x7) as _)), - Argument::BranchDest(BranchDest( - ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) - as i32) - << 2u8) as _, - )), - ], - ins: self, - }; - } - if ((self.code >> 21u8) & 0x1f) & 0b11110 == 12 && ((self.code >> 16u8) & 0x1f) == 3 - { - return SimplifiedIns { - mnemonic: "bso", - suffix: { - { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('l'); - } - if self.bit(30usize) { - s.push('a'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 - && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) - .wrapping_sub(0x2000)) - as i32) - << 2u8) - >= 0 - { - s.push('+'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 - && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) - .wrapping_sub(0x2000)) - as i32) - << 2u8) - < 0 - { - s.push('-'); - } - s - } - }, - args: vec![Argument::BranchDest(BranchDest( - ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) - as i32) - << 2u8) as _, - ))], - ins: self, - }; - } - if ((self.code >> 21u8) & 0x1f) & 0b11110 == 12 - && ((self.code >> 16u8) & 0x1f) & 0b11 == 3 - { - return SimplifiedIns { - mnemonic: "bso", - suffix: { - { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('l'); - } - if self.bit(30usize) { - s.push('a'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 - && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) - .wrapping_sub(0x2000)) - as i32) - << 2u8) - >= 0 - { - s.push('+'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 - && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) - .wrapping_sub(0x2000)) - as i32) - << 2u8) - < 0 - { - s.push('-'); - } - s - } - }, - args: vec![ - Argument::CRField(CRField(((self.code >> 18u8) & 0x7) as _)), - Argument::BranchDest(BranchDest( - ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) - as i32) - << 2u8) as _, - )), - ], - ins: self, - }; - } - if ((self.code >> 21u8) & 0x1f) & 0b11110 == 4 && ((self.code >> 16u8) & 0x1f) == 3 - { - return SimplifiedIns { - mnemonic: "bns", - suffix: { - { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('l'); - } - if self.bit(30usize) { - s.push('a'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 - && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) - .wrapping_sub(0x2000)) - as i32) - << 2u8) - >= 0 - { - s.push('+'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 - && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) - .wrapping_sub(0x2000)) - as i32) - << 2u8) - < 0 - { - s.push('-'); - } - s - } - }, - args: vec![Argument::BranchDest(BranchDest( - ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) - as i32) - << 2u8) as _, - ))], - ins: self, - }; - } - if ((self.code >> 21u8) & 0x1f) & 0b11110 == 4 - && ((self.code >> 16u8) & 0x1f) & 0b11 == 3 - { - return SimplifiedIns { - mnemonic: "bns", - suffix: { - { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('l'); - } - if self.bit(30usize) { - s.push('a'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 - && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) - .wrapping_sub(0x2000)) - as i32) - << 2u8) - >= 0 - { - s.push('+'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 - && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) - .wrapping_sub(0x2000)) - as i32) - << 2u8) - < 0 - { - s.push('-'); - } - s - } - }, - args: vec![ - Argument::CRField(CRField(((self.code >> 18u8) & 0x7) as _)), - Argument::BranchDest(BranchDest( - ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) - as i32) - << 2u8) as _, - )), - ], - ins: self, - }; - } - if ((self.code >> 21u8) & 0x1f) & 0b11110 == 16 && ((self.code >> 16u8) & 0x1f) == 0 - { - return SimplifiedIns { - mnemonic: "bdnz", - suffix: { - { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('l'); - } - if self.bit(30usize) { - s.push('a'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 - && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) - .wrapping_sub(0x2000)) - as i32) - << 2u8) - >= 0 - { - s.push('+'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 - && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) - .wrapping_sub(0x2000)) - as i32) - << 2u8) - < 0 - { - s.push('-'); - } - s - } - }, - args: vec![Argument::BranchDest(BranchDest( - ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) - as i32) - << 2u8) as _, - ))], - ins: self, - }; - } - if ((self.code >> 21u8) & 0x1f) & 0b11110 == 8 { - return SimplifiedIns { - mnemonic: "bdnzt", - suffix: { - { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('l'); - } - if self.bit(30usize) { - s.push('a'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 - && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) - .wrapping_sub(0x2000)) - as i32) - << 2u8) - >= 0 - { - s.push('+'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 - && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) - .wrapping_sub(0x2000)) - as i32) - << 2u8) - < 0 - { - s.push('-'); - } - s - } - }, - args: vec![ - Argument::CRBit(CRBit(((self.code >> 16u8) & 0x1f) as _)), - Argument::BranchDest(BranchDest( - ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) - as i32) - << 2u8) as _, - )), - ], - ins: self, - }; - } - if ((self.code >> 21u8) & 0x1f) & 0b11110 == 0 { - return SimplifiedIns { - mnemonic: "bdnzf", - suffix: { - { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('l'); - } - if self.bit(30usize) { - s.push('a'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 - && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) - .wrapping_sub(0x2000)) - as i32) - << 2u8) - >= 0 - { - s.push('+'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 - && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) - .wrapping_sub(0x2000)) - as i32) - << 2u8) - < 0 - { - s.push('-'); - } - s - } - }, - args: vec![ - Argument::CRBit(CRBit(((self.code >> 16u8) & 0x1f) as _)), - Argument::BranchDest(BranchDest( - ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) - as i32) - << 2u8) as _, - )), - ], - ins: self, - }; - } - if ((self.code >> 21u8) & 0x1f) & 0b11110 == 18 && ((self.code >> 16u8) & 0x1f) == 0 - { - return SimplifiedIns { - mnemonic: "bdz", - suffix: { - { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('l'); - } - if self.bit(30usize) { - s.push('a'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 - && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) - .wrapping_sub(0x2000)) - as i32) - << 2u8) - >= 0 - { - s.push('+'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 - && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) - .wrapping_sub(0x2000)) - as i32) - << 2u8) - < 0 - { - s.push('-'); - } - s - } - }, - args: vec![Argument::BranchDest(BranchDest( - ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) - as i32) - << 2u8) as _, - ))], - ins: self, - }; - } - if ((self.code >> 21u8) & 0x1f) & 0b11110 == 10 { - return SimplifiedIns { - mnemonic: "bdzt", - suffix: { - { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('l'); - } - if self.bit(30usize) { - s.push('a'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 - && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) - .wrapping_sub(0x2000)) - as i32) - << 2u8) - >= 0 - { - s.push('+'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 - && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) - .wrapping_sub(0x2000)) - as i32) - << 2u8) - < 0 - { - s.push('-'); - } - s - } - }, - args: vec![ - Argument::CRBit(CRBit(((self.code >> 16u8) & 0x1f) as _)), - Argument::BranchDest(BranchDest( - ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) - as i32) - << 2u8) as _, - )), - ], - ins: self, - }; - } - if ((self.code >> 21u8) & 0x1f) & 0b11110 == 2 { - return SimplifiedIns { - mnemonic: "bdzf", - suffix: { - { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('l'); - } - if self.bit(30usize) { - s.push('a'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 - && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) - .wrapping_sub(0x2000)) - as i32) - << 2u8) - >= 0 - { - s.push('+'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 - && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) - .wrapping_sub(0x2000)) - as i32) - << 2u8) - < 0 - { - s.push('-'); - } - s - } - }, - args: vec![ - Argument::CRBit(CRBit(((self.code >> 16u8) & 0x1f) as _)), - Argument::BranchDest(BranchDest( - ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) - as i32) - << 2u8) as _, - )), - ], - ins: self, - }; - } - } - Opcode::Bcctr => { - if ((self.code >> 21u8) & 0x1f) == 20 && ((self.code >> 16u8) & 0x1f) == 0 { - return SimplifiedIns { - mnemonic: "bctr", - suffix: { - { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('l'); - } - s - } - }, - args: vec![], - ins: self, - }; - } - if ((self.code >> 21u8) & 0x1f) & 0b11110 == 12 && ((self.code >> 16u8) & 0x1f) == 0 - { - return SimplifiedIns { - mnemonic: "bltctr", - suffix: { - { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('l'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 { - s.push('+'); - } - s - } - }, - args: vec![], - ins: self, - }; - } - if ((self.code >> 21u8) & 0x1f) & 0b11110 == 12 - && ((self.code >> 16u8) & 0x1f) & 0b11 == 0 - { - return SimplifiedIns { - mnemonic: "bltctr", - suffix: { - { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('l'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 { - s.push('+'); - } - s - } - }, - args: vec![Argument::CRField(CRField(((self.code >> 18u8) & 0x7) as _))], - ins: self, - }; - } - if ((self.code >> 21u8) & 0x1f) & 0b11110 == 4 && ((self.code >> 16u8) & 0x1f) == 1 - { - return SimplifiedIns { - mnemonic: "blectr", - suffix: { - { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('l'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 { - s.push('+'); - } - s - } - }, - args: vec![], - ins: self, - }; - } - if ((self.code >> 21u8) & 0x1f) & 0b11110 == 4 - && ((self.code >> 16u8) & 0x1f) & 0b11 == 1 - { - return SimplifiedIns { - mnemonic: "blectr", - suffix: { - { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('l'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 { - s.push('+'); - } - s - } - }, - args: vec![Argument::CRField(CRField(((self.code >> 18u8) & 0x7) as _))], - ins: self, - }; - } - if ((self.code >> 21u8) & 0x1f) & 0b11110 == 12 && ((self.code >> 16u8) & 0x1f) == 2 - { - return SimplifiedIns { - mnemonic: "beqctr", - suffix: { - { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('l'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 { - s.push('+'); - } - s - } - }, - args: vec![], - ins: self, - }; - } - if ((self.code >> 21u8) & 0x1f) & 0b11110 == 12 - && ((self.code >> 16u8) & 0x1f) & 0b11 == 2 - { - return SimplifiedIns { - mnemonic: "beqctr", - suffix: { - { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('l'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 { - s.push('+'); - } - s - } - }, - args: vec![Argument::CRField(CRField(((self.code >> 18u8) & 0x7) as _))], - ins: self, - }; - } - if ((self.code >> 21u8) & 0x1f) & 0b11110 == 4 && ((self.code >> 16u8) & 0x1f) == 0 - { - return SimplifiedIns { - mnemonic: "bgectr", - suffix: { - { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('l'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 { - s.push('+'); - } - s - } - }, - args: vec![], - ins: self, - }; - } - if ((self.code >> 21u8) & 0x1f) & 0b11110 == 4 - && ((self.code >> 16u8) & 0x1f) & 0b11 == 0 - { - return SimplifiedIns { - mnemonic: "bgectr", - suffix: { - { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('l'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 { - s.push('+'); - } - s - } - }, - args: vec![Argument::CRField(CRField(((self.code >> 18u8) & 0x7) as _))], - ins: self, - }; - } - if ((self.code >> 21u8) & 0x1f) & 0b11110 == 12 && ((self.code >> 16u8) & 0x1f) == 1 - { - return SimplifiedIns { - mnemonic: "bgtctr", - suffix: { - { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('l'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 { - s.push('+'); - } - s - } - }, - args: vec![], - ins: self, - }; - } - if ((self.code >> 21u8) & 0x1f) & 0b11110 == 12 - && ((self.code >> 16u8) & 0x1f) & 0b11 == 1 - { - return SimplifiedIns { - mnemonic: "bgtctr", - suffix: { - { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('l'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 { - s.push('+'); - } - s - } - }, - args: vec![Argument::CRField(CRField(((self.code >> 18u8) & 0x7) as _))], - ins: self, - }; - } - if ((self.code >> 21u8) & 0x1f) & 0b11110 == 4 && ((self.code >> 16u8) & 0x1f) == 2 - { - return SimplifiedIns { - mnemonic: "bnectr", - suffix: { - { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('l'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 { - s.push('+'); - } - s - } - }, - args: vec![], - ins: self, - }; - } - if ((self.code >> 21u8) & 0x1f) & 0b11110 == 4 - && ((self.code >> 16u8) & 0x1f) & 0b11 == 2 - { - return SimplifiedIns { - mnemonic: "bnectr", - suffix: { - { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('l'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 { - s.push('+'); - } - s - } - }, - args: vec![Argument::CRField(CRField(((self.code >> 18u8) & 0x7) as _))], - ins: self, - }; - } - if ((self.code >> 21u8) & 0x1f) & 0b11110 == 12 && ((self.code >> 16u8) & 0x1f) == 3 - { - return SimplifiedIns { - mnemonic: "bsoctr", - suffix: { - { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('l'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 { - s.push('+'); - } - s - } - }, - args: vec![], - ins: self, - }; - } - if ((self.code >> 21u8) & 0x1f) & 0b11110 == 12 - && ((self.code >> 16u8) & 0x1f) & 0b11 == 3 - { - return SimplifiedIns { - mnemonic: "bsoctr", - suffix: { - { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('l'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 { - s.push('+'); - } - s - } - }, - args: vec![Argument::CRField(CRField(((self.code >> 18u8) & 0x7) as _))], - ins: self, - }; - } - if ((self.code >> 21u8) & 0x1f) & 0b11110 == 4 && ((self.code >> 16u8) & 0x1f) == 3 - { - return SimplifiedIns { - mnemonic: "bnsctr", - suffix: { - { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('l'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 { - s.push('+'); - } - s - } - }, - args: vec![], - ins: self, - }; - } - if ((self.code >> 21u8) & 0x1f) & 0b11110 == 4 - && ((self.code >> 16u8) & 0x1f) & 0b11 == 3 - { - return SimplifiedIns { - mnemonic: "bnsctr", - suffix: { - { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('l'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 { - s.push('+'); - } - s - } - }, - args: vec![Argument::CRField(CRField(((self.code >> 18u8) & 0x7) as _))], - ins: self, - }; - } - } - Opcode::Bclr => { - if ((self.code >> 21u8) & 0x1f) == 20 && ((self.code >> 16u8) & 0x1f) == 0 { - return SimplifiedIns { - mnemonic: "blr", - suffix: { - { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('l'); - } - s - } - }, - args: vec![], - ins: self, - }; - } - if ((self.code >> 21u8) & 0x1f) & 0b11110 == 12 && ((self.code >> 16u8) & 0x1f) == 0 - { - return SimplifiedIns { - mnemonic: "bltlr", - suffix: { - { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('l'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 { - s.push('+'); - } - s - } - }, - args: vec![], - ins: self, - }; - } - if ((self.code >> 21u8) & 0x1f) & 0b11110 == 12 - && ((self.code >> 16u8) & 0x1f) & 0b11 == 0 - { - return SimplifiedIns { - mnemonic: "bltlr", - suffix: { - { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('l'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 { - s.push('+'); - } - s - } - }, - args: vec![Argument::CRField(CRField(((self.code >> 18u8) & 0x7) as _))], - ins: self, - }; - } - if ((self.code >> 21u8) & 0x1f) & 0b11110 == 4 && ((self.code >> 16u8) & 0x1f) == 1 - { - return SimplifiedIns { - mnemonic: "blelr", - suffix: { - { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('l'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 { - s.push('+'); - } - s - } - }, - args: vec![], - ins: self, - }; - } - if ((self.code >> 21u8) & 0x1f) & 0b11110 == 4 - && ((self.code >> 16u8) & 0x1f) & 0b11 == 1 - { - return SimplifiedIns { - mnemonic: "blelr", - suffix: { - { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('l'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 { - s.push('+'); - } - s - } - }, - args: vec![Argument::CRField(CRField(((self.code >> 18u8) & 0x7) as _))], - ins: self, - }; - } - if ((self.code >> 21u8) & 0x1f) & 0b11110 == 12 && ((self.code >> 16u8) & 0x1f) == 2 - { - return SimplifiedIns { - mnemonic: "beqlr", - suffix: { - { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('l'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 { - s.push('+'); - } - s - } - }, - args: vec![], - ins: self, - }; - } - if ((self.code >> 21u8) & 0x1f) & 0b11110 == 12 - && ((self.code >> 16u8) & 0x1f) & 0b11 == 2 - { - return SimplifiedIns { - mnemonic: "beqlr", - suffix: { - { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('l'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 { - s.push('+'); - } - s - } - }, - args: vec![Argument::CRField(CRField(((self.code >> 18u8) & 0x7) as _))], - ins: self, - }; - } - if ((self.code >> 21u8) & 0x1f) & 0b11110 == 4 && ((self.code >> 16u8) & 0x1f) == 0 - { - return SimplifiedIns { - mnemonic: "bgelr", - suffix: { - { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('l'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 { - s.push('+'); - } - s - } - }, - args: vec![], - ins: self, - }; - } - if ((self.code >> 21u8) & 0x1f) & 0b11110 == 4 - && ((self.code >> 16u8) & 0x1f) & 0b11 == 0 - { - return SimplifiedIns { - mnemonic: "bgelr", - suffix: { - { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('l'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 { - s.push('+'); - } - s - } - }, - args: vec![Argument::CRField(CRField(((self.code >> 18u8) & 0x7) as _))], - ins: self, - }; - } - if ((self.code >> 21u8) & 0x1f) & 0b11110 == 12 && ((self.code >> 16u8) & 0x1f) == 1 - { - return SimplifiedIns { - mnemonic: "bgtlr", - suffix: { - { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('l'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 { - s.push('+'); - } - s - } - }, - args: vec![], - ins: self, - }; - } - if ((self.code >> 21u8) & 0x1f) & 0b11110 == 12 - && ((self.code >> 16u8) & 0x1f) & 0b11 == 1 - { - return SimplifiedIns { - mnemonic: "bgtlr", - suffix: { - { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('l'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 { - s.push('+'); - } - s - } - }, - args: vec![Argument::CRField(CRField(((self.code >> 18u8) & 0x7) as _))], - ins: self, - }; - } - if ((self.code >> 21u8) & 0x1f) & 0b11110 == 4 && ((self.code >> 16u8) & 0x1f) == 2 - { - return SimplifiedIns { - mnemonic: "bnelr", - suffix: { - { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('l'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 { - s.push('+'); - } - s - } - }, - args: vec![], - ins: self, - }; - } - if ((self.code >> 21u8) & 0x1f) & 0b11110 == 4 - && ((self.code >> 16u8) & 0x1f) & 0b11 == 2 - { - return SimplifiedIns { - mnemonic: "bnelr", - suffix: { - { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('l'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 { - s.push('+'); - } - s - } - }, - args: vec![Argument::CRField(CRField(((self.code >> 18u8) & 0x7) as _))], - ins: self, - }; - } - if ((self.code >> 21u8) & 0x1f) & 0b11110 == 12 && ((self.code >> 16u8) & 0x1f) == 3 - { - return SimplifiedIns { - mnemonic: "bsolr", - suffix: { - { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('l'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 { - s.push('+'); - } - s - } - }, - args: vec![], - ins: self, - }; - } - if ((self.code >> 21u8) & 0x1f) & 0b11110 == 12 - && ((self.code >> 16u8) & 0x1f) & 0b11 == 3 - { - return SimplifiedIns { - mnemonic: "bsolr", - suffix: { - { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('l'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 { - s.push('+'); - } - s - } - }, - args: vec![Argument::CRField(CRField(((self.code >> 18u8) & 0x7) as _))], - ins: self, - }; - } - if ((self.code >> 21u8) & 0x1f) & 0b11110 == 4 && ((self.code >> 16u8) & 0x1f) == 3 - { - return SimplifiedIns { - mnemonic: "bnslr", - suffix: { - { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('l'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 { - s.push('+'); - } - s - } - }, - args: vec![], - ins: self, - }; - } - if ((self.code >> 21u8) & 0x1f) & 0b11110 == 4 - && ((self.code >> 16u8) & 0x1f) & 0b11 == 3 - { - return SimplifiedIns { - mnemonic: "bnslr", - suffix: { - { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('l'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 { - s.push('+'); - } - s - } - }, - args: vec![Argument::CRField(CRField(((self.code >> 18u8) & 0x7) as _))], - ins: self, - }; - } - if ((self.code >> 21u8) & 0x1f) & 0b11110 == 16 && ((self.code >> 16u8) & 0x1f) == 0 - { - return SimplifiedIns { - mnemonic: "bdnzlr", - suffix: { - { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('l'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 { - s.push('+'); - } - s - } - }, - args: vec![], - ins: self, - }; - } - if ((self.code >> 21u8) & 0x1f) & 0b11110 == 8 { - return SimplifiedIns { - mnemonic: "bdnztlr", - suffix: { - { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('l'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 { - s.push('+'); - } - s - } - }, - args: vec![Argument::CRBit(CRBit(((self.code >> 16u8) & 0x1f) as _))], - ins: self, - }; - } - if ((self.code >> 21u8) & 0x1f) & 0b11110 == 0 { - return SimplifiedIns { - mnemonic: "bdnzflr", - suffix: { - { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('l'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 { - s.push('+'); - } - s - } - }, - args: vec![Argument::CRBit(CRBit(((self.code >> 16u8) & 0x1f) as _))], - ins: self, - }; - } - if ((self.code >> 21u8) & 0x1f) & 0b11110 == 18 && ((self.code >> 16u8) & 0x1f) == 0 - { - return SimplifiedIns { - mnemonic: "bdzlr", - suffix: { - { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('l'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 { - s.push('+'); - } - s - } - }, - args: vec![], - ins: self, - }; - } - if ((self.code >> 21u8) & 0x1f) & 0b11110 == 10 { - return SimplifiedIns { - mnemonic: "bdztlr", - suffix: { - { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('l'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 { - s.push('+'); - } - s - } - }, - args: vec![Argument::CRBit(CRBit(((self.code >> 16u8) & 0x1f) as _))], - ins: self, - }; - } - if ((self.code >> 21u8) & 0x1f) & 0b11110 == 0 { - return SimplifiedIns { - mnemonic: "bdzflr", - suffix: { - { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('l'); - } - if ((self.code >> 21u8) & 0x1f) & 1 == 1 { - s.push('+'); - } - s - } - }, - args: vec![Argument::CRBit(CRBit(((self.code >> 16u8) & 0x1f) as _))], - ins: self, - }; - } - } - Opcode::Cmp => { - if ((self.code >> 23u8) & 0x7) == 0 && ((self.code >> 21u8) & 0x1) == 0 { - return SimplifiedIns { - mnemonic: "cmpw", - suffix: String::new(), - args: vec![ - Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), - Argument::GPR(GPR(((self.code >> 11u8) & 0x1f) as _)), - ], - ins: self, - }; - } - if ((self.code >> 21u8) & 0x1) == 0 { - return SimplifiedIns { - mnemonic: "cmpw", - suffix: String::new(), - args: vec![ - Argument::CRField(CRField(((self.code >> 23u8) & 0x7) as _)), - Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), - Argument::GPR(GPR(((self.code >> 11u8) & 0x1f) as _)), - ], - ins: self, - }; - } - if ((self.code >> 23u8) & 0x7) == 0 && ((self.code >> 21u8) & 0x1) == 1 { - return SimplifiedIns { - mnemonic: "cmpd", - suffix: String::new(), - args: vec![ - Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), - Argument::GPR(GPR(((self.code >> 11u8) & 0x1f) as _)), - ], - ins: self, - }; - } - if ((self.code >> 21u8) & 0x1) == 1 { - return SimplifiedIns { - mnemonic: "cmpd", - suffix: String::new(), - args: vec![ - Argument::CRField(CRField(((self.code >> 23u8) & 0x7) as _)), - Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), - Argument::GPR(GPR(((self.code >> 11u8) & 0x1f) as _)), - ], - ins: self, - }; - } - } - Opcode::Cmpi => { - if ((self.code >> 23u8) & 0x7) == 0 && ((self.code >> 21u8) & 0x1) == 0 { - return SimplifiedIns { - mnemonic: "cmpwi", - suffix: String::new(), - args: vec![ - Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), - Argument::Simm(Simm( - ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) - as _, - )), - ], - ins: self, - }; - } - if ((self.code >> 21u8) & 0x1) == 0 { - return SimplifiedIns { - mnemonic: "cmpwi", - suffix: String::new(), - args: vec![ - Argument::CRField(CRField(((self.code >> 23u8) & 0x7) as _)), - Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), - Argument::Simm(Simm( - ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) - as _, - )), - ], - ins: self, - }; - } - if ((self.code >> 23u8) & 0x7) == 0 && ((self.code >> 21u8) & 0x1) == 1 { - return SimplifiedIns { - mnemonic: "cmpdi", - suffix: String::new(), - args: vec![ - Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), - Argument::Simm(Simm( - ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) - as _, - )), - ], - ins: self, - }; - } - if ((self.code >> 21u8) & 0x1) == 1 { - return SimplifiedIns { - mnemonic: "cmpdi", - suffix: String::new(), - args: vec![ - Argument::CRField(CRField(((self.code >> 23u8) & 0x7) as _)), - Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), - Argument::Simm(Simm( - ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) - as _, - )), - ], - ins: self, - }; - } - } - Opcode::Cmpl => { - if ((self.code >> 23u8) & 0x7) == 0 && ((self.code >> 21u8) & 0x1) == 0 { - return SimplifiedIns { - mnemonic: "cmplw", - suffix: String::new(), - args: vec![ - Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), - Argument::GPR(GPR(((self.code >> 11u8) & 0x1f) as _)), - ], - ins: self, - }; - } - if ((self.code >> 21u8) & 0x1) == 0 { - return SimplifiedIns { - mnemonic: "cmplw", - suffix: String::new(), - args: vec![ - Argument::CRField(CRField(((self.code >> 23u8) & 0x7) as _)), - Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), - Argument::GPR(GPR(((self.code >> 11u8) & 0x1f) as _)), - ], - ins: self, - }; - } - if ((self.code >> 23u8) & 0x7) == 0 && ((self.code >> 21u8) & 0x1) == 1 { - return SimplifiedIns { - mnemonic: "cmpld", - suffix: String::new(), - args: vec![ - Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), - Argument::GPR(GPR(((self.code >> 11u8) & 0x1f) as _)), - ], - ins: self, - }; - } - if ((self.code >> 21u8) & 0x1) == 1 { - return SimplifiedIns { - mnemonic: "cmpld", - suffix: String::new(), - args: vec![ - Argument::CRField(CRField(((self.code >> 23u8) & 0x7) as _)), - Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), - Argument::GPR(GPR(((self.code >> 11u8) & 0x1f) as _)), - ], - ins: self, - }; - } - } - Opcode::Cmpli => { - if ((self.code >> 23u8) & 0x7) == 0 && ((self.code >> 21u8) & 0x1) == 0 { - return SimplifiedIns { - mnemonic: "cmplwi", - suffix: String::new(), - args: vec![ - Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), - Argument::Uimm(Uimm((self.code & 0xffff) as _)), - ], - ins: self, - }; - } - if ((self.code >> 21u8) & 0x1) == 0 { - return SimplifiedIns { - mnemonic: "cmplwi", - suffix: String::new(), - args: vec![ - Argument::CRField(CRField(((self.code >> 23u8) & 0x7) as _)), - Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), - Argument::Uimm(Uimm((self.code & 0xffff) as _)), - ], - ins: self, - }; - } - if ((self.code >> 23u8) & 0x7) == 0 && ((self.code >> 21u8) & 0x1) == 1 { - return SimplifiedIns { - mnemonic: "cmpldi", - suffix: String::new(), - args: vec![ - Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), - Argument::Uimm(Uimm((self.code & 0xffff) as _)), - ], - ins: self, - }; - } - if ((self.code >> 21u8) & 0x1) == 1 { - return SimplifiedIns { - mnemonic: "cmpldi", - suffix: String::new(), - args: vec![ - Argument::CRField(CRField(((self.code >> 23u8) & 0x7) as _)), - Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), - Argument::Uimm(Uimm((self.code & 0xffff) as _)), - ], - ins: self, - }; - } - } - Opcode::Creqv => { - if ((self.code >> 16u8) & 0x1f) == ((self.code >> 21u8) & 0x1f) - && ((self.code >> 11u8) & 0x1f) == ((self.code >> 21u8) & 0x1f) - { - return SimplifiedIns { - mnemonic: "crset", - suffix: String::new(), - args: vec![Argument::CRBit(CRBit(((self.code >> 21u8) & 0x1f) as _))], - ins: self, - }; - } - } - Opcode::Crnor => { - if ((self.code >> 11u8) & 0x1f) == ((self.code >> 16u8) & 0x1f) { - return SimplifiedIns { - mnemonic: "crnot", - suffix: String::new(), - args: vec![ - Argument::CRBit(CRBit(((self.code >> 21u8) & 0x1f) as _)), - Argument::CRBit(CRBit(((self.code >> 16u8) & 0x1f) as _)), - ], - ins: self, - }; - } - } - Opcode::Cror => { - if ((self.code >> 11u8) & 0x1f) == ((self.code >> 16u8) & 0x1f) { - return SimplifiedIns { - mnemonic: "crmove", - suffix: String::new(), - args: vec![ - Argument::CRBit(CRBit(((self.code >> 21u8) & 0x1f) as _)), - Argument::CRBit(CRBit(((self.code >> 16u8) & 0x1f) as _)), - ], - ins: self, - }; - } - } - Opcode::Crxor => { - if ((self.code >> 16u8) & 0x1f) == ((self.code >> 21u8) & 0x1f) - && ((self.code >> 11u8) & 0x1f) == ((self.code >> 21u8) & 0x1f) - { - return SimplifiedIns { - mnemonic: "crclr", - suffix: String::new(), - args: vec![Argument::CRBit(CRBit(((self.code >> 21u8) & 0x1f) as _))], - ins: self, - }; - } - } - Opcode::Mfspr => { - if (((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32) - | ((((self.code >> 11u8) & 0x3ff) & 0b00000_11111u32) << 5u32)) - as u32 - == 1 - { - return SimplifiedIns { - mnemonic: "mfxer", - suffix: String::new(), - args: vec![Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _))], - ins: self, - }; - } - if (((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32) - | ((((self.code >> 11u8) & 0x3ff) & 0b00000_11111u32) << 5u32)) - as u32 - == 8 - { - return SimplifiedIns { - mnemonic: "mflr", - suffix: String::new(), - args: vec![Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _))], - ins: self, - }; - } - if (((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32) - | ((((self.code >> 11u8) & 0x3ff) & 0b00000_11111u32) << 5u32)) - as u32 - == 9 - { - return SimplifiedIns { - mnemonic: "mfctr", - suffix: String::new(), - args: vec![Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _))], - ins: self, - }; - } - if (((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32) - | ((((self.code >> 11u8) & 0x3ff) & 0b00000_11111u32) << 5u32)) - as u32 - == 18 - { - return SimplifiedIns { - mnemonic: "mfdsisr", - suffix: String::new(), - args: vec![Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _))], - ins: self, - }; - } - if (((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32) - | ((((self.code >> 11u8) & 0x3ff) & 0b00000_11111u32) << 5u32)) - as u32 - == 19 - { - return SimplifiedIns { - mnemonic: "mfdar", - suffix: String::new(), - args: vec![Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _))], - ins: self, - }; - } - if (((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32) - | ((((self.code >> 11u8) & 0x3ff) & 0b00000_11111u32) << 5u32)) - as u32 - == 22 - { - return SimplifiedIns { - mnemonic: "mfdec", - suffix: String::new(), - args: vec![Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _))], - ins: self, - }; - } - if (((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32) - | ((((self.code >> 11u8) & 0x3ff) & 0b00000_11111u32) << 5u32)) - as u32 - == 25 - { - return SimplifiedIns { - mnemonic: "mfsdr1", - suffix: String::new(), - args: vec![Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _))], - ins: self, - }; - } - if (((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32) - | ((((self.code >> 11u8) & 0x3ff) & 0b00000_11111u32) << 5u32)) - as u32 - == 26 - { - return SimplifiedIns { - mnemonic: "mfsrr0", - suffix: String::new(), - args: vec![Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _))], - ins: self, - }; - } - if (((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32) - | ((((self.code >> 11u8) & 0x3ff) & 0b00000_11111u32) << 5u32)) - as u32 - == 27 - { - return SimplifiedIns { - mnemonic: "mfsrr1", - suffix: String::new(), - args: vec![Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _))], - ins: self, - }; - } - if (((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32) - | ((((self.code >> 11u8) & 0x3ff) & 0b00000_11111u32) << 5u32)) - as u32 - & 0b1111111100 - == 272 - { - return SimplifiedIns { - mnemonic: "mfsprg", - suffix: String::new(), - args: vec![ - Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _)), - Argument::OpaqueU(OpaqueU(((self.code >> 16u8) & 0x3) as _)), - ], - ins: self, - }; - } - if (((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32) - | ((((self.code >> 11u8) & 0x3ff) & 0b00000_11111u32) << 5u32)) - as u32 - == 282 - { - return SimplifiedIns { - mnemonic: "mfear", - suffix: String::new(), - args: vec![Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _))], - ins: self, - }; - } - if (((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32) - | ((((self.code >> 11u8) & 0x3ff) & 0b00000_11111u32) << 5u32)) - as u32 - & 0b1111111001 - == 528 - { - return SimplifiedIns { - mnemonic: "mfibatu", - suffix: String::new(), - args: vec![ - Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _)), - Argument::OpaqueU(OpaqueU(((self.code >> 17u8) & 0x3) as _)), - ], - ins: self, - }; - } - if (((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32) - | ((((self.code >> 11u8) & 0x3ff) & 0b00000_11111u32) << 5u32)) - as u32 - & 0b1111111001 - == 529 - { - return SimplifiedIns { - mnemonic: "mfibatl", - suffix: String::new(), - args: vec![ - Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _)), - Argument::OpaqueU(OpaqueU(((self.code >> 17u8) & 0x3) as _)), - ], - ins: self, - }; - } - if (((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32) - | ((((self.code >> 11u8) & 0x3ff) & 0b00000_11111u32) << 5u32)) - as u32 - & 0b1111111001 - == 536 - { - return SimplifiedIns { - mnemonic: "mfdbatu", - suffix: String::new(), - args: vec![ - Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _)), - Argument::OpaqueU(OpaqueU(((self.code >> 17u8) & 0x3) as _)), - ], - ins: self, - }; - } - if (((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32) - | ((((self.code >> 11u8) & 0x3ff) & 0b00000_11111u32) << 5u32)) - as u32 - & 0b1111111001 - == 537 - { - return SimplifiedIns { - mnemonic: "mfdbatl", - suffix: String::new(), - args: vec![ - Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _)), - Argument::OpaqueU(OpaqueU(((self.code >> 17u8) & 0x3) as _)), - ], - ins: self, - }; - } - } - Opcode::Mtspr => { - if (((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32) - | ((((self.code >> 11u8) & 0x3ff) & 0b00000_11111u32) << 5u32)) - as u32 - == 1 - { - return SimplifiedIns { - mnemonic: "mtxer", - suffix: String::new(), - args: vec![Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _))], - ins: self, - }; - } - if (((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32) - | ((((self.code >> 11u8) & 0x3ff) & 0b00000_11111u32) << 5u32)) - as u32 - == 8 - { - return SimplifiedIns { - mnemonic: "mtlr", - suffix: String::new(), - args: vec![Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _))], - ins: self, - }; - } - if (((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32) - | ((((self.code >> 11u8) & 0x3ff) & 0b00000_11111u32) << 5u32)) - as u32 - == 9 - { - return SimplifiedIns { - mnemonic: "mtctr", - suffix: String::new(), - args: vec![Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _))], - ins: self, - }; - } - if (((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32) - | ((((self.code >> 11u8) & 0x3ff) & 0b00000_11111u32) << 5u32)) - as u32 - == 18 - { - return SimplifiedIns { - mnemonic: "mtdsisr", - suffix: String::new(), - args: vec![Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _))], - ins: self, - }; - } - if (((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32) - | ((((self.code >> 11u8) & 0x3ff) & 0b00000_11111u32) << 5u32)) - as u32 - == 19 - { - return SimplifiedIns { - mnemonic: "mtdar", - suffix: String::new(), - args: vec![Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _))], - ins: self, - }; - } - if (((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32) - | ((((self.code >> 11u8) & 0x3ff) & 0b00000_11111u32) << 5u32)) - as u32 - == 22 - { - return SimplifiedIns { - mnemonic: "mtdec", - suffix: String::new(), - args: vec![Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _))], - ins: self, - }; - } - if (((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32) - | ((((self.code >> 11u8) & 0x3ff) & 0b00000_11111u32) << 5u32)) - as u32 - == 25 - { - return SimplifiedIns { - mnemonic: "mtsdr1", - suffix: String::new(), - args: vec![Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _))], - ins: self, - }; - } - if (((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32) - | ((((self.code >> 11u8) & 0x3ff) & 0b00000_11111u32) << 5u32)) - as u32 - == 26 - { - return SimplifiedIns { - mnemonic: "mtsrr0", - suffix: String::new(), - args: vec![Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _))], - ins: self, - }; - } - if (((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32) - | ((((self.code >> 11u8) & 0x3ff) & 0b00000_11111u32) << 5u32)) - as u32 - == 27 - { - return SimplifiedIns { - mnemonic: "mtsrr1", - suffix: String::new(), - args: vec![Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _))], - ins: self, - }; - } - if (((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32) - | ((((self.code >> 11u8) & 0x3ff) & 0b00000_11111u32) << 5u32)) - as u32 - & 0b1111111100 - == 272 - { - return SimplifiedIns { - mnemonic: "mtsprg", - suffix: String::new(), - args: vec![ - Argument::OpaqueU(OpaqueU(((self.code >> 16u8) & 0x3) as _)), - Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _)), - ], - ins: self, - }; - } - if (((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32) - | ((((self.code >> 11u8) & 0x3ff) & 0b00000_11111u32) << 5u32)) - as u32 - == 282 - { - return SimplifiedIns { - mnemonic: "mtear", - suffix: String::new(), - args: vec![Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _))], - ins: self, - }; - } - if (((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32) - | ((((self.code >> 11u8) & 0x3ff) & 0b00000_11111u32) << 5u32)) - as u32 - == 284 - { - return SimplifiedIns { - mnemonic: "mttbl", - suffix: String::new(), - args: vec![Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _))], - ins: self, - }; - } - if (((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32) - | ((((self.code >> 11u8) & 0x3ff) & 0b00000_11111u32) << 5u32)) - as u32 - == 285 - { - return SimplifiedIns { - mnemonic: "mttbu", - suffix: String::new(), - args: vec![Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _))], - ins: self, - }; - } - if (((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32) - | ((((self.code >> 11u8) & 0x3ff) & 0b00000_11111u32) << 5u32)) - as u32 - & 0b1111111001 - == 528 - { - return SimplifiedIns { - mnemonic: "mtibatu", - suffix: String::new(), - args: vec![ - Argument::OpaqueU(OpaqueU(((self.code >> 17u8) & 0x3) as _)), - Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _)), - ], - ins: self, - }; - } - if (((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32) - | ((((self.code >> 11u8) & 0x3ff) & 0b00000_11111u32) << 5u32)) - as u32 - & 0b1111111001 - == 529 - { - return SimplifiedIns { - mnemonic: "mtibatl", - suffix: String::new(), - args: vec![ - Argument::OpaqueU(OpaqueU(((self.code >> 17u8) & 0x3) as _)), - Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _)), - ], - ins: self, - }; - } - if (((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32) - | ((((self.code >> 11u8) & 0x3ff) & 0b00000_11111u32) << 5u32)) - as u32 - & 0b1111111001 - == 536 - { - return SimplifiedIns { - mnemonic: "mtdbatu", - suffix: String::new(), - args: vec![ - Argument::OpaqueU(OpaqueU(((self.code >> 17u8) & 0x3) as _)), - Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _)), - ], - ins: self, - }; - } - if (((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32) - | ((((self.code >> 11u8) & 0x3ff) & 0b00000_11111u32) << 5u32)) - as u32 - & 0b1111111001 - == 537 - { - return SimplifiedIns { - mnemonic: "mtdbatl", - suffix: String::new(), - args: vec![ - Argument::OpaqueU(OpaqueU(((self.code >> 17u8) & 0x3) as _)), - Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _)), - ], - ins: self, - }; - } - } - Opcode::Or => { - if ((self.code >> 11u8) & 0x1f) == ((self.code >> 21u8) & 0x1f) { - return SimplifiedIns { - mnemonic: "mr", - suffix: { - { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - }, - args: vec![ - Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), - Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _)), - ], - ins: self, - }; - } - } - Opcode::Ori => { - if ((self.code >> 16u8) & 0x1f) == 0 - && ((self.code >> 21u8) & 0x1f) == 0 - && (self.code & 0xffff) == 0 - { - return SimplifiedIns { - mnemonic: "nop", - suffix: String::new(), - args: vec![], - ins: self, - }; - } - } - Opcode::Rlwinm => { - if ((self.code >> 11u8) & 0x1f) == 0 - && ((self.code >> 6u8) & 0x1f) == 0 - && ((self.code >> 1u8) & 0x1f) < 32 - { - return SimplifiedIns { - mnemonic: "clrrwi", - suffix: { - { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - }, - args: vec![ - Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), - Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _)), - Argument::OpaqueU(OpaqueU((31 - ((self.code >> 1u8) & 0x1f)) as _)), - ], - ins: self, - }; - } - if ((self.code >> 11u8) & 0x1f) == 0 && ((self.code >> 1u8) & 0x1f) == 31 { - return SimplifiedIns { - mnemonic: "clrlwi", - suffix: { - { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - }, - args: vec![ - Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), - Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _)), - Argument::OpaqueU(OpaqueU(((self.code >> 6u8) & 0x1f) as _)), - ], - ins: self, - }; - } - if ((self.code >> 6u8) & 0x1f) == 0 - && ((self.code >> 1u8) & 0x1f) == 31 - && ((self.code >> 11u8) & 0x1f) <= 16 - { - return SimplifiedIns { - mnemonic: "rotlwi", - suffix: { - { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - }, - args: vec![ - Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), - Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _)), - Argument::OpaqueU(OpaqueU(((self.code >> 11u8) & 0x1f) as _)), - ], - ins: self, - }; - } - if ((self.code >> 6u8) & 0x1f) == 0 - && ((self.code >> 1u8) & 0x1f) == 31 - && ((self.code >> 11u8) & 0x1f) > 16 - { - return SimplifiedIns { - mnemonic: "rotrwi", - suffix: { - { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - }, - args: vec![ - Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), - Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _)), - Argument::OpaqueU(OpaqueU((32 - ((self.code >> 11u8) & 0x1f)) as _)), - ], - ins: self, - }; - } - if ((self.code >> 6u8) & 0x1f) == 0 - && ((self.code >> 1u8) & 0x1f) == 31 - ((self.code >> 11u8) & 0x1f) - { - return SimplifiedIns { - mnemonic: "slwi", - suffix: { - { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - }, - args: vec![ - Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), - Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _)), - Argument::OpaqueU(OpaqueU(((self.code >> 11u8) & 0x1f) as _)), - ], - ins: self, - }; - } - if ((self.code >> 1u8) & 0x1f) == 31 - && ((self.code >> 11u8) & 0x1f) == 32 - ((self.code >> 6u8) & 0x1f) - { - return SimplifiedIns { - mnemonic: "srwi", - suffix: { - { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - }, - args: vec![ - Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), - Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _)), - Argument::OpaqueU(OpaqueU(((self.code >> 6u8) & 0x1f) as _)), - ], - ins: self, - }; - } - if ((self.code >> 11u8) & 0x1f) < 32 - && ((self.code >> 1u8) & 0x1f) == 31 - ((self.code >> 11u8) & 0x1f) - { - return SimplifiedIns { - mnemonic: "clrlslwi", - suffix: { - { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - }, - args: vec![ - Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), - Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _)), - Argument::OpaqueU(OpaqueU( - (((self.code >> 6u8) & 0x1f) + ((self.code >> 11u8) & 0x1f)) as _, - )), - Argument::OpaqueU(OpaqueU(((self.code >> 11u8) & 0x1f) as _)), - ], - ins: self, - }; - } - if ((self.code >> 6u8) & 0x1f) == 0 { - return SimplifiedIns { - mnemonic: "extlwi", - suffix: { - { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - }, - args: vec![ - Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), - Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _)), - Argument::OpaqueU(OpaqueU((((self.code >> 1u8) & 0x1f) + 1) as _)), - Argument::OpaqueU(OpaqueU(((self.code >> 11u8) & 0x1f) as _)), - ], - ins: self, - }; - } - if ((self.code >> 1u8) & 0x1f) == 31 - && ((self.code >> 11u8) & 0x1f) >= 32 - ((self.code >> 6u8) & 0x1f) - { - return SimplifiedIns { - mnemonic: "extrwi", - suffix: { - { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - }, - args: vec![ - Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), - Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _)), - Argument::OpaqueU(OpaqueU((32 - ((self.code >> 6u8) & 0x1f)) as _)), - Argument::OpaqueU(OpaqueU( - (((self.code >> 11u8) & 0x1f) - (32 - ((self.code >> 6u8) & 0x1f))) - as _, - )), - ], - ins: self, - }; - } - } - Opcode::Rlwnm => { - if ((self.code >> 6u8) & 0x1f) == 0 && ((self.code >> 1u8) & 0x1f) == 31 { - return SimplifiedIns { - mnemonic: "rotlw", - suffix: { - { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - }, - args: vec![ - Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), - Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _)), - Argument::GPR(GPR(((self.code >> 11u8) & 0x1f) as _)), - ], - ins: self, - }; - } - } - Opcode::Tw => { - if ((self.code >> 21u8) & 0x1f) == 4 { - return SimplifiedIns { - mnemonic: "tweq", - suffix: String::new(), - args: vec![ - Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), - Argument::GPR(GPR(((self.code >> 11u8) & 0x1f) as _)), - ], - ins: self, - }; - } - if ((self.code >> 21u8) & 0x1f) == 5 { - return SimplifiedIns { - mnemonic: "twlge", - suffix: String::new(), - args: vec![ - Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), - Argument::GPR(GPR(((self.code >> 11u8) & 0x1f) as _)), - ], - ins: self, - }; - } - if ((self.code >> 21u8) & 0x1f) == 31 - && ((self.code >> 16u8) & 0x1f) == 0 - && ((self.code >> 11u8) & 0x1f) == 0 - { - return SimplifiedIns { - mnemonic: "trap", - suffix: String::new(), - args: vec![], - ins: self, - }; - } - } - Opcode::Twi => { - if ((self.code >> 21u8) & 0x1f) == 8 { - return SimplifiedIns { - mnemonic: "twgti", - suffix: String::new(), - args: vec![ - Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), - Argument::Simm(Simm( - ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) - as _, - )), - ], - ins: self, - }; - } - if ((self.code >> 21u8) & 0x1f) == 6 { - return SimplifiedIns { - mnemonic: "twllei", - suffix: String::new(), - args: vec![ - Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), - Argument::Simm(Simm( - ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) - as _, - )), - ], - ins: self, - }; - } - if ((self.code >> 21u8) & 0x1f) == 31 { - return SimplifiedIns { - mnemonic: "twui", - suffix: String::new(), - args: vec![ - Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), - Argument::Simm(Simm( - ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) - as _, - )), - ], - ins: self, - }; - } - } - _ => {} - } - SimplifiedIns::basic_form(self) + /// BO: Branch Options + #[inline(always)] + pub const fn field_bo(&self) -> u8 { + ((self.code >> 21) & 0x1f) as u8 + } + /// BI: Branch Condition Register Bit + #[inline(always)] + pub const fn field_bi(&self) -> u8 { + ((self.code >> 16) & 0x1f) as u8 + } + /// BD: Branch Destination (14-bit) + #[inline(always)] + pub const fn field_bd(&self) -> i16 { + ((self.code & 0xfffc) ^ 0x8000).wrapping_sub(0x8000) as i16 + } + /// LI: Branch Destination (24-bit) + #[inline(always)] + pub const fn field_li(&self) -> i32 { + ((self.code & 0x3fffffc) ^ 0x2000000).wrapping_sub(0x2000000) as i32 + } + /// SH: Shift Amount + #[inline(always)] + pub const fn field_sh(&self) -> u8 { + ((self.code >> 11) & 0x1f) as u8 + } + /// MB: Mask Begin + #[inline(always)] + pub const fn field_mb(&self) -> u8 { + ((self.code >> 6) & 0x1f) as u8 + } + /// ME: Mask End + #[inline(always)] + pub const fn field_me(&self) -> u8 { + ((self.code >> 1) & 0x1f) as u8 + } + /// rS: Source Register + #[inline(always)] + pub const fn field_rs(&self) -> u8 { + ((self.code >> 21) & 0x1f) as u8 + } + /// rD: Destination Register + #[inline(always)] + pub const fn field_rd(&self) -> u8 { + ((self.code >> 21) & 0x1f) as u8 + } + /// rA: Register A + #[inline(always)] + pub const fn field_ra(&self) -> u8 { + ((self.code >> 16) & 0x1f) as u8 + } + /// rB: Register B + #[inline(always)] + pub const fn field_rb(&self) -> u8 { + ((self.code >> 11) & 0x1f) as u8 + } + /// sr: Segment Register + #[inline(always)] + pub const fn field_sr(&self) -> u8 { + ((self.code >> 16) & 0xf) as u8 + } + /// spr: Special Purpose Register + #[inline(always)] + pub const fn field_spr(&self) -> u16 { + let value = ((self.code >> 11) & 0x3ff) as u16; + ((value & 0b11111_00000) >> 5) | ((value & 0b00000_11111) << 5) + } + /// frS: Source Floating-Point Register + #[inline(always)] + pub const fn field_frs(&self) -> u8 { + ((self.code >> 21) & 0x1f) as u8 + } + /// frD: Destination Floating-Point Register + #[inline(always)] + pub const fn field_frd(&self) -> u8 { + ((self.code >> 21) & 0x1f) as u8 + } + /// frA: Floating-Point Register A + #[inline(always)] + pub const fn field_fra(&self) -> u8 { + ((self.code >> 16) & 0x1f) as u8 + } + /// frB: Floating-Point Register B + #[inline(always)] + pub const fn field_frb(&self) -> u8 { + ((self.code >> 11) & 0x1f) as u8 + } + /// frC: Floating-Point Register C + #[inline(always)] + pub const fn field_frc(&self) -> u8 { + ((self.code >> 6) & 0x1f) as u8 + } + /// crbD: Condition Register Bit Destination + #[inline(always)] + pub const fn field_crbd(&self) -> u8 { + ((self.code >> 21) & 0x1f) as u8 + } + /// crbA: Condition Register Bit A + #[inline(always)] + pub const fn field_crba(&self) -> u8 { + ((self.code >> 16) & 0x1f) as u8 + } + /// crbB: Condition Register Bit B + #[inline(always)] + pub const fn field_crbb(&self) -> u8 { + ((self.code >> 11) & 0x1f) as u8 + } + /// crfD: Condition Register Field Destination + #[inline(always)] + pub const fn field_crfd(&self) -> u8 { + ((self.code >> 23) & 0x7) as u8 + } + /// crfS: Condition Register Field Source + #[inline(always)] + pub const fn field_crfs(&self) -> u8 { + ((self.code >> 18) & 0x7) as u8 + } + /// crm: Condition Register Mask + #[inline(always)] + pub const fn field_crm(&self) -> u8 { + ((self.code >> 12) & 0xff) as u8 + } + /// ps_I + #[inline(always)] + pub const fn field_ps_i(&self) -> u8 { + ((self.code >> 12) & 0x7) as u8 + } + /// ps_IX + #[inline(always)] + pub const fn field_ps_ix(&self) -> u8 { + ((self.code >> 7) & 0x7) as u8 + } + /// ps_W + #[inline(always)] + pub const fn field_ps_w(&self) -> u8 { + ((self.code >> 15) & 0x1) as u8 + } + /// ps_WX + #[inline(always)] + pub const fn field_ps_wx(&self) -> u8 { + ((self.code >> 10) & 0x1) as u8 + } + /// NB + #[inline(always)] + pub const fn field_nb(&self) -> u8 { + ((self.code >> 11) & 0x1f) as u8 + } + /// tbr: Time Base + #[inline(always)] + pub const fn field_tbr(&self) -> u16 { + let value = ((self.code >> 11) & 0x3ff) as u16; + ((value & 0b11111_00000) >> 5) | ((value & 0b00000_11111) << 5) + } + /// mtfsf_FM: Field Mask for mtfsf + #[inline(always)] + pub const fn field_mtfsf_fm(&self) -> u8 { + ((self.code >> 17) & 0xff) as u8 + } + /// mtfsf_IMM: Immediate for mtfsfi + #[inline(always)] + pub const fn field_mtfsf_imm(&self) -> u8 { + ((self.code >> 12) & 0xf) as u8 + } + /// spr_SPRG: SPRG index for m[tf]sprg + #[inline(always)] + pub const fn field_spr_sprg(&self) -> u8 { + ((self.code >> 16) & 0x3) as u8 + } + /// spr_BAT: IBAT/DBAT index for m[tf][id]bat[ul] + #[inline(always)] + pub const fn field_spr_bat(&self) -> u8 { + ((self.code >> 17) & 0x3) as u8 + } + /// TO: Bitset for tw and twi + #[inline(always)] + pub const fn field_to(&self) -> u8 { + ((self.code >> 21) & 0x1f) as u8 + } + /// L: Bitset for cmp, cmpi, cmpl, cmpli + #[inline(always)] + pub const fn field_l(&self) -> u8 { + ((self.code >> 21) & 0x1) as u8 + } + /// OE: Field used by XO-form instructions to enable setting OV and SO in the XER. + #[inline(always)] + pub const fn field_oe(&self) -> bool { + (self.code & 0x400) == 0x400 + } + /// Rc: Record Bit + #[inline(always)] + pub const fn field_rc(&self) -> bool { + (self.code & 0x1) == 0x1 + } + /// LK: Link Bit + #[inline(always)] + pub const fn field_lk(&self) -> bool { + (self.code & 0x1) == 0x1 + } + /// AA: Absolute Address Bit + #[inline(always)] + pub const fn field_aa(&self) -> bool { + (self.code & 0x2) == 0x2 + } + /// BP: Predict branch to be taken + #[inline(always)] + pub const fn field_bp(&self) -> bool { + (self.code & 0x200000) == 0x200000 && self.field_bd() >= 0x0 + } + /// BNP: Predict branch not to be taken (fall through) + #[inline(always)] + pub const fn field_bnp(&self) -> bool { + (self.code & 0x200000) == 0x200000 && self.field_bd() < 0x0 + } + /// BP_ND: Predict branch to be taken (implicit dest for LR/CTR) + #[inline(always)] + pub const fn field_bp_nd(&self) -> bool { + (self.code & 0x200000) == 0x200000 } } -#[allow(clippy::all, non_snake_case)] -impl Ins { - #[inline(always)] - pub fn field_simm(&self) -> isize { - ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _ - } - #[inline(always)] - pub fn field_uimm(&self) -> usize { - (self.code & 0xffff) as _ - } - #[inline(always)] - pub fn field_offset(&self) -> isize { - ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _ - } - #[inline(always)] - pub fn field_ps_offset(&self) -> isize { - ((((self.code & 0xfff) ^ 0x800).wrapping_sub(0x800)) as i32) as _ - } - #[inline(always)] - pub fn field_BO(&self) -> usize { - ((self.code >> 21u8) & 0x1f) as _ - } - #[inline(always)] - pub fn field_BI(&self) -> usize { - ((self.code >> 16u8) & 0x1f) as _ - } - #[inline(always)] - pub fn field_BD(&self) -> isize { - ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) as i32) << 2u8) as _ - } - #[inline(always)] - pub fn field_LI(&self) -> isize { - ((((((self.code >> 2u8) & 0xffffff) ^ 0x800000).wrapping_sub(0x800000)) as i32) << 2u8) as _ - } - #[inline(always)] - pub fn field_SH(&self) -> usize { - ((self.code >> 11u8) & 0x1f) as _ - } - #[inline(always)] - pub fn field_MB(&self) -> usize { - ((self.code >> 6u8) & 0x1f) as _ - } - #[inline(always)] - pub fn field_ME(&self) -> usize { - ((self.code >> 1u8) & 0x1f) as _ - } - #[inline(always)] - pub fn field_rS(&self) -> usize { - ((self.code >> 21u8) & 0x1f) as _ - } - #[inline(always)] - pub fn field_rD(&self) -> usize { - ((self.code >> 21u8) & 0x1f) as _ - } - #[inline(always)] - pub fn field_rA(&self) -> usize { - ((self.code >> 16u8) & 0x1f) as _ - } - #[inline(always)] - pub fn field_rB(&self) -> usize { - ((self.code >> 11u8) & 0x1f) as _ - } - #[inline(always)] - pub fn field_sr(&self) -> usize { - ((self.code >> 16u8) & 0xf) as _ - } - #[inline(always)] - pub fn field_spr(&self) -> usize { - (((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32) - | ((((self.code >> 11u8) & 0x3ff) & 0b00000_11111u32) << 5u32)) as u32 as _ - } - #[inline(always)] - pub fn field_frS(&self) -> usize { - ((self.code >> 21u8) & 0x1f) as _ - } - #[inline(always)] - pub fn field_frD(&self) -> usize { - ((self.code >> 21u8) & 0x1f) as _ - } - #[inline(always)] - pub fn field_frA(&self) -> usize { - ((self.code >> 16u8) & 0x1f) as _ - } - #[inline(always)] - pub fn field_frB(&self) -> usize { - ((self.code >> 11u8) & 0x1f) as _ - } - #[inline(always)] - pub fn field_frC(&self) -> usize { - ((self.code >> 6u8) & 0x1f) as _ - } - #[inline(always)] - pub fn field_crbD(&self) -> usize { - ((self.code >> 21u8) & 0x1f) as _ - } - #[inline(always)] - pub fn field_crbA(&self) -> usize { - ((self.code >> 16u8) & 0x1f) as _ - } - #[inline(always)] - pub fn field_crbB(&self) -> usize { - ((self.code >> 11u8) & 0x1f) as _ - } - #[inline(always)] - pub fn field_crfD(&self) -> usize { - ((self.code >> 23u8) & 0x7) as _ - } - #[inline(always)] - pub fn field_crfS(&self) -> usize { - ((self.code >> 18u8) & 0x7) as _ - } - #[inline(always)] - pub fn field_crm(&self) -> usize { - ((self.code >> 12u8) & 0xff) as _ - } - #[inline(always)] - pub fn field_ps_I(&self) -> usize { - ((self.code >> 12u8) & 0x7) as _ - } - #[inline(always)] - pub fn field_ps_IX(&self) -> usize { - ((self.code >> 7u8) & 0x7) as _ - } - #[inline(always)] - pub fn field_ps_W(&self) -> usize { - ((self.code >> 15u8) & 0x1) as _ - } - #[inline(always)] - pub fn field_ps_WX(&self) -> usize { - ((self.code >> 10u8) & 0x1) as _ - } - #[inline(always)] - pub fn field_NB(&self) -> usize { - ((self.code >> 11u8) & 0x1f) as _ - } - #[inline(always)] - pub fn field_tbr(&self) -> usize { - (((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32) - | ((((self.code >> 11u8) & 0x3ff) & 0b00000_11111u32) << 5u32)) as u32 as _ - } - #[inline(always)] - pub fn field_mtfsf_FM(&self) -> usize { - ((self.code >> 17u8) & 0xff) as _ - } - #[inline(always)] - pub fn field_mtfsf_IMM(&self) -> usize { - ((self.code >> 12u8) & 0xf) as _ - } - #[inline(always)] - pub fn field_spr_SPRG(&self) -> usize { - ((self.code >> 16u8) & 0x3) as _ - } - #[inline(always)] - pub fn field_spr_BAT(&self) -> usize { - ((self.code >> 17u8) & 0x3) as _ - } - #[inline(always)] - pub fn field_TO(&self) -> usize { - ((self.code >> 21u8) & 0x1f) as _ - } - #[inline(always)] - pub fn field_L(&self) -> usize { - ((self.code >> 21u8) & 0x1) as _ - } - #[inline(always)] - pub fn field_OE(&self) -> bool { - self.bit(21usize) - } - #[inline(always)] - pub fn field_Rc(&self) -> bool { - self.bit(31usize) - } - #[inline(always)] - pub fn field_LK(&self) -> bool { - self.bit(31usize) - } - #[inline(always)] - pub fn field_AA(&self) -> bool { - self.bit(30usize) - } - #[inline(always)] - pub fn field_BP(&self) -> bool { - ((self.code >> 21u8) & 0x1f) & 1 == 1 - && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) as i32) << 2u8) - >= 0 - } - #[inline(always)] - pub fn field_BNP(&self) -> bool { - ((self.code >> 21u8) & 0x1f) & 1 == 1 - && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) as i32) << 2u8) < 0 - } - #[inline(always)] - pub fn field_BP_ND(&self) -> bool { - ((self.code >> 21u8) & 0x1f) & 1 == 1 - } +pub type Arguments = [Argument; 5]; +pub type MnemonicFunction = fn(&Ins) -> (&'static str, Arguments); +#[inline(always)] +const fn base_twi(ins: &Ins) -> (&'static str, Arguments) { + ( + "twi", + [ + Argument::OpaqueU(OpaqueU(ins.field_to() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::Simm(Simm(ins.field_simm() as _)), + Argument::None, + Argument::None, + ], + ) } +const fn simplified_twi(ins: &Ins) -> (&'static str, Arguments) { + if ins.field_to() == 0x8 { + return ( + "twgti", + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::Simm(Simm(ins.field_simm() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if ins.field_to() == 0x6 { + return ( + "twllei", + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::Simm(Simm(ins.field_simm() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if ins.field_to() == 0x1f { + return ( + "twui", + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::Simm(Simm(ins.field_simm() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + base_twi(ins) +} +const fn base_dcbz_l(ins: &Ins) -> (&'static str, Arguments) { + ( + "dcbz_l", + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ) +} +const fn base_psq_lux(ins: &Ins) -> (&'static str, Arguments) { + ( + "psq_lux", + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::OpaqueU(OpaqueU(ins.field_ps_wx() as _)), + Argument::GQR(GQR(ins.field_ps_ix() as _)), + ], + ) +} +const fn base_psq_lx(ins: &Ins) -> (&'static str, Arguments) { + ( + "psq_lx", + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::OpaqueU(OpaqueU(ins.field_ps_wx() as _)), + Argument::GQR(GQR(ins.field_ps_ix() as _)), + ], + ) +} +const fn base_psq_stux(ins: &Ins) -> (&'static str, Arguments) { + ( + "psq_stux", + [ + Argument::FPR(FPR(ins.field_frs() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::OpaqueU(OpaqueU(ins.field_ps_wx() as _)), + Argument::GQR(GQR(ins.field_ps_ix() as _)), + ], + ) +} +const fn base_psq_stx(ins: &Ins) -> (&'static str, Arguments) { + ( + "psq_stx", + [ + Argument::FPR(FPR(ins.field_frs() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::OpaqueU(OpaqueU(ins.field_ps_wx() as _)), + Argument::GQR(GQR(ins.field_ps_ix() as _)), + ], + ) +} +const fn base_ps_abs(ins: &Ins) -> (&'static str, Arguments) { + ( + ["ps_abs", "ps_abs."][ins.field_rc() as usize], + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ) +} +const fn base_ps_add(ins: &Ins) -> (&'static str, Arguments) { + ( + ["ps_add", "ps_add."][ins.field_rc() as usize], + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::FPR(FPR(ins.field_fra() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_ps_cmpo0(ins: &Ins) -> (&'static str, Arguments) { + ( + "ps_cmpo0", + [ + Argument::CRField(CRField(ins.field_crfd() as _)), + Argument::FPR(FPR(ins.field_fra() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_ps_cmpo1(ins: &Ins) -> (&'static str, Arguments) { + ( + "ps_cmpo1", + [ + Argument::CRField(CRField(ins.field_crfd() as _)), + Argument::FPR(FPR(ins.field_fra() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_ps_cmpu0(ins: &Ins) -> (&'static str, Arguments) { + ( + "ps_cmpu0", + [ + Argument::CRField(CRField(ins.field_crfd() as _)), + Argument::FPR(FPR(ins.field_fra() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_ps_cmpu1(ins: &Ins) -> (&'static str, Arguments) { + ( + "ps_cmpu1", + [ + Argument::CRField(CRField(ins.field_crfd() as _)), + Argument::FPR(FPR(ins.field_fra() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_ps_div(ins: &Ins) -> (&'static str, Arguments) { + ( + ["ps_div", "ps_div."][ins.field_rc() as usize], + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::FPR(FPR(ins.field_fra() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_ps_madd(ins: &Ins) -> (&'static str, Arguments) { + ( + ["ps_madd", "ps_madd."][ins.field_rc() as usize], + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::FPR(FPR(ins.field_fra() as _)), + Argument::FPR(FPR(ins.field_frc() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + ], + ) +} +const fn base_ps_madds0(ins: &Ins) -> (&'static str, Arguments) { + ( + ["ps_madds0", "ps_madds0."][ins.field_rc() as usize], + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::FPR(FPR(ins.field_fra() as _)), + Argument::FPR(FPR(ins.field_frc() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + ], + ) +} +const fn base_ps_madds1(ins: &Ins) -> (&'static str, Arguments) { + ( + ["ps_madds1", "ps_madds1."][ins.field_rc() as usize], + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::FPR(FPR(ins.field_fra() as _)), + Argument::FPR(FPR(ins.field_frc() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + ], + ) +} +const fn base_ps_merge00(ins: &Ins) -> (&'static str, Arguments) { + ( + ["ps_merge00", "ps_merge00."][ins.field_rc() as usize], + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::FPR(FPR(ins.field_fra() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_ps_merge01(ins: &Ins) -> (&'static str, Arguments) { + ( + ["ps_merge01", "ps_merge01."][ins.field_rc() as usize], + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::FPR(FPR(ins.field_fra() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_ps_merge10(ins: &Ins) -> (&'static str, Arguments) { + ( + ["ps_merge10", "ps_merge10."][ins.field_rc() as usize], + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::FPR(FPR(ins.field_fra() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_ps_merge11(ins: &Ins) -> (&'static str, Arguments) { + ( + ["ps_merge11", "ps_merge11."][ins.field_rc() as usize], + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::FPR(FPR(ins.field_fra() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_ps_mr(ins: &Ins) -> (&'static str, Arguments) { + ( + ["ps_mr", "ps_mr."][ins.field_rc() as usize], + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ) +} +const fn base_ps_msub(ins: &Ins) -> (&'static str, Arguments) { + ( + ["ps_msub", "ps_msub."][ins.field_rc() as usize], + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::FPR(FPR(ins.field_fra() as _)), + Argument::FPR(FPR(ins.field_frc() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + ], + ) +} +const fn base_ps_mul(ins: &Ins) -> (&'static str, Arguments) { + ( + ["ps_mul", "ps_mul."][ins.field_rc() as usize], + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::FPR(FPR(ins.field_fra() as _)), + Argument::FPR(FPR(ins.field_frc() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_ps_muls0(ins: &Ins) -> (&'static str, Arguments) { + ( + ["ps_muls0", "ps_muls0."][ins.field_rc() as usize], + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::FPR(FPR(ins.field_fra() as _)), + Argument::FPR(FPR(ins.field_frc() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_ps_muls1(ins: &Ins) -> (&'static str, Arguments) { + ( + ["ps_muls1", "ps_muls1."][ins.field_rc() as usize], + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::FPR(FPR(ins.field_fra() as _)), + Argument::FPR(FPR(ins.field_frc() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_ps_nabs(ins: &Ins) -> (&'static str, Arguments) { + ( + ["ps_nabs", "ps_nabs."][ins.field_rc() as usize], + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ) +} +const fn base_ps_neg(ins: &Ins) -> (&'static str, Arguments) { + ( + ["ps_neg", "ps_neg."][ins.field_rc() as usize], + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ) +} +const fn base_ps_nmadd(ins: &Ins) -> (&'static str, Arguments) { + ( + ["ps_nmadd", "ps_nmadd."][ins.field_rc() as usize], + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::FPR(FPR(ins.field_fra() as _)), + Argument::FPR(FPR(ins.field_frc() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + ], + ) +} +const fn base_ps_nmsub(ins: &Ins) -> (&'static str, Arguments) { + ( + ["ps_nmsub", "ps_nmsub."][ins.field_rc() as usize], + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::FPR(FPR(ins.field_fra() as _)), + Argument::FPR(FPR(ins.field_frc() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + ], + ) +} +const fn base_ps_res(ins: &Ins) -> (&'static str, Arguments) { + ( + ["ps_res", "ps_res."][ins.field_rc() as usize], + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ) +} +const fn base_ps_rsqrte(ins: &Ins) -> (&'static str, Arguments) { + ( + ["ps_rsqrte", "ps_rsqrte."][ins.field_rc() as usize], + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ) +} +const fn base_ps_sel(ins: &Ins) -> (&'static str, Arguments) { + ( + ["ps_sel", "ps_sel."][ins.field_rc() as usize], + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::FPR(FPR(ins.field_fra() as _)), + Argument::FPR(FPR(ins.field_frc() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + ], + ) +} +const fn base_ps_sub(ins: &Ins) -> (&'static str, Arguments) { + ( + ["ps_sub", "ps_sub."][ins.field_rc() as usize], + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::FPR(FPR(ins.field_fra() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_ps_sum0(ins: &Ins) -> (&'static str, Arguments) { + ( + ["ps_sum0", "ps_sum0."][ins.field_rc() as usize], + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::FPR(FPR(ins.field_fra() as _)), + Argument::FPR(FPR(ins.field_frc() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + ], + ) +} +const fn base_ps_sum1(ins: &Ins) -> (&'static str, Arguments) { + ( + ["ps_sum1", "ps_sum1."][ins.field_rc() as usize], + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::FPR(FPR(ins.field_fra() as _)), + Argument::FPR(FPR(ins.field_frc() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + ], + ) +} +const fn base_mulli(ins: &Ins) -> (&'static str, Arguments) { + ( + "mulli", + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::Simm(Simm(ins.field_simm() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_subfic(ins: &Ins) -> (&'static str, Arguments) { + ( + "subfic", + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::Simm(Simm(ins.field_simm() as _)), + Argument::None, + Argument::None, + ], + ) +} +#[inline(always)] +const fn base_cmpli(ins: &Ins) -> (&'static str, Arguments) { + ( + "cmpli", + [ + Argument::CRField(CRField(ins.field_crfd() as _)), + Argument::OpaqueU(OpaqueU(ins.field_l() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::Uimm(Uimm(ins.field_uimm() as _)), + Argument::None, + ], + ) +} +const fn simplified_cmpli(ins: &Ins) -> (&'static str, Arguments) { + if ins.field_crfd() == 0x0 && ins.field_l() == 0x0 { + return ( + "cmplwi", + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::Uimm(Uimm(ins.field_uimm() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if ins.field_l() == 0x0 { + return ( + "cmplwi", + [ + Argument::CRField(CRField(ins.field_crfd() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::Uimm(Uimm(ins.field_uimm() as _)), + Argument::None, + Argument::None, + ], + ); + } + if ins.field_crfd() == 0x0 && ins.field_l() == 0x1 { + return ( + "cmpldi", + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::Uimm(Uimm(ins.field_uimm() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if ins.field_l() == 0x1 { + return ( + "cmpldi", + [ + Argument::CRField(CRField(ins.field_crfd() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::Uimm(Uimm(ins.field_uimm() as _)), + Argument::None, + Argument::None, + ], + ); + } + base_cmpli(ins) +} +#[inline(always)] +const fn base_cmpi(ins: &Ins) -> (&'static str, Arguments) { + ( + "cmpi", + [ + Argument::CRField(CRField(ins.field_crfd() as _)), + Argument::OpaqueU(OpaqueU(ins.field_l() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::Simm(Simm(ins.field_simm() as _)), + Argument::None, + ], + ) +} +const fn simplified_cmpi(ins: &Ins) -> (&'static str, Arguments) { + if ins.field_crfd() == 0x0 && ins.field_l() == 0x0 { + return ( + "cmpwi", + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::Simm(Simm(ins.field_simm() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if ins.field_l() == 0x0 { + return ( + "cmpwi", + [ + Argument::CRField(CRField(ins.field_crfd() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::Simm(Simm(ins.field_simm() as _)), + Argument::None, + Argument::None, + ], + ); + } + if ins.field_crfd() == 0x0 && ins.field_l() == 0x1 { + return ( + "cmpdi", + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::Simm(Simm(ins.field_simm() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if ins.field_l() == 0x1 { + return ( + "cmpdi", + [ + Argument::CRField(CRField(ins.field_crfd() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::Simm(Simm(ins.field_simm() as _)), + Argument::None, + Argument::None, + ], + ); + } + base_cmpi(ins) +} +#[inline(always)] +const fn base_addic(ins: &Ins) -> (&'static str, Arguments) { + ( + "addic", + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::Simm(Simm(ins.field_simm() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn simplified_addic(ins: &Ins) -> (&'static str, Arguments) { + if ins.field_simm() < 0x0 && ins.field_simm() != -0x8000 { + return ( + "subic", + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::Simm(Simm((-ins.field_simm()) as _)), + Argument::None, + Argument::None, + ], + ); + } + base_addic(ins) +} +#[inline(always)] +const fn base_addic_(ins: &Ins) -> (&'static str, Arguments) { + ( + "addic.", + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::Simm(Simm(ins.field_simm() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn simplified_addic_(ins: &Ins) -> (&'static str, Arguments) { + if ins.field_simm() < 0x0 && ins.field_simm() != -0x8000 { + return ( + "subic.", + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::Simm(Simm((-ins.field_simm()) as _)), + Argument::None, + Argument::None, + ], + ); + } + base_addic_(ins) +} +#[inline(always)] +const fn base_addi(ins: &Ins) -> (&'static str, Arguments) { + ( + "addi", + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::Simm(Simm(ins.field_simm() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn simplified_addi(ins: &Ins) -> (&'static str, Arguments) { + if ins.field_ra() == 0x0 { + return ( + "li", + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::Simm(Simm(ins.field_simm() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if ins.field_simm() < 0x0 && ins.field_simm() != -0x8000 { + return ( + "subi", + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::Simm(Simm((-ins.field_simm()) as _)), + Argument::None, + Argument::None, + ], + ); + } + base_addi(ins) +} +#[inline(always)] +const fn base_addis(ins: &Ins) -> (&'static str, Arguments) { + ( + "addis", + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::Uimm(Uimm(ins.field_uimm() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn simplified_addis(ins: &Ins) -> (&'static str, Arguments) { + if ins.field_ra() == 0x0 { + return ( + "lis", + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::Uimm(Uimm(ins.field_uimm() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if ins.field_simm() < 0x0 && ins.field_simm() != -0x8000 { + return ( + "subis", + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::Simm(Simm((-ins.field_simm()) as _)), + Argument::None, + Argument::None, + ], + ); + } + base_addis(ins) +} +#[inline(always)] +const fn base_bc(ins: &Ins) -> (&'static str, Arguments) { + ( + [ + "bc", + "bcl", + "bca", + "bcla", + "bc+", + "bcl+", + "bca+", + "bcla+", + "bc-", + "bcl-", + "bca-", + "bcla-", + "", + "", + "", + "", + ][ins.field_lk() as usize | (ins.field_aa() as usize) << 1 + | (ins.field_bp() as usize) << 2 | (ins.field_bnp() as usize) << 3], + [ + Argument::OpaqueU(OpaqueU(ins.field_bo() as _)), + Argument::CRBit(CRBit(ins.field_bi() as _)), + Argument::BranchDest(BranchDest(ins.field_bd() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn simplified_bc(ins: &Ins) -> (&'static str, Arguments) { + if (ins.field_bo() & 0x1e) == 0xc && ins.field_bi() == 0x0 { + return ( + [ + "blt", + "bltl", + "blta", + "bltla", + "blt+", + "bltl+", + "blta+", + "bltla+", + "blt-", + "bltl-", + "blta-", + "bltla-", + "", + "", + "", + "", + ][ins.field_lk() as usize | (ins.field_aa() as usize) << 1 + | (ins.field_bp() as usize) << 2 | (ins.field_bnp() as usize) << 3], + [ + Argument::BranchDest(BranchDest(ins.field_bd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if (ins.field_bo() & 0x1e) == 0xc && (ins.field_bi() & 0x3) == 0x0 { + return ( + [ + "blt", + "bltl", + "blta", + "bltla", + "blt+", + "bltl+", + "blta+", + "bltla+", + "blt-", + "bltl-", + "blta-", + "bltla-", + "", + "", + "", + "", + ][ins.field_lk() as usize | (ins.field_aa() as usize) << 1 + | (ins.field_bp() as usize) << 2 | (ins.field_bnp() as usize) << 3], + [ + Argument::CRField(CRField(ins.field_crfs() as _)), + Argument::BranchDest(BranchDest(ins.field_bd() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if (ins.field_bo() & 0x1e) == 0x4 && ins.field_bi() == 0x1 { + return ( + [ + "ble", + "blel", + "blea", + "blela", + "ble+", + "blel+", + "blea+", + "blela+", + "ble-", + "blel-", + "blea-", + "blela-", + "", + "", + "", + "", + ][ins.field_lk() as usize | (ins.field_aa() as usize) << 1 + | (ins.field_bp() as usize) << 2 | (ins.field_bnp() as usize) << 3], + [ + Argument::BranchDest(BranchDest(ins.field_bd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if (ins.field_bo() & 0x1e) == 0x4 && (ins.field_bi() & 0x3) == 0x1 { + return ( + [ + "ble", + "blel", + "blea", + "blela", + "ble+", + "blel+", + "blea+", + "blela+", + "ble-", + "blel-", + "blea-", + "blela-", + "", + "", + "", + "", + ][ins.field_lk() as usize | (ins.field_aa() as usize) << 1 + | (ins.field_bp() as usize) << 2 | (ins.field_bnp() as usize) << 3], + [ + Argument::CRField(CRField(ins.field_crfs() as _)), + Argument::BranchDest(BranchDest(ins.field_bd() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if (ins.field_bo() & 0x1e) == 0xc && ins.field_bi() == 0x2 { + return ( + [ + "beq", + "beql", + "beqa", + "beqla", + "beq+", + "beql+", + "beqa+", + "beqla+", + "beq-", + "beql-", + "beqa-", + "beqla-", + "", + "", + "", + "", + ][ins.field_lk() as usize | (ins.field_aa() as usize) << 1 + | (ins.field_bp() as usize) << 2 | (ins.field_bnp() as usize) << 3], + [ + Argument::BranchDest(BranchDest(ins.field_bd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if (ins.field_bo() & 0x1e) == 0xc && (ins.field_bi() & 0x3) == 0x2 { + return ( + [ + "beq", + "beql", + "beqa", + "beqla", + "beq+", + "beql+", + "beqa+", + "beqla+", + "beq-", + "beql-", + "beqa-", + "beqla-", + "", + "", + "", + "", + ][ins.field_lk() as usize | (ins.field_aa() as usize) << 1 + | (ins.field_bp() as usize) << 2 | (ins.field_bnp() as usize) << 3], + [ + Argument::CRField(CRField(ins.field_crfs() as _)), + Argument::BranchDest(BranchDest(ins.field_bd() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if (ins.field_bo() & 0x1e) == 0x4 && ins.field_bi() == 0x0 { + return ( + [ + "bge", + "bgel", + "bgea", + "bgela", + "bge+", + "bgel+", + "bgea+", + "bgela+", + "bge-", + "bgel-", + "bgea-", + "bgela-", + "", + "", + "", + "", + ][ins.field_lk() as usize | (ins.field_aa() as usize) << 1 + | (ins.field_bp() as usize) << 2 | (ins.field_bnp() as usize) << 3], + [ + Argument::BranchDest(BranchDest(ins.field_bd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if (ins.field_bo() & 0x1e) == 0x4 && (ins.field_bi() & 0x3) == 0x0 { + return ( + [ + "bge", + "bgel", + "bgea", + "bgela", + "bge+", + "bgel+", + "bgea+", + "bgela+", + "bge-", + "bgel-", + "bgea-", + "bgela-", + "", + "", + "", + "", + ][ins.field_lk() as usize | (ins.field_aa() as usize) << 1 + | (ins.field_bp() as usize) << 2 | (ins.field_bnp() as usize) << 3], + [ + Argument::CRField(CRField(ins.field_crfs() as _)), + Argument::BranchDest(BranchDest(ins.field_bd() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if (ins.field_bo() & 0x1e) == 0xc && ins.field_bi() == 0x1 { + return ( + [ + "bgt", + "bgtl", + "bgta", + "bgtla", + "bgt+", + "bgtl+", + "bgta+", + "bgtla+", + "bgt-", + "bgtl-", + "bgta-", + "bgtla-", + "", + "", + "", + "", + ][ins.field_lk() as usize | (ins.field_aa() as usize) << 1 + | (ins.field_bp() as usize) << 2 | (ins.field_bnp() as usize) << 3], + [ + Argument::BranchDest(BranchDest(ins.field_bd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if (ins.field_bo() & 0x1e) == 0xc && (ins.field_bi() & 0x3) == 0x1 { + return ( + [ + "bgt", + "bgtl", + "bgta", + "bgtla", + "bgt+", + "bgtl+", + "bgta+", + "bgtla+", + "bgt-", + "bgtl-", + "bgta-", + "bgtla-", + "", + "", + "", + "", + ][ins.field_lk() as usize | (ins.field_aa() as usize) << 1 + | (ins.field_bp() as usize) << 2 | (ins.field_bnp() as usize) << 3], + [ + Argument::CRField(CRField(ins.field_crfs() as _)), + Argument::BranchDest(BranchDest(ins.field_bd() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if (ins.field_bo() & 0x1e) == 0x4 && ins.field_bi() == 0x2 { + return ( + [ + "bne", + "bnel", + "bnea", + "bnela", + "bne+", + "bnel+", + "bnea+", + "bnela+", + "bne-", + "bnel-", + "bnea-", + "bnela-", + "", + "", + "", + "", + ][ins.field_lk() as usize | (ins.field_aa() as usize) << 1 + | (ins.field_bp() as usize) << 2 | (ins.field_bnp() as usize) << 3], + [ + Argument::BranchDest(BranchDest(ins.field_bd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if (ins.field_bo() & 0x1e) == 0x4 && (ins.field_bi() & 0x3) == 0x2 { + return ( + [ + "bne", + "bnel", + "bnea", + "bnela", + "bne+", + "bnel+", + "bnea+", + "bnela+", + "bne-", + "bnel-", + "bnea-", + "bnela-", + "", + "", + "", + "", + ][ins.field_lk() as usize | (ins.field_aa() as usize) << 1 + | (ins.field_bp() as usize) << 2 | (ins.field_bnp() as usize) << 3], + [ + Argument::CRField(CRField(ins.field_crfs() as _)), + Argument::BranchDest(BranchDest(ins.field_bd() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if (ins.field_bo() & 0x1e) == 0xc && ins.field_bi() == 0x3 { + return ( + [ + "bso", + "bsol", + "bsoa", + "bsola", + "bso+", + "bsol+", + "bsoa+", + "bsola+", + "bso-", + "bsol-", + "bsoa-", + "bsola-", + "", + "", + "", + "", + ][ins.field_lk() as usize | (ins.field_aa() as usize) << 1 + | (ins.field_bp() as usize) << 2 | (ins.field_bnp() as usize) << 3], + [ + Argument::BranchDest(BranchDest(ins.field_bd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if (ins.field_bo() & 0x1e) == 0xc && (ins.field_bi() & 0x3) == 0x3 { + return ( + [ + "bso", + "bsol", + "bsoa", + "bsola", + "bso+", + "bsol+", + "bsoa+", + "bsola+", + "bso-", + "bsol-", + "bsoa-", + "bsola-", + "", + "", + "", + "", + ][ins.field_lk() as usize | (ins.field_aa() as usize) << 1 + | (ins.field_bp() as usize) << 2 | (ins.field_bnp() as usize) << 3], + [ + Argument::CRField(CRField(ins.field_crfs() as _)), + Argument::BranchDest(BranchDest(ins.field_bd() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if (ins.field_bo() & 0x1e) == 0x4 && ins.field_bi() == 0x3 { + return ( + [ + "bns", + "bnsl", + "bnsa", + "bnsla", + "bns+", + "bnsl+", + "bnsa+", + "bnsla+", + "bns-", + "bnsl-", + "bnsa-", + "bnsla-", + "", + "", + "", + "", + ][ins.field_lk() as usize | (ins.field_aa() as usize) << 1 + | (ins.field_bp() as usize) << 2 | (ins.field_bnp() as usize) << 3], + [ + Argument::BranchDest(BranchDest(ins.field_bd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if (ins.field_bo() & 0x1e) == 0x4 && (ins.field_bi() & 0x3) == 0x3 { + return ( + [ + "bns", + "bnsl", + "bnsa", + "bnsla", + "bns+", + "bnsl+", + "bnsa+", + "bnsla+", + "bns-", + "bnsl-", + "bnsa-", + "bnsla-", + "", + "", + "", + "", + ][ins.field_lk() as usize | (ins.field_aa() as usize) << 1 + | (ins.field_bp() as usize) << 2 | (ins.field_bnp() as usize) << 3], + [ + Argument::CRField(CRField(ins.field_crfs() as _)), + Argument::BranchDest(BranchDest(ins.field_bd() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if (ins.field_bo() & 0x1e) == 0x10 && ins.field_bi() == 0x0 { + return ( + [ + "bdnz", + "bdnzl", + "bdnza", + "bdnzla", + "bdnz+", + "bdnzl+", + "bdnza+", + "bdnzla+", + "bdnz-", + "bdnzl-", + "bdnza-", + "bdnzla-", + "", + "", + "", + "", + ][ins.field_lk() as usize | (ins.field_aa() as usize) << 1 + | (ins.field_bp() as usize) << 2 | (ins.field_bnp() as usize) << 3], + [ + Argument::BranchDest(BranchDest(ins.field_bd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if (ins.field_bo() & 0x1e) == 0x8 { + return ( + [ + "bdnzt", + "bdnztl", + "bdnzta", + "bdnztla", + "bdnzt+", + "bdnztl+", + "bdnzta+", + "bdnztla+", + "bdnzt-", + "bdnztl-", + "bdnzta-", + "bdnztla-", + "", + "", + "", + "", + ][ins.field_lk() as usize | (ins.field_aa() as usize) << 1 + | (ins.field_bp() as usize) << 2 | (ins.field_bnp() as usize) << 3], + [ + Argument::CRBit(CRBit(ins.field_bi() as _)), + Argument::BranchDest(BranchDest(ins.field_bd() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if (ins.field_bo() & 0x1e) == 0x0 { + return ( + [ + "bdnzf", + "bdnzfl", + "bdnzfa", + "bdnzfla", + "bdnzf+", + "bdnzfl+", + "bdnzfa+", + "bdnzfla+", + "bdnzf-", + "bdnzfl-", + "bdnzfa-", + "bdnzfla-", + "", + "", + "", + "", + ][ins.field_lk() as usize | (ins.field_aa() as usize) << 1 + | (ins.field_bp() as usize) << 2 | (ins.field_bnp() as usize) << 3], + [ + Argument::CRBit(CRBit(ins.field_bi() as _)), + Argument::BranchDest(BranchDest(ins.field_bd() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if (ins.field_bo() & 0x1e) == 0x12 && ins.field_bi() == 0x0 { + return ( + [ + "bdz", + "bdzl", + "bdza", + "bdzla", + "bdz+", + "bdzl+", + "bdza+", + "bdzla+", + "bdz-", + "bdzl-", + "bdza-", + "bdzla-", + "", + "", + "", + "", + ][ins.field_lk() as usize | (ins.field_aa() as usize) << 1 + | (ins.field_bp() as usize) << 2 | (ins.field_bnp() as usize) << 3], + [ + Argument::BranchDest(BranchDest(ins.field_bd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if (ins.field_bo() & 0x1e) == 0xa { + return ( + [ + "bdzt", + "bdztl", + "bdzta", + "bdztla", + "bdzt+", + "bdztl+", + "bdzta+", + "bdztla+", + "bdzt-", + "bdztl-", + "bdzta-", + "bdztla-", + "", + "", + "", + "", + ][ins.field_lk() as usize | (ins.field_aa() as usize) << 1 + | (ins.field_bp() as usize) << 2 | (ins.field_bnp() as usize) << 3], + [ + Argument::CRBit(CRBit(ins.field_bi() as _)), + Argument::BranchDest(BranchDest(ins.field_bd() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if (ins.field_bo() & 0x1e) == 0x2 { + return ( + [ + "bdzf", + "bdzfl", + "bdzfa", + "bdzfla", + "bdzf+", + "bdzfl+", + "bdzfa+", + "bdzfla+", + "bdzf-", + "bdzfl-", + "bdzfa-", + "bdzfla-", + "", + "", + "", + "", + ][ins.field_lk() as usize | (ins.field_aa() as usize) << 1 + | (ins.field_bp() as usize) << 2 | (ins.field_bnp() as usize) << 3], + [ + Argument::CRBit(CRBit(ins.field_bi() as _)), + Argument::BranchDest(BranchDest(ins.field_bd() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + base_bc(ins) +} +const fn base_sc(ins: &Ins) -> (&'static str, Arguments) { + ( + "sc", + [Argument::None, Argument::None, Argument::None, Argument::None, Argument::None], + ) +} +const fn base_b(ins: &Ins) -> (&'static str, Arguments) { + ( + [ + "b", + "bl", + "ba", + "bla", + ][ins.field_lk() as usize | (ins.field_aa() as usize) << 1], + [ + Argument::BranchDest(BranchDest(ins.field_li() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ) +} +#[inline(always)] +const fn base_bcctr(ins: &Ins) -> (&'static str, Arguments) { + ( + [ + "bcctr", + "bcctrl", + "bcctr+", + "bcctrl+", + ][ins.field_lk() as usize | (ins.field_bp_nd() as usize) << 1], + [ + Argument::OpaqueU(OpaqueU(ins.field_bo() as _)), + Argument::CRBit(CRBit(ins.field_bi() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ) +} +const fn simplified_bcctr(ins: &Ins) -> (&'static str, Arguments) { + if ins.field_bo() == 0x14 && ins.field_bi() == 0x0 { + return ( + ["bctr", "bctrl"][ins.field_lk() as usize], + [ + Argument::None, + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if (ins.field_bo() & 0x1e) == 0xc && ins.field_bi() == 0x0 { + return ( + [ + "bltctr", + "bltctrl", + "bltctr+", + "bltctrl+", + ][ins.field_lk() as usize | (ins.field_bp_nd() as usize) << 1], + [ + Argument::None, + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if (ins.field_bo() & 0x1e) == 0xc && (ins.field_bi() & 0x3) == 0x0 { + return ( + [ + "bltctr", + "bltctrl", + "bltctr+", + "bltctrl+", + ][ins.field_lk() as usize | (ins.field_bp_nd() as usize) << 1], + [ + Argument::CRField(CRField(ins.field_crfs() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if (ins.field_bo() & 0x1e) == 0x4 && ins.field_bi() == 0x1 { + return ( + [ + "blectr", + "blectrl", + "blectr+", + "blectrl+", + ][ins.field_lk() as usize | (ins.field_bp_nd() as usize) << 1], + [ + Argument::None, + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if (ins.field_bo() & 0x1e) == 0x4 && (ins.field_bi() & 0x3) == 0x1 { + return ( + [ + "blectr", + "blectrl", + "blectr+", + "blectrl+", + ][ins.field_lk() as usize | (ins.field_bp_nd() as usize) << 1], + [ + Argument::CRField(CRField(ins.field_crfs() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if (ins.field_bo() & 0x1e) == 0xc && ins.field_bi() == 0x2 { + return ( + [ + "beqctr", + "beqctrl", + "beqctr+", + "beqctrl+", + ][ins.field_lk() as usize | (ins.field_bp_nd() as usize) << 1], + [ + Argument::None, + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if (ins.field_bo() & 0x1e) == 0xc && (ins.field_bi() & 0x3) == 0x2 { + return ( + [ + "beqctr", + "beqctrl", + "beqctr+", + "beqctrl+", + ][ins.field_lk() as usize | (ins.field_bp_nd() as usize) << 1], + [ + Argument::CRField(CRField(ins.field_crfs() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if (ins.field_bo() & 0x1e) == 0x4 && ins.field_bi() == 0x0 { + return ( + [ + "bgectr", + "bgectrl", + "bgectr+", + "bgectrl+", + ][ins.field_lk() as usize | (ins.field_bp_nd() as usize) << 1], + [ + Argument::None, + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if (ins.field_bo() & 0x1e) == 0x4 && (ins.field_bi() & 0x3) == 0x0 { + return ( + [ + "bgectr", + "bgectrl", + "bgectr+", + "bgectrl+", + ][ins.field_lk() as usize | (ins.field_bp_nd() as usize) << 1], + [ + Argument::CRField(CRField(ins.field_crfs() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if (ins.field_bo() & 0x1e) == 0xc && ins.field_bi() == 0x1 { + return ( + [ + "bgtctr", + "bgtctrl", + "bgtctr+", + "bgtctrl+", + ][ins.field_lk() as usize | (ins.field_bp_nd() as usize) << 1], + [ + Argument::None, + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if (ins.field_bo() & 0x1e) == 0xc && (ins.field_bi() & 0x3) == 0x1 { + return ( + [ + "bgtctr", + "bgtctrl", + "bgtctr+", + "bgtctrl+", + ][ins.field_lk() as usize | (ins.field_bp_nd() as usize) << 1], + [ + Argument::CRField(CRField(ins.field_crfs() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if (ins.field_bo() & 0x1e) == 0x4 && ins.field_bi() == 0x2 { + return ( + [ + "bnectr", + "bnectrl", + "bnectr+", + "bnectrl+", + ][ins.field_lk() as usize | (ins.field_bp_nd() as usize) << 1], + [ + Argument::None, + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if (ins.field_bo() & 0x1e) == 0x4 && (ins.field_bi() & 0x3) == 0x2 { + return ( + [ + "bnectr", + "bnectrl", + "bnectr+", + "bnectrl+", + ][ins.field_lk() as usize | (ins.field_bp_nd() as usize) << 1], + [ + Argument::CRField(CRField(ins.field_crfs() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if (ins.field_bo() & 0x1e) == 0xc && ins.field_bi() == 0x3 { + return ( + [ + "bsoctr", + "bsoctrl", + "bsoctr+", + "bsoctrl+", + ][ins.field_lk() as usize | (ins.field_bp_nd() as usize) << 1], + [ + Argument::None, + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if (ins.field_bo() & 0x1e) == 0xc && (ins.field_bi() & 0x3) == 0x3 { + return ( + [ + "bsoctr", + "bsoctrl", + "bsoctr+", + "bsoctrl+", + ][ins.field_lk() as usize | (ins.field_bp_nd() as usize) << 1], + [ + Argument::CRField(CRField(ins.field_crfs() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if (ins.field_bo() & 0x1e) == 0x4 && ins.field_bi() == 0x3 { + return ( + [ + "bnsctr", + "bnsctrl", + "bnsctr+", + "bnsctrl+", + ][ins.field_lk() as usize | (ins.field_bp_nd() as usize) << 1], + [ + Argument::None, + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if (ins.field_bo() & 0x1e) == 0x4 && (ins.field_bi() & 0x3) == 0x3 { + return ( + [ + "bnsctr", + "bnsctrl", + "bnsctr+", + "bnsctrl+", + ][ins.field_lk() as usize | (ins.field_bp_nd() as usize) << 1], + [ + Argument::CRField(CRField(ins.field_crfs() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + base_bcctr(ins) +} +#[inline(always)] +const fn base_bclr(ins: &Ins) -> (&'static str, Arguments) { + ( + [ + "bclr", + "bclrl", + "bclr+", + "bclrl+", + ][ins.field_lk() as usize | (ins.field_bp_nd() as usize) << 1], + [ + Argument::OpaqueU(OpaqueU(ins.field_bo() as _)), + Argument::CRBit(CRBit(ins.field_bi() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ) +} +const fn simplified_bclr(ins: &Ins) -> (&'static str, Arguments) { + if ins.field_bo() == 0x14 && ins.field_bi() == 0x0 { + return ( + ["blr", "blrl"][ins.field_lk() as usize], + [ + Argument::None, + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if (ins.field_bo() & 0x1e) == 0xc && ins.field_bi() == 0x0 { + return ( + [ + "bltlr", + "bltlrl", + "bltlr+", + "bltlrl+", + ][ins.field_lk() as usize | (ins.field_bp_nd() as usize) << 1], + [ + Argument::None, + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if (ins.field_bo() & 0x1e) == 0xc && (ins.field_bi() & 0x3) == 0x0 { + return ( + [ + "bltlr", + "bltlrl", + "bltlr+", + "bltlrl+", + ][ins.field_lk() as usize | (ins.field_bp_nd() as usize) << 1], + [ + Argument::CRField(CRField(ins.field_crfs() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if (ins.field_bo() & 0x1e) == 0x4 && ins.field_bi() == 0x1 { + return ( + [ + "blelr", + "blelrl", + "blelr+", + "blelrl+", + ][ins.field_lk() as usize | (ins.field_bp_nd() as usize) << 1], + [ + Argument::None, + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if (ins.field_bo() & 0x1e) == 0x4 && (ins.field_bi() & 0x3) == 0x1 { + return ( + [ + "blelr", + "blelrl", + "blelr+", + "blelrl+", + ][ins.field_lk() as usize | (ins.field_bp_nd() as usize) << 1], + [ + Argument::CRField(CRField(ins.field_crfs() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if (ins.field_bo() & 0x1e) == 0xc && ins.field_bi() == 0x2 { + return ( + [ + "beqlr", + "beqlrl", + "beqlr+", + "beqlrl+", + ][ins.field_lk() as usize | (ins.field_bp_nd() as usize) << 1], + [ + Argument::None, + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if (ins.field_bo() & 0x1e) == 0xc && (ins.field_bi() & 0x3) == 0x2 { + return ( + [ + "beqlr", + "beqlrl", + "beqlr+", + "beqlrl+", + ][ins.field_lk() as usize | (ins.field_bp_nd() as usize) << 1], + [ + Argument::CRField(CRField(ins.field_crfs() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if (ins.field_bo() & 0x1e) == 0x4 && ins.field_bi() == 0x0 { + return ( + [ + "bgelr", + "bgelrl", + "bgelr+", + "bgelrl+", + ][ins.field_lk() as usize | (ins.field_bp_nd() as usize) << 1], + [ + Argument::None, + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if (ins.field_bo() & 0x1e) == 0x4 && (ins.field_bi() & 0x3) == 0x0 { + return ( + [ + "bgelr", + "bgelrl", + "bgelr+", + "bgelrl+", + ][ins.field_lk() as usize | (ins.field_bp_nd() as usize) << 1], + [ + Argument::CRField(CRField(ins.field_crfs() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if (ins.field_bo() & 0x1e) == 0xc && ins.field_bi() == 0x1 { + return ( + [ + "bgtlr", + "bgtlrl", + "bgtlr+", + "bgtlrl+", + ][ins.field_lk() as usize | (ins.field_bp_nd() as usize) << 1], + [ + Argument::None, + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if (ins.field_bo() & 0x1e) == 0xc && (ins.field_bi() & 0x3) == 0x1 { + return ( + [ + "bgtlr", + "bgtlrl", + "bgtlr+", + "bgtlrl+", + ][ins.field_lk() as usize | (ins.field_bp_nd() as usize) << 1], + [ + Argument::CRField(CRField(ins.field_crfs() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if (ins.field_bo() & 0x1e) == 0x4 && ins.field_bi() == 0x2 { + return ( + [ + "bnelr", + "bnelrl", + "bnelr+", + "bnelrl+", + ][ins.field_lk() as usize | (ins.field_bp_nd() as usize) << 1], + [ + Argument::None, + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if (ins.field_bo() & 0x1e) == 0x4 && (ins.field_bi() & 0x3) == 0x2 { + return ( + [ + "bnelr", + "bnelrl", + "bnelr+", + "bnelrl+", + ][ins.field_lk() as usize | (ins.field_bp_nd() as usize) << 1], + [ + Argument::CRField(CRField(ins.field_crfs() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if (ins.field_bo() & 0x1e) == 0xc && ins.field_bi() == 0x3 { + return ( + [ + "bsolr", + "bsolrl", + "bsolr+", + "bsolrl+", + ][ins.field_lk() as usize | (ins.field_bp_nd() as usize) << 1], + [ + Argument::None, + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if (ins.field_bo() & 0x1e) == 0xc && (ins.field_bi() & 0x3) == 0x3 { + return ( + [ + "bsolr", + "bsolrl", + "bsolr+", + "bsolrl+", + ][ins.field_lk() as usize | (ins.field_bp_nd() as usize) << 1], + [ + Argument::CRField(CRField(ins.field_crfs() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if (ins.field_bo() & 0x1e) == 0x4 && ins.field_bi() == 0x3 { + return ( + [ + "bnslr", + "bnslrl", + "bnslr+", + "bnslrl+", + ][ins.field_lk() as usize | (ins.field_bp_nd() as usize) << 1], + [ + Argument::None, + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if (ins.field_bo() & 0x1e) == 0x4 && (ins.field_bi() & 0x3) == 0x3 { + return ( + [ + "bnslr", + "bnslrl", + "bnslr+", + "bnslrl+", + ][ins.field_lk() as usize | (ins.field_bp_nd() as usize) << 1], + [ + Argument::CRField(CRField(ins.field_crfs() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if (ins.field_bo() & 0x1e) == 0x10 && ins.field_bi() == 0x0 { + return ( + [ + "bdnzlr", + "bdnzlrl", + "bdnzlr+", + "bdnzlrl+", + ][ins.field_lk() as usize | (ins.field_bp_nd() as usize) << 1], + [ + Argument::None, + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if (ins.field_bo() & 0x1e) == 0x8 { + return ( + [ + "bdnztlr", + "bdnztlrl", + "bdnztlr+", + "bdnztlrl+", + ][ins.field_lk() as usize | (ins.field_bp_nd() as usize) << 1], + [ + Argument::CRBit(CRBit(ins.field_bi() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if (ins.field_bo() & 0x1e) == 0x0 { + return ( + [ + "bdnzflr", + "bdnzflrl", + "bdnzflr+", + "bdnzflrl+", + ][ins.field_lk() as usize | (ins.field_bp_nd() as usize) << 1], + [ + Argument::CRBit(CRBit(ins.field_bi() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if (ins.field_bo() & 0x1e) == 0x12 && ins.field_bi() == 0x0 { + return ( + [ + "bdzlr", + "bdzlrl", + "bdzlr+", + "bdzlrl+", + ][ins.field_lk() as usize | (ins.field_bp_nd() as usize) << 1], + [ + Argument::None, + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if (ins.field_bo() & 0x1e) == 0xa { + return ( + [ + "bdztlr", + "bdztlrl", + "bdztlr+", + "bdztlrl+", + ][ins.field_lk() as usize | (ins.field_bp_nd() as usize) << 1], + [ + Argument::CRBit(CRBit(ins.field_bi() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if (ins.field_bo() & 0x1e) == 0x0 { + return ( + [ + "bdzflr", + "bdzflrl", + "bdzflr+", + "bdzflrl+", + ][ins.field_lk() as usize | (ins.field_bp_nd() as usize) << 1], + [ + Argument::CRBit(CRBit(ins.field_bi() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + base_bclr(ins) +} +const fn base_crand(ins: &Ins) -> (&'static str, Arguments) { + ( + "crand", + [ + Argument::CRBit(CRBit(ins.field_crbd() as _)), + Argument::CRBit(CRBit(ins.field_crba() as _)), + Argument::CRBit(CRBit(ins.field_crbb() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_crandc(ins: &Ins) -> (&'static str, Arguments) { + ( + "crandc", + [ + Argument::CRBit(CRBit(ins.field_crbd() as _)), + Argument::CRBit(CRBit(ins.field_crba() as _)), + Argument::CRBit(CRBit(ins.field_crbb() as _)), + Argument::None, + Argument::None, + ], + ) +} +#[inline(always)] +const fn base_creqv(ins: &Ins) -> (&'static str, Arguments) { + ( + "creqv", + [ + Argument::CRBit(CRBit(ins.field_crbd() as _)), + Argument::CRBit(CRBit(ins.field_crba() as _)), + Argument::CRBit(CRBit(ins.field_crbb() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn simplified_creqv(ins: &Ins) -> (&'static str, Arguments) { + if ins.field_crba() == ins.field_crbd() && ins.field_crbb() == ins.field_crbd() { + return ( + "crset", + [ + Argument::CRBit(CRBit(ins.field_crbd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + base_creqv(ins) +} +const fn base_crnand(ins: &Ins) -> (&'static str, Arguments) { + ( + "crnand", + [ + Argument::CRBit(CRBit(ins.field_crbd() as _)), + Argument::CRBit(CRBit(ins.field_crba() as _)), + Argument::CRBit(CRBit(ins.field_crbb() as _)), + Argument::None, + Argument::None, + ], + ) +} +#[inline(always)] +const fn base_crnor(ins: &Ins) -> (&'static str, Arguments) { + ( + "crnor", + [ + Argument::CRBit(CRBit(ins.field_crbd() as _)), + Argument::CRBit(CRBit(ins.field_crba() as _)), + Argument::CRBit(CRBit(ins.field_crbb() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn simplified_crnor(ins: &Ins) -> (&'static str, Arguments) { + if ins.field_crbb() == ins.field_crba() { + return ( + "crnot", + [ + Argument::CRBit(CRBit(ins.field_crbd() as _)), + Argument::CRBit(CRBit(ins.field_crba() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + base_crnor(ins) +} +#[inline(always)] +const fn base_cror(ins: &Ins) -> (&'static str, Arguments) { + ( + "cror", + [ + Argument::CRBit(CRBit(ins.field_crbd() as _)), + Argument::CRBit(CRBit(ins.field_crba() as _)), + Argument::CRBit(CRBit(ins.field_crbb() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn simplified_cror(ins: &Ins) -> (&'static str, Arguments) { + if ins.field_crbb() == ins.field_crba() { + return ( + "crmove", + [ + Argument::CRBit(CRBit(ins.field_crbd() as _)), + Argument::CRBit(CRBit(ins.field_crba() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + base_cror(ins) +} +const fn base_crorc(ins: &Ins) -> (&'static str, Arguments) { + ( + "crorc", + [ + Argument::CRBit(CRBit(ins.field_crbd() as _)), + Argument::CRBit(CRBit(ins.field_crba() as _)), + Argument::CRBit(CRBit(ins.field_crbb() as _)), + Argument::None, + Argument::None, + ], + ) +} +#[inline(always)] +const fn base_crxor(ins: &Ins) -> (&'static str, Arguments) { + ( + "crxor", + [ + Argument::CRBit(CRBit(ins.field_crbd() as _)), + Argument::CRBit(CRBit(ins.field_crba() as _)), + Argument::CRBit(CRBit(ins.field_crbb() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn simplified_crxor(ins: &Ins) -> (&'static str, Arguments) { + if ins.field_crba() == ins.field_crbd() && ins.field_crbb() == ins.field_crbd() { + return ( + "crclr", + [ + Argument::CRBit(CRBit(ins.field_crbd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + base_crxor(ins) +} +const fn base_isync(ins: &Ins) -> (&'static str, Arguments) { + ( + "isync", + [Argument::None, Argument::None, Argument::None, Argument::None, Argument::None], + ) +} +const fn base_mcrf(ins: &Ins) -> (&'static str, Arguments) { + ( + "mcrf", + [ + Argument::CRField(CRField(ins.field_crfd() as _)), + Argument::CRField(CRField(ins.field_crfs() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ) +} +const fn base_rfi(ins: &Ins) -> (&'static str, Arguments) { + ( + "rfi", + [Argument::None, Argument::None, Argument::None, Argument::None, Argument::None], + ) +} +const fn base_rlwimi(ins: &Ins) -> (&'static str, Arguments) { + ( + ["rlwimi", "rlwimi."][ins.field_rc() as usize], + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::OpaqueU(OpaqueU(ins.field_sh() as _)), + Argument::OpaqueU(OpaqueU(ins.field_mb() as _)), + Argument::OpaqueU(OpaqueU(ins.field_me() as _)), + ], + ) +} +#[inline(always)] +const fn base_rlwinm(ins: &Ins) -> (&'static str, Arguments) { + ( + ["rlwinm", "rlwinm."][ins.field_rc() as usize], + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::OpaqueU(OpaqueU(ins.field_sh() as _)), + Argument::OpaqueU(OpaqueU(ins.field_mb() as _)), + Argument::OpaqueU(OpaqueU(ins.field_me() as _)), + ], + ) +} +const fn simplified_rlwinm(ins: &Ins) -> (&'static str, Arguments) { + if ins.field_sh() == 0x0 && ins.field_mb() == 0x0 { + return ( + ["clrrwi", "clrrwi."][ins.field_rc() as usize], + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::OpaqueU(OpaqueU((31 - ins.field_me()) as _)), + Argument::None, + Argument::None, + ], + ); + } + if ins.field_sh() == 0x0 && ins.field_me() == 0x1f { + return ( + ["clrlwi", "clrlwi."][ins.field_rc() as usize], + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::OpaqueU(OpaqueU(ins.field_mb() as _)), + Argument::None, + Argument::None, + ], + ); + } + if ins.field_mb() == 0x0 && ins.field_me() == 0x1f && ins.field_sh() <= 0x10 { + return ( + ["rotlwi", "rotlwi."][ins.field_rc() as usize], + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::OpaqueU(OpaqueU(ins.field_sh() as _)), + Argument::None, + Argument::None, + ], + ); + } + if ins.field_mb() == 0x0 && ins.field_me() == 0x1f && ins.field_sh() > 0x10 { + return ( + ["rotrwi", "rotrwi."][ins.field_rc() as usize], + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::OpaqueU(OpaqueU((32 - ins.field_sh()) as _)), + Argument::None, + Argument::None, + ], + ); + } + if ins.field_mb() == 0x0 && ins.field_me() == 31 - ins.field_sh() { + return ( + ["slwi", "slwi."][ins.field_rc() as usize], + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::OpaqueU(OpaqueU(ins.field_sh() as _)), + Argument::None, + Argument::None, + ], + ); + } + if ins.field_me() == 0x1f && ins.field_sh() == 32 - ins.field_mb() { + return ( + ["srwi", "srwi."][ins.field_rc() as usize], + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::OpaqueU(OpaqueU(ins.field_mb() as _)), + Argument::None, + Argument::None, + ], + ); + } + if ins.field_sh() < 0x20 && ins.field_me() == 31 - ins.field_sh() { + return ( + ["clrlslwi", "clrlslwi."][ins.field_rc() as usize], + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::OpaqueU(OpaqueU((ins.field_mb() + ins.field_sh()) as _)), + Argument::OpaqueU(OpaqueU(ins.field_sh() as _)), + Argument::None, + ], + ); + } + if ins.field_mb() == 0x0 { + return ( + ["extlwi", "extlwi."][ins.field_rc() as usize], + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::OpaqueU(OpaqueU((ins.field_me() + 1) as _)), + Argument::OpaqueU(OpaqueU(ins.field_sh() as _)), + Argument::None, + ], + ); + } + if ins.field_me() == 0x1f && ins.field_sh() >= 32 - ins.field_mb() { + return ( + ["extrwi", "extrwi."][ins.field_rc() as usize], + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::OpaqueU(OpaqueU((32 - ins.field_mb()) as _)), + Argument::OpaqueU( + OpaqueU((ins.field_sh() - (32 - ins.field_mb())) as _), + ), + Argument::None, + ], + ); + } + base_rlwinm(ins) +} +#[inline(always)] +const fn base_rlwnm(ins: &Ins) -> (&'static str, Arguments) { + ( + ["rlwnm", "rlwnm."][ins.field_rc() as usize], + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::OpaqueU(OpaqueU(ins.field_mb() as _)), + Argument::OpaqueU(OpaqueU(ins.field_me() as _)), + ], + ) +} +const fn simplified_rlwnm(ins: &Ins) -> (&'static str, Arguments) { + if ins.field_mb() == 0x0 && ins.field_me() == 0x1f { + return ( + ["rotlw", "rotlw."][ins.field_rc() as usize], + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + ], + ); + } + base_rlwnm(ins) +} +#[inline(always)] +const fn base_ori(ins: &Ins) -> (&'static str, Arguments) { + ( + "ori", + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::Uimm(Uimm(ins.field_uimm() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn simplified_ori(ins: &Ins) -> (&'static str, Arguments) { + if ins.field_ra() == 0x0 && ins.field_rs() == 0x0 && ins.field_uimm() == 0x0 { + return ( + "nop", + [ + Argument::None, + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + base_ori(ins) +} +const fn base_oris(ins: &Ins) -> (&'static str, Arguments) { + ( + "oris", + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::Uimm(Uimm(ins.field_uimm() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_xori(ins: &Ins) -> (&'static str, Arguments) { + ( + "xori", + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::Uimm(Uimm(ins.field_uimm() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_xoris(ins: &Ins) -> (&'static str, Arguments) { + ( + "xoris", + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::Uimm(Uimm(ins.field_uimm() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_andi_(ins: &Ins) -> (&'static str, Arguments) { + ( + "andi.", + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::Uimm(Uimm(ins.field_uimm() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_andis_(ins: &Ins) -> (&'static str, Arguments) { + ( + "andis.", + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::Uimm(Uimm(ins.field_uimm() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_add(ins: &Ins) -> (&'static str, Arguments) { + ( + [ + "add", + "addo", + "add.", + "addo.", + ][ins.field_oe() as usize | (ins.field_rc() as usize) << 1], + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_addc(ins: &Ins) -> (&'static str, Arguments) { + ( + [ + "addc", + "addco", + "addc.", + "addco.", + ][ins.field_oe() as usize | (ins.field_rc() as usize) << 1], + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_adde(ins: &Ins) -> (&'static str, Arguments) { + ( + [ + "adde", + "addeo", + "adde.", + "addeo.", + ][ins.field_oe() as usize | (ins.field_rc() as usize) << 1], + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_addme(ins: &Ins) -> (&'static str, Arguments) { + ( + [ + "addme", + "addmeo", + "addme.", + "addmeo.", + ][ins.field_oe() as usize | (ins.field_rc() as usize) << 1], + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ) +} +const fn base_addze(ins: &Ins) -> (&'static str, Arguments) { + ( + [ + "addze", + "addzeo", + "addze.", + "addzeo.", + ][ins.field_oe() as usize | (ins.field_rc() as usize) << 1], + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ) +} +const fn base_and(ins: &Ins) -> (&'static str, Arguments) { + ( + ["and", "and."][ins.field_rc() as usize], + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_andc(ins: &Ins) -> (&'static str, Arguments) { + ( + ["andc", "andc."][ins.field_rc() as usize], + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + ], + ) +} +#[inline(always)] +const fn base_cmp(ins: &Ins) -> (&'static str, Arguments) { + ( + "cmp", + [ + Argument::CRField(CRField(ins.field_crfd() as _)), + Argument::OpaqueU(OpaqueU(ins.field_l() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + ], + ) +} +const fn simplified_cmp(ins: &Ins) -> (&'static str, Arguments) { + if ins.field_crfd() == 0x0 && ins.field_l() == 0x0 { + return ( + "cmpw", + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if ins.field_l() == 0x0 { + return ( + "cmpw", + [ + Argument::CRField(CRField(ins.field_crfd() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + ], + ); + } + if ins.field_crfd() == 0x0 && ins.field_l() == 0x1 { + return ( + "cmpd", + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if ins.field_l() == 0x1 { + return ( + "cmpd", + [ + Argument::CRField(CRField(ins.field_crfd() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + ], + ); + } + base_cmp(ins) +} +#[inline(always)] +const fn base_cmpl(ins: &Ins) -> (&'static str, Arguments) { + ( + "cmpl", + [ + Argument::CRField(CRField(ins.field_crfd() as _)), + Argument::OpaqueU(OpaqueU(ins.field_l() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + ], + ) +} +const fn simplified_cmpl(ins: &Ins) -> (&'static str, Arguments) { + if ins.field_crfd() == 0x0 && ins.field_l() == 0x0 { + return ( + "cmplw", + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if ins.field_l() == 0x0 { + return ( + "cmplw", + [ + Argument::CRField(CRField(ins.field_crfd() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + ], + ); + } + if ins.field_crfd() == 0x0 && ins.field_l() == 0x1 { + return ( + "cmpld", + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if ins.field_l() == 0x1 { + return ( + "cmpld", + [ + Argument::CRField(CRField(ins.field_crfd() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + ], + ); + } + base_cmpl(ins) +} +const fn base_cntlzw(ins: &Ins) -> (&'static str, Arguments) { + ( + ["cntlzw", "cntlzw."][ins.field_rc() as usize], + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ) +} +const fn base_dcbf(ins: &Ins) -> (&'static str, Arguments) { + ( + "dcbf", + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ) +} +const fn base_dcbi(ins: &Ins) -> (&'static str, Arguments) { + ( + "dcbi", + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ) +} +const fn base_dcbst(ins: &Ins) -> (&'static str, Arguments) { + ( + "dcbst", + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ) +} +const fn base_dcbt(ins: &Ins) -> (&'static str, Arguments) { + ( + "dcbt", + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ) +} +const fn base_dcbtst(ins: &Ins) -> (&'static str, Arguments) { + ( + "dcbtst", + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ) +} +const fn base_dcbz(ins: &Ins) -> (&'static str, Arguments) { + ( + "dcbz", + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ) +} +const fn base_divw(ins: &Ins) -> (&'static str, Arguments) { + ( + [ + "divw", + "divwo", + "divw.", + "divwo.", + ][ins.field_oe() as usize | (ins.field_rc() as usize) << 1], + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_divwu(ins: &Ins) -> (&'static str, Arguments) { + ( + [ + "divwu", + "divwuo", + "divwu.", + "divwuo.", + ][ins.field_oe() as usize | (ins.field_rc() as usize) << 1], + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_eciwx(ins: &Ins) -> (&'static str, Arguments) { + ( + "eciwx", + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_ecowx(ins: &Ins) -> (&'static str, Arguments) { + ( + "ecowx", + [ + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_eieio(ins: &Ins) -> (&'static str, Arguments) { + ( + "eieio", + [Argument::None, Argument::None, Argument::None, Argument::None, Argument::None], + ) +} +const fn base_eqv(ins: &Ins) -> (&'static str, Arguments) { + ( + ["eqv", "eqv."][ins.field_rc() as usize], + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_extsb(ins: &Ins) -> (&'static str, Arguments) { + ( + ["extsb", "extsb."][ins.field_rc() as usize], + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ) +} +const fn base_extsh(ins: &Ins) -> (&'static str, Arguments) { + ( + ["extsh", "extsh."][ins.field_rc() as usize], + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ) +} +const fn base_icbi(ins: &Ins) -> (&'static str, Arguments) { + ( + ["icbi", "icbi."][ins.field_rc() as usize], + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ) +} +const fn base_lbzux(ins: &Ins) -> (&'static str, Arguments) { + ( + "lbzux", + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_lbzx(ins: &Ins) -> (&'static str, Arguments) { + ( + "lbzx", + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_lfdux(ins: &Ins) -> (&'static str, Arguments) { + ( + "lfdux", + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_lfdx(ins: &Ins) -> (&'static str, Arguments) { + ( + "lfdx", + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_lfsux(ins: &Ins) -> (&'static str, Arguments) { + ( + "lfsux", + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_lfsx(ins: &Ins) -> (&'static str, Arguments) { + ( + "lfsx", + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_lhaux(ins: &Ins) -> (&'static str, Arguments) { + ( + "lhaux", + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_lhax(ins: &Ins) -> (&'static str, Arguments) { + ( + "lhax", + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_lhbrx(ins: &Ins) -> (&'static str, Arguments) { + ( + "lhbrx", + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_lhzux(ins: &Ins) -> (&'static str, Arguments) { + ( + "lhzux", + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_lhzx(ins: &Ins) -> (&'static str, Arguments) { + ( + "lhzx", + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_lswi(ins: &Ins) -> (&'static str, Arguments) { + ( + "lswi", + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::OpaqueU(OpaqueU(ins.field_nb() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_lswx(ins: &Ins) -> (&'static str, Arguments) { + ( + "lswx", + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_lwarx(ins: &Ins) -> (&'static str, Arguments) { + ( + "lwarx", + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_lwbrx(ins: &Ins) -> (&'static str, Arguments) { + ( + "lwbrx", + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_lwzux(ins: &Ins) -> (&'static str, Arguments) { + ( + "lwzux", + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_lwzx(ins: &Ins) -> (&'static str, Arguments) { + ( + "lwzx", + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_mcrxr(ins: &Ins) -> (&'static str, Arguments) { + ( + "mcrxr", + [ + Argument::CRField(CRField(ins.field_crfd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ) +} +const fn base_mfcr(ins: &Ins) -> (&'static str, Arguments) { + ( + "mfcr", + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ) +} +const fn base_mfmsr(ins: &Ins) -> (&'static str, Arguments) { + ( + "mfmsr", + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ) +} +#[inline(always)] +const fn base_mfspr(ins: &Ins) -> (&'static str, Arguments) { + ( + "mfspr", + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::SPR(SPR(ins.field_spr() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ) +} +const fn simplified_mfspr(ins: &Ins) -> (&'static str, Arguments) { + if ins.field_spr() == 0x1 { + return ( + "mfxer", + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if ins.field_spr() == 0x8 { + return ( + "mflr", + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if ins.field_spr() == 0x9 { + return ( + "mfctr", + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if ins.field_spr() == 0x12 { + return ( + "mfdsisr", + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if ins.field_spr() == 0x13 { + return ( + "mfdar", + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if ins.field_spr() == 0x16 { + return ( + "mfdec", + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if ins.field_spr() == 0x19 { + return ( + "mfsdr1", + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if ins.field_spr() == 0x1a { + return ( + "mfsrr0", + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if ins.field_spr() == 0x1b { + return ( + "mfsrr1", + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if (ins.field_spr() & 0x3fc) == 0x110 { + return ( + "mfsprg", + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::OpaqueU(OpaqueU(ins.field_spr_sprg() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if ins.field_spr() == 0x11a { + return ( + "mfear", + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if (ins.field_spr() & 0x3f9) == 0x210 { + return ( + "mfibatu", + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::OpaqueU(OpaqueU(ins.field_spr_bat() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if (ins.field_spr() & 0x3f9) == 0x211 { + return ( + "mfibatl", + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::OpaqueU(OpaqueU(ins.field_spr_bat() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if (ins.field_spr() & 0x3f9) == 0x218 { + return ( + "mfdbatu", + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::OpaqueU(OpaqueU(ins.field_spr_bat() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if (ins.field_spr() & 0x3f9) == 0x219 { + return ( + "mfdbatl", + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::OpaqueU(OpaqueU(ins.field_spr_bat() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + base_mfspr(ins) +} +const fn base_mfsr(ins: &Ins) -> (&'static str, Arguments) { + ( + "mfsr", + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::SR(SR(ins.field_sr() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ) +} +const fn base_mfsrin(ins: &Ins) -> (&'static str, Arguments) { + ( + "mfsrin", + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ) +} +const fn base_mftb(ins: &Ins) -> (&'static str, Arguments) { + ( + "mftb", + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::OpaqueU(OpaqueU(ins.field_tbr() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ) +} +const fn base_mtcrf(ins: &Ins) -> (&'static str, Arguments) { + ( + "mtcrf", + [ + Argument::OpaqueU(OpaqueU(ins.field_crm() as _)), + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ) +} +const fn base_mtmsr(ins: &Ins) -> (&'static str, Arguments) { + ( + "mtmsr", + [ + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ) +} +#[inline(always)] +const fn base_mtspr(ins: &Ins) -> (&'static str, Arguments) { + ( + "mtspr", + [ + Argument::SPR(SPR(ins.field_spr() as _)), + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ) +} +const fn simplified_mtspr(ins: &Ins) -> (&'static str, Arguments) { + if ins.field_spr() == 0x1 { + return ( + "mtxer", + [ + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if ins.field_spr() == 0x8 { + return ( + "mtlr", + [ + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if ins.field_spr() == 0x9 { + return ( + "mtctr", + [ + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if ins.field_spr() == 0x12 { + return ( + "mtdsisr", + [ + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if ins.field_spr() == 0x13 { + return ( + "mtdar", + [ + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if ins.field_spr() == 0x16 { + return ( + "mtdec", + [ + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if ins.field_spr() == 0x19 { + return ( + "mtsdr1", + [ + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if ins.field_spr() == 0x1a { + return ( + "mtsrr0", + [ + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if ins.field_spr() == 0x1b { + return ( + "mtsrr1", + [ + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if (ins.field_spr() & 0x3fc) == 0x110 { + return ( + "mtsprg", + [ + Argument::OpaqueU(OpaqueU(ins.field_spr_sprg() as _)), + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if ins.field_spr() == 0x11a { + return ( + "mtear", + [ + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if ins.field_spr() == 0x11c { + return ( + "mttbl", + [ + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if ins.field_spr() == 0x11d { + return ( + "mttbu", + [ + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if (ins.field_spr() & 0x3f9) == 0x210 { + return ( + "mtibatu", + [ + Argument::OpaqueU(OpaqueU(ins.field_spr_bat() as _)), + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if (ins.field_spr() & 0x3f9) == 0x211 { + return ( + "mtibatl", + [ + Argument::OpaqueU(OpaqueU(ins.field_spr_bat() as _)), + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if (ins.field_spr() & 0x3f9) == 0x218 { + return ( + "mtdbatu", + [ + Argument::OpaqueU(OpaqueU(ins.field_spr_bat() as _)), + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if (ins.field_spr() & 0x3f9) == 0x219 { + return ( + "mtdbatl", + [ + Argument::OpaqueU(OpaqueU(ins.field_spr_bat() as _)), + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + base_mtspr(ins) +} +const fn base_mtsr(ins: &Ins) -> (&'static str, Arguments) { + ( + "mtsr", + [ + Argument::SR(SR(ins.field_sr() as _)), + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ) +} +const fn base_mtsrin(ins: &Ins) -> (&'static str, Arguments) { + ( + "mtsrin", + [ + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ) +} +const fn base_mulhw(ins: &Ins) -> (&'static str, Arguments) { + ( + ["mulhw", "mulhw."][ins.field_rc() as usize], + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_mulhwu(ins: &Ins) -> (&'static str, Arguments) { + ( + ["mulhwu", "mulhwu."][ins.field_rc() as usize], + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_mullw(ins: &Ins) -> (&'static str, Arguments) { + ( + [ + "mullw", + "mullwo", + "mullw.", + "mullwo.", + ][ins.field_oe() as usize | (ins.field_rc() as usize) << 1], + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_nand(ins: &Ins) -> (&'static str, Arguments) { + ( + ["nand", "nand."][ins.field_rc() as usize], + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_neg(ins: &Ins) -> (&'static str, Arguments) { + ( + [ + "neg", + "nego", + "neg.", + "nego.", + ][ins.field_oe() as usize | (ins.field_rc() as usize) << 1], + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ) +} +const fn base_nor(ins: &Ins) -> (&'static str, Arguments) { + ( + ["nor", "nor."][ins.field_rc() as usize], + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + ], + ) +} +#[inline(always)] +const fn base_or(ins: &Ins) -> (&'static str, Arguments) { + ( + ["or", "or."][ins.field_rc() as usize], + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn simplified_or(ins: &Ins) -> (&'static str, Arguments) { + if ins.field_rb() == ins.field_rs() { + return ( + ["mr", "mr."][ins.field_rc() as usize], + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + base_or(ins) +} +const fn base_orc(ins: &Ins) -> (&'static str, Arguments) { + ( + ["orc", "orc."][ins.field_rc() as usize], + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_slw(ins: &Ins) -> (&'static str, Arguments) { + ( + ["slw", "slw."][ins.field_rc() as usize], + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_sraw(ins: &Ins) -> (&'static str, Arguments) { + ( + ["sraw", "sraw."][ins.field_rc() as usize], + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_srawi(ins: &Ins) -> (&'static str, Arguments) { + ( + ["srawi", "srawi."][ins.field_rc() as usize], + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::OpaqueU(OpaqueU(ins.field_sh() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_srw(ins: &Ins) -> (&'static str, Arguments) { + ( + ["srw", "srw."][ins.field_rc() as usize], + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_stbux(ins: &Ins) -> (&'static str, Arguments) { + ( + "stbux", + [ + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_stbx(ins: &Ins) -> (&'static str, Arguments) { + ( + "stbx", + [ + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_stfdux(ins: &Ins) -> (&'static str, Arguments) { + ( + "stfdux", + [ + Argument::FPR(FPR(ins.field_frs() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_stfdx(ins: &Ins) -> (&'static str, Arguments) { + ( + "stfdx", + [ + Argument::FPR(FPR(ins.field_frs() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_stfiwx(ins: &Ins) -> (&'static str, Arguments) { + ( + "stfiwx", + [ + Argument::FPR(FPR(ins.field_frs() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_stfsux(ins: &Ins) -> (&'static str, Arguments) { + ( + "stfsux", + [ + Argument::FPR(FPR(ins.field_frs() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_stfsx(ins: &Ins) -> (&'static str, Arguments) { + ( + "stfsx", + [ + Argument::FPR(FPR(ins.field_frs() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_sthbrx(ins: &Ins) -> (&'static str, Arguments) { + ( + "sthbrx", + [ + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_sthux(ins: &Ins) -> (&'static str, Arguments) { + ( + "sthux", + [ + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_sthx(ins: &Ins) -> (&'static str, Arguments) { + ( + "sthx", + [ + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_stswi(ins: &Ins) -> (&'static str, Arguments) { + ( + "stswi", + [ + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::OpaqueU(OpaqueU(ins.field_nb() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_stswx(ins: &Ins) -> (&'static str, Arguments) { + ( + "stswx", + [ + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_stwbrx(ins: &Ins) -> (&'static str, Arguments) { + ( + "stwbrx", + [ + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_stwcx_(ins: &Ins) -> (&'static str, Arguments) { + ( + "stwcx.", + [ + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_stwux(ins: &Ins) -> (&'static str, Arguments) { + ( + "stwux", + [ + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_stwx(ins: &Ins) -> (&'static str, Arguments) { + ( + "stwx", + [ + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_subf(ins: &Ins) -> (&'static str, Arguments) { + ( + [ + "subf", + "subfo", + "subf.", + "subfo.", + ][ins.field_oe() as usize | (ins.field_rc() as usize) << 1], + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_subfc(ins: &Ins) -> (&'static str, Arguments) { + ( + [ + "subfc", + "subfco", + "subfc.", + "subfco.", + ][ins.field_oe() as usize | (ins.field_rc() as usize) << 1], + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_subfe(ins: &Ins) -> (&'static str, Arguments) { + ( + [ + "subfe", + "subfeo", + "subfe.", + "subfeo.", + ][ins.field_oe() as usize | (ins.field_rc() as usize) << 1], + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_subfme(ins: &Ins) -> (&'static str, Arguments) { + ( + [ + "subfme", + "subfmeo", + "subfme.", + "subfmeo.", + ][ins.field_oe() as usize | (ins.field_rc() as usize) << 1], + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ) +} +const fn base_subfze(ins: &Ins) -> (&'static str, Arguments) { + ( + [ + "subfze", + "subfzeo", + "subfze.", + "subfzeo.", + ][ins.field_oe() as usize | (ins.field_rc() as usize) << 1], + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ) +} +const fn base_sync(ins: &Ins) -> (&'static str, Arguments) { + ( + "sync", + [Argument::None, Argument::None, Argument::None, Argument::None, Argument::None], + ) +} +const fn base_tlbie(ins: &Ins) -> (&'static str, Arguments) { + ( + "tlbie", + [ + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ) +} +const fn base_tlbsync(ins: &Ins) -> (&'static str, Arguments) { + ( + "tlbsync", + [Argument::None, Argument::None, Argument::None, Argument::None, Argument::None], + ) +} +#[inline(always)] +const fn base_tw(ins: &Ins) -> (&'static str, Arguments) { + ( + "tw", + [ + Argument::OpaqueU(OpaqueU(ins.field_to() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn simplified_tw(ins: &Ins) -> (&'static str, Arguments) { + if ins.field_to() == 0x4 { + return ( + "tweq", + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if ins.field_to() == 0x5 { + return ( + "twlge", + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + if ins.field_to() == 0x1f && ins.field_ra() == 0x0 && ins.field_rb() == 0x0 { + return ( + "trap", + [ + Argument::None, + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ); + } + base_tw(ins) +} +const fn base_xor(ins: &Ins) -> (&'static str, Arguments) { + ( + ["xor", "xor."][ins.field_rc() as usize], + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_lwz(ins: &Ins) -> (&'static str, Arguments) { + ( + "lwz", + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::Offset(Offset(ins.field_offset() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_lwzu(ins: &Ins) -> (&'static str, Arguments) { + ( + "lwzu", + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::Offset(Offset(ins.field_offset() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_lbz(ins: &Ins) -> (&'static str, Arguments) { + ( + "lbz", + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::Offset(Offset(ins.field_offset() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_lbzu(ins: &Ins) -> (&'static str, Arguments) { + ( + "lbzu", + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::Offset(Offset(ins.field_offset() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_stw(ins: &Ins) -> (&'static str, Arguments) { + ( + "stw", + [ + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::Offset(Offset(ins.field_offset() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_stwu(ins: &Ins) -> (&'static str, Arguments) { + ( + "stwu", + [ + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::Offset(Offset(ins.field_offset() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_stb(ins: &Ins) -> (&'static str, Arguments) { + ( + "stb", + [ + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::Offset(Offset(ins.field_offset() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_stbu(ins: &Ins) -> (&'static str, Arguments) { + ( + "stbu", + [ + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::Offset(Offset(ins.field_offset() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_lhz(ins: &Ins) -> (&'static str, Arguments) { + ( + "lhz", + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::Offset(Offset(ins.field_offset() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_lhzu(ins: &Ins) -> (&'static str, Arguments) { + ( + "lhzu", + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::Offset(Offset(ins.field_offset() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_lha(ins: &Ins) -> (&'static str, Arguments) { + ( + "lha", + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::Offset(Offset(ins.field_offset() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_lhau(ins: &Ins) -> (&'static str, Arguments) { + ( + "lhau", + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::Offset(Offset(ins.field_offset() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_sth(ins: &Ins) -> (&'static str, Arguments) { + ( + "sth", + [ + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::Offset(Offset(ins.field_offset() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_sthu(ins: &Ins) -> (&'static str, Arguments) { + ( + "sthu", + [ + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::Offset(Offset(ins.field_offset() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_lmw(ins: &Ins) -> (&'static str, Arguments) { + ( + "lmw", + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::Offset(Offset(ins.field_offset() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_stmw(ins: &Ins) -> (&'static str, Arguments) { + ( + "stmw", + [ + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::Offset(Offset(ins.field_offset() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_lfs(ins: &Ins) -> (&'static str, Arguments) { + ( + "lfs", + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::Offset(Offset(ins.field_offset() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_lfsu(ins: &Ins) -> (&'static str, Arguments) { + ( + "lfsu", + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::Offset(Offset(ins.field_offset() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_lfd(ins: &Ins) -> (&'static str, Arguments) { + ( + "lfd", + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::Offset(Offset(ins.field_offset() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_lfdu(ins: &Ins) -> (&'static str, Arguments) { + ( + "lfdu", + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::Offset(Offset(ins.field_offset() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_stfs(ins: &Ins) -> (&'static str, Arguments) { + ( + "stfs", + [ + Argument::FPR(FPR(ins.field_frs() as _)), + Argument::Offset(Offset(ins.field_offset() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_stfsu(ins: &Ins) -> (&'static str, Arguments) { + ( + "stfsu", + [ + Argument::FPR(FPR(ins.field_frs() as _)), + Argument::Offset(Offset(ins.field_offset() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_stfd(ins: &Ins) -> (&'static str, Arguments) { + ( + "stfd", + [ + Argument::FPR(FPR(ins.field_frs() as _)), + Argument::Offset(Offset(ins.field_offset() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_stfdu(ins: &Ins) -> (&'static str, Arguments) { + ( + "stfdu", + [ + Argument::FPR(FPR(ins.field_frs() as _)), + Argument::Offset(Offset(ins.field_offset() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_psq_l(ins: &Ins) -> (&'static str, Arguments) { + ( + "psq_l", + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::Offset(Offset(ins.field_ps_offset() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::OpaqueU(OpaqueU(ins.field_ps_w() as _)), + Argument::GQR(GQR(ins.field_ps_i() as _)), + ], + ) +} +const fn base_psq_lu(ins: &Ins) -> (&'static str, Arguments) { + ( + "psq_lu", + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::Offset(Offset(ins.field_ps_offset() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::OpaqueU(OpaqueU(ins.field_ps_w() as _)), + Argument::GQR(GQR(ins.field_ps_i() as _)), + ], + ) +} +const fn base_fadds(ins: &Ins) -> (&'static str, Arguments) { + ( + ["fadds", "fadds."][ins.field_rc() as usize], + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::FPR(FPR(ins.field_fra() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_fdivs(ins: &Ins) -> (&'static str, Arguments) { + ( + ["fdivs", "fdivs."][ins.field_rc() as usize], + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::FPR(FPR(ins.field_fra() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_fmadds(ins: &Ins) -> (&'static str, Arguments) { + ( + ["fmadds", "fmadds."][ins.field_rc() as usize], + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::FPR(FPR(ins.field_fra() as _)), + Argument::FPR(FPR(ins.field_frc() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + ], + ) +} +const fn base_fmsubs(ins: &Ins) -> (&'static str, Arguments) { + ( + ["fmsubs", "fmsubs."][ins.field_rc() as usize], + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::FPR(FPR(ins.field_fra() as _)), + Argument::FPR(FPR(ins.field_frc() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + ], + ) +} +const fn base_fmuls(ins: &Ins) -> (&'static str, Arguments) { + ( + ["fmuls", "fmuls."][ins.field_rc() as usize], + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::FPR(FPR(ins.field_fra() as _)), + Argument::FPR(FPR(ins.field_frc() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_fnmadds(ins: &Ins) -> (&'static str, Arguments) { + ( + ["fnmadds", "fnmadds."][ins.field_rc() as usize], + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::FPR(FPR(ins.field_fra() as _)), + Argument::FPR(FPR(ins.field_frc() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + ], + ) +} +const fn base_fnmsubs(ins: &Ins) -> (&'static str, Arguments) { + ( + ["fnmsubs", "fnmsubs."][ins.field_rc() as usize], + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::FPR(FPR(ins.field_fra() as _)), + Argument::FPR(FPR(ins.field_frc() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + ], + ) +} +const fn base_fres(ins: &Ins) -> (&'static str, Arguments) { + ( + ["fres", "fres."][ins.field_rc() as usize], + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ) +} +const fn base_fsubs(ins: &Ins) -> (&'static str, Arguments) { + ( + ["fsubs", "fsubs."][ins.field_rc() as usize], + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::FPR(FPR(ins.field_fra() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_psq_st(ins: &Ins) -> (&'static str, Arguments) { + ( + "psq_st", + [ + Argument::FPR(FPR(ins.field_frs() as _)), + Argument::Offset(Offset(ins.field_ps_offset() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::OpaqueU(OpaqueU(ins.field_ps_w() as _)), + Argument::GQR(GQR(ins.field_ps_i() as _)), + ], + ) +} +const fn base_psq_stu(ins: &Ins) -> (&'static str, Arguments) { + ( + "psq_stu", + [ + Argument::FPR(FPR(ins.field_frs() as _)), + Argument::Offset(Offset(ins.field_ps_offset() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::OpaqueU(OpaqueU(ins.field_ps_w() as _)), + Argument::GQR(GQR(ins.field_ps_i() as _)), + ], + ) +} +const fn base_fabs(ins: &Ins) -> (&'static str, Arguments) { + ( + ["fabs", "fabs."][ins.field_rc() as usize], + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ) +} +const fn base_fadd(ins: &Ins) -> (&'static str, Arguments) { + ( + ["fadd", "fadd."][ins.field_rc() as usize], + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::FPR(FPR(ins.field_fra() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_fcmpo(ins: &Ins) -> (&'static str, Arguments) { + ( + "fcmpo", + [ + Argument::CRField(CRField(ins.field_crfd() as _)), + Argument::FPR(FPR(ins.field_fra() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_fcmpu(ins: &Ins) -> (&'static str, Arguments) { + ( + "fcmpu", + [ + Argument::CRField(CRField(ins.field_crfd() as _)), + Argument::FPR(FPR(ins.field_fra() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_fctiw(ins: &Ins) -> (&'static str, Arguments) { + ( + ["fctiw", "fctiw."][ins.field_rc() as usize], + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ) +} +const fn base_fctiwz(ins: &Ins) -> (&'static str, Arguments) { + ( + ["fctiwz", "fctiwz."][ins.field_rc() as usize], + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ) +} +const fn base_fdiv(ins: &Ins) -> (&'static str, Arguments) { + ( + ["fdiv", "fdiv."][ins.field_rc() as usize], + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::FPR(FPR(ins.field_fra() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_fmadd(ins: &Ins) -> (&'static str, Arguments) { + ( + ["fmadd", "fmadd."][ins.field_rc() as usize], + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::FPR(FPR(ins.field_fra() as _)), + Argument::FPR(FPR(ins.field_frc() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + ], + ) +} +const fn base_fmr(ins: &Ins) -> (&'static str, Arguments) { + ( + ["fmr", "fmr."][ins.field_rc() as usize], + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ) +} +const fn base_fmsub(ins: &Ins) -> (&'static str, Arguments) { + ( + ["fmsub", "fmsub."][ins.field_rc() as usize], + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::FPR(FPR(ins.field_fra() as _)), + Argument::FPR(FPR(ins.field_frc() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + ], + ) +} +const fn base_fmul(ins: &Ins) -> (&'static str, Arguments) { + ( + ["fmul", "fmul."][ins.field_rc() as usize], + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::FPR(FPR(ins.field_fra() as _)), + Argument::FPR(FPR(ins.field_frc() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_fnabs(ins: &Ins) -> (&'static str, Arguments) { + ( + ["fnabs", "fnabs."][ins.field_rc() as usize], + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ) +} +const fn base_fneg(ins: &Ins) -> (&'static str, Arguments) { + ( + ["fneg", "fneg."][ins.field_rc() as usize], + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ) +} +const fn base_fnmadd(ins: &Ins) -> (&'static str, Arguments) { + ( + ["fnmadd", "fnmadd."][ins.field_rc() as usize], + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::FPR(FPR(ins.field_fra() as _)), + Argument::FPR(FPR(ins.field_frc() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + ], + ) +} +const fn base_fnmsub(ins: &Ins) -> (&'static str, Arguments) { + ( + ["fnmsub", "fnmsub."][ins.field_rc() as usize], + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::FPR(FPR(ins.field_fra() as _)), + Argument::FPR(FPR(ins.field_frc() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + ], + ) +} +const fn base_frsp(ins: &Ins) -> (&'static str, Arguments) { + ( + ["frsp", "frsp."][ins.field_rc() as usize], + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ) +} +const fn base_frsqrte(ins: &Ins) -> (&'static str, Arguments) { + ( + ["frsqrte", "frsqrte."][ins.field_rc() as usize], + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ) +} +const fn base_fsel(ins: &Ins) -> (&'static str, Arguments) { + ( + ["fsel", "fsel."][ins.field_rc() as usize], + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::FPR(FPR(ins.field_fra() as _)), + Argument::FPR(FPR(ins.field_frc() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + ], + ) +} +const fn base_fsub(ins: &Ins) -> (&'static str, Arguments) { + ( + ["fsub", "fsub."][ins.field_rc() as usize], + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::FPR(FPR(ins.field_fra() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + ], + ) +} +const fn base_mcrfs(ins: &Ins) -> (&'static str, Arguments) { + ( + "mcrfs", + [ + Argument::CRField(CRField(ins.field_crfd() as _)), + Argument::CRField(CRField(ins.field_crfs() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ) +} +const fn base_mffs(ins: &Ins) -> (&'static str, Arguments) { + ( + ["mffs", "mffs."][ins.field_rc() as usize], + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ) +} +const fn base_mtfsb0(ins: &Ins) -> (&'static str, Arguments) { + ( + ["mtfsb0", "mtfsb0."][ins.field_rc() as usize], + [ + Argument::CRBit(CRBit(ins.field_crbd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ) +} +const fn base_mtfsb1(ins: &Ins) -> (&'static str, Arguments) { + ( + ["mtfsb1", "mtfsb1."][ins.field_rc() as usize], + [ + Argument::CRBit(CRBit(ins.field_crbd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ], + ) +} +const fn base_mtfsf(ins: &Ins) -> (&'static str, Arguments) { + ( + ["mtfsf", "mtfsf."][ins.field_rc() as usize], + [ + Argument::OpaqueU(OpaqueU(ins.field_mtfsf_fm() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ) +} +const fn base_mtfsfi(ins: &Ins) -> (&'static str, Arguments) { + ( + ["mtfsfi", "mtfsfi."][ins.field_rc() as usize], + [ + Argument::CRField(CRField(ins.field_crfd() as _)), + Argument::OpaqueU(OpaqueU(ins.field_mtfsf_imm() as _)), + Argument::None, + Argument::None, + Argument::None, + ], + ) +} +const fn mnemonic_illegal(_ins: &Ins) -> (&'static str, Arguments) { + ( + "", + [Argument::None, Argument::None, Argument::None, Argument::None, Argument::None], + ) +} +pub const BASE_MNEMONICS: [MnemonicFunction; 256] = [ + base_twi, + base_dcbz_l, + base_psq_lux, + base_psq_lx, + base_psq_stux, + base_psq_stx, + base_ps_abs, + base_ps_add, + base_ps_cmpo0, + base_ps_cmpo1, + base_ps_cmpu0, + base_ps_cmpu1, + base_ps_div, + base_ps_madd, + base_ps_madds0, + base_ps_madds1, + base_ps_merge00, + base_ps_merge01, + base_ps_merge10, + base_ps_merge11, + base_ps_mr, + base_ps_msub, + base_ps_mul, + base_ps_muls0, + base_ps_muls1, + base_ps_nabs, + base_ps_neg, + base_ps_nmadd, + base_ps_nmsub, + base_ps_res, + base_ps_rsqrte, + base_ps_sel, + base_ps_sub, + base_ps_sum0, + base_ps_sum1, + base_mulli, + base_subfic, + base_cmpli, + base_cmpi, + base_addic, + base_addic_, + base_addi, + base_addis, + base_bc, + base_sc, + base_b, + base_bcctr, + base_bclr, + base_crand, + base_crandc, + base_creqv, + base_crnand, + base_crnor, + base_cror, + base_crorc, + base_crxor, + base_isync, + base_mcrf, + base_rfi, + base_rlwimi, + base_rlwinm, + base_rlwnm, + base_ori, + base_oris, + base_xori, + base_xoris, + base_andi_, + base_andis_, + base_add, + base_addc, + base_adde, + base_addme, + base_addze, + base_and, + base_andc, + base_cmp, + base_cmpl, + base_cntlzw, + base_dcbf, + base_dcbi, + base_dcbst, + base_dcbt, + base_dcbtst, + base_dcbz, + base_divw, + base_divwu, + base_eciwx, + base_ecowx, + base_eieio, + base_eqv, + base_extsb, + base_extsh, + base_icbi, + base_lbzux, + base_lbzx, + base_lfdux, + base_lfdx, + base_lfsux, + base_lfsx, + base_lhaux, + base_lhax, + base_lhbrx, + base_lhzux, + base_lhzx, + base_lswi, + base_lswx, + base_lwarx, + base_lwbrx, + base_lwzux, + base_lwzx, + base_mcrxr, + base_mfcr, + base_mfmsr, + base_mfspr, + base_mfsr, + base_mfsrin, + base_mftb, + base_mtcrf, + base_mtmsr, + base_mtspr, + base_mtsr, + base_mtsrin, + base_mulhw, + base_mulhwu, + base_mullw, + base_nand, + base_neg, + base_nor, + base_or, + base_orc, + base_slw, + base_sraw, + base_srawi, + base_srw, + base_stbux, + base_stbx, + base_stfdux, + base_stfdx, + base_stfiwx, + base_stfsux, + base_stfsx, + base_sthbrx, + base_sthux, + base_sthx, + base_stswi, + base_stswx, + base_stwbrx, + base_stwcx_, + base_stwux, + base_stwx, + base_subf, + base_subfc, + base_subfe, + base_subfme, + base_subfze, + base_sync, + base_tlbie, + base_tlbsync, + base_tw, + base_xor, + base_lwz, + base_lwzu, + base_lbz, + base_lbzu, + base_stw, + base_stwu, + base_stb, + base_stbu, + base_lhz, + base_lhzu, + base_lha, + base_lhau, + base_sth, + base_sthu, + base_lmw, + base_stmw, + base_lfs, + base_lfsu, + base_lfd, + base_lfdu, + base_stfs, + base_stfsu, + base_stfd, + base_stfdu, + base_psq_l, + base_psq_lu, + base_fadds, + base_fdivs, + base_fmadds, + base_fmsubs, + base_fmuls, + base_fnmadds, + base_fnmsubs, + base_fres, + base_fsubs, + base_psq_st, + base_psq_stu, + base_fabs, + base_fadd, + base_fcmpo, + base_fcmpu, + base_fctiw, + base_fctiwz, + base_fdiv, + base_fmadd, + base_fmr, + base_fmsub, + base_fmul, + base_fnabs, + base_fneg, + base_fnmadd, + base_fnmsub, + base_frsp, + base_frsqrte, + base_fsel, + base_fsub, + base_mcrfs, + base_mffs, + base_mtfsb0, + base_mtfsb1, + base_mtfsf, + base_mtfsfi, + mnemonic_illegal, + mnemonic_illegal, + mnemonic_illegal, + mnemonic_illegal, + mnemonic_illegal, + mnemonic_illegal, + mnemonic_illegal, + mnemonic_illegal, + mnemonic_illegal, + mnemonic_illegal, + mnemonic_illegal, + mnemonic_illegal, + mnemonic_illegal, + mnemonic_illegal, + mnemonic_illegal, + mnemonic_illegal, + mnemonic_illegal, + mnemonic_illegal, + mnemonic_illegal, + mnemonic_illegal, + mnemonic_illegal, + mnemonic_illegal, + mnemonic_illegal, + mnemonic_illegal, + mnemonic_illegal, + mnemonic_illegal, + mnemonic_illegal, + mnemonic_illegal, + mnemonic_illegal, + mnemonic_illegal, + mnemonic_illegal, + mnemonic_illegal, + mnemonic_illegal, + mnemonic_illegal, +]; +pub const SIMPLIFIED_MNEMONICS: [MnemonicFunction; 256] = [ + simplified_twi, + base_dcbz_l, + base_psq_lux, + base_psq_lx, + base_psq_stux, + base_psq_stx, + base_ps_abs, + base_ps_add, + base_ps_cmpo0, + base_ps_cmpo1, + base_ps_cmpu0, + base_ps_cmpu1, + base_ps_div, + base_ps_madd, + base_ps_madds0, + base_ps_madds1, + base_ps_merge00, + base_ps_merge01, + base_ps_merge10, + base_ps_merge11, + base_ps_mr, + base_ps_msub, + base_ps_mul, + base_ps_muls0, + base_ps_muls1, + base_ps_nabs, + base_ps_neg, + base_ps_nmadd, + base_ps_nmsub, + base_ps_res, + base_ps_rsqrte, + base_ps_sel, + base_ps_sub, + base_ps_sum0, + base_ps_sum1, + base_mulli, + base_subfic, + simplified_cmpli, + simplified_cmpi, + simplified_addic, + simplified_addic_, + simplified_addi, + simplified_addis, + simplified_bc, + base_sc, + base_b, + simplified_bcctr, + simplified_bclr, + base_crand, + base_crandc, + simplified_creqv, + base_crnand, + simplified_crnor, + simplified_cror, + base_crorc, + simplified_crxor, + base_isync, + base_mcrf, + base_rfi, + base_rlwimi, + simplified_rlwinm, + simplified_rlwnm, + simplified_ori, + base_oris, + base_xori, + base_xoris, + base_andi_, + base_andis_, + base_add, + base_addc, + base_adde, + base_addme, + base_addze, + base_and, + base_andc, + simplified_cmp, + simplified_cmpl, + base_cntlzw, + base_dcbf, + base_dcbi, + base_dcbst, + base_dcbt, + base_dcbtst, + base_dcbz, + base_divw, + base_divwu, + base_eciwx, + base_ecowx, + base_eieio, + base_eqv, + base_extsb, + base_extsh, + base_icbi, + base_lbzux, + base_lbzx, + base_lfdux, + base_lfdx, + base_lfsux, + base_lfsx, + base_lhaux, + base_lhax, + base_lhbrx, + base_lhzux, + base_lhzx, + base_lswi, + base_lswx, + base_lwarx, + base_lwbrx, + base_lwzux, + base_lwzx, + base_mcrxr, + base_mfcr, + base_mfmsr, + simplified_mfspr, + base_mfsr, + base_mfsrin, + base_mftb, + base_mtcrf, + base_mtmsr, + simplified_mtspr, + base_mtsr, + base_mtsrin, + base_mulhw, + base_mulhwu, + base_mullw, + base_nand, + base_neg, + base_nor, + simplified_or, + base_orc, + base_slw, + base_sraw, + base_srawi, + base_srw, + base_stbux, + base_stbx, + base_stfdux, + base_stfdx, + base_stfiwx, + base_stfsux, + base_stfsx, + base_sthbrx, + base_sthux, + base_sthx, + base_stswi, + base_stswx, + base_stwbrx, + base_stwcx_, + base_stwux, + base_stwx, + base_subf, + base_subfc, + base_subfe, + base_subfme, + base_subfze, + base_sync, + base_tlbie, + base_tlbsync, + simplified_tw, + base_xor, + base_lwz, + base_lwzu, + base_lbz, + base_lbzu, + base_stw, + base_stwu, + base_stb, + base_stbu, + base_lhz, + base_lhzu, + base_lha, + base_lhau, + base_sth, + base_sthu, + base_lmw, + base_stmw, + base_lfs, + base_lfsu, + base_lfd, + base_lfdu, + base_stfs, + base_stfsu, + base_stfd, + base_stfdu, + base_psq_l, + base_psq_lu, + base_fadds, + base_fdivs, + base_fmadds, + base_fmsubs, + base_fmuls, + base_fnmadds, + base_fnmsubs, + base_fres, + base_fsubs, + base_psq_st, + base_psq_stu, + base_fabs, + base_fadd, + base_fcmpo, + base_fcmpu, + base_fctiw, + base_fctiwz, + base_fdiv, + base_fmadd, + base_fmr, + base_fmsub, + base_fmul, + base_fnabs, + base_fneg, + base_fnmadd, + base_fnmsub, + base_frsp, + base_frsqrte, + base_fsel, + base_fsub, + base_mcrfs, + base_mffs, + base_mtfsb0, + base_mtfsb1, + base_mtfsf, + base_mtfsfi, + mnemonic_illegal, + mnemonic_illegal, + mnemonic_illegal, + mnemonic_illegal, + mnemonic_illegal, + mnemonic_illegal, + mnemonic_illegal, + mnemonic_illegal, + mnemonic_illegal, + mnemonic_illegal, + mnemonic_illegal, + mnemonic_illegal, + mnemonic_illegal, + mnemonic_illegal, + mnemonic_illegal, + mnemonic_illegal, + mnemonic_illegal, + mnemonic_illegal, + mnemonic_illegal, + mnemonic_illegal, + mnemonic_illegal, + mnemonic_illegal, + mnemonic_illegal, + mnemonic_illegal, + mnemonic_illegal, + mnemonic_illegal, + mnemonic_illegal, + mnemonic_illegal, + mnemonic_illegal, + mnemonic_illegal, + mnemonic_illegal, + mnemonic_illegal, + mnemonic_illegal, + mnemonic_illegal, +]; +const fn defs_twi(ins: &Ins) -> Arguments { + [Argument::None, Argument::None, Argument::None, Argument::None, Argument::None] +} +const fn uses_twi(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_dcbz_l(ins: &Ins) -> Arguments { + [Argument::None, Argument::None, Argument::None, Argument::None, Argument::None] +} +const fn uses_dcbz_l(ins: &Ins) -> Arguments { + [ + if ins.field_ra() != 0 { + Argument::GPR(GPR(ins.field_ra() as _)) + } else { + Argument::None + }, + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_psq_lux(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_psq_lux(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_psq_lx(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_psq_lx(ins: &Ins) -> Arguments { + [ + if ins.field_ra() != 0 { + Argument::GPR(GPR(ins.field_ra() as _)) + } else { + Argument::None + }, + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_psq_stux(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_psq_stux(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frs() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + ] +} +const fn defs_psq_stx(ins: &Ins) -> Arguments { + [Argument::None, Argument::None, Argument::None, Argument::None, Argument::None] +} +const fn uses_psq_stx(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frs() as _)), + if ins.field_ra() != 0 { + Argument::GPR(GPR(ins.field_ra() as _)) + } else { + Argument::None + }, + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + ] +} +const fn defs_ps_abs(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_ps_abs(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_ps_add(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_ps_add(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_fra() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_ps_cmpo0(ins: &Ins) -> Arguments { + [ + Argument::CRField(CRField(ins.field_crfd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_ps_cmpo0(ins: &Ins) -> Arguments { + [ + if ins.field_fra() != 0 { + Argument::FPR(FPR(ins.field_fra() as _)) + } else { + Argument::None + }, + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_ps_cmpo1(ins: &Ins) -> Arguments { + [ + Argument::CRField(CRField(ins.field_crfd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_ps_cmpo1(ins: &Ins) -> Arguments { + [ + if ins.field_fra() != 0 { + Argument::FPR(FPR(ins.field_fra() as _)) + } else { + Argument::None + }, + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_ps_cmpu0(ins: &Ins) -> Arguments { + [ + Argument::CRField(CRField(ins.field_crfd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_ps_cmpu0(ins: &Ins) -> Arguments { + [ + if ins.field_fra() != 0 { + Argument::FPR(FPR(ins.field_fra() as _)) + } else { + Argument::None + }, + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_ps_cmpu1(ins: &Ins) -> Arguments { + [ + Argument::CRField(CRField(ins.field_crfd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_ps_cmpu1(ins: &Ins) -> Arguments { + [ + if ins.field_fra() != 0 { + Argument::FPR(FPR(ins.field_fra() as _)) + } else { + Argument::None + }, + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_ps_div(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_ps_div(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_fra() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_ps_madd(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_ps_madd(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_fra() as _)), + Argument::FPR(FPR(ins.field_frc() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + ] +} +const fn defs_ps_madds0(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_ps_madds0(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_fra() as _)), + Argument::FPR(FPR(ins.field_frc() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + ] +} +const fn defs_ps_madds1(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_ps_madds1(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_fra() as _)), + Argument::FPR(FPR(ins.field_frc() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + ] +} +const fn defs_ps_merge00(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_ps_merge00(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_fra() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_ps_merge01(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_ps_merge01(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_fra() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_ps_merge10(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_ps_merge10(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_fra() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_ps_merge11(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_ps_merge11(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_fra() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_ps_mr(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_ps_mr(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_ps_msub(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_ps_msub(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_fra() as _)), + Argument::FPR(FPR(ins.field_frc() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + ] +} +const fn defs_ps_mul(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_ps_mul(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_fra() as _)), + Argument::FPR(FPR(ins.field_frc() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_ps_muls0(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_ps_muls0(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_fra() as _)), + Argument::FPR(FPR(ins.field_frc() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_ps_muls1(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_ps_muls1(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_fra() as _)), + Argument::FPR(FPR(ins.field_frc() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_ps_nabs(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_ps_nabs(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_ps_neg(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_ps_neg(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_ps_nmadd(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_ps_nmadd(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_fra() as _)), + Argument::FPR(FPR(ins.field_frc() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + ] +} +const fn defs_ps_nmsub(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_ps_nmsub(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_fra() as _)), + Argument::FPR(FPR(ins.field_frc() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + ] +} +const fn defs_ps_res(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_ps_res(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_ps_rsqrte(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_ps_rsqrte(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_ps_sel(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_ps_sel(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_fra() as _)), + Argument::FPR(FPR(ins.field_frc() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + ] +} +const fn defs_ps_sub(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_ps_sub(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_fra() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_ps_sum0(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_ps_sum0(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_fra() as _)), + Argument::FPR(FPR(ins.field_frc() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + ] +} +const fn defs_ps_sum1(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_ps_sum1(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_fra() as _)), + Argument::FPR(FPR(ins.field_frc() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + ] +} +const fn defs_mulli(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_mulli(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_subfic(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_subfic(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_cmpli(ins: &Ins) -> Arguments { + [ + Argument::CRField(CRField(ins.field_crfd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_cmpli(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_cmpi(ins: &Ins) -> Arguments { + [ + Argument::CRField(CRField(ins.field_crfd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_cmpi(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_addic(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_addic(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_addic_(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_addic_(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_addi(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_addi(ins: &Ins) -> Arguments { + [ + if ins.field_ra() != 0 { + Argument::GPR(GPR(ins.field_ra() as _)) + } else { + Argument::None + }, + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_addis(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_addis(ins: &Ins) -> Arguments { + [ + if ins.field_ra() != 0 { + Argument::GPR(GPR(ins.field_ra() as _)) + } else { + Argument::None + }, + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_bc(ins: &Ins) -> Arguments { + [Argument::None, Argument::None, Argument::None, Argument::None, Argument::None] +} +const fn uses_bc(ins: &Ins) -> Arguments { + [Argument::None, Argument::None, Argument::None, Argument::None, Argument::None] +} +const fn defs_sc(ins: &Ins) -> Arguments { + [Argument::None, Argument::None, Argument::None, Argument::None, Argument::None] +} +const fn uses_sc(ins: &Ins) -> Arguments { + [Argument::None, Argument::None, Argument::None, Argument::None, Argument::None] +} +const fn defs_b(ins: &Ins) -> Arguments { + [Argument::None, Argument::None, Argument::None, Argument::None, Argument::None] +} +const fn uses_b(ins: &Ins) -> Arguments { + [Argument::None, Argument::None, Argument::None, Argument::None, Argument::None] +} +const fn defs_bcctr(ins: &Ins) -> Arguments { + [Argument::None, Argument::None, Argument::None, Argument::None, Argument::None] +} +const fn uses_bcctr(ins: &Ins) -> Arguments { + [Argument::None, Argument::None, Argument::None, Argument::None, Argument::None] +} +const fn defs_bclr(ins: &Ins) -> Arguments { + [Argument::None, Argument::None, Argument::None, Argument::None, Argument::None] +} +const fn uses_bclr(ins: &Ins) -> Arguments { + [Argument::None, Argument::None, Argument::None, Argument::None, Argument::None] +} +const fn defs_crand(ins: &Ins) -> Arguments { + [ + Argument::CRBit(CRBit(ins.field_crbd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_crand(ins: &Ins) -> Arguments { + [ + Argument::CRBit(CRBit(ins.field_crba() as _)), + Argument::CRBit(CRBit(ins.field_crbb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_crandc(ins: &Ins) -> Arguments { + [ + Argument::CRBit(CRBit(ins.field_crbd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_crandc(ins: &Ins) -> Arguments { + [ + Argument::CRBit(CRBit(ins.field_crba() as _)), + Argument::CRBit(CRBit(ins.field_crbb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_creqv(ins: &Ins) -> Arguments { + [ + Argument::CRBit(CRBit(ins.field_crbd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_creqv(ins: &Ins) -> Arguments { + [ + Argument::CRBit(CRBit(ins.field_crba() as _)), + Argument::CRBit(CRBit(ins.field_crbb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_crnand(ins: &Ins) -> Arguments { + [ + Argument::CRBit(CRBit(ins.field_crbd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_crnand(ins: &Ins) -> Arguments { + [ + Argument::CRBit(CRBit(ins.field_crba() as _)), + Argument::CRBit(CRBit(ins.field_crbb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_crnor(ins: &Ins) -> Arguments { + [ + Argument::CRBit(CRBit(ins.field_crbd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_crnor(ins: &Ins) -> Arguments { + [ + Argument::CRBit(CRBit(ins.field_crba() as _)), + Argument::CRBit(CRBit(ins.field_crbb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_cror(ins: &Ins) -> Arguments { + [ + Argument::CRBit(CRBit(ins.field_crbd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_cror(ins: &Ins) -> Arguments { + [ + Argument::CRBit(CRBit(ins.field_crba() as _)), + Argument::CRBit(CRBit(ins.field_crbb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_crorc(ins: &Ins) -> Arguments { + [ + Argument::CRBit(CRBit(ins.field_crbd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_crorc(ins: &Ins) -> Arguments { + [ + Argument::CRBit(CRBit(ins.field_crba() as _)), + Argument::CRBit(CRBit(ins.field_crbb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_crxor(ins: &Ins) -> Arguments { + [ + Argument::CRBit(CRBit(ins.field_crbd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_crxor(ins: &Ins) -> Arguments { + [ + Argument::CRBit(CRBit(ins.field_crba() as _)), + Argument::CRBit(CRBit(ins.field_crbb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_isync(ins: &Ins) -> Arguments { + [Argument::None, Argument::None, Argument::None, Argument::None, Argument::None] +} +const fn uses_isync(ins: &Ins) -> Arguments { + [Argument::None, Argument::None, Argument::None, Argument::None, Argument::None] +} +const fn defs_mcrf(ins: &Ins) -> Arguments { + [ + Argument::CRField(CRField(ins.field_crfd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_mcrf(ins: &Ins) -> Arguments { + [ + Argument::CRField(CRField(ins.field_crfs() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_rfi(ins: &Ins) -> Arguments { + [Argument::None, Argument::None, Argument::None, Argument::None, Argument::None] +} +const fn uses_rfi(ins: &Ins) -> Arguments { + [Argument::None, Argument::None, Argument::None, Argument::None, Argument::None] +} +const fn defs_rlwimi(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_rlwimi(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::OpaqueU(OpaqueU(ins.field_sh() as _)), + Argument::None, + Argument::None, + ] +} +const fn defs_rlwinm(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_rlwinm(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::OpaqueU(OpaqueU(ins.field_sh() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_rlwnm(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_rlwnm(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_ori(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_ori(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_oris(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_oris(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_xori(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_xori(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_xoris(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_xoris(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_andi_(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_andi_(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_andis_(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_andis_(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_add(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_add(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_addc(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_addc(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_adde(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_adde(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_addme(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_addme(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_addze(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_addze(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_and(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_and(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_andc(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_andc(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_cmp(ins: &Ins) -> Arguments { + [ + Argument::CRField(CRField(ins.field_crfd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_cmp(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_cmpl(ins: &Ins) -> Arguments { + [ + Argument::CRField(CRField(ins.field_crfd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_cmpl(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_cntlzw(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_cntlzw(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_dcbf(ins: &Ins) -> Arguments { + [Argument::None, Argument::None, Argument::None, Argument::None, Argument::None] +} +const fn uses_dcbf(ins: &Ins) -> Arguments { + [ + if ins.field_ra() != 0 { + Argument::GPR(GPR(ins.field_ra() as _)) + } else { + Argument::None + }, + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_dcbi(ins: &Ins) -> Arguments { + [Argument::None, Argument::None, Argument::None, Argument::None, Argument::None] +} +const fn uses_dcbi(ins: &Ins) -> Arguments { + [ + if ins.field_ra() != 0 { + Argument::GPR(GPR(ins.field_ra() as _)) + } else { + Argument::None + }, + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_dcbst(ins: &Ins) -> Arguments { + [Argument::None, Argument::None, Argument::None, Argument::None, Argument::None] +} +const fn uses_dcbst(ins: &Ins) -> Arguments { + [ + if ins.field_ra() != 0 { + Argument::GPR(GPR(ins.field_ra() as _)) + } else { + Argument::None + }, + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_dcbt(ins: &Ins) -> Arguments { + [Argument::None, Argument::None, Argument::None, Argument::None, Argument::None] +} +const fn uses_dcbt(ins: &Ins) -> Arguments { + [ + if ins.field_ra() != 0 { + Argument::GPR(GPR(ins.field_ra() as _)) + } else { + Argument::None + }, + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_dcbtst(ins: &Ins) -> Arguments { + [Argument::None, Argument::None, Argument::None, Argument::None, Argument::None] +} +const fn uses_dcbtst(ins: &Ins) -> Arguments { + [ + if ins.field_ra() != 0 { + Argument::GPR(GPR(ins.field_ra() as _)) + } else { + Argument::None + }, + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_dcbz(ins: &Ins) -> Arguments { + [Argument::None, Argument::None, Argument::None, Argument::None, Argument::None] +} +const fn uses_dcbz(ins: &Ins) -> Arguments { + [ + if ins.field_ra() != 0 { + Argument::GPR(GPR(ins.field_ra() as _)) + } else { + Argument::None + }, + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_divw(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_divw(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_divwu(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_divwu(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_eciwx(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_eciwx(ins: &Ins) -> Arguments { + [ + if ins.field_ra() != 0 { + Argument::GPR(GPR(ins.field_ra() as _)) + } else { + Argument::None + }, + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_ecowx(ins: &Ins) -> Arguments { + [Argument::None, Argument::None, Argument::None, Argument::None, Argument::None] +} +const fn uses_ecowx(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rs() as _)), + if ins.field_ra() != 0 { + Argument::GPR(GPR(ins.field_ra() as _)) + } else { + Argument::None + }, + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + ] +} +const fn defs_eieio(ins: &Ins) -> Arguments { + [Argument::None, Argument::None, Argument::None, Argument::None, Argument::None] +} +const fn uses_eieio(ins: &Ins) -> Arguments { + [Argument::None, Argument::None, Argument::None, Argument::None, Argument::None] +} +const fn defs_eqv(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_eqv(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_extsb(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_extsb(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_extsh(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_extsh(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_icbi(ins: &Ins) -> Arguments { + [Argument::None, Argument::None, Argument::None, Argument::None, Argument::None] +} +const fn uses_icbi(ins: &Ins) -> Arguments { + [ + if ins.field_ra() != 0 { + Argument::GPR(GPR(ins.field_ra() as _)) + } else { + Argument::None + }, + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_lbzux(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_lbzux(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_lbzx(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_lbzx(ins: &Ins) -> Arguments { + [ + if ins.field_ra() != 0 { + Argument::GPR(GPR(ins.field_ra() as _)) + } else { + Argument::None + }, + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_lfdux(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_lfdux(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_lfdx(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_lfdx(ins: &Ins) -> Arguments { + [ + if ins.field_ra() != 0 { + Argument::GPR(GPR(ins.field_ra() as _)) + } else { + Argument::None + }, + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_lfsux(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_lfsux(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_lfsx(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_lfsx(ins: &Ins) -> Arguments { + [ + if ins.field_ra() != 0 { + Argument::GPR(GPR(ins.field_ra() as _)) + } else { + Argument::None + }, + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_lhaux(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_lhaux(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_lhax(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_lhax(ins: &Ins) -> Arguments { + [ + if ins.field_ra() != 0 { + Argument::GPR(GPR(ins.field_ra() as _)) + } else { + Argument::None + }, + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_lhbrx(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_lhbrx(ins: &Ins) -> Arguments { + [ + if ins.field_ra() != 0 { + Argument::GPR(GPR(ins.field_ra() as _)) + } else { + Argument::None + }, + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_lhzux(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_lhzux(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_lhzx(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_lhzx(ins: &Ins) -> Arguments { + [ + if ins.field_ra() != 0 { + Argument::GPR(GPR(ins.field_ra() as _)) + } else { + Argument::None + }, + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_lswi(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_lswi(ins: &Ins) -> Arguments { + [ + if ins.field_ra() != 0 { + Argument::GPR(GPR(ins.field_ra() as _)) + } else { + Argument::None + }, + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_lswx(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_lswx(ins: &Ins) -> Arguments { + [ + if ins.field_ra() != 0 { + Argument::GPR(GPR(ins.field_ra() as _)) + } else { + Argument::None + }, + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_lwarx(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_lwarx(ins: &Ins) -> Arguments { + [ + if ins.field_ra() != 0 { + Argument::GPR(GPR(ins.field_ra() as _)) + } else { + Argument::None + }, + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_lwbrx(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_lwbrx(ins: &Ins) -> Arguments { + [ + if ins.field_ra() != 0 { + Argument::GPR(GPR(ins.field_ra() as _)) + } else { + Argument::None + }, + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_lwzux(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_lwzux(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_lwzx(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_lwzx(ins: &Ins) -> Arguments { + [ + if ins.field_ra() != 0 { + Argument::GPR(GPR(ins.field_ra() as _)) + } else { + Argument::None + }, + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_mcrxr(ins: &Ins) -> Arguments { + [ + Argument::CRField(CRField(ins.field_crfd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_mcrxr(ins: &Ins) -> Arguments { + [Argument::None, Argument::None, Argument::None, Argument::None, Argument::None] +} +const fn defs_mfcr(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_mfcr(ins: &Ins) -> Arguments { + [Argument::None, Argument::None, Argument::None, Argument::None, Argument::None] +} +const fn defs_mfmsr(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_mfmsr(ins: &Ins) -> Arguments { + [Argument::None, Argument::None, Argument::None, Argument::None, Argument::None] +} +const fn defs_mfspr(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_mfspr(ins: &Ins) -> Arguments { + [Argument::None, Argument::None, Argument::None, Argument::None, Argument::None] +} +const fn defs_mfsr(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_mfsr(ins: &Ins) -> Arguments { + [Argument::None, Argument::None, Argument::None, Argument::None, Argument::None] +} +const fn defs_mfsrin(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_mfsrin(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_mftb(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_mftb(ins: &Ins) -> Arguments { + [Argument::None, Argument::None, Argument::None, Argument::None, Argument::None] +} +const fn defs_mtcrf(ins: &Ins) -> Arguments { + [Argument::None, Argument::None, Argument::None, Argument::None, Argument::None] +} +const fn uses_mtcrf(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_mtmsr(ins: &Ins) -> Arguments { + [Argument::None, Argument::None, Argument::None, Argument::None, Argument::None] +} +const fn uses_mtmsr(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_mtspr(ins: &Ins) -> Arguments { + [Argument::None, Argument::None, Argument::None, Argument::None, Argument::None] +} +const fn uses_mtspr(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_mtsr(ins: &Ins) -> Arguments { + [Argument::None, Argument::None, Argument::None, Argument::None, Argument::None] +} +const fn uses_mtsr(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_mtsrin(ins: &Ins) -> Arguments { + [Argument::None, Argument::None, Argument::None, Argument::None, Argument::None] +} +const fn uses_mtsrin(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_mulhw(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_mulhw(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_mulhwu(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_mulhwu(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_mullw(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_mullw(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_nand(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_nand(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_neg(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_neg(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_nor(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_nor(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_or(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_or(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_orc(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_orc(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_slw(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_slw(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_sraw(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_sraw(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_srawi(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_srawi(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_srw(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_srw(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_stbux(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_stbux(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + ] +} +const fn defs_stbx(ins: &Ins) -> Arguments { + [Argument::None, Argument::None, Argument::None, Argument::None, Argument::None] +} +const fn uses_stbx(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rs() as _)), + if ins.field_ra() != 0 { + Argument::GPR(GPR(ins.field_ra() as _)) + } else { + Argument::None + }, + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + ] +} +const fn defs_stfdux(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_stfdux(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frs() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + ] +} +const fn defs_stfdx(ins: &Ins) -> Arguments { + [Argument::None, Argument::None, Argument::None, Argument::None, Argument::None] +} +const fn uses_stfdx(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frs() as _)), + if ins.field_ra() != 0 { + Argument::GPR(GPR(ins.field_ra() as _)) + } else { + Argument::None + }, + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + ] +} +const fn defs_stfiwx(ins: &Ins) -> Arguments { + [Argument::None, Argument::None, Argument::None, Argument::None, Argument::None] +} +const fn uses_stfiwx(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frs() as _)), + if ins.field_ra() != 0 { + Argument::GPR(GPR(ins.field_ra() as _)) + } else { + Argument::None + }, + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + ] +} +const fn defs_stfsux(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_stfsux(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frs() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + ] +} +const fn defs_stfsx(ins: &Ins) -> Arguments { + [Argument::None, Argument::None, Argument::None, Argument::None, Argument::None] +} +const fn uses_stfsx(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frs() as _)), + if ins.field_ra() != 0 { + Argument::GPR(GPR(ins.field_ra() as _)) + } else { + Argument::None + }, + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + ] +} +const fn defs_sthbrx(ins: &Ins) -> Arguments { + [Argument::None, Argument::None, Argument::None, Argument::None, Argument::None] +} +const fn uses_sthbrx(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rs() as _)), + if ins.field_ra() != 0 { + Argument::GPR(GPR(ins.field_ra() as _)) + } else { + Argument::None + }, + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + ] +} +const fn defs_sthux(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_sthux(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + ] +} +const fn defs_sthx(ins: &Ins) -> Arguments { + [Argument::None, Argument::None, Argument::None, Argument::None, Argument::None] +} +const fn uses_sthx(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rs() as _)), + if ins.field_ra() != 0 { + Argument::GPR(GPR(ins.field_ra() as _)) + } else { + Argument::None + }, + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + ] +} +const fn defs_stswi(ins: &Ins) -> Arguments { + [Argument::None, Argument::None, Argument::None, Argument::None, Argument::None] +} +const fn uses_stswi(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rs() as _)), + if ins.field_ra() != 0 { + Argument::GPR(GPR(ins.field_ra() as _)) + } else { + Argument::None + }, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_stswx(ins: &Ins) -> Arguments { + [Argument::None, Argument::None, Argument::None, Argument::None, Argument::None] +} +const fn uses_stswx(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rs() as _)), + if ins.field_ra() != 0 { + Argument::GPR(GPR(ins.field_ra() as _)) + } else { + Argument::None + }, + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + ] +} +const fn defs_stwbrx(ins: &Ins) -> Arguments { + [Argument::None, Argument::None, Argument::None, Argument::None, Argument::None] +} +const fn uses_stwbrx(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rs() as _)), + if ins.field_ra() != 0 { + Argument::GPR(GPR(ins.field_ra() as _)) + } else { + Argument::None + }, + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + ] +} +const fn defs_stwcx_(ins: &Ins) -> Arguments { + [Argument::None, Argument::None, Argument::None, Argument::None, Argument::None] +} +const fn uses_stwcx_(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rs() as _)), + if ins.field_ra() != 0 { + Argument::GPR(GPR(ins.field_ra() as _)) + } else { + Argument::None + }, + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + ] +} +const fn defs_stwux(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_stwux(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + ] +} +const fn defs_stwx(ins: &Ins) -> Arguments { + [Argument::None, Argument::None, Argument::None, Argument::None, Argument::None] +} +const fn uses_stwx(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rs() as _)), + if ins.field_ra() != 0 { + Argument::GPR(GPR(ins.field_ra() as _)) + } else { + Argument::None + }, + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + ] +} +const fn defs_subf(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_subf(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_subfc(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_subfc(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_subfe(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_subfe(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_subfme(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_subfme(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_subfze(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_subfze(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_sync(ins: &Ins) -> Arguments { + [Argument::None, Argument::None, Argument::None, Argument::None, Argument::None] +} +const fn uses_sync(ins: &Ins) -> Arguments { + [Argument::None, Argument::None, Argument::None, Argument::None, Argument::None] +} +const fn defs_tlbie(ins: &Ins) -> Arguments { + [Argument::None, Argument::None, Argument::None, Argument::None, Argument::None] +} +const fn uses_tlbie(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_tlbsync(ins: &Ins) -> Arguments { + [Argument::None, Argument::None, Argument::None, Argument::None, Argument::None] +} +const fn uses_tlbsync(ins: &Ins) -> Arguments { + [Argument::None, Argument::None, Argument::None, Argument::None, Argument::None] +} +const fn defs_tw(ins: &Ins) -> Arguments { + [Argument::None, Argument::None, Argument::None, Argument::None, Argument::None] +} +const fn uses_tw(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_xor(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_xor(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::GPR(GPR(ins.field_rb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_lwz(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_lwz(ins: &Ins) -> Arguments { + [ + Argument::Offset(Offset(ins.field_offset() as _)), + if ins.field_ra() != 0 { + Argument::GPR(GPR(ins.field_ra() as _)) + } else { + Argument::None + }, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_lwzu(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_lwzu(ins: &Ins) -> Arguments { + [ + Argument::Offset(Offset(ins.field_offset() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_lbz(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_lbz(ins: &Ins) -> Arguments { + [ + Argument::Offset(Offset(ins.field_offset() as _)), + if ins.field_ra() != 0 { + Argument::GPR(GPR(ins.field_ra() as _)) + } else { + Argument::None + }, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_lbzu(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_lbzu(ins: &Ins) -> Arguments { + [ + Argument::Offset(Offset(ins.field_offset() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_stw(ins: &Ins) -> Arguments { + [Argument::None, Argument::None, Argument::None, Argument::None, Argument::None] +} +const fn uses_stw(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rs() as _)), + if ins.field_ra() != 0 { + Argument::GPR(GPR(ins.field_ra() as _)) + } else { + Argument::None + }, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_stwu(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_stwu(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_stb(ins: &Ins) -> Arguments { + [Argument::None, Argument::None, Argument::None, Argument::None, Argument::None] +} +const fn uses_stb(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rs() as _)), + if ins.field_ra() != 0 { + Argument::GPR(GPR(ins.field_ra() as _)) + } else { + Argument::None + }, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_stbu(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_stbu(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_lhz(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_lhz(ins: &Ins) -> Arguments { + [ + Argument::Offset(Offset(ins.field_offset() as _)), + if ins.field_ra() != 0 { + Argument::GPR(GPR(ins.field_ra() as _)) + } else { + Argument::None + }, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_lhzu(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_lhzu(ins: &Ins) -> Arguments { + [ + Argument::Offset(Offset(ins.field_offset() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_lha(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_lha(ins: &Ins) -> Arguments { + [ + Argument::Offset(Offset(ins.field_offset() as _)), + if ins.field_ra() != 0 { + Argument::GPR(GPR(ins.field_ra() as _)) + } else { + Argument::None + }, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_lhau(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_lhau(ins: &Ins) -> Arguments { + [ + Argument::Offset(Offset(ins.field_offset() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_sth(ins: &Ins) -> Arguments { + [Argument::None, Argument::None, Argument::None, Argument::None, Argument::None] +} +const fn uses_sth(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rs() as _)), + if ins.field_ra() != 0 { + Argument::GPR(GPR(ins.field_ra() as _)) + } else { + Argument::None + }, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_sthu(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_sthu(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rs() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_lmw(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_lmw(ins: &Ins) -> Arguments { + [ + Argument::Offset(Offset(ins.field_offset() as _)), + if ins.field_ra() != 0 { + Argument::GPR(GPR(ins.field_ra() as _)) + } else { + Argument::None + }, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_stmw(ins: &Ins) -> Arguments { + [Argument::None, Argument::None, Argument::None, Argument::None, Argument::None] +} +const fn uses_stmw(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_rs() as _)), + if ins.field_ra() != 0 { + Argument::GPR(GPR(ins.field_ra() as _)) + } else { + Argument::None + }, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_lfs(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_lfs(ins: &Ins) -> Arguments { + [ + Argument::Offset(Offset(ins.field_offset() as _)), + if ins.field_ra() != 0 { + Argument::GPR(GPR(ins.field_ra() as _)) + } else { + Argument::None + }, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_lfsu(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_lfsu(ins: &Ins) -> Arguments { + [ + Argument::Offset(Offset(ins.field_offset() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_lfd(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_lfd(ins: &Ins) -> Arguments { + [ + Argument::Offset(Offset(ins.field_offset() as _)), + if ins.field_ra() != 0 { + Argument::GPR(GPR(ins.field_ra() as _)) + } else { + Argument::None + }, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_lfdu(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_lfdu(ins: &Ins) -> Arguments { + [ + Argument::Offset(Offset(ins.field_offset() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_stfs(ins: &Ins) -> Arguments { + [Argument::None, Argument::None, Argument::None, Argument::None, Argument::None] +} +const fn uses_stfs(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frs() as _)), + if ins.field_ra() != 0 { + Argument::GPR(GPR(ins.field_ra() as _)) + } else { + Argument::None + }, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_stfsu(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_stfsu(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frs() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_stfd(ins: &Ins) -> Arguments { + [Argument::None, Argument::None, Argument::None, Argument::None, Argument::None] +} +const fn uses_stfd(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frs() as _)), + if ins.field_ra() != 0 { + Argument::GPR(GPR(ins.field_ra() as _)) + } else { + Argument::None + }, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_stfdu(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_stfdu(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frs() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_psq_l(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_psq_l(ins: &Ins) -> Arguments { + [ + if ins.field_ra() != 0 { + Argument::GPR(GPR(ins.field_ra() as _)) + } else { + Argument::None + }, + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_psq_lu(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_psq_lu(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_fadds(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_fadds(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_fra() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_fdivs(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_fdivs(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_fra() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_fmadds(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_fmadds(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_fra() as _)), + Argument::FPR(FPR(ins.field_frc() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + ] +} +const fn defs_fmsubs(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_fmsubs(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_fra() as _)), + Argument::FPR(FPR(ins.field_frc() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + ] +} +const fn defs_fmuls(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_fmuls(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_fra() as _)), + Argument::FPR(FPR(ins.field_frc() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_fnmadds(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_fnmadds(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_fra() as _)), + Argument::FPR(FPR(ins.field_frc() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + ] +} +const fn defs_fnmsubs(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_fnmsubs(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_fra() as _)), + Argument::FPR(FPR(ins.field_frc() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + ] +} +const fn defs_fres(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_fres(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_fsubs(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_fsubs(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_fra() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_psq_st(ins: &Ins) -> Arguments { + [Argument::None, Argument::None, Argument::None, Argument::None, Argument::None] +} +const fn uses_psq_st(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frs() as _)), + if ins.field_ra() != 0 { + Argument::GPR(GPR(ins.field_ra() as _)) + } else { + Argument::None + }, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_psq_stu(ins: &Ins) -> Arguments { + [ + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_psq_stu(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frs() as _)), + Argument::GPR(GPR(ins.field_ra() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_fabs(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_fabs(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_fadd(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_fadd(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_fra() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_fcmpo(ins: &Ins) -> Arguments { + [ + Argument::CRField(CRField(ins.field_crfd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_fcmpo(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_fra() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_fcmpu(ins: &Ins) -> Arguments { + [ + Argument::CRField(CRField(ins.field_crfd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_fcmpu(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_fra() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_fctiw(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_fctiw(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_fctiwz(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_fctiwz(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_fdiv(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_fdiv(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_fra() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_fmadd(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_fmadd(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_fra() as _)), + Argument::FPR(FPR(ins.field_frc() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + ] +} +const fn defs_fmr(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_fmr(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_fmsub(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_fmsub(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_fra() as _)), + Argument::FPR(FPR(ins.field_frc() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + ] +} +const fn defs_fmul(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_fmul(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_fra() as _)), + Argument::FPR(FPR(ins.field_frc() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_fnabs(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_fnabs(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_fneg(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_fneg(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_fnmadd(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_fnmadd(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_fra() as _)), + Argument::FPR(FPR(ins.field_frc() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + ] +} +const fn defs_fnmsub(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_fnmsub(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_fra() as _)), + Argument::FPR(FPR(ins.field_frc() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + ] +} +const fn defs_frsp(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_frsp(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_frsqrte(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_frsqrte(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_fsel(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_fsel(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_fra() as _)), + Argument::FPR(FPR(ins.field_frc() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + ] +} +const fn defs_fsub(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_fsub(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_fra() as _)), + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_mcrfs(ins: &Ins) -> Arguments { + [ + Argument::CRField(CRField(ins.field_crfd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_mcrfs(ins: &Ins) -> Arguments { + [ + Argument::CRField(CRField(ins.field_crfs() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_mffs(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_mffs(ins: &Ins) -> Arguments { + [Argument::None, Argument::None, Argument::None, Argument::None, Argument::None] +} +const fn defs_mtfsb0(ins: &Ins) -> Arguments { + [ + Argument::CRBit(CRBit(ins.field_crbd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_mtfsb0(ins: &Ins) -> Arguments { + [Argument::None, Argument::None, Argument::None, Argument::None, Argument::None] +} +const fn defs_mtfsb1(ins: &Ins) -> Arguments { + [ + Argument::CRBit(CRBit(ins.field_crbd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_mtfsb1(ins: &Ins) -> Arguments { + [Argument::None, Argument::None, Argument::None, Argument::None, Argument::None] +} +const fn defs_mtfsf(ins: &Ins) -> Arguments { + [Argument::None, Argument::None, Argument::None, Argument::None, Argument::None] +} +const fn uses_mtfsf(ins: &Ins) -> Arguments { + [ + Argument::FPR(FPR(ins.field_frb() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn defs_mtfsfi(ins: &Ins) -> Arguments { + [ + Argument::CRField(CRField(ins.field_crfd() as _)), + Argument::None, + Argument::None, + Argument::None, + Argument::None, + ] +} +const fn uses_mtfsfi(ins: &Ins) -> Arguments { + [Argument::None, Argument::None, Argument::None, Argument::None, Argument::None] +} +const fn defs_uses_illegal(_ins: &Ins) -> Arguments { + [Argument::None, Argument::None, Argument::None, Argument::None, Argument::None] +} +pub type DefsUsesFunction = fn(&Ins) -> Arguments; +pub const DEFS_FUNCTIONS: [DefsUsesFunction; 256] = [ + defs_twi, + defs_dcbz_l, + defs_psq_lux, + defs_psq_lx, + defs_psq_stux, + defs_psq_stx, + defs_ps_abs, + defs_ps_add, + defs_ps_cmpo0, + defs_ps_cmpo1, + defs_ps_cmpu0, + defs_ps_cmpu1, + defs_ps_div, + defs_ps_madd, + defs_ps_madds0, + defs_ps_madds1, + defs_ps_merge00, + defs_ps_merge01, + defs_ps_merge10, + defs_ps_merge11, + defs_ps_mr, + defs_ps_msub, + defs_ps_mul, + defs_ps_muls0, + defs_ps_muls1, + defs_ps_nabs, + defs_ps_neg, + defs_ps_nmadd, + defs_ps_nmsub, + defs_ps_res, + defs_ps_rsqrte, + defs_ps_sel, + defs_ps_sub, + defs_ps_sum0, + defs_ps_sum1, + defs_mulli, + defs_subfic, + defs_cmpli, + defs_cmpi, + defs_addic, + defs_addic_, + defs_addi, + defs_addis, + defs_bc, + defs_sc, + defs_b, + defs_bcctr, + defs_bclr, + defs_crand, + defs_crandc, + defs_creqv, + defs_crnand, + defs_crnor, + defs_cror, + defs_crorc, + defs_crxor, + defs_isync, + defs_mcrf, + defs_rfi, + defs_rlwimi, + defs_rlwinm, + defs_rlwnm, + defs_ori, + defs_oris, + defs_xori, + defs_xoris, + defs_andi_, + defs_andis_, + defs_add, + defs_addc, + defs_adde, + defs_addme, + defs_addze, + defs_and, + defs_andc, + defs_cmp, + defs_cmpl, + defs_cntlzw, + defs_dcbf, + defs_dcbi, + defs_dcbst, + defs_dcbt, + defs_dcbtst, + defs_dcbz, + defs_divw, + defs_divwu, + defs_eciwx, + defs_ecowx, + defs_eieio, + defs_eqv, + defs_extsb, + defs_extsh, + defs_icbi, + defs_lbzux, + defs_lbzx, + defs_lfdux, + defs_lfdx, + defs_lfsux, + defs_lfsx, + defs_lhaux, + defs_lhax, + defs_lhbrx, + defs_lhzux, + defs_lhzx, + defs_lswi, + defs_lswx, + defs_lwarx, + defs_lwbrx, + defs_lwzux, + defs_lwzx, + defs_mcrxr, + defs_mfcr, + defs_mfmsr, + defs_mfspr, + defs_mfsr, + defs_mfsrin, + defs_mftb, + defs_mtcrf, + defs_mtmsr, + defs_mtspr, + defs_mtsr, + defs_mtsrin, + defs_mulhw, + defs_mulhwu, + defs_mullw, + defs_nand, + defs_neg, + defs_nor, + defs_or, + defs_orc, + defs_slw, + defs_sraw, + defs_srawi, + defs_srw, + defs_stbux, + defs_stbx, + defs_stfdux, + defs_stfdx, + defs_stfiwx, + defs_stfsux, + defs_stfsx, + defs_sthbrx, + defs_sthux, + defs_sthx, + defs_stswi, + defs_stswx, + defs_stwbrx, + defs_stwcx_, + defs_stwux, + defs_stwx, + defs_subf, + defs_subfc, + defs_subfe, + defs_subfme, + defs_subfze, + defs_sync, + defs_tlbie, + defs_tlbsync, + defs_tw, + defs_xor, + defs_lwz, + defs_lwzu, + defs_lbz, + defs_lbzu, + defs_stw, + defs_stwu, + defs_stb, + defs_stbu, + defs_lhz, + defs_lhzu, + defs_lha, + defs_lhau, + defs_sth, + defs_sthu, + defs_lmw, + defs_stmw, + defs_lfs, + defs_lfsu, + defs_lfd, + defs_lfdu, + defs_stfs, + defs_stfsu, + defs_stfd, + defs_stfdu, + defs_psq_l, + defs_psq_lu, + defs_fadds, + defs_fdivs, + defs_fmadds, + defs_fmsubs, + defs_fmuls, + defs_fnmadds, + defs_fnmsubs, + defs_fres, + defs_fsubs, + defs_psq_st, + defs_psq_stu, + defs_fabs, + defs_fadd, + defs_fcmpo, + defs_fcmpu, + defs_fctiw, + defs_fctiwz, + defs_fdiv, + defs_fmadd, + defs_fmr, + defs_fmsub, + defs_fmul, + defs_fnabs, + defs_fneg, + defs_fnmadd, + defs_fnmsub, + defs_frsp, + defs_frsqrte, + defs_fsel, + defs_fsub, + defs_mcrfs, + defs_mffs, + defs_mtfsb0, + defs_mtfsb1, + defs_mtfsf, + defs_mtfsfi, + defs_uses_illegal, + defs_uses_illegal, + defs_uses_illegal, + defs_uses_illegal, + defs_uses_illegal, + defs_uses_illegal, + defs_uses_illegal, + defs_uses_illegal, + defs_uses_illegal, + defs_uses_illegal, + defs_uses_illegal, + defs_uses_illegal, + defs_uses_illegal, + defs_uses_illegal, + defs_uses_illegal, + defs_uses_illegal, + defs_uses_illegal, + defs_uses_illegal, + defs_uses_illegal, + defs_uses_illegal, + defs_uses_illegal, + defs_uses_illegal, + defs_uses_illegal, + defs_uses_illegal, + defs_uses_illegal, + defs_uses_illegal, + defs_uses_illegal, + defs_uses_illegal, + defs_uses_illegal, + defs_uses_illegal, + defs_uses_illegal, + defs_uses_illegal, + defs_uses_illegal, + defs_uses_illegal, +]; +pub const USES_FUNCTIONS: [DefsUsesFunction; 256] = [ + uses_twi, + uses_dcbz_l, + uses_psq_lux, + uses_psq_lx, + uses_psq_stux, + uses_psq_stx, + uses_ps_abs, + uses_ps_add, + uses_ps_cmpo0, + uses_ps_cmpo1, + uses_ps_cmpu0, + uses_ps_cmpu1, + uses_ps_div, + uses_ps_madd, + uses_ps_madds0, + uses_ps_madds1, + uses_ps_merge00, + uses_ps_merge01, + uses_ps_merge10, + uses_ps_merge11, + uses_ps_mr, + uses_ps_msub, + uses_ps_mul, + uses_ps_muls0, + uses_ps_muls1, + uses_ps_nabs, + uses_ps_neg, + uses_ps_nmadd, + uses_ps_nmsub, + uses_ps_res, + uses_ps_rsqrte, + uses_ps_sel, + uses_ps_sub, + uses_ps_sum0, + uses_ps_sum1, + uses_mulli, + uses_subfic, + uses_cmpli, + uses_cmpi, + uses_addic, + uses_addic_, + uses_addi, + uses_addis, + uses_bc, + uses_sc, + uses_b, + uses_bcctr, + uses_bclr, + uses_crand, + uses_crandc, + uses_creqv, + uses_crnand, + uses_crnor, + uses_cror, + uses_crorc, + uses_crxor, + uses_isync, + uses_mcrf, + uses_rfi, + uses_rlwimi, + uses_rlwinm, + uses_rlwnm, + uses_ori, + uses_oris, + uses_xori, + uses_xoris, + uses_andi_, + uses_andis_, + uses_add, + uses_addc, + uses_adde, + uses_addme, + uses_addze, + uses_and, + uses_andc, + uses_cmp, + uses_cmpl, + uses_cntlzw, + uses_dcbf, + uses_dcbi, + uses_dcbst, + uses_dcbt, + uses_dcbtst, + uses_dcbz, + uses_divw, + uses_divwu, + uses_eciwx, + uses_ecowx, + uses_eieio, + uses_eqv, + uses_extsb, + uses_extsh, + uses_icbi, + uses_lbzux, + uses_lbzx, + uses_lfdux, + uses_lfdx, + uses_lfsux, + uses_lfsx, + uses_lhaux, + uses_lhax, + uses_lhbrx, + uses_lhzux, + uses_lhzx, + uses_lswi, + uses_lswx, + uses_lwarx, + uses_lwbrx, + uses_lwzux, + uses_lwzx, + uses_mcrxr, + uses_mfcr, + uses_mfmsr, + uses_mfspr, + uses_mfsr, + uses_mfsrin, + uses_mftb, + uses_mtcrf, + uses_mtmsr, + uses_mtspr, + uses_mtsr, + uses_mtsrin, + uses_mulhw, + uses_mulhwu, + uses_mullw, + uses_nand, + uses_neg, + uses_nor, + uses_or, + uses_orc, + uses_slw, + uses_sraw, + uses_srawi, + uses_srw, + uses_stbux, + uses_stbx, + uses_stfdux, + uses_stfdx, + uses_stfiwx, + uses_stfsux, + uses_stfsx, + uses_sthbrx, + uses_sthux, + uses_sthx, + uses_stswi, + uses_stswx, + uses_stwbrx, + uses_stwcx_, + uses_stwux, + uses_stwx, + uses_subf, + uses_subfc, + uses_subfe, + uses_subfme, + uses_subfze, + uses_sync, + uses_tlbie, + uses_tlbsync, + uses_tw, + uses_xor, + uses_lwz, + uses_lwzu, + uses_lbz, + uses_lbzu, + uses_stw, + uses_stwu, + uses_stb, + uses_stbu, + uses_lhz, + uses_lhzu, + uses_lha, + uses_lhau, + uses_sth, + uses_sthu, + uses_lmw, + uses_stmw, + uses_lfs, + uses_lfsu, + uses_lfd, + uses_lfdu, + uses_stfs, + uses_stfsu, + uses_stfd, + uses_stfdu, + uses_psq_l, + uses_psq_lu, + uses_fadds, + uses_fdivs, + uses_fmadds, + uses_fmsubs, + uses_fmuls, + uses_fnmadds, + uses_fnmsubs, + uses_fres, + uses_fsubs, + uses_psq_st, + uses_psq_stu, + uses_fabs, + uses_fadd, + uses_fcmpo, + uses_fcmpu, + uses_fctiw, + uses_fctiwz, + uses_fdiv, + uses_fmadd, + uses_fmr, + uses_fmsub, + uses_fmul, + uses_fnabs, + uses_fneg, + uses_fnmadd, + uses_fnmsub, + uses_frsp, + uses_frsqrte, + uses_fsel, + uses_fsub, + uses_mcrfs, + uses_mffs, + uses_mtfsb0, + uses_mtfsb1, + uses_mtfsf, + uses_mtfsfi, + defs_uses_illegal, + defs_uses_illegal, + defs_uses_illegal, + defs_uses_illegal, + defs_uses_illegal, + defs_uses_illegal, + defs_uses_illegal, + defs_uses_illegal, + defs_uses_illegal, + defs_uses_illegal, + defs_uses_illegal, + defs_uses_illegal, + defs_uses_illegal, + defs_uses_illegal, + defs_uses_illegal, + defs_uses_illegal, + defs_uses_illegal, + defs_uses_illegal, + defs_uses_illegal, + defs_uses_illegal, + defs_uses_illegal, + defs_uses_illegal, + defs_uses_illegal, + defs_uses_illegal, + defs_uses_illegal, + defs_uses_illegal, + defs_uses_illegal, + defs_uses_illegal, + defs_uses_illegal, + defs_uses_illegal, + defs_uses_illegal, + defs_uses_illegal, + defs_uses_illegal, + defs_uses_illegal, +]; diff --git a/disasm/src/iter.rs b/disasm/src/iter.rs deleted file mode 100644 index 5a3065b..0000000 --- a/disasm/src/iter.rs +++ /dev/null @@ -1,34 +0,0 @@ -use crate::Ins; - -/// Returns an iterator of instructions in the given byte slice. -pub fn disasm_iter(code: &[u8], addr: u32) -> DisasmIterator { - DisasmIterator { code, addr } -} - -pub struct DisasmIterator<'a> { - code: &'a [u8], - addr: u32, -} - -impl<'a> Iterator for DisasmIterator<'a> { - type Item = Ins; - - fn next(&mut self) -> Option { - if self.code.len() < 4 { - return None; - } - let code = ((self.code[0] as u32) << 24) - | ((self.code[1] as u32) << 16) - | ((self.code[2] as u32) << 8) - | (self.code[3] as u32); - self.code = &self.code[4..]; - let addr = self.addr; - self.addr += 4; - Some(Ins::new(code, addr)) - } - - fn size_hint(&self) -> (usize, Option) { - let count = self.code.len() / 4; - (count, Some(count)) - } -} diff --git a/disasm/src/lib.rs b/disasm/src/lib.rs index 1081fce..dbc8bfe 100644 --- a/disasm/src/lib.rs +++ b/disasm/src/lib.rs @@ -1,458 +1,9 @@ -use std::fmt::{Display, Formatter, LowerHex, UpperHex, Write}; -use std::ops::Range; - -use num_traits::{AsPrimitive, PrimInt}; - -pub use crate::iter::{disasm_iter, DisasmIterator}; - -pub mod formatter; +#![no_std] +mod disasm; mod generated; -mod iter; -pub use generated::*; -pub mod prelude { - pub use crate::formatter::FormattedIns; - pub use crate::Argument; - pub use crate::Field::*; - pub use crate::Ins; - pub use crate::Opcode::*; - pub use crate::SimplifiedIns; - pub use crate::{ - Bit, BranchDest, CRBit, CRField, Offset, OpaqueU, Simm, Uimm, FPR, GPR, GQR, SPR, SR, - }; -} - -macro_rules! field_arg_no_display { - ($name:ident, $typ:ident) => { - #[derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq)] - pub struct $name(pub $typ); - impl std::convert::From<$name> for Argument { - fn from(x: $name) -> Argument { - Argument::$name(x) - } - } - }; -} - -macro_rules! field_arg { - ($name:ident, $typ:ident) => { - field_arg_no_display!($name, $typ); - impl Display for $name { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", self.0) - } - } - }; - ($name:ident, $typ:ident, $format:literal) => { - field_arg_no_display!($name, $typ); - impl Display for $name { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - write!(f, $format, self.0) - } - } - }; - ($name:ident, $typ:ident, $format:literal, $format_arg:expr) => { - field_arg_no_display!($name, $typ); - impl Display for $name { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - write!(f, $format, $format_arg(self.0)) - } - } - }; -} - -#[inline(always)] -fn bit(x: u32, idx: usize) -> bool { - ((x >> (32 - idx - 1)) & 1) == 1 -} - -#[inline(always)] -fn bits(x: u32, range: Range) -> F -where - F: 'static + std::marker::Copy, - u32: AsPrimitive, -{ - let masked: u32 = (x >> (32 - range.end)) & ((1 << range.len()) - 1); - masked.as_() -} - -// https://stackoverflow.com/questions/44711012/how-do-i-format-a-signed-integer-to-a-sign-aware-hexadecimal-representation -struct ReallySigned(N); - -impl LowerHex for ReallySigned { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - let num = self.0.to_i32().unwrap(); - let prefix = if f.alternate() { "0x" } else { "" }; - let bare_hex = format!("{:x}", num.abs()); - f.pad_integral(num >= 0, prefix, &bare_hex) - } -} - -impl UpperHex for ReallySigned { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - let num = self.0.to_i32().unwrap(); - let prefix = if f.alternate() { "0x" } else { "" }; - let bare_hex = format!("{:X}", num.abs()); - f.pad_integral(num >= 0, prefix, &bare_hex) - } -} - -// General-purpose register. -field_arg!(GPR, u8, "r{}"); -// Floating-point register (direct or paired-singles mode). -field_arg!(FPR, u8, "f{}"); -// Segment register. -field_arg!(SR, u8); -// Special-purpose register. -field_arg_no_display!(SPR, u16); -impl Display for SPR { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - f.write_str(match self.0 { - 1 => "XER", - 8 => "LR", - 9 => "CTR", - 18 => "DSISR", - 19 => "DAR", - 22 => "DEC", - 25 => "SDR1", - 26 => "SRR0", - 27 => "SRR1", - 272 => "SPRG0", - 273 => "SPRG1", - 274 => "SPRG2", - 275 => "SPRG3", - 282 => "EAR", - 287 => "PVR", - 528 => "IBAT0U", - 529 => "IBAT0L", - 530 => "IBAT1U", - 531 => "IBAT1L", - 532 => "IBAT2U", - 533 => "IBAT2L", - 534 => "IBAT3U", - 535 => "IBAT3L", - 536 => "DBAT0U", - 537 => "DBAT0L", - 538 => "DBAT1U", - 539 => "DBAT1L", - 540 => "DBAT2U", - 541 => "DBAT2L", - 542 => "DBAT3U", - 543 => "DBAT3L", - 912 => "GQR0", - 913 => "GQR1", - 914 => "GQR2", - 915 => "GQR3", - 916 => "GQR4", - 917 => "GQR5", - 918 => "GQR6", - 919 => "GQR7", - 920 => "HID2", - 921 => "WPAR", - 922 => "DMA_U", - 923 => "DMA_L", - 936 => "UMMCR0", - 937 => "UPMC1", - 938 => "UPMC2", - 939 => "USIA", - 940 => "UMMCR1", - 941 => "UPMC3", - 942 => "UPMC4", - 943 => "USDA", - 952 => "MMCR0", - 953 => "PMC1", - 954 => "PMC2", - 955 => "SIA", - 956 => "MMCR1", - 957 => "PMC3", - 958 => "PMC4", - 959 => "SDA", - 1008 => "HID0", - 1009 => "HID1", - 1010 => "IABR", - 1013 => "DABR", - 1017 => "L2CR", - 1019 => "ICTC", - 1020 => "THRM1", - 1021 => "THRM2", - 1022 => "THRM3", - _ => return write!(f, "{}", self.0), - }) - } -} -// Condition register field. -field_arg!(CRField, u8, "cr{}"); -// Condition register bit (index + condition case). -field_arg_no_display!(CRBit, u8); -impl Display for CRBit { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - let cr = self.0 >> 2; - let cc = self.0 & 3; - if cr != 0 { - write!(f, "{}", CRField(cr))?; - } - const CR_NAMES: [&str; 4] = ["lt", "gt", "eq", "un"]; - f.write_str(CR_NAMES[cc as usize]) - } -} -// Paired-single graphics quantization register -field_arg!(GQR, u8, "qr{}"); -// Unsigned immediate. -field_arg!(Uimm, u16, "{:#x}"); -// Signed immediate. -field_arg!(Simm, i16, "{:#x}", ReallySigned); -// Offset for indirect memory reference. -field_arg!(Offset, i16, "{:#x}", ReallySigned); -// Branch destination. -field_arg!(BranchDest, i32, "{:#x}", ReallySigned); -// Opaque zero or one argument. -field_arg_no_display!(Bit, bool); -impl Display for Bit { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - f.write_char(if self.0 { '1' } else { '0' }) - } -} -// Unsigned opaque argument. -field_arg!(OpaqueU, u32); - -#[derive(Debug, Clone, Eq, PartialEq)] -pub enum Argument { - GPR(GPR), - FPR(FPR), - SR(SR), - SPR(SPR), - CRField(CRField), - CRBit(CRBit), - GQR(GQR), - Uimm(Uimm), - Simm(Simm), - Offset(Offset), - BranchDest(BranchDest), - Bit(Bit), - OpaqueU(OpaqueU), -} - -impl Display for Argument { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - match self { - Argument::GPR(x) => x.fmt(f), - Argument::FPR(x) => x.fmt(f), - Argument::SR(x) => x.fmt(f), - Argument::SPR(x) => x.fmt(f), - Argument::CRField(x) => x.fmt(f), - Argument::CRBit(x) => x.fmt(f), - Argument::GQR(x) => x.fmt(f), - Argument::Uimm(x) => x.fmt(f), - Argument::Simm(x) => x.fmt(f), - Argument::Offset(x) => x.fmt(f), - Argument::BranchDest(x) => x.fmt(f), - Argument::Bit(x) => x.fmt(f), - Argument::OpaqueU(x) => x.fmt(f), - } - } -} - -impl From for i64 { - fn from(arg: Argument) -> Self { - match arg { - Argument::GPR(x) => x.0 as i64, - Argument::FPR(x) => x.0 as i64, - Argument::SR(x) => x.0 as i64, - Argument::SPR(x) => x.0 as i64, - Argument::CRField(x) => x.0 as i64, - Argument::CRBit(x) => x.0 as i64, - Argument::GQR(x) => x.0 as i64, - Argument::Uimm(x) => x.0 as i64, - Argument::Simm(x) => x.0 as i64, - Argument::Offset(x) => x.0 as i64, - Argument::BranchDest(x) => x.0 as i64, - Argument::Bit(x) => x.0 as i64, - Argument::OpaqueU(x) => x.0 as i64, - } - } -} - -impl TryInto for &Field { - type Error = (); - fn try_into(self) -> Result { - self.argument().ok_or(()) - } -} - -impl Opcode { - /// Detects the opcode of a machine code instruction. - pub fn detect(code: u32) -> Self { - Self::_detect(code) // auto-generated - } - - /// Prints the basic mnemonic of an opcode. - pub fn mnemonic(self) -> &'static str { - self._mnemonic() // auto-generated - } -} - -impl Default for Opcode { - fn default() -> Self { - Opcode::Illegal - } -} - -impl std::string::ToString for Opcode { - fn to_string(&self) -> String { - let mnemonic = self.mnemonic(); - mnemonic.to_owned() - } -} - -/// A PowerPC 750CL instruction. -#[derive(Default, Clone, Debug, Eq, PartialEq)] -pub struct Ins { - pub code: u32, - pub addr: u32, - pub op: Opcode, -} - -impl Ins { - const BLR: u32 = 0x4e800020; - - /// Constructs an instruction from the given machine code and address. - pub fn new(code: u32, addr: u32) -> Self { - Self { - code, - addr, - op: Opcode::detect(code), - } - } - - /// Returns the simplified representation of an instruction. - pub fn simplified(self) -> SimplifiedIns { - self._simplified() // auto-generated - } - - /// Gets the fields of an instruction. - pub fn fields(&self) -> Vec { - self._fields() // auto-generated - } - - /// Gets the suffix of an instruction mnemonic. - pub fn suffix(&self) -> String { - self._suffix() // auto-generated - } - - /// Gets the defs of an instruction. - pub fn defs(&self) -> Vec { - self._defs() // auto-generated - } - - /// Gets the uses of an instruction. - pub fn uses(&self) -> Vec { - self._uses() // auto-generated - } - - /// Gets the given bit from the machine code instruction. - pub fn bit(&self, idx: usize) -> bool { - bit(self.code, idx) - } - - /// Gets the given range of btis from the machine code instruction. - pub fn bits(&self, range: Range) -> u32 { - bits(self.code, range) - } - - pub fn branch_offset(&self) -> Option { - match self.op { - Opcode::B => Some(self.field_LI() as i32), - Opcode::Bc => Some(self.field_BD() as i32), - _ => None, - } - } - - pub fn branch_dest(&self) -> Option { - self.branch_offset().and_then(|offset| { - if self.field_AA() { - Some(offset as u32) - } else if offset < 0 { - self.addr.checked_sub((-offset) as u32) - } else { - self.addr.checked_add(offset as u32) - } - }) - } - - pub fn is_branch(&self) -> bool { - matches!( - self.op, - Opcode::B | Opcode::Bc | Opcode::Bcctr | Opcode::Bclr - ) - } - - pub fn is_direct_branch(&self) -> bool { - matches!(self.op, Opcode::B | Opcode::Bc) - } - - pub fn is_unconditional_branch(&self) -> bool { - match self.op { - Opcode::B => true, - Opcode::Bc | Opcode::Bcctr | Opcode::Bclr => { - self.field_BO() == 20 && self.field_BI() == 0 - } - _ => false, - } - } - - pub fn is_conditional_branch(&self) -> bool { - self.is_branch() && !self.is_unconditional_branch() - } - - #[inline] - pub fn is_blr(&self) -> bool { - // self.op == Opcode::Bclr && self.is_unconditional_branch() && !self.field_LK() - self.code == Ins::BLR - } -} - -/// A simplified PowerPC 750CL instruction. -pub struct SimplifiedIns { - pub ins: Ins, - pub mnemonic: &'static str, - pub suffix: String, - pub args: Vec, -} - -impl Display for SimplifiedIns { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - write!(f, "{}{} ", self.mnemonic, self.suffix)?; - let mut writing_offset = false; - for (i, argument) in self.args.iter().enumerate() { - write!(f, "{}", argument)?; - if let Argument::Offset(_) = argument { - write!(f, "(")?; - writing_offset = true; - continue; - } - if writing_offset { - write!(f, ")")?; - writing_offset = false; - } - if i != self.args.len() - 1 { - write!(f, ", ")?; - } - } - Ok(()) - } -} - -impl SimplifiedIns { - pub fn basic_form(ins: Ins) -> Self { - Self { - mnemonic: ins.op.mnemonic(), - suffix: ins.suffix(), - args: ins - .fields() - .iter() - .flat_map(|field| field.argument()) - .collect(), - ins, - } - } -} +pub use disasm::{ + Argument, BranchDest, CRBit, CRField, Ins, Offset, OpaqueU, Simm, SimplifiedIns, Uimm, FPR, + GPR, GQR, SPR, SR, +}; +pub use generated::{Arguments, Opcode}; diff --git a/disasm/tests/test_disasm.rs b/disasm/tests/test_disasm.rs index 6271313..f01faf4 100644 --- a/disasm/tests/test_disasm.rs +++ b/disasm/tests/test_disasm.rs @@ -1,12 +1,22 @@ -use ppc750cl::prelude::*; +use ppc750cl::{Argument, Ins, Opcode, SimplifiedIns, FPR, GPR}; macro_rules! assert_asm { ($ins:ident, $disasm:literal) => {{ - assert_eq!(format!("{}", FormattedIns($ins)), $disasm) + assert_eq!(format!("{}", SimplifiedIns::new($ins)), $disasm) }}; ($code:literal, $disasm:literal) => {{ - let ins = Ins::new($code, 0x8000_0000); - assert_eq!(format!("{}", FormattedIns(ins)), $disasm) + let ins = Ins::new($code); + assert_eq!(format!("{}", SimplifiedIns::new(ins)), $disasm) + }}; +} + +macro_rules! assert_basic { + ($ins:ident, $disasm:literal) => {{ + assert_eq!(format!("{}", SimplifiedIns::basic_form($ins)), $disasm) + }}; + ($code:literal, $disasm:literal) => {{ + let ins = Ins::new($code); + assert_eq!(format!("{}", SimplifiedIns::basic_form(ins)), $disasm) }}; } @@ -20,9 +30,9 @@ fn test_ins_add() { #[test] fn test_ins_addc() { - let ins = Ins::new(0x7c002014, 0x8000_0000u32); - assert_eq!(ins.op, Addc); - assert_eq!(ins.fields(), vec![rD(GPR(0)), rA(GPR(0)), rB(GPR(4))]); + let ins = Ins::new(0x7c002014); + assert_eq!(ins.op, Opcode::Addc); + // assert_eq!(ins.fields(), vec![rD(GPR(0)), rA(GPR(0)), rB(GPR(4))]); assert_asm!(ins, "addc r0, r0, r4"); assert_asm!(0x7C432014, "addc r2, r3, r4"); assert_asm!(0x7CE62815, "addc. r7, r6, r5"); @@ -32,14 +42,20 @@ fn test_ins_addc() { #[test] fn test_ins_addi() { - let ins = Ins::new(0x38010140, 0x8000_0000u32); - assert_eq!(ins.op, Addi); + let ins = Ins::new(0x38010140); + assert_eq!(ins.op, Opcode::Addi); + // assert_eq!( + // ins.fields(), + // vec![rD(GPR(0)), rA(GPR(1)), simm(Simm(0x140))] + // ); assert_eq!( - ins.fields(), - vec![rD(GPR(0)), rA(GPR(1)), simm(Simm(0x140))] + ins.defs(), + [Argument::GPR(GPR(0)), Argument::None, Argument::None, Argument::None, Argument::None] + ); + assert_eq!( + ins.uses(), + [Argument::GPR(GPR(1)), Argument::None, Argument::None, Argument::None, Argument::None] ); - assert_eq!(ins.defs(), vec![rD(GPR(0))]); - assert_eq!(ins.uses(), vec![rA(GPR(1))]); assert_asm!(ins, "addi r0, r1, 0x140"); assert_asm!(0x38010008, "addi r0, r1, 0x8"); @@ -48,6 +64,7 @@ fn test_ins_addi() { assert_asm!(0x38010140, "addi r0, r1, 0x140"); assert_asm!(0x38049000, "subi r0, r4, 0x7000"); assert_asm!(0x38a00000, "li r5, 0x0"); + assert_basic!(0x38a00000, "addi r5, r0, 0x0"); } #[test] @@ -710,20 +727,26 @@ fn test_ins_psq_lu() { #[test] fn test_ins_psq_lx() { - let ins = Ins::new(0x1000000C, 0x8000_0000u32); - assert_eq!(ins.op, PsqLx); + let ins = Ins::new(0x1000000C); + assert_eq!(ins.op, Opcode::PsqLx); + // assert_eq!( + // ins.fields(), + // vec![ + // frD(FPR(0)), + // rA(GPR(0)), + // rB(GPR(0)), + // ps_WX(OpaqueU(0)), + // ps_IX(GQR(0)), + // ] + // ); assert_eq!( - ins.fields(), - vec![ - frD(FPR(0)), - rA(GPR(0)), - rB(GPR(0)), - ps_WX(OpaqueU(0)), - ps_IX(GQR(0)), - ] + ins.defs(), + [Argument::FPR(FPR(0)), Argument::None, Argument::None, Argument::None, Argument::None] + ); + assert_eq!( + ins.uses(), + [Argument::None, Argument::GPR(GPR(0)), Argument::None, Argument::None, Argument::None] ); - assert_eq!(ins.defs(), vec![frD(FPR(0))]); - assert_eq!(ins.uses(), vec![rB(GPR(0))]); assert_asm!(0x1000000C, "psq_lx f0, r0, r0, 0, qr0"); } @@ -885,6 +908,7 @@ fn test_ins_rlwimi() { fn test_ins_rlwinm() { assert_asm!(0x54000423, "rlwinm. r0, r0, 0, 16, 17"); assert_asm!(0x54000432, "rlwinm r0, r0, 0, 16, 25"); + assert_basic!(0x54096226, "rlwinm r9, r0, 12, 8, 19"); // mnemonics assert_asm!(0x57E5103A, "slwi r5, r31, 2"); diff --git a/dol/Cargo.toml b/dol/Cargo.toml deleted file mode 100644 index 5b3a995..0000000 --- a/dol/Cargo.toml +++ /dev/null @@ -1,13 +0,0 @@ -[package] -name = "dol" -version = "0.1.0" -edition = "2021" -authors = ["Richard Patel "] -license = "GPL-3.0-or-later" -description = "Deserializer for the DOL executable format" -repository = "https://github.com/terorie/ppc750cl" - -[dependencies] -bincode = "1.3" -serde = { version = "1.0", features = ["derive"] } -thiserror = "1.0" diff --git a/dol/src/lib.rs b/dol/src/lib.rs deleted file mode 100644 index 8ff53e8..0000000 --- a/dol/src/lib.rs +++ /dev/null @@ -1,237 +0,0 @@ -use std::io::{Read, Seek, SeekFrom}; - -use bincode::Options; -use serde::{Deserialize, Serialize}; -use thiserror::Error; - -/// A loaded DOL executable. -pub struct Dol { - pub header: DolHeader, - pub memory: Vec, - pub memory_offset: u32, -} - -/// An error that can be raised during DOL parsing. -#[derive(Error, Debug)] -pub enum Error { - #[error("{0}")] - BincodeError(bincode::Error), - #[error("{0}")] - IOError(std::io::Error), - #[error("No sections in DOL")] - NoSections, - #[error("Overlapping sections: {0:8>X} {1:8>X}")] - OverlappingSections(u32, u32), - #[error("Section sizes too large")] - SectionsTooLarge, - #[error("Attempted to access {0:08X} past DOL bounds")] - OutOfBounds(u32), -} - -impl From for Error { - fn from(e: bincode::Error) -> Self { - Self::BincodeError(e) - } -} - -impl From for Error { - fn from(e: std::io::Error) -> Self { - Self::IOError(e) - } -} - -/// The result of a DOL parsing. -pub type Result = std::result::Result; - -impl Dol { - /// Reads a DOL executable from a `Reader`. - pub fn read_from(mut r: R) -> Result - where - R: Read + Seek, - { - // Read header. - let header_data = DolHeaderData::read_from(&mut r)?; - let header: DolHeader = (&header_data).into(); - Dol::read_with_header(r, header) - } - - /// Reads a DOL body from a `Reader` given a header. - pub fn read_with_header(mut r: R, header: DolHeader) -> Result - where - R: Read + Seek, - { - let dol_start = r.stream_position()? - DolHeaderData::SERIALIZED_SIZE; - if header.sections.is_empty() { - return Err(Error::NoSections); - } - /* - // Verify that sections are not overlapping. - let mut end_target_addr = 0u32; - for section in &header.sections { - if section.target < end_target_addr { - return Err(Error::OverlappingSections(end_target_addr, section.target)); - } - end_target_addr = section.target + section.size - } - */ - // Remember the memory offset of the first section. - // Then shift all sections to the beginning of memory. - let memory_offset = header.sections[0].target; - // Get the size of all sections combined. - let mut total_size = 0usize; - for section in &header.sections { - if let Some(sum) = total_size.checked_add(section.size as usize) { - total_size = sum; - } else { - return Err(Error::SectionsTooLarge); - } - } - // Cannot be larger than 24 MiB. - if total_size > 0x180_0000 { - return Err(Error::SectionsTooLarge); - } - // Create memory. - let mut memory = vec![0u8; total_size]; - // Read sections into memory. - for section in &header.sections { - if section.kind == DolSectionType::Bss { - continue; - } - r.seek(SeekFrom::Start(dol_start + section.offset as u64))?; - let mem_start = (section.target - memory_offset) as usize; - let mem_end = mem_start + section.size as usize; - r.read_exact(&mut memory[mem_start..mem_end])?; - } - Ok(Self { - header, - memory, - memory_offset, - }) - } - - pub fn section_data(&self, section: &DolSection) -> &[u8] { - self.virtual_data_at(section.target, section.size).unwrap() - } - - /// Returns a slice of DOL data. Does not support bss. - pub fn virtual_data_at(&self, virtual_addr: u32, read_len: u32) -> Result<&[u8]> { - if virtual_addr < self.memory_offset { - return Err(Error::OutOfBounds(virtual_addr)); - } - - let offset = (virtual_addr - self.memory_offset) as usize; - if offset + (read_len as usize) < self.memory.len() { - Ok(&self.memory[offset..offset + (read_len as usize)]) - } else { - Err(Error::OutOfBounds(virtual_addr + read_len)) - } - } - - /// Reads bytes into a destination buffer given a virtual address. - pub fn virtual_read(&self, data: &mut [u8], virtual_addr: u32) -> Result<()> { - if virtual_addr < self.memory_offset { - return Err(Error::OutOfBounds(virtual_addr)); - } - - let offset = (virtual_addr - self.memory_offset) as usize; - let read_len = data.len(); - if offset + read_len < self.memory.len() { - data.copy_from_slice(&self.memory[offset..offset + data.len()]); - Ok(()) - } else { - Err(Error::OutOfBounds(virtual_addr + (read_len as u32))) - } - } -} - -#[derive(Debug, Clone, Copy, Eq, PartialEq)] -pub enum DolSectionType { - Text, - Data, - Bss, -} - -#[derive(Debug, Clone)] -pub struct DolSection { - pub kind: DolSectionType, - pub index: usize, - pub offset: u32, - pub target: u32, - pub size: u32, -} - -pub struct DolHeader { - pub sections: Vec, - pub entry_point: u32, -} - -impl From<&DolHeaderData> for DolHeader { - fn from(header: &DolHeaderData) -> Self { - let mut sections = Vec::with_capacity(DolHeaderData::SECTION_COUNT); - for i in 0..DolHeaderData::SECTION_COUNT { - let kind = if i < 7 { - DolSectionType::Text - } else { - DolSectionType::Data - }; - - if header.section_sizes[i] > 0 { - sections.push(DolSection { - kind, - index: i, - offset: header.section_offsets[i], - target: header.section_targets[i], - size: header.section_sizes[i], - }); - } - } - if header.bss_target > 0 { - sections.push(DolSection { - kind: DolSectionType::Bss, - index: 0, - offset: 0, - target: header.bss_target, - size: header.bss_size, - }) - } - // Sort sections by target address to prepare them for mapping. - sections.sort_by_key(|s| s.target); - Self { - sections, - entry_point: header.entry_point, - } - } -} - -impl DolHeader { - pub fn section_at(&self, addr: u32) -> Option<&DolSection> { - self.sections - .iter() - .find(|§ion| (section.target..(section.target + section.size)).contains(&addr)) - } -} - -#[derive(Debug, Serialize, Deserialize)] -pub struct DolHeaderData { - pub section_offsets: [u32; Self::SECTION_COUNT], - pub section_targets: [u32; Self::SECTION_COUNT], - pub section_sizes: [u32; Self::SECTION_COUNT], - pub bss_target: u32, - pub bss_size: u32, - pub entry_point: u32, - pub padding: [u8; 0x1c], -} - -impl DolHeaderData { - const SECTION_COUNT: usize = 18; - const SERIALIZED_SIZE: u64 = 0x100; - - /// Reads the DOL header from a `Reader`. - pub fn read_from(mut r: R) -> bincode::Result { - bincode::DefaultOptions::new() - .with_big_endian() - .allow_trailing_bytes() - .with_fixint_encoding() - .deserialize_from(&mut r) - } -} diff --git a/flow-graph/Cargo.toml b/flow-graph/Cargo.toml deleted file mode 100644 index 6c6092a..0000000 --- a/flow-graph/Cargo.toml +++ /dev/null @@ -1,16 +0,0 @@ -[package] -name = "ppc750cl-flow-graph" -version = "0.2.0" -edition = "2021" -authors = ["riidefi ", "Richard Patel "] -license = "GPL-3.0-or-later" -description = "Control flow graph analysis for PowerPC 750CL" -repository = "https://github.com/terorie/ppc750cl" - -[dependencies] -clap = "3" -dol = { version = "0.1.0", path = "../dol" } -itertools = "0.10" -parse_int = "0.6" -petgraph = "0.6" -ppc750cl = { version = "0.2.0", path = "../disasm" } diff --git a/flow-graph/src/flow.rs b/flow-graph/src/flow.rs deleted file mode 100644 index 8ded08f..0000000 --- a/flow-graph/src/flow.rs +++ /dev/null @@ -1,178 +0,0 @@ -use std::collections::{BTreeMap, HashMap}; -use std::fmt::{Debug, Display, Formatter}; -use std::hash::{Hash, Hasher}; -use std::ops::{Index, Range}; - -use itertools::Itertools; -use petgraph::algo::dominators::Dominators; -use petgraph::graph::{DefaultIx, NodeIndex}; -use petgraph::Graph; - -use ppc750cl::formatter::FormattedIns; -use ppc750cl::{Ins, Opcode}; - -use crate::slices::{BasicSlices, CodeIdx}; - -#[derive(Default)] -pub struct BasicBlock<'a> { - pub range: Range, - pub code: &'a [Ins], - pub data_refs: HashMap, -} - -impl<'a> PartialEq for BasicBlock<'a> { - fn eq(&self, other: &Self) -> bool { - self.range == other.range - } -} - -impl<'a> Eq for BasicBlock<'a> {} - -impl<'a> Hash for BasicBlock<'a> { - fn hash(&self, state: &mut H) { - self.range.hash(state) - } -} - -impl<'a> BasicBlock<'a> { - pub fn from_code_slice(range: Range, complete_code: &'a [Ins]) -> BasicBlock { - let start_idx = complete_code.first().unwrap().addr / 4; - assert!(start_idx <= range.start); - let offset = (range.start - start_idx) as usize; - let code = &complete_code[offset..(offset + (range.len() as usize))]; - BasicBlock { - range, - code, - data_refs: Self::detect_data_refs(code), - } - } - - /// Very simple algorithm to detect data references. - fn detect_data_refs(code: &[Ins]) -> HashMap { - let mut defs = HashMap::::new(); - let mut data_refs = HashMap::::new(); - for ins in code { - match ins.op { - Opcode::Addis => { - if ins.field_rA() == 0 { - // lis - defs.insert(ins.field_rD() as u8, ins.field_uimm() as u16); - } else { - defs.remove(&(ins.field_rD() as u8)); - } - } - Opcode::Addi => { - if let Some(hi) = defs.get(&(ins.field_rA() as u8)) { - data_refs.insert( - ins.addr / 4, - ((*hi as u32) << 16) + (ins.field_uimm() as u32), - ); - } - defs.remove(&(ins.field_rD() as u8)); - } - _ => (), - } - } - data_refs - } -} - -impl<'a> Display for BasicBlock<'a> { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - write!(f, "{:0>#8x}", self.range.start * 4) - } -} - -impl<'a> Debug for BasicBlock<'a> { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - writeln!( - f, - "// {:0>#8x}..{:0>#8x}", - self.range.start * 4, - self.range.end * 4 - )?; - for ins in self.code { - writeln!(f, "{}", FormattedIns(ins.clone()))?; - if let Some(addr) = self.data_refs.get(&(ins.addr / 4)) { - writeln!(f, " ref: {:0>#8x}", addr)?; - } - } - Ok(()) - } -} - -/// A control-flow graph of a function. -pub struct FlowGraph<'a> { - pub graph: Graph, ()>, - pub root_idx: NodeIndex, -} - -impl<'a> FlowGraph<'a> { - /// Creates a control-flow graph from basic slices. - pub fn from_basic_slices(slices: &BasicSlices, code: &'a [Ins]) -> Self { - assert!(!code.is_empty(), "Attempt to create empty flow graph"); - // Walk set cuts and create basic blocks. - let mut graph = Graph::new(); - let mut node_by_addr = BTreeMap::>::new(); - let mut block_start: CodeIdx = code[0].addr / 4; - for cut in &slices.cuts { - if *cut > block_start { - node_by_addr.insert( - block_start, - graph.add_node(BasicBlock::from_code_slice(block_start..*cut, code)), - ); - } - block_start = *cut; - } - // Last block. - let func_end: CodeIdx = (code.last().unwrap().addr / 4) + 1; - if func_end > block_start { - node_by_addr.insert( - block_start, - graph.add_node(BasicBlock::from_code_slice(block_start..func_end, code)), - ); - } - // Walk set of branches and connect graph. - for branch in &slices.branches { - let src_node_idx = match node_by_addr.range(..branch.0 + 1).last() { - None => continue, - Some(idx) => *idx.1, - }; - debug_assert!(graph[src_node_idx].range.contains(&branch.0)); - let dst_node_idx = match node_by_addr.range(..branch.1 + 1).last() { - None => continue, - Some(idx) => *idx.1, - }; - debug_assert!(graph[dst_node_idx].range.contains(&branch.1)); - graph.add_edge(src_node_idx, dst_node_idx, ()); - } - // Walk blocks and re-connect nodes that were split off. - for (src_node_idx, dst_node_idx) in node_by_addr.values().tuple_windows::<(_, _)>() { - // Get pairs of two blocks as a sliding window. - let src_block: &BasicBlock = &graph[*src_node_idx]; - let dst_block: &BasicBlock = &graph[*dst_node_idx]; - assert_eq!(src_block.range.end, dst_block.range.start); - // Get last instruction of left block. - // Unless it's an unconditional branch, we can connect the blocks. - let last_ins = &src_block.code.last().unwrap(); - if last_ins.code == 0x4E800020 - || (last_ins.op == Opcode::B && last_ins.field_BO() == 0b10100) - { - continue; - } - // Execution can continue past the last instruction of a block, - // so re-connect two blocks that were split off. - if !graph.contains_edge(*src_node_idx, *dst_node_idx) { - graph.add_edge(*src_node_idx, *dst_node_idx, ()); - } - } - Self { - graph, - root_idx: *node_by_addr.index(node_by_addr.keys().next().unwrap()), - } - } - - pub fn dominators(&self) -> Dominators { - petgraph::algo::dominators::simple_fast(&self.graph, self.root_idx) - } -} diff --git a/flow-graph/src/main.rs b/flow-graph/src/main.rs deleted file mode 100644 index 5f27efa..0000000 --- a/flow-graph/src/main.rs +++ /dev/null @@ -1,69 +0,0 @@ -use petgraph::dot::{Config as DotConfig, Dot}; - -use ppc750cl::{disasm_iter, Ins}; - -pub mod flow; -pub mod slices; - -use crate::flow::FlowGraph; -use crate::slices::BasicSlices; -use dol::Dol; - -fn main() { - let matches = clap::Command::new("ppc750cl-flow-graph") - .version("0.2.0") - .about("Control flow graph analysis for PowerPC 750CL") - .arg( - clap::Arg::new("START") - .long("--start") - .required(true) - .takes_value(true) - .help("Start address"), - ) - .arg( - clap::Arg::new("STOP") - .long("--stop") - .required(true) - .takes_value(true) - .help("Stop address"), - ) - .arg( - clap::Arg::new("INPUT") - .required(true) - .help("Binary input file"), - ) - .get_matches(); - - let start_addr = matches.value_of("START").unwrap(); - let start_addr: u32 = ::parse_int::parse(start_addr).expect("Invalid address flag"); - let stop_addr = matches.value_of("STOP").unwrap(); - let stop_addr: u32 = ::parse_int::parse(stop_addr).expect("Invalid address flag"); - - let file_path = matches.value_of("INPUT").unwrap(); - let dol_file = std::fs::File::open(file_path).expect("Failed to read file"); - let dol = Dol::read_from(&dol_file).expect("Invalid DOL file"); - drop(dol_file); - let mut bytes = vec![0u8; (stop_addr - start_addr) as usize]; - dol.virtual_read(&mut bytes, start_addr) - .expect("Invalid address range"); - - // Create control flow graph. - let ins_list: Vec = disasm_iter(&bytes, start_addr).collect(); - let basic_slices = BasicSlices::from_code(&ins_list); - let graph = FlowGraph::from_basic_slices(&basic_slices, &ins_list); - - // Output graphviz. - let graphviz = Dot::with_config( - &graph.graph, - &[DotConfig::EdgeNoLabel, DotConfig::GraphContentOnly], - ); - println!( - concat!( - "digraph func {{\n", - "node [shape=record fontname=Arial];\n", - "{:?}\n", - "}}" - ), - graphviz - ); -} diff --git a/flow-graph/src/slices.rs b/flow-graph/src/slices.rs deleted file mode 100644 index 6b62759..0000000 --- a/flow-graph/src/slices.rs +++ /dev/null @@ -1,62 +0,0 @@ -use std::collections::{BTreeSet, HashSet}; - -use ppc750cl::{Ins, Opcode}; - -/// The instruction address divided by four. -pub type CodeIdx = u32; - -pub struct BasicSlices { - /// The indexes separating instructions into basic blocks. - /// Used to create a list of consecutive basic blocks. - pub cuts: BTreeSet, - /// The possible branches from one instruction to another. - /// Used to link together basic blocks into a directed graph. - pub branches: HashSet<(CodeIdx, CodeIdx)>, -} - -impl BasicSlices { - /// Computes basic slices from instructions. - pub fn from_code(code: &[Ins]) -> Self { - let mut cuts = BTreeSet::::new(); - let mut branches = HashSet::<(CodeIdx, CodeIdx)>::new(); - for ins in code { - let cur_index = ins.addr / 4; - let is_control_flow_ins = match ins.op { - // Direct branches are control flow instructions if they don't save the link register. - // If they do, we encountered a function call. - Opcode::B | Opcode::Bc => !ins.field_LK(), - // Switch table - Opcode::Bcctr => panic!("jump tables not supported yet"), - _ => false, - }; - if !is_control_flow_ins { - continue; - } - // We encountered some kind of control flow instruction. - if ins.field_BO() == 20 && ins.field_BI() == 0 { - // There's a possibility that branch can be taken. - // Branch destinations are always the first instruction of a block. - // Thus, we also found the end of another block. - let new_index = ins.branch_dest().unwrap() / 4; - cuts.insert(new_index); - branches.insert((cur_index, new_index)); - } - if is_conditional_branch(ins) { - // There's a possibility that branch is not taken. - // End block anyways. - cuts.insert(cur_index + 1); - branches.insert((cur_index, cur_index + 1)); - } - } - Self { cuts, branches } - } -} - -fn is_conditional_branch(ins: &Ins) -> bool { - match ins.op { - Opcode::Bc | Opcode::Bcctr | Opcode::Bclr => (), - _ => return false, - }; - // Check whether bits "branch always". - ins.field_BO() & 0b10100 != 0b10100 -} diff --git a/fuzz/Cargo.toml b/fuzz/Cargo.toml index 138eca2..59f229d 100644 --- a/fuzz/Cargo.toml +++ b/fuzz/Cargo.toml @@ -1,13 +1,14 @@ [package] name = "ppc750cl-fuzz" -version = "0.2.0" +version = "0.3.0" edition = "2021" authors = ["Richard Patel "] license = "GPL-3.0-or-later" description = "Complete fuzzer for ppc750cl" repository = "https://github.com/terorie/ppc750cl" +publish = false [dependencies] clap = "3" num_cpus = "1.13" -ppc750cl = { path = "../disasm", version = "0.2.0" } +ppc750cl = { path = "../disasm" } diff --git a/fuzz/src/main.rs b/fuzz/src/main.rs index ed0e5b5..bed61b8 100644 --- a/fuzz/src/main.rs +++ b/fuzz/src/main.rs @@ -5,7 +5,6 @@ use std::sync::atomic::{AtomicU32, Ordering}; use std::sync::Arc; use std::time::{Duration, Instant}; -use ppc750cl::formatter::FormattedIns; use ppc750cl::Ins; fn main() { @@ -91,10 +90,7 @@ struct Fuzzer { impl Fuzzer { fn new(range: Range) -> Self { - Self { - range, - counter: Arc::new(AtomicU32::new(0)), - } + Self { range, counter: Arc::new(AtomicU32::new(0)) } } fn dispatch(&self) -> std::thread::JoinHandle<()> { @@ -104,8 +100,8 @@ impl Fuzzer { let range = self.range.clone(); std::thread::spawn(move || { for x in range.clone() { - let ins = Ins::new(x, 0x8000_0000); - writeln!(&mut devnull, "{}", FormattedIns(ins)).unwrap(); + let ins = Ins::new(x); + writeln!(&mut devnull, "{}", ins.simplified()).unwrap(); if x % (1 << 19) == 0 { counter.store(x, Ordering::Relaxed); } diff --git a/genisa/Cargo.toml b/genisa/Cargo.toml index 625e8b8..6be35a7 100644 --- a/genisa/Cargo.toml +++ b/genisa/Cargo.toml @@ -1,17 +1,23 @@ [package] name = "ppc750cl-genisa" -version = "0.2.0" +version = "0.3.0" edition = "2021" -authors = ["Richard Patel "] -license = "GPL-3.0-or-later" +authors = ["Luke Street "] +license = "MIT OR Apache-2.0" description = "Rust code generator for ppc750cl" -repository = "https://github.com/terorie/ppc750cl" - +repository = "https://github.com/encounter/ppc750cl" +publish = false [dependencies] -itertools = "0.10" +anyhow = "1.0" +log = "0.4" +num-traits = "0.2" +prettyplease = "0.2" proc-macro2 = "1.0" quote = "1.0" -syn = "1.0" serde = { version = "1.0", features = ["derive"] } -serde_yaml = "0.8" +serde_yaml = "0.9" +simple_logger = "4.3" +syn = { version = "2", default-features = false, features = ["full", "parsing"] } +phf = "0.11" +phf_codegen = "0.11" diff --git a/genisa/src/asm.rs b/genisa/src/asm.rs new file mode 100644 index 0000000..c42a10c --- /dev/null +++ b/genisa/src/asm.rs @@ -0,0 +1,306 @@ +use crate::condition::{parse_conditions, replace_fields, ConditionOp, ConditionValue}; +use crate::isa::{ + modifiers_iter, modifiers_valid, to_ident, Field, HexLiteral, Isa, Mnemonic, Opcode, + SignedHexLiteral, +}; +use anyhow::{bail, Context, Result}; +use proc_macro2::{Literal, TokenStream}; +use quote::{format_ident, quote}; +use std::collections::HashMap; + +pub fn gen_asm(isa: &Isa, max_args: usize) -> Result { + let mut functions = TokenStream::new(); + + let mut func_map = phf_codegen::Map::new(); + for opcode in &isa.opcodes { + let name = format_ident!("gen_{}", opcode.ident()); + let inner = gen_opcode(opcode, isa)?; + functions.extend(quote! { + fn #name(args: &Arguments, modifiers: u32) -> Result { #inner } + }); + } + + let mut mnemonic_map = HashMap::>::new(); + for mnemonic in &isa.mnemonics { + mnemonic_map.entry(mnemonic.name.clone()).or_default().push(mnemonic.clone()); + } + for (name, mnemonics) in &mnemonic_map { + let fn_name = format!("gen_{}", to_ident(name)); + let fn_ident = format_ident!("{}", fn_name); + let mut inner; + if mnemonics.len() > 1 { + inner = TokenStream::new(); + let mut max_args = 0; + for mnemonic in mnemonics { + let gen = gen_mnemonic(mnemonic, isa, false)?; + let arg_n = Literal::usize_unsuffixed(mnemonic.args.len()); + inner.extend(quote! { + #arg_n => { #gen } + }); + max_args = max_args.max(mnemonic.args.len()); + } + let max_args = Literal::usize_unsuffixed(max_args); + inner.extend(quote! { + value => Err(ArgumentError::ArgCount { value, expected: #max_args }) + }); + inner = quote! { match arg_count(args) { #inner } }; + } else { + inner = gen_mnemonic(mnemonics.first().unwrap(), isa, true)?; + } + functions.extend(quote! { + fn #fn_ident(args: &Arguments, modifiers: u32) -> Result { #inner } + }); + } + + for (opcode, modifiers) in isa.opcodes.iter().flat_map(|o| { + modifiers_iter(&o.modifiers, isa).filter(|m| modifiers_valid(m)).map(move |m| (o, m)) + }) { + let suffix = modifiers.iter().map(|m| m.suffix).collect::(); + let mut pattern = 0; + for modifier in &modifiers { + pattern |= modifier.mask(); + } + func_map.entry( + format!("{}{}", opcode.name, suffix), + &format!("(gen_{}, {:#x})", opcode.ident(), pattern), + ); + } + + for (mnemonic, modifiers) in mnemonic_map.iter().flat_map(|(_, mnemonics)| { + let mnemonic = mnemonics.first().unwrap(); + let opcode = isa.find_opcode(&mnemonic.opcode).unwrap(); + let modifiers = mnemonic.modifiers.as_deref().unwrap_or(&opcode.modifiers); + modifiers_iter(modifiers, isa).filter(|m| modifiers_valid(m)).map(move |m| (mnemonic, m)) + }) { + let suffix = modifiers.iter().map(|m| m.suffix).collect::(); + let mut pattern = 0; + for modifier in &modifiers { + pattern |= modifier.mask(); + } + func_map.entry( + format!("{}{}", mnemonic.name, suffix), + &format!("(gen_{}, {:#x})", to_ident(&mnemonic.name), pattern), + ); + } + + let func_map = syn::parse_str::(&func_map.build().to_string())?; + let max_args = Literal::usize_unsuffixed(max_args); + Ok(quote! { + #![allow(unused)] + #![cfg_attr(rustfmt, rustfmt_skip)] + use crate::types::*; + pub type Arguments = [Argument; #max_args]; + #functions + type MnemonicFn = fn(&Arguments, u32) -> Result; + const MNEMONIC_MAP: phf::Map<&'static str, (MnemonicFn, u32)> = #func_map; + pub fn assemble(mnemonic: &str, args: &Arguments) -> Result { + if let Some(&(fn_ptr, modifiers)) = MNEMONIC_MAP.get(mnemonic) { + fn_ptr(args, modifiers) + } else { + Err(ArgumentError::UnknownMnemonic) + } + } + }) +} + +fn gen_parse_field(field: &Field, i: usize) -> Result<(TokenStream, bool)> { + let Some(bits) = field.bits else { bail!("Field {} has no bits", field.name) }; + let i = Literal::usize_unsuffixed(i); + Ok(if field.signed { + let max_value = 1 << (bits.len() - 1 + field.shift_left); + let min_value = SignedHexLiteral(-max_value); + let max_value = SignedHexLiteral(max_value); + (quote! { parse_signed(args, #i, #min_value, #max_value)? }, true) + } else { + let min_value = HexLiteral(0); + let max_value = HexLiteral(bits.max_value() << field.shift_left); + (quote! { parse_unsigned(args, #i, #min_value, #max_value)? }, false) + }) +} + +fn gen_field( + field: &Field, + mut accessor: TokenStream, + finalize: fn(TokenStream) -> TokenStream, + signed: bool, +) -> Result { + let Some(bits) = field.bits else { bail!("Field {} has no bits", field.name) }; + let mut shift_right = bits.shift(); + let mut shift_left = field.shift_left; + if shift_right == shift_left { + // Optimization: these cancel each other out + // Adjust subsequent operations to operate on the full value + shift_right = 0; + shift_left = 0; + } + + // Handle the operations (in reverse order from disassembly) + let mut operations = TokenStream::new(); + let mut inner; + + if signed { + accessor = quote! { #accessor as u32 }; + } + + // Swap 5-bit halves (SPR, TBR) + if field.split { + operations.extend(quote! { + value = ((value & 0b11111_00000) >> 5) | ((value & 0b00000_11111) << 5); + }); + inner = quote! { value }; + } else { + inner = accessor.clone(); + } + + // Handle left shift + if shift_left > 0 { + let shift_left = Literal::u8_unsuffixed(shift_left); + inner = quote! { (#inner >> #shift_left) }; + } + + // Mask + let mask = HexLiteral(bits.mask() >> shift_right); + inner = quote! { #inner & #mask }; + + // Shift right + if shift_right > 0 { + let shift = Literal::u8_unsuffixed(shift_right); + inner = quote! { (#inner) << #shift }; + } + + if operations.is_empty() { + Ok(finalize(inner)) + } else { + inner = finalize(inner); + Ok(quote! {{ + let mut value = #accessor; + #operations + #inner + }}) + } +} + +fn gen_opcode(opcode: &Opcode, isa: &Isa) -> Result { + let mut args = TokenStream::new(); + for (i, arg) in opcode.args.iter().enumerate() { + let field = isa.find_field(arg).unwrap(); + let comment = format!(" {}", field.name); + let (accessor, signed) = gen_parse_field(field, i)?; + let value = gen_field(field, accessor, |s| s, signed)?; + args.extend(quote! { + #[comment = #comment] + code |= #value; + }); + } + + let arg_count = Literal::usize_unsuffixed(opcode.args.len()); + let pattern = HexLiteral(opcode.pattern); + Ok(quote! { + check_arg_count(args, #arg_count)?; + let mut code = #pattern | modifiers; + #args + Ok(code) + }) +} + +fn gen_mnemonic(mnemonic: &Mnemonic, isa: &Isa, check_arg_count: bool) -> Result { + let Some(opcode) = isa.find_opcode(&mnemonic.opcode) else { + bail!("Unknown opcode {}", mnemonic.opcode) + }; + let mut args = TokenStream::new(); + for (i, arg) in mnemonic.args.iter().enumerate() { + let comment = format!(" {}", arg); + let arg = gen_argument(&mnemonic.args, i, isa, mnemonic.replace_assemble.get(arg))?; + args.extend(quote! { + #[comment = #comment] + code |= #arg; + }); + } + + let mut pattern = opcode.pattern; + for condition in parse_conditions(&mnemonic.condition, isa)? { + if condition.op == ConditionOp::Eq { + match condition.value { + ConditionValue::ConstantUnsigned(value) => { + pattern |= condition.field.shift_value(value); + } + ConditionValue::ConstantSigned(value) => { + pattern |= condition.field.shift_value(value as u32); + } + ConditionValue::Field(in_field) => { + let comment = format!(" {}", condition.field.name); + let arg_n = mnemonic + .args + .iter() + .position(|a| a == &in_field.name) + .with_context(|| { + format!("Mnemonic {}: unknown field {}", mnemonic.name, in_field.name) + })?; + let (accessor, signed) = gen_parse_field(in_field, arg_n)?; + let arg = gen_field(condition.field, accessor, |s| s, signed)?; + args.extend(quote! { + #[comment = #comment] + code |= #arg; + }); + } + ConditionValue::Complex(c) => { + let comment = format!(" {}", condition.field.name); + let mut any_signed = false; + let arg = replace_fields(c, isa, |f| { + let arg_n = + mnemonic.args.iter().position(|a| a == &f.name).with_context(|| { + format!("Mnemonic {}: unknown field {}", mnemonic.name, f.name) + })?; + let (s, signed) = gen_parse_field(f, arg_n)?; + any_signed |= signed; + Ok(s) + })?; + let arg = gen_field(condition.field, quote! { (#arg) }, |s| s, any_signed)?; + args.extend(quote! { + #[comment = #comment] + code |= #arg; + }); + } + } + } + } + + let arg_count = Literal::usize_unsuffixed(mnemonic.args.len()); + let mut result = TokenStream::new(); + if check_arg_count { + result.extend(quote! { check_arg_count(args, #arg_count)?; }); + } + + let pattern = HexLiteral(pattern); + result.extend(quote! { + let mut code = #pattern | modifiers; + #args + Ok(code) + }); + Ok(result) +} + +fn gen_argument( + args: &[String], + arg_n: usize, + isa: &Isa, + replace: Option<&String>, +) -> Result { + let field = &args[arg_n]; + let Some(field) = isa.find_field(field) else { bail!("Unknown field {}", field) }; + if let Some(replace) = replace { + let mut any_signed = false; + let stream = replace_fields(replace, isa, |f| { + let arg_n = args.iter().position(|a| a == &f.name).with_context(|| { + format!("Field {} references unknown argument {}", field.name, f.name) + })?; + let (parse, signed) = gen_parse_field(field, arg_n)?; + any_signed |= signed; + Ok(parse) + })?; + gen_field(field, quote! { (#stream) }, |s| s, any_signed) + } else { + let (accessor, signed) = gen_parse_field(field, arg_n)?; + gen_field(field, accessor, |s| s, signed) + } +} diff --git a/genisa/src/condition.rs b/genisa/src/condition.rs new file mode 100644 index 0000000..2e76f7e --- /dev/null +++ b/genisa/src/condition.rs @@ -0,0 +1,166 @@ +use std::str::FromStr; + +use anyhow::{anyhow, Context, Result}; +use proc_macro2::{Group, Ident, TokenStream, TokenTree}; +use quote::quote; + +use crate::isa::{parse_signed, parse_unsigned, Field, HexLiteral, Isa, SignedHexLiteral}; + +/// A condition that must be met for a modifier to be applied +/// or for a simplified mnemonic to be matched. +#[derive(Clone, Debug)] +pub struct Condition<'a> { + pub field: &'a Field, + pub field_mask: u32, + pub op: ConditionOp, + pub value: ConditionValue<'a>, +} + +/// The operation of a complex condition. +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +pub enum ConditionOp { + /// Equal to. (e.g. `MB == 0`) + Eq, + /// Not equal to. (e.g. `simm != -0x8000`) + Ne, + /// Less than. (e.g. `simm < 0`) + Lt, + /// Greater than. (e.g. `SH > 16`) + Gt, + /// Less than or equal to. (e.g. `SH <= 16`) + Lte, + /// Greater than or equal to. (e.g. `SH >= 32 - MB`) + Gte, +} + +/// The value of a condition. +#[derive(Clone, Debug)] +pub enum ConditionValue<'a> { + /// A constant unsigned value. (e.g. `MB == 0`) + ConstantUnsigned(u32), + /// A constant signed value. (e.g. `simm != -0x8000`) + ConstantSigned(i32), + /// A field value. (e.g. `rB == rS`) + Field(&'a Field), + /// A complex condition. (e.g. `SH >= 32 - MB`) + Complex(&'a str), +} + +/// Parse a condition string into a list of conditions. (e.g. `SH >= 32 - MB && MB == 0`) +/// Maybe turn this into a real lexer/parser if it gets more complex. +pub fn parse_conditions<'a>(condition: &'a str, isa: &'a Isa) -> Result>> { + let mut conditions = Vec::new(); + for tok in condition.split(" && ") { + let (mut field, value, op) = if let Some((field, value)) = tok.split_once(" == ") { + (field, value, ConditionOp::Eq) + } else if let Some((field, value)) = tok.split_once(" != ") { + (field, value, ConditionOp::Ne) + } else if let Some((field, value)) = tok.split_once(" < ") { + (field, value, ConditionOp::Lt) + } else if let Some((field, value)) = tok.split_once(" > ") { + (field, value, ConditionOp::Gt) + } else if let Some((field, value)) = tok.split_once(" <= ") { + (field, value, ConditionOp::Lte) + } else if let Some((field, value)) = tok.split_once(" >= ") { + (field, value, ConditionOp::Gte) + } else { + log::error!("Invalid condition: {}", tok); + continue; + }; + let mut field_mask = u32::MAX; + if let Some((n, mask)) = field.split_once(" & ") { + field = n; + field_mask = parse_unsigned(mask)?; + }; + let field = isa + .find_field(field) + .with_context(|| format!("Condition references unknown field {}", field))?; + let value = if let Ok(value) = parse_unsigned(value) { + ConditionValue::ConstantUnsigned(value) + } else if let Ok(value) = parse_signed(value) { + ConditionValue::ConstantSigned(value) + } else if let Some(field) = isa.find_field(value) { + ConditionValue::Field(field) + } else { + ConditionValue::Complex(value) + }; + conditions.push(Condition { field, field_mask, op, value }); + } + Ok(conditions) +} + +impl Condition<'_> { + pub fn to_token_stream(&self, isa: &Isa, self_ident: Ident) -> Result { + // Accessor + let field = self.field; + let mut accessor = quote!(#self_ident.#field()); + if self.field_mask != u32::MAX { + let mask = HexLiteral(self.field_mask); + accessor = quote! { (#accessor & #mask) }; + } + + // Operator + let op = match self.op { + ConditionOp::Eq => quote! { == }, + ConditionOp::Ne => quote! { != }, + ConditionOp::Lt => quote! { < }, + ConditionOp::Gt => quote! { > }, + ConditionOp::Lte => quote! { <= }, + ConditionOp::Gte => quote! { >= }, + }; + + // Value + let value = match self.value { + ConditionValue::ConstantUnsigned(v) => { + let v = HexLiteral(v); + quote! { #v } + } + ConditionValue::ConstantSigned(v) => { + let v = SignedHexLiteral(v); + quote! { #v } + } + ConditionValue::Field(f) => { + quote! { #self_ident.#f() } + } + ConditionValue::Complex(c) => { + replace_fields(c, isa, |f| Ok(quote! { #self_ident.#f() }))? + } + }; + + Ok(quote! { #accessor #op #value }) + } +} + +pub fn replace_fields( + s: &str, + isa: &Isa, + mut accessor: impl FnMut(&Field) -> Result, +) -> Result { + fn replace_inner( + s: TokenStream, + isa: &Isa, + accessor: &mut impl FnMut(&Field) -> Result, + ) -> Result { + s.into_iter() + .map(|t| -> Result { + match &t { + TokenTree::Ident(ident) => { + if let Some(field) = isa.find_field(&ident.to_string()) { + return accessor(field); + } + } + TokenTree::Group(g) => { + return Ok(TokenStream::from(TokenTree::Group(Group::new( + g.delimiter(), + replace_inner(g.stream(), isa, accessor)?, + )))); + } + _ => {} + } + Ok(TokenStream::from(t)) + }) + .collect::>() + } + let stream = TokenStream::from_str(s).map_err(|e| anyhow!("{}", e))?; + replace_inner(stream, isa, &mut accessor) +} diff --git a/genisa/src/disasm.rs b/genisa/src/disasm.rs new file mode 100644 index 0000000..9d37961 --- /dev/null +++ b/genisa/src/disasm.rs @@ -0,0 +1,416 @@ +use crate::condition::{parse_conditions, replace_fields}; +use crate::ident; +use crate::isa::{modifiers_iter, modifiers_valid, HexLiteral, Isa, Opcode}; +use anyhow::{bail, ensure, Result}; +use proc_macro2::{Literal, TokenStream}; +use quote::{format_ident, quote}; +use std::collections::HashMap; + +pub fn gen_disasm(isa: &Isa, max_args: usize) -> Result { + // The entry table allows us to quickly find the range of possible opcodes + // for a given 6-bit prefix. 2*64 bytes should fit in a cache line (or two). + struct OpcodeEntry { + start: u8, + count: u8, + } + let mut sorted_ops = Vec::::new(); + let mut entries = Vec::::new(); + for i in 0..64 { + let mut entry = OpcodeEntry { start: 0, count: 0 }; + for opcode in &isa.opcodes { + if (opcode.pattern >> 26) as u8 == i { + if entry.count == 0 { + entry.start = sorted_ops.len() as u8; + } + // Sanity check for duplicate opcodes + if sorted_ops.iter().any(|op| op.name == opcode.name) { + bail!("Duplicate opcode: {}", opcode.name); + } + sorted_ops.push(opcode.clone()); + entry.count += 1; + } + } + if entry.count > 1 { + log::info!("{:#X}: {} opcodes", i, entry.count); + } else if let Some(op) = (entry.count == 1).then(|| &sorted_ops[entry.start as usize]) { + log::info!("{:#X}: {}", i, op.name); + } else { + log::info!("{:#X}: ", i); + } + entries.push(entry); + } + ensure!(sorted_ops.len() == isa.opcodes.len()); + + // Generate the opcode entries table + let mut opcode_entries = TokenStream::new(); + for entry in &entries { + let start = Literal::u8_unsuffixed(entry.start); + let end = Literal::u8_unsuffixed(entry.start + entry.count); + opcode_entries.extend(quote! { (#start, #end), }); + } + + // Generate the opcode tables + let mut opcode_patterns = TokenStream::new(); + let mut opcode_enum = TokenStream::new(); + let mut opcode_names = TokenStream::new(); + for (idx, opcode) in sorted_ops.iter().enumerate() { + let bitmask = HexLiteral(opcode.mask(isa)); + let pattern = HexLiteral(opcode.pattern); + let enum_idx = Literal::u8_unsuffixed(idx as u8); + let name = &opcode.name; + opcode_patterns.extend(quote! { (#bitmask, #pattern), }); + opcode_names.extend(quote! { #name, }); + let doc = opcode.doc(); + let variant = opcode.variant(); + opcode_enum.extend(quote! { + #[doc = #doc] + #variant = #enum_idx, + }); + } + + // Generate field and modifier accessors + let mut ins_fields = TokenStream::new(); + for field in &isa.fields { + let Some(bits) = field.bits else { + continue; + }; + // TODO get rid of .nz hack + if field.name.ends_with(".nz") { + continue; + } + + let mut sign_bit = bits.len() - 1; + let mut shift_right = bits.shift(); + let mut shift_left = field.shift_left; + if shift_right == shift_left { + // Optimization: these cancel each other out + // Adjust subsequent operations to operate on the full value + sign_bit += shift_left; + shift_right = 0; + shift_left = 0; + } + + // Shift right and mask + let mut inner = quote! { self.code }; + if shift_right > 0 { + let shift = Literal::u8_unsuffixed(shift_right); + inner = quote! { (#inner >> #shift) }; + } + let mask = HexLiteral(bits.mask() >> shift_right); + inner = quote! { #inner & #mask }; + + // Determine the smallest integer type that can hold the value + let num_bits = bits.len() + field.shift_left; + let (out_type, cast) = match (num_bits, field.signed) { + (1..=8, false) => (ident!(u8), true), + (9..=16, false) => (ident!(u16), true), + (17..=32, false) => (ident!(u32), false), + (1..=8, true) => (ident!(i8), true), + (9..=16, true) => (ident!(i16), true), + (17..=32, true) => (ident!(i32), true), + (v, _) => bail!("Unsupported field size {v}"), + }; + + // Handle sign extension + if field.signed { + let sign_value = HexLiteral(1 << sign_bit); + inner = quote! { ((#inner) ^ #sign_value).wrapping_sub(#sign_value) as #out_type }; + } else if cast { + inner = quote! { (#inner) as #out_type }; + } + + // Handle left shift + if shift_left > 0 { + let shift_left = Literal::u8_unsuffixed(shift_left); + inner = quote! { (#inner) << #shift_left }; + } + + // Swap 5-bit halves (SPR, TBR) + if field.split { + inner = quote! { + let value = #inner; + ((value & 0b11111_00000) >> 5) | ((value & 0b00000_11111) << 5) + }; + } + + // Write the accessor + let doc = field.doc(); + ins_fields.extend(quote! { + #[doc = #doc] + #[inline(always)] + pub const fn #field(&self) -> #out_type { #inner } + }); + } + for modifier in &isa.modifiers { + let mask = HexLiteral(modifier.mask()); + let mut inner = quote! { (self.code & #mask) == #mask }; + if let Some(condition) = &modifier.condition { + for condition in parse_conditions(condition, isa)? { + let stream = condition.to_token_stream(isa, ident!(self))?; + inner.extend(quote! { && #stream }); + } + }; + + // Write the accessor + let doc = modifier.doc(); + ins_fields.extend(quote! { + #[doc = #doc] + #[inline(always)] + pub const fn #modifier(&self) -> bool { #inner } + }); + } + + // Generate simplified mnemonics + let mut mnemonic_functions = TokenStream::new(); + let mut base_functions_ref = TokenStream::new(); + let mut simplified_functions_ref = TokenStream::new(); + for opcode in &sorted_ops { + let mnemonics = + isa.mnemonics.iter().filter(|m| m.opcode == opcode.name).collect::>(); + let mut mnemonic_conditions = TokenStream::new(); + + // Generate conditions for each simplified mnemonic + for mnemonic in &mnemonics { + let conditions = parse_conditions(&mnemonic.condition, isa)? + .iter() + .map(|c| c.to_token_stream(isa, ident!(ins))) + .collect::>>()?; + let modifiers = mnemonic.modifiers.as_deref().unwrap_or(&opcode.modifiers); + let inner = gen_mnemonic( + &mnemonic.name, + &mnemonic.args, + modifiers, + isa, + max_args, + Some(&mnemonic.replace), + )?; + mnemonic_conditions.extend(quote! { + if #(#conditions)&&* { + return #inner; + } + }); + } + + // Fallback to the base opcode name if no mnemonic matches + let inner = + gen_mnemonic(&opcode.name, &opcode.args, &opcode.modifiers, isa, max_args, None)?; + let base_name = format_ident!("base_{}", opcode.ident()); + if mnemonics.is_empty() { + mnemonic_functions.extend(quote! { + const fn #base_name(ins: &Ins) -> (&'static str, Arguments) { + #inner + } + }); + base_functions_ref.extend(quote! { #base_name, }); + simplified_functions_ref.extend(quote! { #base_name, }); + } else { + let simplified_name = format_ident!("simplified_{}", opcode.ident()); + mnemonic_functions.extend(quote! { + #[inline(always)] + const fn #base_name(ins: &Ins) -> (&'static str, Arguments) { + #inner + } + const fn #simplified_name(ins: &Ins) -> (&'static str, Arguments) { + #mnemonic_conditions + #base_name(ins) + } + }); + base_functions_ref.extend(quote! { #base_name, }); + simplified_functions_ref.extend(quote! { #simplified_name, }); + } + } + let mut none_args = TokenStream::new(); + for _ in 0..max_args { + none_args.extend(quote! { Argument::None, }); + } + mnemonic_functions.extend(quote! { + const fn mnemonic_illegal(_ins: &Ins) -> (&'static str, Arguments) { + ("", [#none_args]) + } + }); + + // TODO rework defs/uses to account for modifiers and special registers (CTR, LR, etc) + let mut defs_uses_functions = TokenStream::new(); + let mut defs_refs = TokenStream::new(); + let mut uses_refs = TokenStream::new(); + for opcode in &sorted_ops { + let mut defs = TokenStream::new(); + let mut uses = TokenStream::new(); + let mut defs_count = 0; + for def in &opcode.defs { + if isa.find_field(def).is_some_and(|f| f.arg.is_none()) { + continue; + } + let arg = gen_argument(def, isa, None)?; + defs.extend(quote! { #arg, }); + defs_count += 1; + } + for _ in defs_count..max_args { + defs.extend(quote! { Argument::None, }); + } + let mut use_count = 0; + for use_ in &opcode.uses { + if let Some(use_) = use_.strip_suffix(".nz") { + let Some(field) = isa.find_field(use_) else { bail!("Unknown field {}", use_) }; + let ident = field.ident(); + let arg = gen_argument(use_, isa, None)?; + uses.extend(quote! { if ins.#ident() != 0 { #arg } else { Argument::None }, }); + use_count += 1; + continue; + } else if isa.find_field(use_).is_some_and(|f| f.arg.is_none()) { + continue; + } + let arg = gen_argument(use_, isa, None)?; + uses.extend(quote! { #arg, }); + use_count += 1; + } + for _ in use_count..max_args { + uses.extend(quote! { Argument::None, }); + } + let defs_name = format_ident!("defs_{}", opcode.ident()); + let uses_name = format_ident!("uses_{}", opcode.ident()); + defs_uses_functions.extend(quote! { + const fn #defs_name(ins: &Ins) -> Arguments { [#defs] } + const fn #uses_name(ins: &Ins) -> Arguments { [#uses] } + }); + defs_refs.extend(quote! { #defs_name, }); + uses_refs.extend(quote! { #uses_name, }); + } + defs_uses_functions.extend(quote! { + const fn defs_uses_illegal(_ins: &Ins) -> Arguments { [#none_args] } + }); + + // Filling the tables to 256 entries to avoid bounds checks + for _ in sorted_ops.len()..256 { + opcode_patterns.extend(quote! { (0, 0), }); + opcode_names.extend(quote! { "", }); + base_functions_ref.extend(quote! { mnemonic_illegal, }); + simplified_functions_ref.extend(quote! { mnemonic_illegal, }); + defs_refs.extend(quote! { defs_uses_illegal, }); + uses_refs.extend(quote! { defs_uses_illegal, }); + } + + let max_args = Literal::usize_unsuffixed(max_args); + Ok(quote! { + #![allow(unused)] + #![cfg_attr(rustfmt, rustfmt_skip)] + use crate::disasm::*; + #[doc = " The entry table allows us to quickly find the range of possible opcodes for a"] + #[doc = " given 6-bit prefix. 2*64 bytes should fit in a cache line (or two)."] + const OPCODE_ENTRIES: [(u8, u8); 64] = [#opcode_entries]; + #[doc = " The bitmask and pattern for each opcode."] + const OPCODE_PATTERNS: [(u32, u32); 256] = [#opcode_patterns]; + #[doc = " The name of each opcode."] + const OPCODE_NAMES: [&str; 256] = [#opcode_names]; + + #[derive(Copy, Clone, Debug, Default, PartialEq, Eq)] + #[repr(u8)] + #[non_exhaustive] + pub enum Opcode { + #[doc = " An illegal or unknown opcode"] + #[default] + Illegal = u8::MAX, + #opcode_enum + } + impl Opcode { + #[inline] + pub const fn _mnemonic(self) -> &'static str { + OPCODE_NAMES[self as usize] + } + + #[inline] + pub const fn _detect(code: u32) -> Self { + let entry = OPCODE_ENTRIES[(code >> 26) as usize]; + let mut i = entry.0; + while i < entry.1 { + let pattern = OPCODE_PATTERNS[i as usize]; + if (code & pattern.0) == pattern.1 { + #[comment = " Safety: The enum is repr(u8) and marked non_exhaustive"] + return unsafe { core::mem::transmute(i) }; + } + i += 1; + } + Self::Illegal + } + } + + impl Ins { + #ins_fields + } + + pub type Arguments = [Argument; #max_args]; + pub type MnemonicFunction = fn(&Ins) -> (&'static str, Arguments); + #mnemonic_functions + pub const BASE_MNEMONICS: [MnemonicFunction; 256] = [#base_functions_ref]; + pub const SIMPLIFIED_MNEMONICS: [MnemonicFunction; 256] = [#simplified_functions_ref]; + #defs_uses_functions + pub type DefsUsesFunction = fn(&Ins) -> Arguments; + pub const DEFS_FUNCTIONS: [DefsUsesFunction; 256] = [#defs_refs]; + pub const USES_FUNCTIONS: [DefsUsesFunction; 256] = [#uses_refs]; + }) +} + +fn modifier_names(name: &str, modifiers: &[String], isa: &Isa) -> Vec { + // For every combination of modifiers, generate a name + let mut names = Vec::with_capacity(1 << modifiers.len()); + for v in modifiers_iter(modifiers, isa) { + if modifiers_valid(&v) { + let mut name = name.to_string(); + for modifier in &v { + name.push(modifier.suffix); + } + names.push(name); + } else { + names.push("".to_string()); + } + } + names +} + +fn gen_argument(field: &str, isa: &Isa, replace: Option<&String>) -> Result { + let Some(field) = isa.find_field(field) else { bail!("Unknown field {}", field) }; + let Some(arg) = &field.arg else { bail!("Field {} has no argument", field.name) }; + let value = if let Some(replace) = replace { + let stream = replace_fields(replace, isa, |f| Ok(quote! { ins.#f() }))?; + quote! { (#stream) } + } else { + quote! { ins.#field() } + }; + let arg = format_ident!("{}", arg); + Ok(quote! { Argument::#arg(#arg(#value as _)) }) +} + +fn gen_mnemonic( + name: &str, + args: &[String], + modifiers: &[String], + isa: &Isa, + max_args: usize, + replace: Option<&HashMap>, +) -> Result { + let mut arguments = TokenStream::new(); + for field in args { + let arg = gen_argument(field, isa, replace.and_then(|m| m.get(field)))?; + arguments.extend(quote! { #arg, }); + } + for _ in args.len()..max_args { + arguments.extend(quote! { Argument::None, }); + } + + if modifiers.is_empty() { + Ok(quote! { (#name, [#arguments]) }) + } else { + let names = modifier_names(name, modifiers, isa); + let mut bitset = quote! { 0 }; + for (i, modifier) in modifiers.iter().enumerate() { + let modifier = isa.find_modifier(modifier).unwrap(); + if i == 0 { + bitset = quote! { ins.#modifier() as usize }; + } else { + let i = Literal::u8_unsuffixed(i as u8); + bitset.extend(quote! { | (ins.#modifier() as usize) << #i }); + } + } + Ok(quote! { ([#(#names),*][#bitset], [#arguments]) }) + } +} diff --git a/genisa/src/isa.rs b/genisa/src/isa.rs new file mode 100644 index 0000000..47ac4cb --- /dev/null +++ b/genisa/src/isa.rs @@ -0,0 +1,416 @@ +use std::collections::HashMap; +use std::{fs::File, path::Path, str::FromStr}; + +use anyhow::{Context, Result}; +use num_traits::PrimInt; +use proc_macro2::{Ident, Span, TokenStream}; +use quote::{format_ident, ToTokens}; +use serde::{Deserialize, Deserializer, Serialize}; + +pub fn load_isa(path: &Path) -> Result { + let yaml_file = + File::open(path).with_context(|| format!("Failed to open file {}", path.display()))?; + let isa: Isa = serde_yaml::from_reader(yaml_file) + .with_context(|| format!("While parsing file {}", path.display()))?; + Ok(isa) +} + +#[derive(Deserialize, Serialize, Clone, Debug, Default)] +#[serde(default)] +pub struct Isa { + pub fields: Vec, + pub modifiers: Vec, + pub opcodes: Vec, + pub mnemonics: Vec, +} + +impl Isa { + pub fn find_field(&self, name: &str) -> Option<&Field> { + self.fields.iter().find(|f| f.name == name) + } + + pub fn find_modifier(&self, name: &str) -> Option<&Modifier> { + self.modifiers.iter().find(|m| m.name == name) + } + + pub fn find_opcode(&self, name: &str) -> Option<&Opcode> { + self.opcodes.iter().find(|o| o.name == name) + } +} + +#[derive(Deserialize, Serialize, Clone, Debug, Default)] +#[serde(default)] +pub struct Field { + pub name: String, + pub desc: String, + #[serde(skip_serializing_if = "Option::is_none")] + pub bits: Option, + pub signed: bool, + pub split: bool, + #[serde(skip_serializing_if = "Option::is_none")] + pub arg: Option, + pub shift_left: u8, +} + +impl Field { + /// Calculate the field mask from its bit range + pub fn mask(&self) -> u32 { + self.bits.map(|b| b.mask()).unwrap_or(0) + } + + /// Shift and mask a value according to the field + pub fn shift_value(&self, mut value: u32) -> u32 { + if self.split { + // Swap 5-bit halves (SPR, TBR) + value = ((value & 0b11111_00000u32) >> 5) | ((value & 0b00000_11111u32) << 5); + } + self.bits.map(|b| b.shift_value(value >> self.shift_left)).unwrap_or(0) + } + + pub fn ident(&self) -> Ident { + format_ident!("field_{}", to_ident(&self.name)) + } + + pub fn doc(&self) -> String { + if self.desc.is_empty() { + format!(" {}", self.name) + } else { + format!(" {}: {}", self.name, self.desc) + } + } +} + +impl ToTokens for Field { + fn to_tokens(&self, tokens: &mut TokenStream) { + self.ident().to_tokens(tokens) + } +} + +#[derive(Deserialize, Serialize, Clone, Debug, Default)] +#[serde(default)] +pub struct Opcode { + pub name: String, + pub desc: String, + pub bitmask: u32, + pub pattern: u32, + #[serde(skip_serializing_if = "Vec::is_empty")] + pub modifiers: Vec, + #[serde(skip_serializing_if = "Vec::is_empty")] + pub args: Vec, + #[serde(skip_serializing_if = "Vec::is_empty")] + pub defs: Vec, + #[serde(skip_serializing_if = "Vec::is_empty")] + pub uses: Vec, +} + +impl Opcode { + /// Calculate the opcode mask from its fields and modifiers + pub fn mask(&self, isa: &Isa) -> u32 { + let mut calc_bitmask = 0u32; + for arg_n in &self.args { + let Some(field) = isa.find_field(arg_n) else { + continue; + }; + calc_bitmask |= field.mask(); + } + for modifier_n in &self.modifiers { + let Some(modifier) = isa.find_modifier(modifier_n) else { + continue; + }; + calc_bitmask |= modifier.mask(); + } + !calc_bitmask + } + + pub fn ident(&self) -> Ident { + Ident::new(&to_ident(&self.name), Span::call_site()) + } + + pub fn variant(&self) -> Ident { + Ident::new(&to_variant(&self.name), Span::call_site()) + } + + pub fn doc(&self) -> String { + if self.desc.is_empty() { + format!(" {}", self.name) + } else { + format!(" {}: {}", self.name, self.desc) + } + } +} + +impl ToTokens for Opcode { + fn to_tokens(&self, tokens: &mut TokenStream) { + self.ident().to_tokens(tokens) + } +} + +#[derive(Deserialize, Serialize, Clone, Debug, Default)] +#[serde(default)] +pub struct Mnemonic { + pub name: String, + pub desc: String, + pub opcode: String, + #[serde(skip_serializing_if = "Option::is_none")] + // Overrides modifier list from opcode + pub modifiers: Option>, + #[serde(skip_serializing_if = "Vec::is_empty")] + pub args: Vec, + pub condition: String, + #[serde(skip_serializing_if = "HashMap::is_empty")] + pub replace: HashMap, + #[serde(skip_serializing_if = "HashMap::is_empty")] + pub replace_assemble: HashMap, +} + +#[derive(Deserialize, Serialize, Clone, Debug, Default)] +#[serde(default)] +pub struct Modifier { + pub name: String, + pub desc: String, + pub suffix: char, + pub bit: u8, + #[serde(skip_serializing_if = "Vec::is_empty")] + pub defs: Vec, + #[serde(skip_serializing_if = "Option::is_none")] + pub condition: Option, +} + +impl Modifier { + /// Calculate the modifier mask from its bit + pub fn mask(&self) -> u32 { + 1 << (31 - self.bit) + } + + pub fn ident(&self) -> Ident { + format_ident!("field_{}", to_ident(&self.name)) + } + + pub fn doc(&self) -> String { + if self.desc.is_empty() { + format!(" {}", self.name) + } else { + format!(" {}: {}", self.name, self.desc) + } + } +} + +impl ToTokens for Modifier { + fn to_tokens(&self, tokens: &mut TokenStream) { + self.ident().to_tokens(tokens) + } +} + +/// A collection of modifiers +type Modifiers<'a> = Vec<&'a Modifier>; + +/// Whether a collection of modifiers is valid (all bits are unique) +pub fn modifiers_valid(modifiers: &Modifiers) -> bool { + let bits = modifiers.iter().map(|m| m.bit).collect::>(); + bits.iter().all(|&b| bits.iter().filter(|&&x| x == b).count() == 1) +} + +/// Iterate over all possible combinations of modifiers +pub fn modifiers_iter<'a>( + modifiers: &'a [String], + isa: &'a Isa, +) -> impl Iterator> { + (0..=(1 << modifiers.len()) - 1).map(move |b| { + modifiers + .iter() + .enumerate() + .filter(|(i, _)| b & (1 << i) != 0) + .map(|(_, m)| isa.find_modifier(m).unwrap()) + .collect::>() + }) +} + +#[derive(Copy, Clone, Debug, Default)] +pub struct BitRange(pub (u8, u8)); + +impl BitRange { + #[inline] + pub fn new(start: u8, end: u8) -> Self { + Self((start, end)) + } + + #[inline] + pub fn start(&self) -> u8 { + self.0 .0 + } + + #[inline] + pub fn end(&self) -> u8 { + self.0 .1 + } + + /// Calculate the mask from the range + #[inline] + pub fn mask(&self) -> u32 { + self.max_value() << self.shift() + } + + /// Number of bits to shift + #[inline] + pub fn shift(&self) -> u8 { + 32 - self.end() + } + + /// Number of bits in the range + #[inline] + pub fn len(&self) -> u8 { + self.end() - self.start() + } + + /// Shift and mask a value according to the range + #[inline] + pub fn shift_value(&self, value: u32) -> u32 { + (value & self.max_value()) << self.shift() + } + + /// Calculate the maximum value that can be represented by the range + #[inline] + pub fn max_value(&self) -> u32 { + (1 << self.len()) - 1 + } +} + +impl<'de> Deserialize<'de> for BitRange { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let range_str: String = Deserialize::deserialize(deserializer)?; + if let Some((start_str, end_str)) = range_str.split_once("..") { + let start = start_str.parse::().map_err(serde::de::Error::custom)?; + let end = end_str.parse::().map_err(serde::de::Error::custom)?; + Ok(Self::new(start, end)) + } else { + let bit_idx = range_str.parse::().map_err(serde::de::Error::custom)?; + Ok(Self::new(bit_idx, bit_idx)) + } + } +} + +impl Serialize for BitRange { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + if self.start() == self.end() { + self.start().serialize(serializer) + } else { + format!("{}..{}", self.start(), self.end()).serialize(serializer) + } + } +} + +pub fn to_ident(key: &str) -> String { + key.to_ascii_lowercase().replace('.', "_").replace('+', "p").replace('-', "m") +} + +pub fn to_variant(key: &str) -> String { + let mut s = String::new(); + let mut chars = key.chars(); + loop { + // Make first char uppercase. + let c = match chars.next() { + None => return s, + Some(c) => c, + }; + s.push(match c { + 'a'..='z' => c.to_ascii_uppercase(), + 'A'..='Z' => c, + _ => panic!("invalid identifier: {}", key), + }); + loop { + let c = match chars.next() { + None => return s, + Some(c) => c, + }; + match c.to_ascii_lowercase() { + '0'..='9' | 'a'..='z' => s.push(c), + '_' => break, + '.' => { + s.push('_'); + break; + } + _ => panic!("invalid character in variant: {}", key), + } + } + } +} + +/// Parse an unsigned number in decimal, binary, or hexadecimal format. +pub fn parse_unsigned(mask: &str) -> Result { + if let Some(mask) = mask.strip_prefix("0b") { + u32::from_str_radix(mask, 2) + } else if let Some(mask) = mask.strip_prefix("0x") { + u32::from_str_radix(mask, 16) + } else { + mask.parse::() + } +} + +/// Parse a signed number in decimal, binary, or hexadecimal format. +pub fn parse_signed(mask: &str) -> Result { + if let Some(mask) = mask.strip_prefix('-') { + if let Some(mask) = mask.strip_prefix("0b") { + i32::from_str_radix(mask, 2).map(|n| -n) + } else if let Some(mask) = mask.strip_prefix("0x") { + i32::from_str_radix(mask, 16).map(|n| -n) + } else { + mask.parse::().map(|n| -n) + } + } else { + parse_unsigned(mask).map(|n| n as i32) + } +} + +pub struct HexLiteral(pub T); + +impl std::fmt::LowerHex for HexLiteral +where + T: std::fmt::LowerHex, +{ + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + std::fmt::LowerHex::fmt(&self.0, f) + } +} + +impl ToTokens for HexLiteral +where + T: std::fmt::LowerHex, +{ + fn to_tokens(&self, tokens: &mut TokenStream) { + let s = format!("{:#x}", self); + tokens.extend(TokenStream::from_str(&s).unwrap()); + } +} + +pub struct SignedHexLiteral(pub T); + +impl std::fmt::LowerHex for SignedHexLiteral +where + T: PrimInt + std::fmt::LowerHex, +{ + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if self.0 < T::zero() { + write!(f, "-")?; + let int = self.0.to_i64().unwrap_or_default(); + std::fmt::LowerHex::fmt(&-int, f) + } else { + std::fmt::LowerHex::fmt(&self.0, f) + } + } +} + +impl ToTokens for SignedHexLiteral +where + T: PrimInt + std::fmt::LowerHex, +{ + fn to_tokens(&self, tokens: &mut TokenStream) { + let s = format!("{:#x}", self); + tokens.extend(TokenStream::from_str(&s).unwrap()); + } +} diff --git a/genisa/src/main.rs b/genisa/src/main.rs index 6ca34cd..6e9d367 100644 --- a/genisa/src/main.rs +++ b/genisa/src/main.rs @@ -1,771 +1,162 @@ -use std::collections::HashMap; -use std::fs::File; -use std::io::Write; -use std::ops::Range; -use std::process::{Command, Stdio}; -use std::str::FromStr; +mod asm; +mod condition; +mod disasm; +mod isa; -use itertools::Itertools; -use proc_macro2::{Group, Ident, Literal, Span, TokenStream, TokenTree}; -use quote::quote; -use serde::{Deserialize, Deserializer}; -use syn::{LitChar, LitInt, LitStr}; +use crate::asm::gen_asm; +use crate::disasm::gen_disasm; +use anyhow::{ensure, Context, Result}; +use condition::{parse_conditions, ConditionOp, ConditionValue}; +use isa::load_isa; +use std::path::Path; -macro_rules! token_stream { - ($stream:ident) => { - TokenStream::from_iter($stream.into_iter()) +/// Identifier literal. +#[macro_export] +macro_rules! ident { + ($name:ident) => { + proc_macro2::Ident::new(stringify!($name), proc_macro2::Span::call_site()) }; } -fn main() { - if let Err(err) = _main() { - eprintln!("{}", err); - std::process::exit(1); - } -} +fn main() -> Result<()> { + simple_logger::SimpleLogger::new().env().init().unwrap(); -type Error = Box; -type Result = std::result::Result; + let isa = load_isa(Path::new("isa.yaml"))?; + // Make sure we can fit the opcodes into a u8 + ensure!(isa.opcodes.len() <= 255); -fn _main() -> Result<()> { - let isa = load_isa()?; - - let mut unformatted_code = Vec::::new(); - writeln!( - &mut unformatted_code, - "{}", - quote! { - use crate::prelude::*; + // Sanity check the opcodes and mnemonics + // Calculate the bitmask for each opcode and compare it to the stored bitmask + let mut max_args = 0; + for opcode in &isa.opcodes { + let mut calc_bitmask = opcode.mask(&isa); + if opcode.bitmask != calc_bitmask { + log::warn!( + "Opcode {}: Calculated bitmask mismatch: {:#010X} != {:#010X} ({:032b} != {:032b})", + opcode.name, + opcode.bitmask, + calc_bitmask, + opcode.bitmask, + calc_bitmask + ); + } + if opcode.pattern & !opcode.bitmask != 0 { + log::warn!( + "Opcode {}: Pattern has bits set outside of bitmask: {:#010X} & !{:#010X} != 0 ({:032b} & !{:032b} != 0)", + opcode.name, + opcode.pattern, + opcode.bitmask, + opcode.pattern, + opcode.bitmask + ); } - )?; - writeln!(&mut unformatted_code, "{}", isa.gen_opcode_enum()?)?; - writeln!(&mut unformatted_code, "{}", isa.gen_field_enum()?)?; - writeln!(&mut unformatted_code, "{}", isa.gen_field_impl()?)?; - writeln!(&mut unformatted_code, "{}", isa.gen_ins_impl()?)?; - let formatted_code = rustfmt(unformatted_code); - File::create("./disasm/src/generated.rs")?.write_all(&formatted_code)?; + // Make sure we can account for every bit with fields and modifiers + for arg in &opcode.args { + let field = isa + .find_field(arg) + .with_context(|| format!("Opcode {}: unknown field {}", opcode.name, arg))?; + calc_bitmask |= field.mask(); + } + for modifier_name in &opcode.modifiers { + let modifier = isa.find_modifier(modifier_name).with_context(|| { + format!("Opcode {}: unknown modifier {}", opcode.name, modifier_name) + })?; + if let Some(condition) = &modifier.condition { + for condition in parse_conditions(condition, &isa)? { + // Only check constant conditions + if condition.op == ConditionOp::Eq + && matches!( + condition.value, + ConditionValue::ConstantUnsigned(_) | ConditionValue::ConstantSigned(_) + ) + { + calc_bitmask |= condition.field.shift_value(condition.field_mask); + } + } + } else { + calc_bitmask |= modifier.mask(); + } + } + if calc_bitmask != u32::MAX { + log::warn!( + "Opcode {}: Calculated bitmask is non-exhaustive: {:#010X}, {:032b}", + opcode.name, + calc_bitmask, + calc_bitmask + ); + } + + max_args = max_args.max(opcode.args.len()); + } + + // Check each mnemonic, make sure we can account for every bit + // with fields, modifiers, and conditions + for mnemonic in &isa.mnemonics { + let opcode = isa.find_opcode(&mnemonic.opcode).with_context(|| { + format!("Mnemonic {}: unknown opcode {}", mnemonic.name, mnemonic.opcode) + })?; + let mut calc_bitmask = opcode.mask(&isa); + for arg in &mnemonic.args { + let field = isa + .find_field(arg) + .with_context(|| format!("Mnemonic {}: unknown field {}", mnemonic.name, arg))?; + calc_bitmask |= field.mask(); + } + for modifier_name in mnemonic.modifiers.as_deref().unwrap_or(&opcode.modifiers) { + let modifier = isa.find_modifier(modifier_name).with_context(|| { + format!("Mnemonic {}: unknown modifier {}", mnemonic.name, modifier_name) + })?; + if let Some(condition) = &modifier.condition { + for condition in parse_conditions(condition, &isa)? { + // Only check constant conditions + if condition.op == ConditionOp::Eq + && matches!( + condition.value, + ConditionValue::ConstantUnsigned(_) | ConditionValue::ConstantSigned(_) + ) + { + calc_bitmask |= condition.field.shift_value(condition.field_mask); + } + } + } else { + calc_bitmask |= modifier.mask(); + } + } + for condition in parse_conditions(&mnemonic.condition, &isa)? { + if condition.op != ConditionOp::Eq { + continue; + } + let field_bitmask = condition.field.shift_value(condition.field_mask); + if calc_bitmask & field_bitmask != 0 { + log::warn!( + "Mnmemonic {}: {:#010X} & {:#010X} != 0", + mnemonic.name, + calc_bitmask, + field_bitmask, + ); + } + calc_bitmask |= field_bitmask; + } + if calc_bitmask != u32::MAX { + log::warn!( + "Mnemonic {}: Calculated bitmask is non-exhaustive: {:#010X}, {:032b}", + mnemonic.name, + calc_bitmask, + calc_bitmask + ); + } + } + + let tokens = gen_disasm(&isa, max_args)?; + let file = syn::parse2(tokens)?; + let formatted = prettyplease::unparse(&file); + std::fs::write("disasm/src/generated.rs", formatted)?; + + let tokens = gen_asm(&isa, max_args)?; + let file = syn::parse2(tokens)?; + let formatted = prettyplease::unparse(&file); + std::fs::write("asm/src/generated.rs", formatted)?; Ok(()) } - -fn rustfmt(code: Vec) -> Vec { - let mut rustfmt = Command::new("rustfmt") - .stdin(Stdio::piped()) - .stdout(Stdio::piped()) - .spawn() - .expect("failed to spawn rustfmt"); - - let mut stdin = rustfmt.stdin.take().unwrap(); - std::thread::spawn(move || { - let _ = stdin.write_all(&code); - }); - - let rustfmt_res = rustfmt.wait_with_output().expect("failed to run rustfmt"); - if !rustfmt_res.status.success() { - panic!("rustfmt failed"); - } - - rustfmt_res.stdout -} - -#[derive(Default)] -pub(crate) struct BitRange(Range); - -impl<'de> Deserialize<'de> for BitRange { - fn deserialize(deserializer: D) -> std::result::Result - where - D: Deserializer<'de>, - { - let range_str: String = Deserialize::deserialize(deserializer)?; - if let Some((start_str, stop_str)) = range_str.split_once("..") { - let start = start_str.parse::().map_err(serde::de::Error::custom)?; - let stop = stop_str.parse::().map_err(serde::de::Error::custom)?; - Ok(Self(start..stop)) - } else { - let bit_idx = range_str.parse::().map_err(serde::de::Error::custom)?; - Ok(Self(bit_idx..bit_idx)) - } - } -} - -#[derive(Deserialize, Default)] -#[serde(default)] -pub(crate) struct Field { - name: String, - desc: String, - bits: BitRange, - signed: bool, - split: bool, - arg: Option, - shift_left: u8, -} - -impl Field { - fn variant_identifier(&self) -> Option { - self.identifier("") - } - - fn identifier(&self, prefix: &str) -> Option { - if self.name.strip_suffix(".nz").is_none() { - Some(to_rust_ident(prefix, &self.name)) - } else { - None - } - } - - fn express_value(&self, code: TokenStream) -> TokenStream { - let mut val = quote!(#code); - - let shift = 32 - self.bits.0.end; - if shift > 0 { - val = quote!((#val >> #shift)); - } - - let mask = (1u32 << self.bits.0.len()) - 1; - if mask != 0xFFFF_FFFF { - let mask = LitInt::new(&format!("0x{:x}", mask), Span::call_site()); - val = quote!((#val & #mask)); - } - - if self.split { - val = quote!((((#val & 0b11111_00000u32) >> 5u32) | ((#val & 0b00000_11111u32) << 5u32)) as u32); - } - - // https://graphics.stanford.edu/~seander/bithacks.html#VariableSignExtend - if self.signed { - let mask2 = 1u32 << (self.bits.0.len() - 1); - let mask2 = LitInt::new(&format!("0x{:x}", mask2), Span::call_site()); - val = quote!((((#val ^ #mask2).wrapping_sub(#mask2)) as i32)) - } - - let val_shift = self.shift_left; - if val_shift > 0 { - val = quote!((#val << #val_shift)); - } - - val - } - - fn express_value_self(&self) -> TokenStream { - self.express_value(quote!(self.code)) - } - - fn enum_variant_definition(&self) -> Option { - let ident = self.variant_identifier()?; - Some(if let Some(arg) = &self.arg { - let arg = TokenTree::Ident(Ident::new(arg, Span::call_site())); - quote! { - #ident(#arg), - } - } else { - quote! { - #ident, - } - }) - } - - pub(crate) fn construct_variant(&self, code: TokenStream) -> TokenStream { - let field_variant = self.variant_identifier(); - if let Some(arg) = &self.arg { - let field_arg = TokenTree::Ident(Ident::new(arg, Span::call_site())); - let value = self.express_value(code); - quote! { - Field::#field_variant(#field_arg(#value as _)) - } - } else { - quote! { - Field::#field_variant - } - } - } - - fn construct_variant_self(&self) -> TokenStream { - self.construct_variant(quote!(self.code)) - } - - fn construct_accessor(&self) -> TokenStream { - let field_variant = match self.identifier("field_") { - Some(v) => v, - None => return TokenStream::new(), - }; - if self.arg.is_none() { - return TokenStream::new(); - } - let value = self.express_value_self(); - let ret_type = if self.signed { - quote!(isize) - } else { - quote!(usize) - }; - quote! { - #[inline(always)] - pub fn #field_variant(&self) -> #ret_type { - #value as _ - } - } - } -} - -#[derive(Deserialize, Default)] -#[serde(default)] -pub(crate) struct Opcode { - name: String, - desc: String, - bitmask: u32, - pattern: u32, - modifiers: Vec, - side_effects: Vec, - args: Vec, - defs: Vec, - uses: Vec, -} - -impl Opcode { - fn variant_identifier(&self) -> Result { - to_rust_variant(&self.name) - } -} - -#[derive(Deserialize, Default)] -#[serde(default)] -pub(crate) struct Mnemonic { - name: String, - opcode: String, - // Overrides modifier list from opcode - modifiers: Option>, - args: Vec, - condition: String, -} - -#[derive(Deserialize, Default)] -#[serde(default)] -pub(crate) struct Modifier { - name: String, - suffix: char, - bit: u8, - condition: String, -} - -impl Modifier { - fn express_value_self(&self, field_by_name: &HashMap) -> Result { - if self.condition.is_empty() { - let modifier_bit = self.bit as usize; - Ok(quote!(self.bit(#modifier_bit))) - } else { - compile_mnemonic_condition(field_by_name, &self.condition) - } - } - - fn construct_accessor(&self, field_by_name: &HashMap) -> Result { - let field_variant = to_rust_ident("field_", &self.name); - let value = self.express_value_self(field_by_name)?; - Ok(quote! { - #[inline(always)] - pub fn #field_variant(&self) -> bool { - #value - } - }) - } -} - -#[derive(Deserialize, Default)] -#[serde(default)] -pub(crate) struct Isa { - fields: Vec, - modifiers: Vec, - opcodes: Vec, - mnemonics: Vec, -} - -fn load_isa() -> Result { - let yaml_file = File::open("isa.yaml")?; - let isa: Isa = serde_yaml::from_reader(yaml_file)?; - Ok(isa) -} - -impl Isa { - fn gen_opcode_enum(&self) -> Result { - // Create enum variants. - let enum_variants = self - .opcodes - .iter() - .map(|opcode| -> Result { - let ident = opcode.variant_identifier()?; - Ok(quote! { - #ident, - }) - }) - .try_collect::, Error>()?; - let enum_variants = token_stream!(enum_variants); - - // Create functions. - let mnemonic_fn = self.gen_mnemonic_fn()?; - let detect_fn = self.gen_opcode_detect()?; - - // Create final enum. - let opcode_enum = quote! { - #[derive(Debug, Copy, Clone, Eq, PartialEq)] - pub enum Opcode { - Illegal = -1, - #enum_variants - } - #[allow(clippy::all)] - impl Opcode { - #mnemonic_fn - #detect_fn - } - }; - Ok(opcode_enum) - } - - fn gen_mnemonic_fn(&self) -> Result { - // Create match arms. - let match_arms = self - .opcodes - .iter() - .map(|opcode| { - let variant = opcode.variant_identifier()?; - let literal = Literal::string(&opcode.name); - Ok(quote! { - Opcode::#variant => #literal, - }) - }) - .try_collect::, Error>()?; - let match_arms = token_stream!(match_arms); - // Create final function. - let mnemonic_fn = quote! { - pub(crate) fn _mnemonic(self) -> &'static str { - match self { - Opcode::Illegal => "", - #match_arms - } - } - }; - Ok(mnemonic_fn) - } - - fn gen_opcode_detect(&self) -> Result { - // Generate if chain. - let if_chain = self - .opcodes - .iter() - .map(|opcode| { - let bitmask_str = format!("{:>#8x}", opcode.bitmask); - let bitmask = LitInt::new(&bitmask_str, Span::call_site()); - let pattern_str = format!("{:>#8x}", opcode.pattern); - let pattern = LitInt::new(&pattern_str, Span::call_site()); - let identifier = opcode.variant_identifier()?; - Ok(quote! { - if code & #bitmask == #pattern { - return Opcode::#identifier; - } - }) - }) - .try_collect::, Error>()?; - let if_chain = token_stream!(if_chain); - // Generate function. - let func = quote! { - pub(crate) fn _detect(code: u32) -> Self { - #if_chain - Opcode::Illegal - } - }; - Ok(func) - } - - fn gen_field_enum(&self) -> Result { - // Create enum variants. - let mut enum_variants = Vec::new(); - for field in &self.fields { - if let Some(field) = field.enum_variant_definition() { - enum_variants.push(field); - } - } - let enum_variants = token_stream!(enum_variants); - - // Create final enum. - let field_enum = quote! { - #[allow(non_camel_case_types)] - #[derive(Debug, Copy, Clone, Eq, PartialEq)] - pub enum Field { - #enum_variants - } - }; - Ok(field_enum) - } - - fn gen_field_argument(&self) -> Result { - let mut match_arms = Vec::new(); - for field in &self.fields { - if let Some(variant) = field.variant_identifier() { - if let Some(arg_str) = field.arg.as_ref() { - let arg = Ident::new(arg_str, Span::call_site()); - match_arms.push(quote! { Field::#variant(x) => Some(Argument::#arg(*x)), }); - } - } - } - let match_arms = token_stream!(match_arms); - Ok(quote! { - pub fn argument(&self) -> Option { - match self { - #match_arms - _ => None, - } - } - }) - } - - fn gen_field_name(&self) -> Result { - let mut match_arms = Vec::new(); - for field in &self.fields { - if let Some(variant) = field.variant_identifier() { - let name = LitStr::new(&variant.to_string(), Span::call_site()); - let arg = field.arg.as_ref().map(|_| quote!((_))); - match_arms.push(quote! { Field::#variant #arg => #name, }); - } - } - let match_arms = token_stream!(match_arms); - Ok(quote! { - pub fn name(&self) -> &'static str { - match self { - #match_arms - } - } - }) - } - - fn gen_field_impl(&self) -> Result { - let field_argument = self.gen_field_argument()?; - let field_name = self.gen_field_name()?; - Ok(quote! { - impl Field { - #field_argument - #field_name - } - }) - } - - fn gen_ins_impl(&self) -> Result { - // Map fields by name. - let mut field_by_name = HashMap::::new(); - for field in &self.fields { - field_by_name.insert(field.name.clone(), field); - } - let mut modifier_by_name = HashMap::::new(); - for modifier in &self.modifiers { - modifier_by_name.insert(modifier.name.clone(), modifier); - } - // Map mnemonics by opcode. - let mut mnemonics_by_opcode = HashMap::<&String, Vec<&Mnemonic>>::new(); - for simple in &self.mnemonics { - mnemonics_by_opcode - .entry(&simple.opcode) - .or_insert_with(Vec::new) - .push(simple) - } - // Generate match arms for each opcode. - let mut field_match_arms = Vec::new(); - let mut def_match_arms = Vec::new(); - let mut use_match_arms = Vec::new(); - let mut suffix_match_arms = Vec::new(); - let mut simplified_ins_match_arms = Vec::new(); - for opcode in &self.opcodes { - // Generate fields of opcode. - let mut fields = Vec::new(); - for arg in &opcode.args { - let field: &Field = field_by_name - .get(arg) - .ok_or_else(|| Error::from(format!("undefined field {}", arg)))?; - let variant = field.construct_variant_self(); - fields.extend(quote! { #variant, }) - } - let fields = token_stream!(fields); - // Emit match arm. - let ident = opcode.variant_identifier()?; - field_match_arms.push(quote! { - Opcode::#ident => vec![#fields], - }); - - // Generate modifiers. - let suffix = express_suffix(&modifier_by_name, &field_by_name, &opcode.modifiers)?; - suffix_match_arms.push(quote! { - Opcode::#ident => #suffix, - }); - - // Generate defs. - let mut defs = Vec::new(); - for arg in &opcode.defs { - let field: &Field = field_by_name.get(arg).ok_or_else(|| { - syn::Error::new(Span::call_site(), format!("undefined field {}", arg)) - })?; - let variant = field.construct_variant_self(); - defs.extend(quote! { #variant, }) - } - let defs = token_stream!(defs); - let ident = opcode.variant_identifier()?; - def_match_arms.push(quote! { - Opcode::#ident => vec![#defs], - }); - - // Generate uses. - let mut uses = Vec::new(); - let mut special_uses = Vec::new(); - for arg in &opcode.uses { - // Detect non-zero modifier. - let mut arg = arg.as_str(); - let mut non_zero = false; - if let Some(substr) = arg.strip_suffix(".nz") { - non_zero = true; - arg = substr; - } - // Get underlying field. - let field: &Field = field_by_name.get(arg).ok_or_else(|| { - syn::Error::new(Span::call_site(), format!("undefined field {}", arg)) - })?; - let variant = field.construct_variant_self(); - if non_zero { - let value = field.express_value_self(); - special_uses.extend(quote! { - if (#value) != 0 { - uses.push(#variant); - } - }) - } else { - uses.extend(quote! { - #variant, - }) - } - } - let uses = token_stream!(uses); - let ident = opcode.variant_identifier()?; - let special_uses = token_stream!(special_uses); - use_match_arms.push(quote! { - Opcode::#ident => { - let mut uses = vec![#uses]; - #special_uses - uses - }, - }); - - // Generate instruction simplification. - if let Some(mnemonics) = mnemonics_by_opcode.get(&opcode.name) { - let mut simplified_conditions = Vec::new(); - for mnemonic in mnemonics { - if mnemonic.condition.is_empty() { - continue; // TODO else branch - } - simplified_conditions.push(quote!(if)); - simplified_conditions.push(compile_mnemonic_condition( - &field_by_name, - &mnemonic.condition, - )?); - // Emit branch. - let mnemonic_lit = LitStr::new(&mnemonic.name, Span::call_site()); - // Emit suffix. - let modifiers = mnemonic.modifiers.as_ref().unwrap_or(&opcode.modifiers); - let suffix = express_suffix(&modifier_by_name, &field_by_name, modifiers)?; - // Extract arguments. - let mut args = Vec::new(); - for arg in &mnemonic.args { - let (field_name, expression) = arg.split_once('=').unwrap_or((arg, arg)); - let field = field_by_name - .get(field_name) - .unwrap_or_else(|| panic!("field not found: {}", arg)); - let variant = Ident::new(field.arg.as_ref().unwrap(), Span::call_site()); - let value = compile_mnemonic_condition(&field_by_name, expression)?; - args.push(quote!(Argument::#variant(#variant((#value) as _)),)); - } - let args = token_stream!(args); - simplified_conditions.push(quote! { - { - return SimplifiedIns { - mnemonic: #mnemonic_lit, - suffix: #suffix, - args: vec![#args], - ins: self, - }; - } - }); - } - let simplified_conditions = token_stream!(simplified_conditions); - simplified_ins_match_arms.push(quote! { - Opcode::#ident => { - #simplified_conditions - }, - }); - } - } - let field_match_arms = token_stream!(field_match_arms); - let def_match_arms = token_stream!(def_match_arms); - let use_match_arms = token_stream!(use_match_arms); - let suffix_match_arms = token_stream!(suffix_match_arms); - let simplified_ins_match_arms = token_stream!(simplified_ins_match_arms); - let field_accessors = - TokenStream::from_iter(self.fields.iter().map(|field| field.construct_accessor())); - let modifiers: Vec = self - .modifiers - .iter() - .map(|modifier| modifier.construct_accessor(&field_by_name)) - .try_collect()?; - let modifier_accessors = TokenStream::from_iter(modifiers); - // Generate final fields function. - let ins_impl = quote! { - #[allow(clippy::all, unused_mut)] - impl Ins { - pub(crate) fn _fields(&self) -> Vec { - match self.op { - Opcode::Illegal => vec![], - #field_match_arms - } - } - - pub(crate) fn _defs(&self) -> Vec { - match self.op { - Opcode::Illegal => vec![], - #def_match_arms - } - } - - pub(crate) fn _uses(&self) -> Vec { - match self.op { - Opcode::Illegal => vec![], - #use_match_arms - } - } - - pub(crate) fn _suffix(&self) -> String { - match self.op { - Opcode::Illegal => String::new(), - #suffix_match_arms - } - } - - pub(crate) fn _simplified(self) -> SimplifiedIns { - match self.op { - #simplified_ins_match_arms - _ => {} - } - SimplifiedIns::basic_form(self) - } - } - #[allow(clippy::all, non_snake_case)] - impl Ins { - #field_accessors - #modifier_accessors - } - }; - Ok(ins_impl) - } -} - -/// Converts the given key into an identifier. -fn to_rust_ident(prefix: &str, key: &str) -> TokenTree { - TokenTree::Ident(Ident::new( - &(prefix.to_owned() + &key.replace('.', "_")), - Span::call_site(), - )) -} - -/// Converts the given key into an enum variant key. -fn to_rust_variant(key: &str) -> Result { - Ok(TokenTree::Ident(Ident::new( - &to_rust_variant_str(key)?, - Span::call_site(), - ))) -} - -fn to_rust_variant_str(key: &str) -> Result { - let mut s = String::new(); - let mut chars = key.chars(); - loop { - // Make first char uppercase. - let c = match chars.next() { - None => return Ok(s), - Some(c) => c, - }; - s.push(match c { - 'a'..='z' => c.to_ascii_uppercase(), - 'A'..='Z' => c, - _ => return Err(format!("invalid identifier: {}", key).into()), - }); - loop { - let c = match chars.next() { - None => return Ok(s), - Some(c) => c, - }; - match c.to_ascii_lowercase() { - '0'..='9' | 'a'..='z' => s.push(c), - '_' => break, - '.' => { - s.push('_'); - break; - } - _ => return Err(format!("invalid character in opcode name: {}", key).into()), - } - } - } -} - -/// Compiles conditions such as `S == B` into valid Rust expressions on a PowerPC instruction. -fn compile_mnemonic_condition( - field_by_name: &HashMap, - code: &str, -) -> Result { - let src_stream = TokenStream::from_str(code)?; - fn map_ident(field_by_name: &HashMap, token: TokenTree) -> TokenStream { - match token { - TokenTree::Ident(ref ident) => { - if let Some(field) = field_by_name.get(&ident.to_string()) { - return field.express_value_self(); - } - } - TokenTree::Group(ref group) => { - let iter = group - .stream() - .into_iter() - .flat_map(|token| map_ident(field_by_name, token)); - let stream = TokenStream::from_iter(iter); - return TokenStream::from(TokenTree::Group(Group::new(group.delimiter(), stream))); - } - _ => {} - } - token.into() - } - let token_iter = src_stream - .into_iter() - .flat_map(|token| map_ident(field_by_name, token)); - Ok(TokenStream::from_iter(token_iter)) -} - -fn express_suffix( - modifier_by_name: &HashMap, - field_by_name: &HashMap, - modifiers: &[String], -) -> Result { - Ok(if modifiers.is_empty() { - quote!(String::new()) - } else { - let mut chars = Vec::new(); - for mod_name in modifiers { - let modifier: &Modifier = modifier_by_name - .get(mod_name) - .ok_or_else(|| Error::from(format!("undefined modifier {}", mod_name)))?; - let lit_char = LitChar::new(modifier.suffix, Span::call_site()); - let modifier_bit = modifier.express_value_self(field_by_name)?; - chars.push(quote! { - if #modifier_bit { - s.push(#lit_char); - } - }); - } - let chars = token_stream!(chars); - quote!({ - { - let mut s = String::with_capacity(4); - #chars - s - } - }) - }) -} diff --git a/isa.yaml b/isa.yaml index 3a3076e..d1b77be 100644 --- a/isa.yaml +++ b/isa.yaml @@ -2,108 +2,134 @@ fields: # Immediates - name: simm arg: Simm + desc: Signed Immediate bits: 16..32 signed: true - name: uimm arg: Uimm + desc: Unsigned Immediate bits: 16..32 - name: offset arg: Offset + desc: Branch Offset bits: 16..32 signed: true - name: ps_offset arg: Offset + desc: Paired Single Offset bits: 20..32 signed: true # Branch fields - name: BO arg: OpaqueU + desc: Branch Options bits: 6..11 - name: BI arg: CRBit + desc: Branch Condition Register Bit bits: 11..16 - name: BD arg: BranchDest + desc: Branch Destination (14-bit) bits: 16..30 shift_left: 2 signed: true - name: LI arg: BranchDest + desc: Branch Destination (24-bit) bits: 6..30 signed: true shift_left: 2 # Shift/rotate type fields - name: SH arg: OpaqueU - desc: Shift + desc: Shift Amount bits: 16..21 - name: MB arg: OpaqueU - desc: Mask start + desc: Mask Begin bits: 21..26 - name: ME arg: OpaqueU - desc: Mask stop + desc: Mask End bits: 26..31 # Registers - name: rS arg: GPR + desc: Source Register bits: 6..11 - name: rD arg: GPR + desc: Destination Register bits: 6..11 - name: rA arg: GPR + desc: Register A bits: 11..16 - name: rA.nz arg: GPR + desc: Register A (non-zero) bits: 11..16 - name: rB arg: GPR + desc: Register B bits: 16..21 - name: sr arg: SR + desc: Segment Register bits: 12..16 - name: spr arg: SPR + desc: Special Purpose Register bits: 11..21 split: true # Floating-point registers - name: frS arg: FPR + desc: Source Floating-Point Register bits: 6..11 - name: frD arg: FPR + desc: Destination Floating-Point Register bits: 6..11 - name: frA arg: FPR + desc: Floating-Point Register A bits: 11..16 - name: frB arg: FPR + desc: Floating-Point Register B bits: 16..21 - name: frC arg: FPR + desc: Floating-Point Register C bits: 21..26 # Condition register bits - name: crbD arg: CRBit + desc: Condition Register Bit Destination bits: 6..11 - name: crbA arg: CRBit + desc: Condition Register Bit A bits: 11..16 - name: crbB arg: CRBit + desc: Condition Register Bit B bits: 16..21 # Condition register fields - name: crfD arg: CRField + desc: Condition Register Field Destination bits: 6..9 - name: crfS arg: CRField + desc: Condition Register Field Source bits: 11..14 # Condition register misc - name: crm arg: OpaqueU + desc: Condition Register Mask bits: 12..20 # Paired single fields - name: ps_I @@ -152,37 +178,46 @@ fields: desc: Bitset for cmp, cmpi, cmpl, cmpli bits: 10..11 - name: xer + desc: Fixed-Point Exception Register - name: ctr + desc: Count Register - name: lr + desc: Link Register modifiers: - name: OE + desc: Field used by XO-form instructions to enable setting OV and SO in the XER. suffix: o bit: 21 side_effects: [ xer ] - name: Rc + desc: Record Bit suffix: . bit: 31 side_effects: [ cr0 ] - name: LK + desc: Link Bit suffix: l bit: 31 side_effects: [ lr ] - name: AA + desc: Absolute Address Bit suffix: a bit: 30 - # Predict branch to be taken - name: BP + desc: Predict branch to be taken suffix: + - condition: BO & 1 == 1 && BD >= 0 - # Predict branch not to be taken (fall through) + bit: 10 + condition: BD >= 0 - name: BNP + desc: Predict branch not to be taken (fall through) suffix: '-' - condition: BO & 1 == 1 && BD < 0 - # Predict branch to be taken (implicit dest for LR/CTR) + bit: 10 + condition: BD < 0 - name: BP_ND + desc: Predict branch to be taken (implicit dest for LR/CTR) suffix: + - condition: BO & 1 == 1 + bit: 10 opcodes: - name: add @@ -1998,24 +2033,40 @@ mnemonics: condition: rA == 0 - name: subis opcode: addis - args: [ rD, rA, simm=-simm ] + args: [ rD, rA, simm ] condition: simm < 0 && simm != -0x8000 + replace: + simm: -simm + replace_assemble: + simm: -simm - name: li opcode: addi args: [ rD, simm ] condition: rA == 0 - name: subi opcode: addi - args: [ rD, rA, simm=-simm ] + args: [ rD, rA, simm ] condition: simm < 0 && simm != -0x8000 + replace: + simm: -simm + replace_assemble: + simm: -simm - name: subic opcode: addic - args: [ rD, rA, simm=-simm ] + args: [ rD, rA, simm ] condition: simm < 0 && simm != -0x8000 + replace: + simm: -simm + replace_assemble: + simm: -simm - name: subic. opcode: addic. - args: [ rD, rA, simm=-simm ] + args: [ rD, rA, simm ] condition: simm < 0 && simm != -0x8000 + replace: + simm: -simm + replace_assemble: + simm: -simm - name: mr opcode: or args: [ rA, rS ] @@ -2035,8 +2086,12 @@ mnemonics: # Rotates/Shifts Immediate - name: clrrwi opcode: rlwinm - args: [ rA, rS, ME=31-ME ] - condition: SH == 0 && MB == 0 && ME < 32 + args: [ rA, rS, ME ] + condition: SH == 0 && MB == 0 + replace: + ME: 31 - ME + replace_assemble: + ME: 31 - ME - name: clrlwi opcode: rlwinm args: [ rA, rS, MB ] @@ -2047,8 +2102,12 @@ mnemonics: condition: MB == 0 && ME == 31 && SH <= 16 - name: rotrwi opcode: rlwinm - args: [ rA, rS, SH=32-SH ] + args: [ rA, rS, SH ] condition: MB == 0 && ME == 31 && SH > 16 + replace: + SH: 32 - SH + replace_assemble: + SH: 32 - SH - name: slwi opcode: rlwinm args: [ rA, rS, SH ] @@ -2059,16 +2118,30 @@ mnemonics: condition: ME == 31 && SH == 32 - MB - name: clrlslwi opcode: rlwinm - args: [ rA, rS, MB=MB+SH, SH ] + args: [ rA, rS, MB, SH ] condition: SH < 32 && ME == 31 - SH + replace: + MB: MB + SH + replace_assemble: + MB: MB - SH - name: extlwi opcode: rlwinm - args: [ rA, rS, ME=ME+1, SH ] + args: [ rA, rS, ME, SH ] condition: MB == 0 + replace: + ME: ME + 1 + replace_assemble: + ME: ME - 1 - name: extrwi opcode: rlwinm - args: [ rA, rS, MB=32-MB, SH=SH-(32-MB) ] + args: [ rA, rS, MB, SH ] condition: ME == 31 && SH >= 32 - MB + replace: + MB: 32 - MB + SH: SH - (32 - MB) + replace_assemble: + MB: 32 - MB + SH: SH + MB # Compares Word - name: cmpwi diff --git a/rand/Cargo.toml b/rand/Cargo.toml deleted file mode 100644 index 8f96880..0000000 --- a/rand/Cargo.toml +++ /dev/null @@ -1,13 +0,0 @@ -[package] -name = "ppc750cl-rand" -version = "0.2.0" -edition = "2021" -authors = ["Richard Patel "] -license = "GPL-3.0-or-later" -description = "Generate random PowerPC 750CL instructions" -repository = "https://github.com/terorie/ppc750cl" - -[dependencies] -ppc750cl = { path = "../disasm", version = "0.2.0" } -rand_core = "0.6" -sfmt = "0.7" diff --git a/rand/src/main.rs b/rand/src/main.rs deleted file mode 100644 index 99a75dd..0000000 --- a/rand/src/main.rs +++ /dev/null @@ -1,16 +0,0 @@ -use rand_core::{RngCore, SeedableRng}; -use sfmt::SFMT; - -use ppc750cl::formatter::FormattedIns; -use ppc750cl::{Ins, Opcode}; - -fn main() { - let mut rng = SFMT::seed_from_u64(42); - loop { - let ins = Ins::new(rng.next_u32(), 0); - if ins.op == Opcode::Illegal { - continue; - } - println!("{}", FormattedIns(ins)); - } -} diff --git a/rustfmt.toml b/rustfmt.toml new file mode 100644 index 0000000..90c3849 --- /dev/null +++ b/rustfmt.toml @@ -0,0 +1,2 @@ +use_field_init_shorthand = true +use_small_heuristics = "Max"