summaryrefslogtreecommitdiff
path: root/src/core.rs
diff options
context:
space:
mode:
authorNathan Lee <me@nwlee.tech>2026-06-10 22:27:19 -0500
committerNathan Lee <me@nwlee.tech>2026-06-10 22:27:19 -0500
commitf94c087120bf2a241dda51d6311c565dd03b96be (patch)
tree102d074b949bf5cd8caef386818c80153f254e4c /src/core.rs
parenta37a07533fa9b8bd8962ca3c1aea082ae2548651 (diff)
move atomics into core.rs
Diffstat (limited to 'src/core.rs')
-rw-r--r--src/core.rs94
1 files changed, 92 insertions, 2 deletions
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) {