summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core.rs94
-rw-r--r--src/main.rs100
-rw-r--r--src/state.rs11
3 files changed, 118 insertions, 87 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) {
diff --git a/src/main.rs b/src/main.rs
index 965826e..48ce998 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -128,15 +128,15 @@ fn handle_instruction(state: &mut CpuState) {
match f3 {
0 => {
sb(state, rs1, rs2, imm);
- release_reservations(state, &[addr]);
+ state.release_reservations(&[addr]);
}
1 => {
sh(state, rs1, rs2, imm);
- release_reservations(state, &[addr, addr + 1]);
+ state.release_reservations(&[addr, addr + 1]);
}
2 => {
sw(state, rs1, rs2, imm);
- release_reservations(state, &[addr, addr + 1, addr + 2, addr + 3]);
+ state.release_reservations(&[addr, addr + 1, addr + 2, addr + 3]);
}
_ => panic!("Illegal instruction: {:x}", word),
};
@@ -195,7 +195,7 @@ fn handle_instruction(state: &mut CpuState) {
0b0010111 => {
let imm = word >> 12;
let rd = (word >> 7) & REGISTER_NAME_WIDTH;
- auipc(state, *pc, rd as usize, imm);
+ auipc(state, rd as usize, imm);
}
0b1110011 => {
// ecall
@@ -217,76 +217,17 @@ fn handle_instruction(state: &mut CpuState) {
}
match f5 {
- 2 => {
- let addr = state[rs1] as usize;
- let number: u32 = load_word(&addr);
- state[rd] = number;
- acquire_reservations(reservations, &[addr, addr + 1, addr + 2, addr + 3]);
- } // lr.w
- 3 => {
- let addr = state[rs1] as usize;
- if (*reservations).contains(&addr) {
- memory[addr..addr + 4].copy_from_slice(&state[rs2].to_le_bytes());
- state[rd] = 0;
- } else {
- state[rd] = 1;
- }
- } // sc.w
- 1 => {
- let addr = state[rs1] as usize;
- let number: u32 = load_word(&addr);
- state[rd] = number;
- store_word(addr, state[rs2]);
- } // amoswap.w
- 0 => {
- let addr = state[rs1] as usize;
- let number: u32 = load_word(&addr);
- state[rd] = (number as i32 + state[rs2] as i32) as u32;
- store_word(addr, state[rd]);
- } // amoadd.w
- 12 => {
- let addr = state[rs1] as usize;
- let number: u32 = load_word(&addr);
- state[rd] = number & state[rs2];
- store_word(addr, state[rd]);
- } // amoand.w
- 8 => {
- let addr = state[rs1] as usize;
- let number: u32 = load_word(&addr);
- state[rd] = number | state[rs2];
- store_word(addr, state[rd]);
- } // amoor.w
- 4 => {
- let addr = state[rs1] as usize;
- let number: u32 = load_word(&addr);
- state[rd] = number ^ state[rs2];
- store_word(addr, state[rd]);
- } // amoxor.w
- 20 => {
- let addr = state[rs1] as usize;
- let number: u32 = load_word(&addr);
- state[rd] = std::cmp::max(number as i32, state[rs2] as i32) as u32;
- store_word(addr, state[rd]);
- } // amomax.w
- 16 => {
- let addr = state[rs1] as usize;
- let number: u32 = load_word(&addr);
- state[rd] = std::cmp::min(number as i32, state[rs2] as i32) as u32;
- store_word(addr, state[rd]);
- } // amomin.w
- 28 => {
- let addr = state[rs1] as usize;
- let number: u32 = load_word(&addr);
- state[rd] = std::cmp::max(number, state[rs2]);
- store_word(addr, state[rd]);
- } // amomaxu.w
- 24 => {
- let addr = state[rs1] as usize;
- let number: u32 = load_word(&addr);
- state[rd] = std::cmp::min(number, state[rs2]);
- store_word(addr, state[rd]);
- } // amomin.w
-
+ 2 => lr_w(state, rd, rs1),
+ 3 => sc_w(state, rd, rs1, rs2),
+ 1 => amoswap_w(state, rd, rs1, rs2),
+ 0 => amoadd_w(state, rd, rs1, rs2),
+ 12 => amoand_w(state, rd, rs1, rs2),
+ 8 => amoor_w(state, rd, rs1, rs2),
+ 4 => amoxor_w(state, rd, rs1, rs2),
+ 20 => amomax_w(state, rd, rs1, rs2),
+ 16 => amomin_w(state, rd, rs1, rs2),
+ 28 => amomaxu_w(state, rd, rs1, rs2),
+ 24 => amominu_w(state, rd, rs1, rs2),
_ => panic!("Illegal instruction: {:x}", word),
}
}
@@ -380,15 +321,4 @@ fn handle_instruction(state: &mut CpuState) {
}
state.pc += 4;
-}
-
-fn release_reservations(state: &mut CpuState, indices: &[usize]) {
- for index in indices {
- state.reservations.remove(&index);
- }
-}
-fn acquire_reservations(state: &mut CpuState, indices: &[usize]) {
- for index in indices {
- state.reservations.insert(*index);
- }
} \ No newline at end of file
diff --git a/src/state.rs b/src/state.rs
index dcb1959..adf6a5b 100644
--- a/src/state.rs
+++ b/src/state.rs
@@ -19,4 +19,15 @@ impl CpuState {
reservations: HashSet::new()
}
}
+
+ pub fn release_reservations(&mut self, indices: &[usize]) {
+ for index in indices {
+ self.reservations.remove(&index);
+ }
+ }
+ pub fn acquire_reservations(&mut self, indices: &[usize]) {
+ for index in indices {
+ self.reservations.insert(*index);
+ }
+ }
} \ No newline at end of file