diff --git a/Cargo.lock b/Cargo.lock index 6abd02e..080efbe 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8,6 +8,14 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "bits" +version = "0.1.0" +dependencies = [ + "quote", + "syn 2.0.18", +] + [[package]] name = "modular-bitfield" version = "0.11.2" @@ -26,7 +34,7 @@ checksum = "5a7d5f7076603ebc68de2dc6a650ec331a062a13abaa346975be747bbfa4b789" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -107,18 +115,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.58" +version = "1.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa1fb82fc0c281dd9671101b66b771ebbe1eaf967b96ac8740dcba4b70005ca8" +checksum = "dec2b086b7a862cf4de201096214fa870344cf922b2b30c167badb3af3195406" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.27" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f4f29d145265ec1c483c7c654450edde0bfe043d3938d6972630663356d9500" +checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488" dependencies = [ "proc-macro2", ] @@ -127,6 +135,7 @@ dependencies = [ name = "riscy-rust" version = "0.1.0" dependencies = [ + "bits", "modular-bitfield", "num", ] @@ -148,6 +157,17 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "syn" +version = "2.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32d41677bcbe24c20c52e7c70b0d8db04134c5d1066bf98662e2871ad200ea3e" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + [[package]] name = "unicode-ident" version = "1.0.8" diff --git a/Cargo.toml b/Cargo.toml index 819cea7..09e0ce4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,6 +3,9 @@ name = "riscy-rust" version = "0.1.0" edition = "2021" +[dependencies.bits] +path = "lib/bits" + [dependencies] modular-bitfield = "0.11.2" num = "0.4.0" diff --git a/lib/bits/Cargo.toml b/lib/bits/Cargo.toml new file mode 100644 index 0000000..f2e8f73 --- /dev/null +++ b/lib/bits/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "bits" +version = "0.1.0" +edition = "2021" + +[lib] +proc-macro = true + +[dependencies] +quote = "1.0.28" +syn = {version ="2.0.18", features = ["full"]} diff --git a/lib/bits/src/lib.rs b/lib/bits/src/lib.rs new file mode 100644 index 0000000..e7d209b --- /dev/null +++ b/lib/bits/src/lib.rs @@ -0,0 +1,53 @@ +use proc_macro::TokenStream; +use quote::quote; +use syn::{Expr, LitStr, Token}; + +struct ParsedInput { + expression: Expr, + _comma: Token![,], + token_string: LitStr, +} + +fn parse_input(input: syn::parse::ParseStream) -> syn::Result { + Ok(ParsedInput { + expression: input.parse()?, + _comma: input.parse()?, + token_string: input.parse()?, + }) +} + +#[proc_macro] +pub fn match_mask(input: TokenStream) -> TokenStream { + let parsed = + syn::parse::Parser::parse(parse_input, input).unwrap(); + + let input = parsed.expression; + + let tokens: String = parsed + .token_string + .value() + .parse() + .expect("Failed to parse token string"); + + let mut ones: u32 = 0; + let mut zeros: u32 = 0; + + for (idx, bit) in tokens.chars().rev().enumerate() { + match bit { + '1' => { + ones |= 1 << idx; + zeros |= 1 << idx; + } + '0' => { + zeros |= 1 << idx; + } + _ => continue, + } + } + + let expanded = quote! { + #input & #zeros ^ #ones == 0 + }; + + TokenStream::from(expanded) +} diff --git a/src/ext/decode.rs b/src/ext/decode.rs index 7b262f7..221aed2 100644 --- a/src/ext/decode.rs +++ b/src/ext/decode.rs @@ -1,36 +1,35 @@ +use bits::match_mask; + use crate::system::rv32; use crate::cpu; -macro_rules! match_mask { - ($int:expr, $($bit:expr)+) => { 'scope: { - let mut int = $int; - - $({ - let msb = int & (1 << 31); - let bit = $bit; - if (bit == 0 || bit == 1) && bit != msb.reverse_bits() { - break 'scope false; - } - int <<= 1; - })+ - - true - }}; -} - trait Instruction { - fn get_mask() -> rv32::Word; + fn match_inst(inst: rv32::Word) -> bool; fn step(&self, inst: rv32::Word, state: &mut cpu::CPU); } -struct ADDI {} +struct ADDI; impl Instruction for ADDI { - fn get_mask() -> rv32::Word { + fn match_inst(inst: rv32::Word) -> bool { + match_mask!(inst, "xxxxxxxxxxxxxxxxxx000xxxx0010011") + } + + fn step(&self, inst: rv32::Word, state: &mut cpu::CPU) { } } -pub fn decode_inst(inst: rv32::WORD) -> fn() { - // loop over all bitmasks - // +#[derive(Clone, Copy)] +enum I { + ADDI(ADDI), +} + +#[derive(Clone, Copy)] +enum Extensions { + I, +} + +pub fn decode_inst(inst: rv32::Word) -> fn() { + // we need to go over every instruction and see if it matches + // we can do smarter things with cacheing later - this aint blazin } diff --git a/src/main.rs b/src/main.rs index 3c3df4a..53a63fb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -66,7 +66,7 @@ fn main() { println!("VM Starting Up"); let mut vm = VMRV32I::new(); - vm.load_prog("./test/test.bin"); + vm.load_prog("./test/add.bin"); vm.dump_prog(); vm.dispatch(); }