// Copyright (c) 2025 taitep // SPDX-License-Identifier: MIT // // This file is part of TRVE (https://gitea.taitep.se/taitep/trve) // See LICENSE file in the project root for full license text. mod rvi; use crate::{ core::Core, decode::Instruction, exceptions::ExceptionType::{self, IllegalInstruction}, }; pub(crate) fn find_and_exec(instr: Instruction, core: &mut Core) -> Result<(), ExceptionType> { match instr.opcode_noncompressed() { 0b01100 => match (instr.funct7(), instr.funct3()) { // OP (0b0000000, 0b000) => rvi::add(core, instr), (0b0100000, 0b000) => rvi::sub(core, instr), (0b0000000, 0b111) => rvi::and(core, instr), (0b0000000, 0b110) => rvi::or(core, instr), _ => Err(IllegalInstruction), }, 0b00100 => match instr.funct3() { // OP_IMM 0b000 => rvi::addi(core, instr), 0b001 => { if instr.funct6() == 0 { rvi::slli(core, instr) } else { Err(IllegalInstruction) } } 0b101 => match instr.funct6() { // immediate right-shift 0b000000 => rvi::srli(core, instr), _ => Err(IllegalInstruction), }, 0b111 => rvi::andi(core, instr), _ => Err(IllegalInstruction), }, 0b00110 => match instr.funct3() { // OP_IMM_32 0b000 => rvi::addiw(core, instr), _ => Err(IllegalInstruction), }, 0b01000 => match instr.funct3() { // STORE 0b000 => rvi::sb(core, instr), 0b001 => rvi::sh(core, instr), 0b010 => rvi::sw(core, instr), 0b011 => rvi::sd(core, instr), _ => Err(IllegalInstruction), }, 0b00000 => match instr.funct3() { // LOAD 0b000 => rvi::lb(core, instr), 0b100 => rvi::lbu(core, instr), 0b001 => rvi::lh(core, instr), 0b010 => rvi::lw(core, instr), 0b011 => rvi::ld(core, instr), _ => Err(IllegalInstruction), }, 0b11000 => match instr.funct3() { // BRANCH 0b000 => rvi::beq(core, instr), 0b001 => rvi::bne(core, instr), 0b100 => rvi::blt(core, instr), 0b110 => rvi::bltu(core, instr), 0b111 => rvi::bgeu(core, instr), _ => Err(IllegalInstruction), }, 0b01101 => rvi::lui(core, instr), 0b00101 => rvi::auipc(core, instr), 0b11011 => rvi::jal(core, instr), // 0b11001 => (instr.funct3() == 0).then(|| rvi::jalr(core, instr)), 0b11001 => { if instr.funct3() == 0 { rvi::jalr(core, instr) } else { Err(IllegalInstruction) } } _ => Err(IllegalInstruction), } }