Compare commits

..

10 Commits

Author SHA1 Message Date
758b9c9cb7 Add devshell 2024-02-03 12:02:29 +01:00
91023adad3 Handle builds outside nix 2024-02-03 12:00:36 +01:00
7b15ea828c Short revision 2024-02-03 11:57:07 +01:00
f3f6de5b0b Remove vergen and use nix instead 2024-02-03 11:56:04 +01:00
867e75eeb7 flakeify 2024-02-03 11:55:45 +01:00
Ry
bedf8d54c4
Merge pull request #14 from eiowlta/main
Register Pointer Offsets, optional low hanging optimization, fixedwidth shift/bit operands
2023-07-23 14:25:13 -07:00
eiowlta
b5d88f735a
Merge branch 'fox32-arch:main' into main 2023-07-23 14:37:49 +03:00
eiowlta
4647b9fe63 add support for optional optimization, shorter bit operations and register pointer offsets 2023-07-21 18:34:51 +03:00
Ry
6e2691f50b
Merge pull request #13 from eiowlta/main
support inc r, # in assembler
2023-07-20 15:55:21 -07:00
eiowlta
36a8432411 support inc r, # in assembler 2023-07-20 16:53:30 +03:00
9 changed files with 539 additions and 498 deletions

1
.envrc Normal file
View File

@ -0,0 +1 @@
use flake

2
.gitignore vendored
View File

@ -1,4 +1,4 @@
**/.vscode/
**/debug/
**/target/
result

460
Cargo.lock generated
View File

