diff options
| author | taitep <taitep@taitep.se> | 2025-12-21 12:07:12 +0100 |
|---|---|---|
| committer | taitep <taitep@taitep.se> | 2025-12-21 12:07:12 +0100 |
| commit | ac9506a1a785495a8f5f299ca90f948cce28ecc7 (patch) | |
| tree | a3517406fc74edca336249601cc89b65477f5d2e /src/instructions.rs | |
| parent | e2d521bbe73708da64662478155630d634e00932 (diff) | |
(BIG CHANGE) Switch instruction identification/execution to use a plain match tree, should improve performance by quite a bit
Diffstat (limited to 'src/instructions.rs')
| -rw-r--r-- | src/instructions.rs | 89 |
1 files changed, 19 insertions, 70 deletions
diff --git a/src/instructions.rs b/src/instructions.rs index 2d18a2c..eead29f 100644 --- a/src/instructions.rs +++ b/src/instructions.rs @@ -4,82 +4,31 @@ // This file is part of TRVE (https://gitea.taitep.se/taitep/trve) // See LICENSE file in the project root for full license text. -use once_cell::sync::Lazy; - -mod gen_tools; -mod opcodes; mod rvi; -static INSTRUCTIONS: Lazy<[OpcodeHandler; 32]> = Lazy::new(|| { - let mut instructions = std::array::from_fn(|_i| OpcodeHandler { - handler: None, - splitter: None, - }); - - rvi::add_instrs(&mut instructions); - - instructions -}); - use crate::{ - consts::Word, core::{Core, InstructionResult}, decode::Instruction, }; -type Runner = fn(&mut Core, Instruction) -> InstructionResult; - -#[derive(Clone, Copy)] -struct InstructionHandler { - runner: Runner, -} - -struct OpcodeHandler { - handler: Option<InstructionHandler>, - splitter: Option<Splitter>, -} - -pub fn find_runner(instruction: Instruction) -> Option<Runner> { - let opcode_handler = &INSTRUCTIONS[instruction.opcode_noncompressed() as usize]; - opcode_handler.find_runner(instruction) -} - -impl OpcodeHandler { - fn find_runner(&self, instruction: Instruction) -> Option<Runner> { - if let Some(splitter) = &self.splitter { - splitter.find_runner(instruction) - } else { - self.handler.map(|h| h.runner) - } +pub(crate) fn find_and_exec(instr: Instruction, core: &mut Core) -> Option<InstructionResult> { + match instr.opcode_noncompressed() { + 0b00100 => match instr.funct3() { + // OP_IMM + 0b000 => Some(rvi::addi(core, instr)), + _ => None, + }, + 0b00110 => match instr.funct3() { + // OP_IMM_32 + 0b000 => Some(rvi::addiw(core, instr)), + _ => None, + }, + 0b01000 => match instr.funct3() { + // STORE + 0b011 => Some(rvi::sd(core, instr)), + _ => None, + }, + 0b01101 => Some(rvi::lui(core, instr)), + _ => None, } } - -enum Splitter { - Funct3Splitter(Box<[OpcodeHandler; 8]>), - GeneralSplitter(Box<[GeneralSplitterEntry]>), -} - -impl Splitter { - fn find_runner(&self, instruction: Instruction) -> Option<Runner> { - match self { - Splitter::Funct3Splitter(f3s) => { - f3s[instruction.funct3() as usize].find_runner(instruction) - } - Splitter::GeneralSplitter(entries) => { - for entry in entries { - if instruction.0 & entry.mask == entry.value { - return Some(entry.handler.runner); - } - } - - None - } - } - } -} - -struct GeneralSplitterEntry { - mask: Word, - value: Word, - handler: InstructionHandler, -} |
