From 75c25dc1ccbe88f8187fde0364c0f766caa27ba2 Mon Sep 17 00:00:00 2001 From: Benjamin Kyd Date: Thu, 6 Jul 2023 00:54:02 +0100 Subject: [PATCH] enum dispatch --- Cargo.lock | 19 ++++++++++++++++++ Cargo.toml | 1 + src/ext/decode.rs | 50 ++++++++++++++++------------------------------- src/ext/i/mod.rs | 1 - 4 files changed, 37 insertions(+), 34 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 080efbe..900eaca 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -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", ] diff --git a/Cargo.toml b/Cargo.toml index 09e0ce4..175c31f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,5 +7,6 @@ edition = "2021" path = "lib/bits" [dependencies] +enum_dispatch = "0.3.11" modular-bitfield = "0.11.2" num = "0.4.0" diff --git a/src/ext/decode.rs b/src/ext/decode.rs index 60840e7..971f5cc 100644 --- a/src/ext/decode.rs +++ b/src/ext/decode.rs @@ -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, 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, } +#[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, +#[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 { - match self.instruction_set.iter().find(|instruction| instruction.match_inst(inst)) { - Some(instruction) => Some(instruction), - None => None - } - } +enum Extensions { + ExtensionI(Option), } pub struct DecodeCycle { - extensions: Vec, + extensions: Vec, } 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 { + pub fn decode_inst(&self, inst: rv32::Word) -> Option { // 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 { diff --git a/src/ext/i/mod.rs b/src/ext/i/mod.rs index bdc9623..8b13789 100644 --- a/src/ext/i/mod.rs +++ b/src/ext/i/mod.rs @@ -1,2 +1 @@ -lkkll