From f94c087120bf2a241dda51d6311c565dd03b96be Mon Sep 17 00:00:00 2001 From: Nathan Lee Date: Wed, 10 Jun 2026 22:27:19 -0500 Subject: move atomics into core.rs --- src/core.rs | 94 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 92 insertions(+), 2 deletions(-) (limited to 'src/core.rs') diff --git a/src/core.rs b/src/core.rs index 67a21de..3b59782 100644 --- a/src/core.rs +++ b/src/core.rs @@ -268,8 +268,98 @@ pub fn lui(state: &mut CpuState, rd: usize, imm: u32) { state.registers[rd] = imm << 12; } -pub fn auipc(state: &mut CpuState, pc: u32, rd: usize, imm: u32) { - state.registers[rd] = pc + (imm << 12); +pub fn lr_w(state: &mut CpuState, rd: usize, rs1: usize) { + let addr = state.registers[rs1] as usize; + state.registers[rd] = load_word(state, addr); + state.acquire_reservations(&[addr, addr + 1, addr + 2, addr + 3]); +} + +pub fn sc_w(state: &mut CpuState, rd: usize, rs1: usize, rs2: usize) { + let addr = state.registers[rs1] as usize; + if state.reservations.contains(&addr) { + store_word(state, addr, state.registers[rs2]); + state.registers[rd] = 0; + } else { + state.registers[rd] = 1; + } +} + +pub fn amoswap_w(state: &mut CpuState, rd: usize, rs1: usize, rs2: usize) { + let addr = state.registers[rs1] as usize; + let number: u32 = load_word(state, addr); + state.registers[rd] = number; + store_word(state, addr, state.registers[rs2]); +} + +pub fn amoadd_w(state: &mut CpuState, rd: usize, rs1: usize, rs2: usize) { + let addr = state.registers[rs1] as usize; + let number: u32 = load_word(state, addr); + state.registers[rd] = (number as i32 + state.registers[rs2] as i32) as u32; + store_word(state, addr, state.registers[rd]); +} + +pub fn amoand_w(state: &mut CpuState, rd: usize, rs1: usize, rs2: usize) { + let addr = state.registers[rs1] as usize; + let number: u32 = load_word(state, addr); + state.registers[rd] = number & state.registers[rs2]; + store_word(state, addr, state.registers[rd]); +} + +pub fn amoor_w(state: &mut CpuState, rd: usize, rs1: usize, rs2: usize) { + let addr = state.registers[rs1] as usize; + let number: u32 = load_word(state, addr); + state.registers[rd] = number | state.registers[rs2]; + store_word(state, addr, state.registers[rd]); +} + +pub fn amoxor_w(state: &mut CpuState, rd: usize, rs1: usize, rs2: usize) { + let addr = state.registers[rs1] as usize; + let number: u32 = load_word(state, addr); + state.registers[rd] = number ^ state.registers[rs2]; + store_word(state, addr, state.registers[rd]); +} + +pub fn amomax_w(state: &mut CpuState, rd: usize, rs1: usize, rs2: usize) { + let addr = state.registers[rs1] as usize; + let number: u32 = load_word(state, addr); + state.registers[rd] = std::cmp::max(number as i32, state.registers[rs2] as i32) as u32; + store_word(state, addr, state.registers[rd]); +} + +pub fn amomin_w(state: &mut CpuState, rd: usize, rs1: usize, rs2: usize) { + let addr = state.registers[rs1] as usize; + let number: u32 = load_word(state, addr); + state.registers[rd] = std::cmp::min(number as i32, state.registers[rs2] as i32) as u32; + store_word(state, addr, state.registers[rd]); +} + +pub fn amomaxu_w(state: &mut CpuState, rd: usize, rs1: usize, rs2: usize) { + let addr = state.registers[rs1] as usize; + let number: u32 = load_word(state, addr); + state.registers[rd] = std::cmp::max(number, state.registers[rs2]); + store_word(state, addr, state.registers[rd]); +} + +pub fn amominu_w(state: &mut CpuState, rd: usize, rs1: usize, rs2: usize) { + let addr = state.registers[rs1] as usize; + let number: u32 = load_word(state, addr); + state.registers[rd] = std::cmp::min(number, state.registers[rs2]); + store_word(state, addr, state.registers[rd]); +} + +fn load_word(state: &CpuState, addr: usize) -> u32 { + let slice = state.memory.read_multiple_bytes(addr, 4, 99).unwrap(); + u32::from_le_bytes(slice[0..4].try_into().unwrap()) +} +fn store_word(state: &mut CpuState, addr: usize, value: u32) { + state + .memory + .write_multiple_bytes(addr, &value.to_le_bytes(), 99) + .unwrap(); +} + +pub fn auipc(state: &mut CpuState, rd: usize, imm: u32) { + state.registers[rd] = state.pc + (imm << 12); } pub fn fmadd_s(state: &mut CpuState, rd: usize, rs1: usize, rs2: usize, rs3: usize) { -- cgit v1.2.3