enum dispatch

This commit is contained in:
Benjamin Kyd
2023-07-06 00:54:02 +01:00
parent 7fcc429612
commit 75c25dc1cc
4 changed files with 37 additions and 34 deletions

19
Cargo.lock generated
View File

@@ -16,6 +16,18 @@ dependencies = [
"syn 2.0.18",
]
[[package]]
name = "enum_dispatch"
version = "0.3.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "11f36e95862220b211a6e2aa5eca09b4fa391b13cd52ceb8035a24bf65a79de2"
dependencies = [
"once_cell",
"proc-macro2",
"quote",
"syn 1.0.109",
]
[[package]]
name = "modular-bitfield"
version = "0.11.2"
@@ -113,6 +125,12 @@ dependencies = [
"autocfg",
]
[[package]]
name = "once_cell"
version = "1.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
[[package]]
name = "proc-macro2"
version = "1.0.60"
@@ -136,6 +154,7 @@ name = "riscy-rust"
version = "0.1.0"
dependencies = [
"bits",
"enum_dispatch",
"modular-bitfield",
"num",
]

View File

@@ -7,5 +7,6 @@ edition = "2021"
path = "lib/bits"
[dependencies]
enum_dispatch = "0.3.11"
modular-bitfield = "0.11.2"
num = "0.4.0"

View File

@@ -1,8 +1,9 @@
use modular_bitfield::prelude::*;
use bits::match_mask;
use enum_dispatch::*;
use modular_bitfield::prelude::*;
use crate::system::rv32;
use crate::cpu;
use crate::system::rv32;
// trait Instruction {
// fn impl_register(&self, exts: &mut Vec<Extension>, name: &'static str) {
@@ -59,7 +60,6 @@ pub struct IType {
pub imm: B12,
}
enum EncodingType {
R(RType),
I(IType),
@@ -73,62 +73,48 @@ pub union GenInstruction {
pub I: std::mem::ManuallyDrop<IType>,
}
#[enum_dispatch]
trait Instruction {
fn match_inst(&self, inst: rv32::Word) -> bool;
fn step(&self, inst: rv32::Word, state: &mut cpu::CPU);
}
type SomeInstruction = impl Instruction;
#[derive(Copy, Clone)]
struct ADDI;
impl Instruction for ADDI {
impl Instruction for ADDI {
fn match_inst(&self, inst: rv32::Word) -> bool {
match_mask!(inst, "xxxxxxxxxxxxxxxxxx000xxxx0010011")
}
fn step(&self, inst: rv32::Word, state: &mut cpu::CPU) {
// self.x[inst.rd() as usize] = self.x[inst.rs1() as usize].wrapping_add(inst.imm() as u32);
}
}
#[derive(Copy, Clone)]
struct ADD;
impl Instruction for ADD {
impl Instruction for ADD {
fn match_inst(&self, inst: rv32::Word) -> bool {
match_mask!(inst, "0000000xxxxxxxxxxx000xxxx0110011")
}
fn step(&self, inst: rv32::Word, state: &mut cpu::CPU) {
}
fn step(&self, inst: rv32::Word, state: &mut cpu::CPU) {}
}
struct Extension {
instruction_set: Vec<SomeInstruction>,
#[enum_dispatch(Instruction)]
enum ExtensionI {
ADDI(ADDI),
ADD(ADD),
}
impl Extension {
fn new() -> Extension {
Extension {
instruction_set: Vec::new(),
}
}
pub fn register_inst(&mut self, inst: SomeInstruction) {
self.instruction_set.push(inst);
}
pub fn match_inst(&self, inst: rv32::Word) -> Option<SomeInstruction> {
match self.instruction_set.iter().find(|instruction| instruction.match_inst(inst)) {
Some(instruction) => Some(instruction),
None => None
}
}
enum Extensions {
ExtensionI(Option<ExtensionI>),
}
pub struct DecodeCycle {
extensions: Vec<Extension>,
extensions: Vec<Extensions>,
}
impl DecodeCycle {
@@ -136,9 +122,7 @@ impl DecodeCycle {
for extension in ext {
match extension {
'i' => {
let ext = Extension::new();
// let instructions = vec![ADDI, ADD];
// self.extensions.push();
self.extensions.push(Extensions::ExtensionI(None));
}
_ => {
println!("VM > Unknown Extension '{}'", extension);
@@ -147,7 +131,7 @@ impl DecodeCycle {
}
}
pub fn decode_inst(&self, inst: rv32::Word) -> Option<SomeInstruction> {
pub fn decode_inst(&self, inst: rv32::Word) -> Option<Instruction> {
// we need to go over every instruction and see if it matches
// we can do smarter things with cacheing later - this aint blazin
for extension in &self.extensions {

View File

@@ -1,2 +1 @@
lkkll