diff options
| author | taitep <taitep@taitep.se> | 2025-12-26 14:20:27 +0100 |
|---|---|---|
| committer | taitep <taitep@taitep.se> | 2025-12-26 14:20:27 +0100 |
| commit | 528b519ce98c21049705526442cbde1672495b49 (patch) | |
| tree | 487714ef8a58c9610da6b97d76ecd97e58b8b921 /src/instructions/rvi | |
| parent | 6d9efb7eb85af929f3d6c22111933bb58d1ea07e (diff) | |
(BIG CHANGE) memory handling has changed, MMIO is now a 2 level page table, misaligned access supported, addresses not internally split to page and offset immediately, all load/store instructions implemented. Might still have bugs
Diffstat (limited to 'src/instructions/rvi')
| -rw-r--r-- | src/instructions/rvi/mem.rs | 127 |
1 files changed, 56 insertions, 71 deletions
diff --git a/src/instructions/rvi/mem.rs b/src/instructions/rvi/mem.rs index ad938cb..bc02b7f 100644 --- a/src/instructions/rvi/mem.rs +++ b/src/instructions/rvi/mem.rs @@ -5,75 +5,63 @@ // See LICENSE file in the project root for full license text. use crate::{ - consts::{Addr, Byte, DWord, HWord, Word}, + consts::{Byte, DWord, HWord, Word}, core::Core, exceptions::ExceptionType, instructions::Instruction, - mem::PageNum, }; -// TODO: Support misaligned memory access 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 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()); - - core.mem.write_dword(page, offset, value)?; + core.mem + .write_dword(addr, value) + .map_err(|e| e.to_exception_store())?; core.advance_pc(); - Ok(()) } 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 Err(ExceptionType::LoadAddressMisaligned); - } - - let page = (addr / 4096) as PageNum; - let offset = (addr / 8 & ((4096 / 8 as Addr) - 1)) as u16; - - core.reg_write(instr.rd(), core.mem.read_dword(page, offset)?); + core.reg_write( + instr.rd(), + core.mem + .read_dword(addr) + .map_err(|e| e.to_exception_load())?, + ); core.advance_pc(); Ok(()) } 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 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; - - core.mem.write_word(page, offset, value)?; + core.mem + .write_word(addr, value) + .map_err(|e| e.to_exception_store())?; core.advance_pc(); Ok(()) } pub fn lw(core: &mut Core, instr: Instruction) -> Result<(), ExceptionType> { let addr = core.reg_read(instr.rs1()).wrapping_add(instr.imm_i()); + core.reg_write( + instr.rd(), + core.mem + .read_word(addr) + .map_err(|e| e.to_exception_load())? as i32 as i64 as DWord, + ); + core.advance_pc(); + Ok(()) +} - if !addr.is_multiple_of(std::mem::size_of::<Word>() as Addr) { - return Err(ExceptionType::LoadAddressMisaligned); - } - - let page = (addr / 4096) as PageNum; - let offset = (addr / 4 & ((4096 / 4 as Addr) - 1)) as u16; - +pub fn lwu(core: &mut Core, instr: Instruction) -> Result<(), ExceptionType> { + let addr = core.reg_read(instr.rs1()).wrapping_add(instr.imm_i()); core.reg_write( instr.rd(), - core.mem.read_word(page, offset)? as i32 as i64 as DWord, + core.mem + .read_word(addr) + .map_err(|e| e.to_exception_load())? as DWord, ); core.advance_pc(); Ok(()) @@ -81,33 +69,33 @@ pub fn lw(core: &mut Core, instr: Instruction) -> Result<(), ExceptionType> { 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 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; - - core.mem.write_hword(page, offset, value)?; + core.mem + .write_hword(addr, value) + .map_err(|e| e.to_exception_store())?; core.advance_pc(); Ok(()) } pub fn lh(core: &mut Core, instr: Instruction) -> Result<(), ExceptionType> { let addr = core.reg_read(instr.rs1()).wrapping_add(instr.imm_i()); + core.reg_write( + instr.rd(), + core.mem + .read_hword(addr) + .map_err(|e| e.to_exception_load())? as i16 as i64 as DWord, + ); + core.advance_pc(); + Ok(()) +} - if !addr.is_multiple_of(std::mem::size_of::<HWord>() as Addr) { - return Err(ExceptionType::LoadAddressMisaligned); - } - - let page = (addr / 4096) as PageNum; - let offset = (addr / 2 & ((4096 / 2 as Addr) - 1)) as u16; - +pub fn lhu(core: &mut Core, instr: Instruction) -> Result<(), ExceptionType> { + let addr = core.reg_read(instr.rs1()).wrapping_add(instr.imm_i()); core.reg_write( instr.rd(), - core.mem.read_hword(page, offset)? as i16 as i64 as DWord, + core.mem + .read_hword(addr) + .map_err(|e| e.to_exception_load())? as DWord, ); core.advance_pc(); Ok(()) @@ -115,25 +103,21 @@ pub fn lh(core: &mut Core, instr: Instruction) -> Result<(), ExceptionType> { 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; - - core.mem.write_byte(page, offset, value)?; + core.mem + .write_byte(addr, value) + .map_err(|e| e.to_exception_store())?; core.advance_pc(); Ok(()) } 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; - core.reg_write( instr.rd(), - core.mem.read_byte(page, offset)? as i8 as i64 as DWord, + core.mem + .read_byte(addr) + .map_err(|e| e.to_exception_load())? as i8 as i64 as DWord, ); core.advance_pc(); Ok(()) @@ -141,11 +125,12 @@ pub fn lb(core: &mut Core, instr: Instruction) -> Result<(), ExceptionType> { 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; - - core.reg_write(instr.rd(), core.mem.read_byte(page, offset)? as DWord); + core.reg_write( + instr.rd(), + core.mem + .read_byte(addr) + .map_err(|e| e.to_exception_load())? as DWord, + ); core.advance_pc(); Ok(()) } |
