diff options
Diffstat (limited to 'src/instructions/rvi/mem.rs')
| -rw-r--r-- | src/instructions/rvi/mem.rs | 140 |
1 files changed, 54 insertions, 86 deletions
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::<DWord>() 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::<DWord>() 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::<Word>() 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::<Word>() 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::<HWord>() 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::<HWord>() 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(()) } |