@ -2,66 +2,15 @@
# It is not intended for manual editing.
version = 3
[[package]]
name = "anyhow"
version = "1.0.53"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94a45b455c14666b85fc40a019e8ab9eb75e3a124e05494f5397122bc9eb06e0"
[[package]]
name = "autocfg"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
[[package]]
name = "bitflags"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "block-buffer"
version = "0.7.3"
version = "0.10.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b"
checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
dependencies = [
"block-padding",
"byte-tools",
"byteorder",
"generic-array",
]
[[package]]
name = "block-padding"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5"
dependencies = [
"byte-tools",
]
[[package]]
name = "byte-tools"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7"
[[package]]
name = "byteorder"
version = "1.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
[[package]]
name = "cc"
version = "1.0.72"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee"
dependencies = [
"jobserver",
]
[[package]]
name = "cfg-if"
version = "1.0.0"
@ -69,126 +18,51 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "chrono"
version = "0.4.19"
name = "cpufeatures"
version = "0.2.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73"
checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504"
dependencies = [
"libc",
"num-integer",
"num-traits",
"time",
"winapi",
]
[[package]]
name = "crypto-common"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
dependencies = [
"generic-array",
"typenum",
]
[[package]]
name = "digest"
version = "0.8.1"
version = "0.10.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5"
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
dependencies = [
"generic-array",
]
[[package]]
name = "enum-iterator"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4eeac5c5edb79e4e39fe8439ef35207780a11f69c52cbe424ce3dfad4cb78de6"
dependencies = [
"enum-iterator-derive",
]
[[package]]
name = "enum-iterator-derive"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c134c37760b27a871ba422106eedbb8247da973a09e82558bf26d619c882b159"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "fake-simd"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
[[package]]
name = "form_urlencoded"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191"
dependencies = [
"matches",
"percent-encoding",
"block-buffer",
"crypto-common",
]
[[package]]
name = "fox32asm"
version = "0.3.0"
dependencies = [
"anyhow",
"lazy_static",
"pest",
"pest_derive",
"vergen",
]
[[package]]
name = "generic-array"
version = "0.12.4"
version = "0.14.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd"
checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
dependencies = [
"typenum",
]
[[package]]
name = "getset"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e45727250e75cc04ff2846a66397da8ef2b3db8e40e0cef4df67950a07621eb9"
dependencies = [
"proc-macro-error",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "git2"
version = "0.13.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f29229cc1b24c0e6062f6e742aa3e256492a5323365e5ed3413599f8a5eff7d6"
dependencies = [
"bitflags",
"libc",
"libgit2-sys",
"log",
"url",
]
[[package]]
name = "idna"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8"
dependencies = [
"matches",
"unicode-bidi",
"unicode-normalization",
]
[[package]]
name = "jobserver"
version = "0.1.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af25a77299a7f711a01975c35a6a424eb6862092cc2d6c72c4ed6cbc56dfc1fa"
dependencies = [
"libc",
"version_check",
]
[[package]]
@ -199,100 +73,38 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.115"
version = "0.2.153"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0a8d982fa7a96a000f6ec4cfe966de9703eccde29750df2bb8949da91b0e818d"
checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
[[package]]
name = "libgit2-sys"
version = "0.12.26+1.3.0"
name = "memchr"
version = "2.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19e1c899248e606fbfe68dcb31d8b0176ebab833b103824af31bddf4b7457494"
dependencies = [
"cc",
"libc",
"libz-sys",
"pkg-config",
]
checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149"
[[package]]
name = "libz-sys"
version = "1.1.3"
name = "once_cell"
version = "1.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de5435b8549c16d423ed0c03dbaafe57cf6c3344744f1242520d59c9d8ecec66"
dependencies = [
"cc",
"libc",
"pkg-config",
"vcpkg",
]
[[package]]
name = "log"
version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
dependencies = [
"cfg-if",
]
[[package]]
name = "maplit"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d"
[[package]]
name = "matches"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f"
[[package]]
name = "num-integer"
version = "0.1.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
dependencies = [
"autocfg",
"num-traits",
]
[[package]]
name = "num-traits"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
dependencies = [
"autocfg",
]
[[package]]
name = "opaque-debug"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c"
[[package]]
name = "percent-encoding"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
[[package]]
name = "pest"
version = "2.1.3"
version = "2.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53"
checksum = "1f200d8d83c44a45b21764d1916299752ca035d15ecd46faca3e9a2a2bf6ad06"
dependencies = [
"memchr",
"thiserror",
"ucd-trie",
]
[[package]]
name = "pest_derive"
version = "2.1.0"
version = "2.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "833d1ae558dc601e9a60366421196a8d94bc0ac980476d0b67e1d0988d72b2d0"
checksum = "bcd6ab1236bbdb3a49027e920e693192ebfe8913f6d60e294de57463a493cfde"
dependencies = [
"pest",
"pest_generator",
@ -300,9 +112,9 @@ dependencies = [
[[package]]
name = "pest_generator"
version = "2.1.3"
version = "2.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "99b8db626e31e5b81787b9783425769681b347011cc59471e33ea46d2ea0cf55"
checksum = "2a31940305ffc96863a735bef7c7994a00b325a7138fdbc5bda0f1a0476d3275"
dependencies = [
"pest",
"pest_meta",
@ -313,235 +125,95 @@ dependencies = [
[[package]]
name = "pest_meta"
version = "2.1.3"
version = "2.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "54be6e404f5317079812fc8f9f5279de376d8856929e21c184ecf6bbd692a11d"
checksum = "a7ff62f5259e53b78d1af898941cdcdccfae7385cf7d793a6e55de5d05bb4b7d"
dependencies = [
"maplit",
"once_cell",
"pest",
"sha-1",
]
[[package]]
name = "pkg-config"
version = "0.3.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "58893f751c9b0412871a09abd62ecd2a00298c6c83befa223ef98c52aef40cbe"
[[package]]
name = "proc-macro-error"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
dependencies = [
"proc-macro-error-attr",
"proc-macro2",
"quote",
"syn",
"version_check",
]
[[package]]
name = "proc-macro-error-attr"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
dependencies = [
"proc-macro2",
"quote",
"version_check",
"sha2",
]
[[package]]
name = "proc-macro2"
version = "1.0.32"
version = "1.0.78"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba508cc11742c0dc5c1659771673afbab7a0efab23aa17e854cbab0837ed0b43"
checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae"
dependencies = [
"unicode-xid",
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.10"
version = "1.0.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05"
checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
dependencies = [
"proc-macro2",
]
[[package]]
name = "rustversion"
version = "1.0.6"
name = "sha2"
version = "0.10.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2cc38e8fa666e2de3c4aba7edeb5ffc5246c1c2ed0e3d17e560aeeba736b23f"
[[package]]
name = "sha-1"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7d94d0bede923b3cea61f3f1ff57ff8cdfd77b400fb8f9998949e0cf04163df"
checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8"
dependencies = [
"block-buffer",
"cfg-if",
"cpufeatures",
"digest",
"fake-simd",
"opaque-debug",
]
[[package]]
name = "syn"
version = "1.0.81"
version = "2.0.48"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2afee18b8beb5a596ecb4a2dce128c719b4ba399d34126b9e4396e3f9860966"
checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f"
dependencies = [
"proc-macro2",
"quote",
"unicode-xid",
"unicode-ident",
]
[[package]]
name = "thiserror"
version = "1.0.30"
version = "1.0.56"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417"
checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.30"
version = "1.0.56"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b"
checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "time"
version = "0.1.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255"
dependencies = [
"libc",
"wasi",
"winapi",
]
[[package]]
name = "tinyvec"
version = "1.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c1c1d5a42b6245520c249549ec267180beaffcc0615401ac8e31853d4b6d8d2"
dependencies = [
"tinyvec_macros",
]
[[package]]
name = "tinyvec_macros"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
[[package]]
name = "typenum"
version = "1.14.0"
version = "1.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b63708a265f51345575b27fe43f9500ad611579e764c79edbc2037b1121959ec"
checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
[[package]]
name = "ucd-trie"
version = "0.1.3"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c"
checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9"
[[package]]
name = "unicode-bidi"
version = "0.3.7"
name = "unicode-ident"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a01404663e3db436ed2746d9fefef640d868edae3cceb81c3b8d5732fda678f"
[[package]]
name = "unicode-normalization"
version = "0.1.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9"
dependencies = [
"tinyvec",
]
[[package]]
name = "unicode-xid"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
[[package]]
name = "url"
version = "2.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c"
dependencies = [
"form_urlencoded",
"idna",
"matches",
"percent-encoding",
]
[[package]]
name = "vcpkg"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
[[package]]
name = "vergen"
version = "6.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3893329bee75c101278e0234b646fa72221547d63f97fb66ac112a0569acd110"
dependencies = [
"anyhow",
"cfg-if",
"chrono",
"enum-iterator",
"getset",
"git2",
"rustversion",
"thiserror",
]
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]]
name = "version_check"
version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]]
name = "wasi"
version = "0.10.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"

View File

@ -2,13 +2,8 @@
name = "fox32asm"
version = "0.3.0"
edition = "2021"
build = "build.rs"
[dependencies]
lazy_static = "1.4.0"
pest = "2.1.3"
pest_derive = "2.1.0"
[build-dependencies]
anyhow = "1.0"
vergen = { version = "6", default-features = false, features = ["build", "git"] }

View File

@ -1,8 +0,0 @@
use anyhow::Result;
use vergen::{Config, ShaKind, vergen};
fn main() -> Result<()> {
let mut config = Config::default();
*config.git_mut().sha_kind_mut() = ShaKind::Short;
vergen(config)
}

59
flake.lock Normal file
View File

@ -0,0 +1,59 @@
{
"nodes": {
"flake-utils": {
"inputs": {
"systems": "systems"
},
"locked": {
"lastModified": 1694529238,
"narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "ff7b65b44d01cf9ba6a71320833626af21126384",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1697009197,
"narHash": "sha256-viVRhBTFT8fPJTb1N3brQIpFZnttmwo3JVKNuWRVc3s=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "01441e14af5e29c9d27ace398e6dd0b293e25a54",
"type": "github"
},
"original": {
"id": "nixpkgs",
"type": "indirect"
}
},
"root": {
"inputs": {
"flake-utils": "flake-utils",
"nixpkgs": "nixpkgs"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
}
},
"root": "root",
"version": 7
}

30
flake.nix Normal file
View File

@ -0,0 +1,30 @@
{
description = "fox32asm";
inputs = {
flake-utils.url = "github:numtide/flake-utils";
};
outputs = { self, nixpkgs, flake-utils }:
flake-utils.lib.eachDefaultSystem (sys:
let pkgs = import nixpkgs { system = sys; };
in rec {
packages.fox32asm = pkgs.rustPlatform.buildRustPackage rec {
pname = "fox32asm";
version = "0.3.0";
src = ./. ;
cargoLock = { lockFile = ./Cargo.lock; };
NIX_SEMVER = version;
NIX_GIT_SHA_SHORT = if self ? rev then builtins.substring 0 7 self.rev else "dirty";
};
packages.default = packages.fox32asm;
devShells.default = pkgs.mkShell {
packages = [ pkgs.cargo ];
};
}
);
}

View File

@ -2,7 +2,7 @@ WHITESPACE = _{ " " | "\t" | "\n" | "\r" | "\x0B" | "\x0C" | "\xA0" | SPACE_SEPA
COMMENT = _{ ";" ~ (!"\n" ~ ANY)* }
assembly = {
SOI ~ (origin | include_bin_optional | include_bin | data | constant | label | instruction)* ~ EOI
SOI ~ (origin | include_bin_optional | include_bin | data | constant | label | instruction | opt)* ~ EOI
}
origin = {
@ -12,6 +12,13 @@ origin = {
origin_padding = { "org.pad" ~ operand_value }
origin_no_padding = { "org" ~ operand_value }
opton = { "opton" }
optoff = { "optoff" }
opt = {
opton |
optoff
}
include_bin = { "#include_bin" ~ immediate_str }
include_bin_optional = { "#include_bin_optional" ~ immediate_str }
@ -48,7 +55,9 @@ operand = {
operand_value
}
operand_value_ptr = {
register ~ "+" ~ operand_value |
operand_value
}
operand_value = {
register |
@ -65,6 +74,13 @@ size = @{
".32"
}
incdec_amount = @{
"1" |
"2" |
"4" |
"8"
}
condition = @{
"ifz" |
"ifnz" |
@ -83,6 +99,7 @@ instruction = {
instruction_conditional = {
instruction_zero ~ size? |
instruction_one ~ size? ~ operand |
instruction_incdec ~ size? ~ operand ~ ("," ~ incdec_amount)? |
instruction_two ~ size? ~ operand ~ "," ~ operand
}
@ -99,8 +116,6 @@ instruction_zero = @{
}
instruction_one = @{
"inc" |
"dec" |
"not" |
"jmp" |
"call" |
@ -115,6 +130,11 @@ instruction_one = @{
"flp"
}
instruction_incdec = @{
"inc" |
"dec"
}
instruction_two = @{
"add" |
"sub" |

View File

@ -168,8 +168,6 @@ enum InstructionZero {
#[derive(PartialEq, Debug, Clone, Copy)]
enum InstructionOne {
// one operand
Inc,
Dec,
Not,
Jmp,
Call,
@ -184,6 +182,13 @@ enum InstructionOne {
Flp,
}
#[derive(PartialEq, Debug, Clone, Copy)]
enum InstructionIncDec {
// one or two operands
Inc,
Dec,
}
#[derive(PartialEq, Debug, Clone, Copy)]
enum InstructionTwo {
// two operands
@ -241,26 +246,42 @@ enum LabelKind {
Global,
}
#[derive(PartialEq, Debug, Clone)]
struct OperationZero {
size: Size,
condition: Condition,
instruction: InstructionZero,
}
#[derive(PartialEq, Debug, Clone)]
struct OperationOne {
size: Size,
condition: Condition,
instruction: InstructionOne,
operand: Box<AstNode>,
}
#[derive(PartialEq, Debug, Clone)]
struct OperationIncDec {
size: Size,
condition: Condition,
instruction: InstructionIncDec,
lhs: Box<AstNode>,
rhs: Box<AstNode>,
}
#[derive(PartialEq, Debug, Clone)]
struct OperationTwo {
size: Size,
condition: Condition,
instruction: InstructionTwo,
lhs: Box<AstNode>,
rhs: Box<AstNode>,
}
#[derive(PartialEq, Debug, Clone)]
enum AstNode {
OperationZero {
size: Size,
condition: Condition,
instruction: InstructionZero,
},
OperationOne {
size: Size,
condition: Condition,
instruction: InstructionOne,
operand: Box<AstNode>,
},
OperationTwo {
size: Size,
condition: Condition,
instruction: InstructionTwo,
lhs: Box<AstNode>,
rhs: Box<AstNode>,
},
OperationZero(OperationZero) ,
OperationOne (OperationOne),
OperationIncDec(OperationIncDec) ,
OperationTwo (OperationTwo),
Immediate8(u8),
Immediate16(u16),
@ -268,6 +289,7 @@ enum AstNode {
Register(u8),
ImmediatePointer(u32),
RegisterPointer(u8),
RegisterPointerOffset(u8, u8),
Constant {
name: String,
@ -302,6 +324,7 @@ enum AstNode {
Origin(u32),
OriginPadded(u32),
Optimize(bool)
}
fn format_address_table(m: &HashMap<String, (u32, bool)>) -> String {
@ -314,7 +337,10 @@ fn format_address_table(m: &HashMap<String, (u32, bool)>) -> String {
}
fn main() {
let version_string = format!("fox32asm {} ({})", env!("VERGEN_BUILD_SEMVER"), env!("VERGEN_GIT_SHA_SHORT"));
let version_string = match (option_env!("NIX_SEMVER"), option_env!("NIX_GIT_SHA_SHORT")) {
(Some(semver), Some(sha)) => format!("fox32asm {semver} ({sha})"),
_ => format!("fox32asm (dev)"),
};
println!("{}", version_string);
let args: Vec<String> = env::args().collect();
@ -352,7 +378,7 @@ fn main() {
}
println!("Parsing file...");
let ast = match parse(&input_file) {
let mut ast = match parse(&input_file) {
Ok(x) => x,
Err(x) => {
println!("{:#?}", x);
@ -364,7 +390,9 @@ fn main() {
let mut current_address: u32 = 0;
println!("Assembling...");
for node in ast {
let mut optimize = false;
for mut node in ast {
node = optimize_node(node, &mut optimize);
if let AstNode::LabelDefine {name, ..} = node {
let mut address_table = LABEL_ADDRESSES.lock().unwrap();
if let Some(_) = address_table.get(&name) {
@ -392,6 +420,8 @@ fn main() {
} else if let AstNode::IncludedBinary(binary_vec) = node {
current_address += binary_vec.len() as u32;
instructions.push(binary_vec.into());
} else if let AstNode::Optimize(_) = node {
} else {
let instruction = assemble_node(node);
instruction.set_address(current_address);
@ -551,7 +581,6 @@ fn parse(source: &str) -> Result<Vec<AstNode>, Error<Rule>> {
fn build_ast_from_expression(pair: pest::iterators::Pair<Rule>) -> AstNode {
//println!("{:#?}\n\n", pair); // debug
let pair_rule = pair.as_rule();
let mut inner_pair = pair.into_inner();
*CURRENT_CONDITION.lock().unwrap() = Condition::Always;
@ -574,6 +603,7 @@ fn build_ast_from_expression(pair: pest::iterators::Pair<Rule>) -> AstNode {
Rule::constant => parse_constant(inner_pair),
Rule::label => parse_label(inner_pair.next().unwrap(), inner_pair.next()),
Rule::data => parse_data(inner_pair.next().unwrap()),
Rule::opt => parse_opt(inner_pair.next().unwrap()),
Rule::origin => parse_origin(inner_pair.next().unwrap()),
Rule::include_bin => include_binary_file(inner_pair.next().unwrap(), false),
Rule::include_bin_optional => include_binary_file(inner_pair.next().unwrap(), true),
@ -674,7 +704,13 @@ fn parse_data(pair: pest::iterators::Pair<Rule>) -> AstNode {
_ => panic!("Unsupported data: {}", pair.as_str()),
}
}
fn parse_opt(rule: pest::iterators::Pair<Rule>) -> AstNode {
match rule.as_str() {
"opton"=>AstNode::Optimize(true),
"optoff"=>AstNode::Optimize(false),
_ => panic!("Unknown optimize flag {}", rule.as_str())
}
}
fn parse_origin(pair: pest::iterators::Pair<Rule>) -> AstNode {
//println!("{:#?}", pair);
match pair.as_rule() {
@ -713,6 +749,16 @@ fn parse_size(pair: &pest::iterators::Pair<Rule>) -> Size {
}
}
fn parse_incdec_amount(pair: pest::iterators::Pair<Rule>) -> AstNode {
match pair.as_str() {
"1" => AstNode::Immediate8(0),
"2" => AstNode::Immediate8(1),
"4" => AstNode::Immediate8(2),
"8" => AstNode::Immediate8(3),
_ => panic!("Unsupported increment/decrement: {}", pair.as_str()),
}
}
fn parse_condition(pair: &pest::iterators::Pair<Rule>) -> Condition {
match pair.as_str() {
"ifz" => Condition::Zero,
@ -754,6 +800,21 @@ fn parse_instruction(pair: pest::iterators::Pair<Rule>) -> AstNode {
let operand_ast = build_ast_from_expression(operand);
parse_instruction_one(instruction_conditional_pair, operand_ast, size, condition)
}
Rule::instruction_incdec => {
if inner_pair.peek().unwrap().as_rule() == Rule::size {
size = parse_size(&inner_pair.next().unwrap());
}
*CURRENT_SIZE.lock().unwrap() = size;
let lhs = inner_pair.next().unwrap();
let lhs_ast = build_ast_from_expression(lhs);
let rhs_ast = if inner_pair.peek().is_some() {
let rhs = inner_pair.next().unwrap();
parse_incdec_amount(rhs)
} else {
AstNode::Immediate8(0)
};
parse_instruction_incdec(instruction_conditional_pair, lhs_ast, rhs_ast, size, condition)
}
Rule::instruction_two => {
if inner_pair.peek().unwrap().as_rule() == Rule::size {
size = parse_size(&inner_pair.next().unwrap());
@ -788,45 +849,67 @@ fn immediate_to_astnode(immediate: u32, size: Size, is_pointer: bool) -> AstNode
}
}
fn parse_immediate(pair: pest::iterators::Pair<Rule>) -> u32 {
match pair.as_rule() {
Rule::immediate_bin => {
let body_bin_str = pair.into_inner().next().unwrap().as_str();
u32::from_str_radix(&remove_underscores(body_bin_str), 2).unwrap()
}
Rule::immediate_hex => {
let body_hex_str = pair.into_inner().next().unwrap().as_str();
u32::from_str_radix(&remove_underscores(body_hex_str), 16).unwrap()
}
Rule::immediate_dec => {
let dec_str = pair.as_span().as_str();
remove_underscores(dec_str).parse::<u32>().unwrap()
}
Rule::immediate_char => {
let body_char_str = pair.into_inner().next().unwrap().as_str();
body_char_str.chars().nth(0).unwrap() as u8 as u32
}
_=> {
panic!()
}
}
}
fn parse_register(pair: pest::iterators::Pair<Rule>) -> u8 {
let register_num_pair = pair.into_inner().next().unwrap();
let register_num = if register_num_pair.as_str() == "sp" { 32 }
else if register_num_pair.as_str() == "esp" { 33 }
else if register_num_pair.as_str() == "fp" { 34 }
else { register_num_pair.as_str().parse::<u8>().unwrap() };
if register_num > 34 { panic!("register number out of range"); }
register_num
}
fn parse_operand(mut pair: pest::iterators::Pair<Rule>, is_pointer: bool) -> AstNode {
//println!("parse_operand: {:#?}", pair); // debug
// dbg!(&pair);
let size = *CURRENT_SIZE.lock().unwrap();
let pointer_offset =
if is_pointer {
// skip past the operand_value_ptr pair and look at its operand_value rule
pair = pair.into_inner().next().unwrap();
}
let mut pairs = pair.into_inner();
pair = pairs.next().unwrap();
pairs.next()
// pair = pair.into_inner().next().unwrap();
}else {
None
};
match pair.as_rule() {
Rule::operand_value => {
let mut inner_pair = pair.into_inner();
let operand_value_pair = inner_pair.next().unwrap();
match operand_value_pair.as_rule() {
Rule::immediate_bin => {
let body_bin_str = operand_value_pair.into_inner().next().unwrap().as_str();
let immediate = u32::from_str_radix(&remove_underscores(body_bin_str), 2).unwrap();
immediate_to_astnode(immediate, size, is_pointer)
}
Rule::immediate_bin|
Rule::immediate_char|
Rule::immediate_dec|
Rule::immediate_hex => {
let body_hex_str = operand_value_pair.into_inner().next().unwrap().as_str();
let immediate = u32::from_str_radix(&remove_underscores(body_hex_str), 16).unwrap();
immediate_to_astnode(immediate, size, is_pointer)
}
Rule::immediate_dec => {
let dec_str = operand_value_pair.as_span().as_str();
let immediate = remove_underscores(dec_str).parse::<u32>().unwrap();
immediate_to_astnode(immediate, size, is_pointer)
}
Rule::immediate_char => {
let body_char_str = operand_value_pair.into_inner().next().unwrap().as_str();
let immediate = body_char_str.chars().nth(0).unwrap() as u8 as u32;
immediate_to_astnode(immediate, size, is_pointer)
immediate_to_astnode(parse_immediate(operand_value_pair), size, is_pointer)
}
Rule::register => {
let register_num_pair = operand_value_pair.into_inner().next().unwrap();
let register_num = if register_num_pair.as_str() == "sp" { 32 }
else if register_num_pair.as_str() == "esp" { 33 }
else if register_num_pair.as_str() == "fp" { 34 }
else { register_num_pair.as_str().parse::<u8>().unwrap() };
if register_num > 34 { panic!("register number out of range"); }
let register_num = parse_register(operand_value_pair);
if is_pointer {
AstNode::RegisterPointer(register_num)
} else {
@ -850,12 +933,25 @@ fn parse_operand(mut pair: pest::iterators::Pair<Rule>, is_pointer: bool) -> Ast
_ => todo!(),
}
}
Rule::register => {
let register_num = parse_register(pair);
let offset = if let Some(offset_pair) = pointer_offset {
parse_immediate(offset_pair.into_inner().next().unwrap())
} else {
0
};
if offset == 0 {
AstNode::RegisterPointer(register_num)
} else {
AstNode::RegisterPointerOffset(register_num, offset as u8)
}
}
_ => panic!(),
}
}
fn parse_instruction_zero(pair: pest::iterators::Pair<Rule>, size: Size, condition: Condition) -> AstNode {
AstNode::OperationZero {
AstNode::OperationZero ( OperationZero {
size: size,
condition: condition,
instruction: match pair.as_str() {
@ -869,17 +965,15 @@ fn parse_instruction_zero(pair: pest::iterators::Pair<Rule>, size: Size, conditi
"mse" => InstructionZero::Mse,
"mcl" => InstructionZero::Mcl,
_ => panic!("Unsupported conditional instruction (zero): {}", pair.as_str()),
},
}
}
})
}
fn parse_instruction_one(pair: pest::iterators::Pair<Rule>, mut operand: AstNode, size: Size, condition: Condition) -> AstNode {
AstNode::OperationOne {
AstNode::OperationOne ( OperationOne {
size: size,
condition: condition,
instruction: match pair.as_str() {
"inc" => InstructionOne::Inc,
"dec" => InstructionOne::Dec,
"not" => InstructionOne::Not,
"jmp" => InstructionOne::Jmp,
"call" => InstructionOne::Call,
@ -921,12 +1015,40 @@ fn parse_instruction_one(pair: pest::iterators::Pair<Rule>, mut operand: AstNode
"flp" => InstructionOne::Flp,
_ => panic!("Unsupported conditional instruction (one): {}", pair.as_str()),
},
operand: Box::new(operand),
}
operand: Box::new(operand)
})
}
fn parse_instruction_incdec(pair: pest::iterators::Pair<Rule>, lhs: AstNode, rhs: AstNode, size: Size, condition: Condition) -> AstNode {
AstNode::OperationIncDec ( OperationIncDec {
size: size,
condition: condition,
instruction: match pair.as_str() {
"inc" => InstructionIncDec::Inc,
"dec" => InstructionIncDec::Dec,
_ => panic!("Unsupported conditional instruction (two): {}", pair.as_str()),
},
lhs: Box::new(lhs),
rhs: Box::new(rhs),
})
}
fn parse_instruction_two(pair: pest::iterators::Pair<Rule>, mut lhs: AstNode, mut rhs: AstNode, size: Size, condition: Condition) -> AstNode {
AstNode::OperationTwo {
match pair.as_str() {
"sla" |
"sra" |
"srl" |
"rol" |
"ror" |
"bse" |
"bcl" |
"bts" => if let Some(value) = node_value(&rhs) {
rhs = AstNode::Immediate8(value as u8);
}
_=>()
}
AstNode::OperationTwo ( OperationTwo {
size: size,
condition: condition,
instruction: match pair.as_str() {
@ -975,7 +1097,7 @@ fn parse_instruction_two(pair: pest::iterators::Pair<Rule>, mut lhs: AstNode, mu
},
lhs: Box::new(lhs),
rhs: Box::new(rhs),
}
})
}
fn assemble_node(node: AstNode) -> AssembledInstruction {
@ -1010,12 +1132,14 @@ fn assemble_node(node: AstNode) -> AssembledInstruction {
let mut instruction_data: Vec<u8> = Vec::new();
instruction_data.push(condition_source_destination_to_byte(&node));
let condition_source_destination = condition_source_destination_to_byte(&node);
instruction_data.push(condition_source_destination);
instruction_data.push(instruction_to_byte(&node));
let mut instruction: AssembledInstruction = instruction_data.into();
node_to_immediate_values(&node, &mut instruction);
//0x80 bit determines if we need to write the pointer offsets or not
node_to_immediate_values(&node, &mut instruction, condition_source_destination & 0x80 != 0);
instruction
}
@ -1040,7 +1164,7 @@ fn size_to_byte(size: Size) -> u8 {
fn instruction_to_byte(node: &AstNode) -> u8 {
match *node {
AstNode::OperationZero {size, instruction, ..} => {
AstNode::OperationZero (OperationZero{size, instruction, ..}) => {
match instruction {
InstructionZero::Nop => 0x00 | size_to_byte(size),
InstructionZero::Halt => 0x10 | size_to_byte(size),
@ -1053,10 +1177,8 @@ fn instruction_to_byte(node: &AstNode) -> u8 {
InstructionZero::Mcl => 0x1D | size_to_byte(size),
}
}
AstNode::OperationOne {size, instruction, ..} => {
AstNode::OperationOne (OperationOne{size, instruction, ..}) => {
match instruction {
InstructionOne::Inc => 0x11 | size_to_byte(size),
InstructionOne::Dec => 0x31 | size_to_byte(size),
InstructionOne::Not => 0x33 | size_to_byte(size),
InstructionOne::Jmp => 0x08 | size_to_byte(size),
InstructionOne::Call => 0x18 | size_to_byte(size),
@ -1071,7 +1193,13 @@ fn instruction_to_byte(node: &AstNode) -> u8 {
InstructionOne::Flp => 0x3D | size_to_byte(size),
}
}
AstNode::OperationTwo {size, instruction, ..} => {
AstNode::OperationIncDec (OperationIncDec{size, instruction, ..}) => {
match instruction {
InstructionIncDec::Inc => 0x11 | size_to_byte(size),
InstructionIncDec::Dec => 0x31 | size_to_byte(size),
}
}
AstNode::OperationTwo (OperationTwo{size, instruction, ..}) => {
match instruction {
InstructionTwo::Add => 0x01 | size_to_byte(size),
InstructionTwo::Sub => 0x21 | size_to_byte(size),
@ -1118,20 +1246,32 @@ fn condition_to_bits(condition: &Condition) -> u8 {
fn condition_source_destination_to_byte(node: &AstNode) -> u8 {
let source: u8 = match node {
AstNode::OperationZero {..} => 0x00,
AstNode::OperationOne {operand, ..} => {
AstNode::OperationZero (_) => 0x00,
AstNode::OperationOne (OperationOne{operand, ..}) => {
match operand.as_ref() {
AstNode::Register(_) => 0x00,
AstNode::RegisterPointer(_) => 0x01,
AstNode::RegisterPointerOffset(_, _) => 0x81,
AstNode::Immediate8(_) | AstNode::Immediate16(_) | AstNode::Immediate32(_) | AstNode::LabelOperand {..} => 0x02,
AstNode::ImmediatePointer(_) | AstNode::LabelOperandPointer {..} => 0x03,
_ => panic!("Attempting to parse a non-instruction AST node as an instruction: {:#?}", node),
}
}
AstNode::OperationTwo {rhs, ..} => {
AstNode::OperationIncDec (OperationIncDec{lhs, ..}) => {
match lhs.as_ref() {
AstNode::Register(_) => 0x00,
AstNode::RegisterPointer(_) => 0x01,
AstNode::RegisterPointerOffset(_, _) => 0x81,
AstNode::Immediate8(_) | AstNode::Immediate16(_) | AstNode::Immediate32(_) | AstNode::LabelOperand {..} => 0x02,
AstNode::ImmediatePointer(_) | AstNode::LabelOperandPointer {..} => 0x03,
_ => panic!("Attempting to parse a non-instruction AST node as an instruction: {:#?}", node),
}
}
AstNode::OperationTwo (OperationTwo{rhs, ..}) => {
match rhs.as_ref() {
AstNode::Register(_) => 0x00,
AstNode::RegisterPointer(_) => 0x01,
AstNode::RegisterPointerOffset(_, _) => 0x81,
AstNode::Immediate8(_) | AstNode::Immediate16(_) | AstNode::Immediate32(_) | AstNode::LabelOperand {..} => 0x02,
AstNode::ImmediatePointer(_) | AstNode::LabelOperandPointer {..} => 0x03,
_ => panic!("Attempting to parse a non-instruction AST node as an instruction: {:#?}", node),
@ -1140,12 +1280,19 @@ fn condition_source_destination_to_byte(node: &AstNode) -> u8 {
_ => panic!("Attempting to parse a non-instruction AST node as an instruction: {:#?}", node),
};
let destination: u8 = match node {
AstNode::OperationZero {..} => 0x00,
AstNode::OperationOne {..} => 0x00,
AstNode::OperationTwo {lhs, ..} => {
AstNode::OperationZero(_) => 0x00,
AstNode::OperationOne (_)=> 0x00,
AstNode::OperationIncDec (OperationIncDec{ rhs, ..}) => {
match rhs.as_ref() {
AstNode::Immediate8(n) => *n << 2,
_ => panic!(""),
}
}
AstNode::OperationTwo (OperationTwo{lhs, ..}) => {
match lhs.as_ref() {
AstNode::Register(_) => 0x00,
AstNode::RegisterPointer(_) => 0x04,
AstNode::RegisterPointerOffset(_, _) => 0x84,
AstNode::Immediate8(_) | AstNode::Immediate16(_) | AstNode::Immediate32(_) | AstNode::LabelOperand {..} => 0x08,
AstNode::ImmediatePointer(_) | AstNode::LabelOperandPointer {..} => 0x0C,
_ => panic!("Attempting to parse a non-instruction AST node as an instruction: {:#?}", node),
@ -1154,9 +1301,10 @@ fn condition_source_destination_to_byte(node: &AstNode) -> u8 {
_ => panic!("Attempting to parse a non-instruction AST node as an instruction: {:#?}", node),
};
let condition: u8 = match node {
AstNode::OperationZero {condition, ..} => condition_to_bits(condition),
AstNode::OperationOne {condition, ..} => condition_to_bits(condition),
AstNode::OperationTwo {condition, ..} => condition_to_bits(condition),
AstNode::OperationZero (OperationZero{condition, ..}) => condition_to_bits(condition),
AstNode::OperationOne (OperationOne{condition, ..}) => condition_to_bits(condition),
AstNode::OperationIncDec (OperationIncDec{condition, ..}) => condition_to_bits(condition),
AstNode::OperationTwo (OperationTwo{condition, ..}) => condition_to_bits(condition),
_ => panic!("Attempting to parse a non-instruction AST node as an instruction: {:#?}", node),
};
condition | source | destination
@ -1187,11 +1335,23 @@ fn generate_backpatch_immediate(name: &String, size: Size, instruction: &Assembl
targets.push(BackpatchTarget::new(instruction, index, size, is_relative));
}
fn operand_to_immediate_value(instruction: &AssembledInstruction, node: &AstNode){
fn operand_to_immediate_value(instruction: &AssembledInstruction, node: &AstNode, pointer_offset: bool){
let mut vec = instruction.borrow_mut();
match *node {
AstNode::Register (register) => vec.push(register),
AstNode::RegisterPointer(register) => vec.push(register),
AstNode::RegisterPointer(register) => {
vec.push(register);
if pointer_offset {
vec.push(0);
}
}
AstNode::RegisterPointerOffset(register, offset) => {
vec.push(register);
if pointer_offset {
vec.push(offset);
}
}
AstNode::Immediate8 (immediate) => vec.push(immediate),
AstNode::Immediate16 (immediate) => vec.extend_from_slice(&immediate.to_le_bytes()),
@ -1209,18 +1369,22 @@ fn operand_to_immediate_value(instruction: &AssembledInstruction, node: &AstNode
_ => panic!("Attempting to parse a non-instruction AST node as an instruction: {:#?}", node),
}
}
fn node_to_immediate_values(node: &AstNode, instruction: &AssembledInstruction) {
fn node_to_immediate_values(node: &AstNode, instruction: &AssembledInstruction, pointer_offset: bool) {
{
match node {
AstNode::OperationZero {..} => {}
AstNode::OperationOne {operand, ..} =>
operand_to_immediate_value(instruction, operand.as_ref()),
AstNode::OperationOne (OperationOne{operand, ..}) =>
operand_to_immediate_value(instruction, operand.as_ref(), pointer_offset),
AstNode::OperationTwo {rhs, ..} =>
operand_to_immediate_value(instruction, rhs.as_ref()),
AstNode::OperationIncDec (OperationIncDec{lhs, ..}) =>
operand_to_immediate_value(instruction, lhs.as_ref(), pointer_offset),
AstNode::OperationTwo (OperationTwo{rhs, ..}) =>
operand_to_immediate_value(instruction, rhs.as_ref(), pointer_offset),
_ => panic!("Attempting to parse a non-instruction AST node as an instruction: {:#?}", node),
}
@ -1229,10 +1393,118 @@ fn node_to_immediate_values(node: &AstNode, instruction: &AssembledInstruction)
match node {
AstNode::OperationZero {..} => {}
AstNode::OperationOne {..} => {}
AstNode::OperationIncDec {..} => {}
AstNode::OperationTwo {lhs, ..} =>
operand_to_immediate_value(instruction, lhs.as_ref()),
AstNode::OperationTwo (OperationTwo{lhs, ..}) =>
operand_to_immediate_value(instruction, lhs.as_ref(), pointer_offset),
_ => panic!("Attempting to parse a non-instruction AST node as an instruction: {:#?}", node),
};
}
fn node_value(node: &AstNode) -> Option<u32> {
match *node {
AstNode::Immediate16(n) => Some(n as u32),
AstNode::Immediate32(n) => Some(n as u32),
AstNode::Immediate8(n) => Some(n as u32),
_ => None
}
}
fn optimize_node(node: AstNode, enabled: &mut bool) -> AstNode {
if let AstNode::Optimize(value) = node {
*enabled = value;
}
if *enabled {
match node {
AstNode::OperationTwo(mut n) => {
let v = node_value(&n.rhs);
if let Some(v) = v {
match n.instruction {
InstructionTwo::Add => {
match v {
1 => return AstNode::OperationIncDec(OperationIncDec { size: n.size, condition: n.condition, instruction: InstructionIncDec::Inc, lhs: n.lhs, rhs: Box::new(AstNode::Immediate8(0)) }),
2 => return AstNode::OperationIncDec(OperationIncDec { size: n.size, condition: n.condition, instruction: InstructionIncDec::Inc, lhs: n.lhs, rhs: Box::new(AstNode::Immediate8(1)) }),
4 => return AstNode::OperationIncDec(OperationIncDec { size: n.size, condition: n.condition, instruction: InstructionIncDec::Inc, lhs: n.lhs, rhs: Box::new(AstNode::Immediate8(2)) }),
8 => return AstNode::OperationIncDec(OperationIncDec { size: n.size, condition: n.condition, instruction: InstructionIncDec::Inc, lhs: n.lhs, rhs: Box::new(AstNode::Immediate8(3)) }),
_ => ()
}
},
InstructionTwo::Sub => {
match v {
1 => return AstNode::OperationIncDec(OperationIncDec { size: n.size, condition: n.condition, instruction: InstructionIncDec::Dec, lhs: n.lhs, rhs: Box::new(AstNode::Immediate8(0)) }),
2 => return AstNode::OperationIncDec(OperationIncDec { size: n.size, condition: n.condition, instruction: InstructionIncDec::Dec, lhs: n.lhs, rhs: Box::new(AstNode::Immediate8(1)) }),
4 => return AstNode::OperationIncDec(OperationIncDec { size: n.size, condition: n.condition, instruction: InstructionIncDec::Dec, lhs: n.lhs, rhs: Box::new(AstNode::Immediate8(2)) }),
8 => return AstNode::OperationIncDec(OperationIncDec { size: n.size, condition: n.condition, instruction: InstructionIncDec::Dec, lhs: n.lhs, rhs: Box::new(AstNode::Immediate8(3)) }),
_ => ()
}
},
InstructionTwo::Mov => {
if let Size::Word = n.size {
if let AstNode::Register(_) = *n.lhs {
if v <= 0xff {
n.size = Size::Byte;
n.instruction = InstructionTwo::Movz;
n.rhs = Box::new(AstNode::Immediate8(v as u8));
}
else if v <= 0xffff {
n.size = Size::Half;
n.instruction = InstructionTwo::Movz;
n.rhs = Box::new(AstNode::Immediate16(v as u16));
}
}
}
},
InstructionTwo::Mul => {
if let Size::Word = n.size {
if v.is_power_of_two() {
n.instruction = InstructionTwo::Sla;
n.rhs = Box::new(AstNode::Immediate8(v.trailing_zeros() as u8));
}
}
},
InstructionTwo::Idiv => {
if let Size::Word = n.size {
if v.is_power_of_two() {
n.instruction = InstructionTwo::Sra;
n.rhs = Box::new(AstNode::Immediate8(v.trailing_zeros() as u8));
}
}
},
InstructionTwo::Div => {
if let Size::Word = n.size {
if v.is_power_of_two() {
n.instruction = InstructionTwo::Srl;
n.rhs = Box::new(AstNode::Immediate8(v.trailing_zeros() as u8));
}
}
},
// InstructionTwo::Sla
// | InstructionTwo::Srl | InstructionTwo::Sra
// | InstructionTwo::Bcl | InstructionTwo::Bse
// | InstructionTwo::Bts
// | InstructionTwo::Ror | InstructionTwo::Rol
// => {
// n.rhs = Box::new(AstNode::Immediate8(v as u8));
// }
_ => ()
}
}
AstNode::OperationTwo(n)
}
_=> node
}
} else {
node
}
}