From 09d90643726d2a86952473e27b6e5d64543e41a0 Mon Sep 17 00:00:00 2001 From: taitep Date: Wed, 24 Dec 2025 13:56:41 +0100 Subject: EXCEPTION SYSTEM (initial version - may change later) --- src/instructions/rvi.rs | 77 ++++++++++++------------ src/instructions/rvi/mem.rs | 140 +++++++++++++++++--------------------------- 2 files changed, 91 insertions(+), 126 deletions(-) (limited to 'src/instructions') diff --git a/src/instructions/rvi.rs b/src/instructions/rvi.rs index 6766fdf..d8439fa 100644 --- a/src/instructions/rvi.rs +++ b/src/instructions/rvi.rs @@ -4,157 +4,154 @@ // This file is part of TRVE (https://gitea.taitep.se/taitep/trve) // See LICENSE file in the project root for full license text. -use crate::{ - core::{Core, InstructionResult}, - decode::Instruction, -}; +use crate::{core::Core, decode::Instruction, exceptions::ExceptionType}; mod mem; pub use mem::*; -pub fn add(core: &mut Core, instr: Instruction) -> InstructionResult { +pub fn add(core: &mut Core, instr: Instruction) -> Result<(), ExceptionType> { core.reg_write( instr.rd(), core.reg_read(instr.rs1()) .wrapping_add(core.reg_read(instr.rs2())), ); core.advance_pc(); - InstructionResult::Normal + Ok(()) } -pub fn sub(core: &mut Core, instr: Instruction) -> InstructionResult { +pub fn sub(core: &mut Core, instr: Instruction) -> Result<(), ExceptionType> { core.reg_write( instr.rd(), core.reg_read(instr.rs1()) .wrapping_sub(core.reg_read(instr.rs2())), ); core.advance_pc(); - InstructionResult::Normal + Ok(()) } -pub fn addi(core: &mut Core, instr: Instruction) -> InstructionResult { +pub fn addi(core: &mut Core, instr: Instruction) -> Result<(), ExceptionType> { core.reg_write( instr.rd(), core.reg_read(instr.rs1()).wrapping_add(instr.imm_i()), ); core.advance_pc(); - InstructionResult::Normal + Ok(()) } -pub fn addiw(core: &mut Core, instr: Instruction) -> InstructionResult { +pub fn addiw(core: &mut Core, instr: Instruction) -> Result<(), ExceptionType> { let res = core.reg_read(instr.rs1()).wrapping_add(instr.imm_i()) as i32; core.reg_write(instr.rd(), res as i64 as u64); core.advance_pc(); - InstructionResult::Normal + Ok(()) } -pub fn and(core: &mut Core, instr: Instruction) -> InstructionResult { +pub fn and(core: &mut Core, instr: Instruction) -> Result<(), ExceptionType> { core.reg_write( instr.rd(), core.reg_read(instr.rs1()) & core.reg_read(instr.rs2()), ); core.advance_pc(); - InstructionResult::Normal + Ok(()) } -pub fn andi(core: &mut Core, instr: Instruction) -> InstructionResult { +pub fn andi(core: &mut Core, instr: Instruction) -> Result<(), ExceptionType> { core.reg_write(instr.rd(), core.reg_read(instr.rs1()) & instr.imm_i()); core.advance_pc(); - InstructionResult::Normal + Ok(()) } -pub fn or(core: &mut Core, instr: Instruction) -> InstructionResult { +pub fn or(core: &mut Core, instr: Instruction) -> Result<(), ExceptionType> { core.reg_write( instr.rd(), core.reg_read(instr.rs1()) | core.reg_read(instr.rs2()), ); core.advance_pc(); - InstructionResult::Normal + Ok(()) } -pub fn slli(core: &mut Core, instr: Instruction) -> InstructionResult { +pub fn slli(core: &mut Core, instr: Instruction) -> Result<(), ExceptionType> { core.reg_write(instr.rd(), core.reg_read(instr.rs1()) << instr.imm_shamt()); core.advance_pc(); - InstructionResult::Normal + Ok(()) } -pub fn srli(core: &mut Core, instr: Instruction) -> InstructionResult { +pub fn srli(core: &mut Core, instr: Instruction) -> Result<(), ExceptionType> { core.reg_write(instr.rd(), core.reg_read(instr.rs1()) >> instr.imm_shamt()); core.advance_pc(); - InstructionResult::Normal + Ok(()) } -pub fn lui(core: &mut Core, instr: Instruction) -> InstructionResult { +pub fn lui(core: &mut Core, instr: Instruction) -> Result<(), ExceptionType> { core.reg_write(instr.rd(), instr.imm_u()); core.advance_pc(); - InstructionResult::Normal + Ok(()) } -pub fn auipc(core: &mut Core, instr: Instruction) -> InstructionResult { +pub fn auipc(core: &mut Core, instr: Instruction) -> Result<(), ExceptionType> { core.reg_write(instr.rd(), core.pc.wrapping_add(instr.imm_u())); core.advance_pc(); - InstructionResult::Normal + Ok(()) } -pub fn jal(core: &mut Core, instr: Instruction) -> InstructionResult { +pub fn jal(core: &mut Core, instr: Instruction) -> Result<(), ExceptionType> { core.reg_write(instr.rd(), core.pc.wrapping_add(4)); core.pc = core.pc.wrapping_add(instr.imm_j()); - InstructionResult::Normal + Ok(()) } -pub fn jalr(core: &mut Core, instr: Instruction) -> InstructionResult { +pub fn jalr(core: &mut Core, instr: Instruction) -> Result<(), ExceptionType> { core.reg_write(instr.rd(), core.pc.wrapping_add(4)); core.pc = core.reg_read(instr.rs1()).wrapping_add(instr.imm_i()); - InstructionResult::Normal + Ok(()) } -pub fn beq(core: &mut Core, instr: Instruction) -> InstructionResult { +pub fn beq(core: &mut Core, instr: Instruction) -> Result<(), ExceptionType> { if core.reg_read(instr.rs1()) == core.reg_read(instr.rs2()) { core.pc = core.pc.wrapping_add(instr.imm_b()); } else { core.advance_pc(); } - InstructionResult::Normal + Ok(()) } -pub fn bne(core: &mut Core, instr: Instruction) -> InstructionResult { +pub fn bne(core: &mut Core, instr: Instruction) -> Result<(), ExceptionType> { if core.reg_read(instr.rs1()) != core.reg_read(instr.rs2()) { core.pc = core.pc.wrapping_add(instr.imm_b()); } else { core.advance_pc(); } - InstructionResult::Normal + Ok(()) } -pub fn blt(core: &mut Core, instr: Instruction) -> InstructionResult { +pub fn blt(core: &mut Core, instr: Instruction) -> Result<(), ExceptionType> { if (core.reg_read(instr.rs1()) as i64) < (core.reg_read(instr.rs2()) as i64) { core.pc = core.pc.wrapping_add(instr.imm_b()); } else { core.advance_pc(); } - InstructionResult::Normal + Ok(()) } -pub fn bgeu(core: &mut Core, instr: Instruction) -> InstructionResult { +pub fn bgeu(core: &mut Core, instr: Instruction) -> Result<(), ExceptionType> { if core.reg_read(instr.rs1()) >= core.reg_read(instr.rs2()) { core.pc = core.pc.wrapping_add(instr.imm_b()); } else { core.advance_pc(); } - InstructionResult::Normal + Ok(()) } -pub fn bltu(core: &mut Core, instr: Instruction) -> InstructionResult { +pub fn bltu(core: &mut Core, instr: Instruction) -> Result<(), ExceptionType> { if core.reg_read(instr.rs1()) < core.reg_read(instr.rs2()) { core.pc = core.pc.wrapping_add(instr.imm_b()); } else { core.advance_pc(); } - InstructionResult::Normal + Ok(()) } diff --git a/src/instructions/rvi/mem.rs b/src/instructions/rvi/mem.rs index c948519..ad938cb 100644 --- a/src/instructions/rvi/mem.rs +++ b/src/instructions/rvi/mem.rs @@ -7,177 +7,145 @@ use crate::{ consts::{Addr, Byte, DWord, HWord, Word}, core::Core, - instructions::{Instruction, InstructionResult}, + exceptions::ExceptionType, + instructions::Instruction, mem::PageNum, }; // TODO: Support misaligned memory access -pub fn sd(core: &mut Core, instr: Instruction) -> InstructionResult { +pub fn sd(core: &mut Core, instr: Instruction) -> Result<(), ExceptionType> { let addr = core.reg_read(instr.rs1()).wrapping_add(instr.imm_s()); if !addr.is_multiple_of(std::mem::size_of::() as Addr) { - return InstructionResult::Exception(()); + return Err(ExceptionType::StoreAmoAddressMisaligned); } let page = (addr / 4096) as PageNum; let offset = (addr / 8 & ((4096 / 8 as Addr) - 1)) as u16; let value = core.reg_read(instr.rs2()); - match core.mem.write_dword(page, offset, value) { - Ok(_) => { - core.advance_pc(); - InstructionResult::Normal - } - Err(_) => InstructionResult::Exception(()), - } + core.mem.write_dword(page, offset, value)?; + core.advance_pc(); + + Ok(()) } -pub fn ld(core: &mut Core, instr: Instruction) -> InstructionResult { +pub fn ld(core: &mut Core, instr: Instruction) -> Result<(), ExceptionType> { let addr = core.reg_read(instr.rs1()).wrapping_add(instr.imm_i()); if !addr.is_multiple_of(std::mem::size_of::() as Addr) { - return InstructionResult::Exception(()); + return Err(ExceptionType::LoadAddressMisaligned); } let page = (addr / 4096) as PageNum; let offset = (addr / 8 & ((4096 / 8 as Addr) - 1)) as u16; - match core.mem.read_dword(page, offset) { - Ok(x) => { - core.reg_write(instr.rd(), x); - core.advance_pc(); - InstructionResult::Normal - } - Err(_) => InstructionResult::Exception(()), - } + core.reg_write(instr.rd(), core.mem.read_dword(page, offset)?); + core.advance_pc(); + Ok(()) } -pub fn sw(core: &mut Core, instr: Instruction) -> InstructionResult { +pub fn sw(core: &mut Core, instr: Instruction) -> Result<(), ExceptionType> { let addr = core.reg_read(instr.rs1()).wrapping_add(instr.imm_s()); if !addr.is_multiple_of(std::mem::size_of::() as Addr) { - return InstructionResult::Exception(()); + return Err(ExceptionType::StoreAmoAddressMisaligned); } let page = (addr / 4096) as PageNum; let offset = (addr / 4 & ((4096 / 4 as Addr) - 1)) as u16; let value = core.reg_read(instr.rs2()) as Word; - match core.mem.write_word(page, offset, value) { - Ok(_) => { - core.advance_pc(); - InstructionResult::Normal - } - Err(_) => InstructionResult::Exception(()), - } + core.mem.write_word(page, offset, value)?; + core.advance_pc(); + Ok(()) } -pub fn lw(core: &mut Core, instr: Instruction) -> InstructionResult { +pub fn lw(core: &mut Core, instr: Instruction) -> Result<(), ExceptionType> { let addr = core.reg_read(instr.rs1()).wrapping_add(instr.imm_i()); if !addr.is_multiple_of(std::mem::size_of::() as Addr) { - return InstructionResult::Exception(()); + return Err(ExceptionType::LoadAddressMisaligned); } let page = (addr / 4096) as PageNum; let offset = (addr / 4 & ((4096 / 4 as Addr) - 1)) as u16; - match core.mem.read_word(page, offset) { - Ok(x) => { - core.reg_write(instr.rd(), x as i32 as i64 as DWord); - core.advance_pc(); - InstructionResult::Normal - } - Err(_) => InstructionResult::Exception(()), - } + core.reg_write( + instr.rd(), + core.mem.read_word(page, offset)? as i32 as i64 as DWord, + ); + core.advance_pc(); + Ok(()) } -pub fn sh(core: &mut Core, instr: Instruction) -> InstructionResult { +pub fn sh(core: &mut Core, instr: Instruction) -> Result<(), ExceptionType> { let addr = core.reg_read(instr.rs1()).wrapping_add(instr.imm_s()); if !addr.is_multiple_of(std::mem::size_of::() as Addr) { - return InstructionResult::Exception(()); + return Err(ExceptionType::StoreAmoAddressMisaligned); } let page = (addr / 4096) as PageNum; let offset = (addr / 2 & ((4096 / 2 as Addr) - 1)) as u16; let value = core.reg_read(instr.rs2()) as HWord; - match core.mem.write_hword(page, offset, value) { - Ok(_) => { - core.advance_pc(); - InstructionResult::Normal - } - Err(_) => InstructionResult::Exception(()), - } + core.mem.write_hword(page, offset, value)?; + core.advance_pc(); + Ok(()) } -pub fn lh(core: &mut Core, instr: Instruction) -> InstructionResult { +pub fn lh(core: &mut Core, instr: Instruction) -> Result<(), ExceptionType> { let addr = core.reg_read(instr.rs1()).wrapping_add(instr.imm_i()); if !addr.is_multiple_of(std::mem::size_of::() as Addr) { - return InstructionResult::Exception(()); + return Err(ExceptionType::LoadAddressMisaligned); } let page = (addr / 4096) as PageNum; let offset = (addr / 2 & ((4096 / 2 as Addr) - 1)) as u16; - match core.mem.read_hword(page, offset) { - Ok(x) => { - core.reg_write(instr.rd(), x as i16 as i64 as DWord); - core.advance_pc(); - InstructionResult::Normal - } - Err(_) => InstructionResult::Exception(()), - } + core.reg_write( + instr.rd(), + core.mem.read_hword(page, offset)? as i16 as i64 as DWord, + ); + core.advance_pc(); + Ok(()) } -pub fn sb(core: &mut Core, instr: Instruction) -> InstructionResult { +pub fn sb(core: &mut Core, instr: Instruction) -> Result<(), ExceptionType> { let addr = core.reg_read(instr.rs1()).wrapping_add(instr.imm_s()); let page = (addr / 4096) as PageNum; let offset = (addr & (4096 as Addr - 1)) as u16; let value = core.reg_read(instr.rs2()) as Byte; - match core.mem.write_byte(page, offset, value) { - Ok(_) => { - core.advance_pc(); - InstructionResult::Normal - } - Err(_) => InstructionResult::Exception(()), - } + core.mem.write_byte(page, offset, value)?; + core.advance_pc(); + Ok(()) } -pub fn lb(core: &mut Core, instr: Instruction) -> InstructionResult { +pub fn lb(core: &mut Core, instr: Instruction) -> Result<(), ExceptionType> { let addr = core.reg_read(instr.rs1()).wrapping_add(instr.imm_i()); let page = (addr / 4096) as PageNum; let offset = (addr & (4096 as Addr - 1)) as u16; - match core.mem.read_byte(page, offset) { - Ok(x) => { - let x = x as i8 as i64 as DWord; - core.reg_write(instr.rd(), x); - core.advance_pc(); - InstructionResult::Normal - } - Err(_) => InstructionResult::Exception(()), - } + core.reg_write( + instr.rd(), + core.mem.read_byte(page, offset)? as i8 as i64 as DWord, + ); + core.advance_pc(); + Ok(()) } -pub fn lbu(core: &mut Core, instr: Instruction) -> InstructionResult { +pub fn lbu(core: &mut Core, instr: Instruction) -> Result<(), ExceptionType> { let addr = core.reg_read(instr.rs1()).wrapping_add(instr.imm_i()); let page = (addr / 4096) as PageNum; let offset = (addr & (4096 as Addr - 1)) as u16; - match core.mem.read_byte(page, offset) { - Ok(x) => { - let x = x as DWord; - core.reg_write(instr.rd(), x); - core.advance_pc(); - InstructionResult::Normal - } - Err(_) => InstructionResult::Exception(()), - } + core.reg_write(instr.rd(), core.mem.read_byte(page, offset)? as DWord); + core.advance_pc(); + Ok(()) } -- cgit v1.2.3