use strum::IntoEnumIterator; use super::encoding::{GenInstruction, Instruction}; use crate::cpu; use crate::system::rv32; use crate::ext::i; pub struct DecodeCycle { extensions: Vec, } impl DecodeCycle { pub fn new(ext: Vec) -> DecodeCycle { DecodeCycle { extensions: ext } } // TODO: speed this up by matching based on the opcode field and then fn3 pub fn decode_exec_inst( &self, inst: rv32::Word, state: &mut cpu::CPUState, ) -> Result<(), &str> { // we want to go through each extension and then go through each instruction in that extension // if we find a match, we want to execute it // if we don't find a match, we want to return an error fn enumerate_extension( inst: rv32::Word, state: &mut cpu::CPUState, ) -> Option<()> { for instruction in T::iter() { if instruction.match_inst(inst) { let geninst = GenInstruction { inst }; instruction.step(geninst, state); return Some(()); } } None } for extension in self.extensions.iter() { match extension { 'i' => { if let Some(()) = enumerate_extension::(inst, state) { return Ok(()); } } _ => println!("VM > Unknown Extension"), } } Err("No instruction found") } }