extensions are ez

This commit is contained in:
Benjamin Kyd
2023-06-21 00:55:08 +01:00
parent 22e324c02b
commit 7c6e636f6c
6 changed files with 115 additions and 29 deletions

30
Cargo.lock generated
View File

@@ -8,6 +8,14 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]]
name = "bits"
version = "0.1.0"
dependencies = [
"quote",
"syn 2.0.18",
]
[[package]] [[package]]
name = "modular-bitfield" name = "modular-bitfield"
version = "0.11.2" version = "0.11.2"
@@ -26,7 +34,7 @@ checksum = "5a7d5f7076603ebc68de2dc6a650ec331a062a13abaa346975be747bbfa4b789"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn", "syn 1.0.109",
] ]
[[package]] [[package]]
@@ -107,18 +115,18 @@ dependencies = [
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.58" version = "1.0.60"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa1fb82fc0c281dd9671101b66b771ebbe1eaf967b96ac8740dcba4b70005ca8" checksum = "dec2b086b7a862cf4de201096214fa870344cf922b2b30c167badb3af3195406"
dependencies = [ dependencies = [
"unicode-ident", "unicode-ident",
] ]
[[package]] [[package]]
name = "quote" name = "quote"
version = "1.0.27" version = "1.0.28"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f4f29d145265ec1c483c7c654450edde0bfe043d3938d6972630663356d9500" checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
] ]
@@ -127,6 +135,7 @@ dependencies = [
name = "riscy-rust" name = "riscy-rust"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"bits",
"modular-bitfield", "modular-bitfield",
"num", "num",
] ]
@@ -148,6 +157,17 @@ dependencies = [
"unicode-ident", "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]] [[package]]
name = "unicode-ident" name = "unicode-ident"
version = "1.0.8" version = "1.0.8"

View File

@@ -3,6 +3,9 @@ name = "riscy-rust"
version = "0.1.0" version = "0.1.0"
edition = "2021" edition = "2021"
[dependencies.bits]
path = "lib/bits"
[dependencies] [dependencies]
modular-bitfield = "0.11.2" modular-bitfield = "0.11.2"
num = "0.4.0" num = "0.4.0"

11
lib/bits/Cargo.toml Normal file
View File

@@ -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"]}

53
lib/bits/src/lib.rs Normal file
View File

@@ -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<ParsedInput> {
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)
}

View File

@@ -1,36 +1,35 @@
use bits::match_mask;
use crate::system::rv32; use crate::system::rv32;
use crate::cpu; 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 { trait Instruction {
fn get_mask() -> rv32::Word; fn match_inst(inst: rv32::Word) -> bool;
fn step(&self, inst: rv32::Word, state: &mut cpu::CPU); fn step(&self, inst: rv32::Word, state: &mut cpu::CPU);
} }
struct ADDI {} struct ADDI;
impl Instruction for 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
} }

View File

@@ -66,7 +66,7 @@ fn main() {
println!("VM Starting Up"); println!("VM Starting Up");
let mut vm = VMRV32I::new(); let mut vm = VMRV32I::new();
vm.load_prog("./test/test.bin"); vm.load_prog("./test/add.bin");
vm.dump_prog(); vm.dump_prog();
vm.dispatch(); vm.dispatch();
} }