summaryrefslogtreecommitdiff
path: root/src/main.rs
diff options
context:
space:
mode:
authorNathan Lee <me@nwlee.tech>2026-06-06 20:52:23 -0500
committerNathan Lee <me@nwlee.tech>2026-06-06 20:52:23 -0500
commit615e98a616c851fb6230184029aa4297417cdf6e (patch)
treea88dc22f557599b309c0b7694f8fa4461b7a33dc /src/main.rs
parentf10e66835ae5ba9298786acd9510297be4c18ad2 (diff)
add F extension
Diffstat (limited to 'src/main.rs')
-rw-r--r--src/main.rs90
1 files changed, 90 insertions, 0 deletions
diff --git a/src/main.rs b/src/main.rs
index 4ccd0a1..9ec507b 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -17,6 +17,7 @@ static MEMORY: LazyLock<Mutex<Box<[u8]>>> =
struct CpuState<'a> {
memory: &'a mut Box<[u8]>,
registers: &'a mut [u32; 32],
+ f_registers: &'a mut [f32; 32],
pc: &'a mut u32,
reservations: &'a mut HashSet<usize>,
}
@@ -43,6 +44,7 @@ fn main() {
}
let mut registers: [u32; 32] = [0; 32];
+ let mut f_registers: [f32; 32] = [0f32; 32];
let mut pc: u32 = 0;
let mut reservations: HashSet<usize> = HashSet::new();
@@ -64,6 +66,7 @@ fn main() {
handle_instruction(CpuState {
memory: &mut *memory,
registers: &mut registers,
+ f_registers: &mut f_registers,
pc: &mut pc,
reservations: &mut reservations,
});
@@ -75,6 +78,7 @@ fn handle_instruction(
CpuState {
memory,
registers,
+ f_registers,
pc,
reservations,
}: CpuState,
@@ -352,6 +356,92 @@ fn handle_instruction(
_ => panic!("Illegal instruction: {:x}", word),
}
}
+ 0b1000011 => {
+ // todo: handle rm bit
+ let rd = ((word >> 7) & REGISTER_NAME_WIDTH) as usize;
+ let rs1 = ((word >> 15) & REGISTER_NAME_WIDTH) as usize;
+ let rs2 = ((word >> 20) & REGISTER_NAME_WIDTH) as usize;
+ let rs3 = ((word >> 27) & REGISTER_NAME_WIDTH) as usize;
+
+ fmadd_s(f_registers, rd, rs1, rs2, rs3);
+ }
+ 0b1000111 => {
+ // todo: handle rm bit
+ let rd = ((word >> 7) & REGISTER_NAME_WIDTH) as usize;
+ let rs1 = ((word >> 15) & REGISTER_NAME_WIDTH) as usize;
+ let rs2 = ((word >> 20) & REGISTER_NAME_WIDTH) as usize;
+ let rs3 = ((word >> 27) & REGISTER_NAME_WIDTH) as usize;
+
+ fmsub_s(f_registers, rd, rs1, rs2, rs3);
+ }
+ 0b1001011 => {
+ // todo: handle rm bit
+ let rd = ((word >> 7) & REGISTER_NAME_WIDTH) as usize;
+ let rs1 = ((word >> 15) & REGISTER_NAME_WIDTH) as usize;
+ let rs2 = ((word >> 20) & REGISTER_NAME_WIDTH) as usize;
+ let rs3 = ((word >> 27) & REGISTER_NAME_WIDTH) as usize;
+
+ fnmsub_s(f_registers, rd, rs1, rs2, rs3);
+ }
+ 0b1001111 => {
+ // todo: handle rm bit
+ let rd = ((word >> 7) & REGISTER_NAME_WIDTH) as usize;
+ let rs1 = ((word >> 15) & REGISTER_NAME_WIDTH) as usize;
+ let rs2 = ((word >> 20) & REGISTER_NAME_WIDTH) as usize;
+ let rs3 = ((word >> 27) & REGISTER_NAME_WIDTH) as usize;
+
+ fnmadd_s(f_registers, rd, rs1, rs2, rs3);
+ }
+ 0b1010011 => {
+ // todo: handle rm bit
+ let rd = ((word >> 7) & REGISTER_NAME_WIDTH) as usize;
+ let rs1 = ((word >> 15) & REGISTER_NAME_WIDTH) as usize;
+ let rs2 = ((word >> 20) & REGISTER_NAME_WIDTH) as usize;
+ let f5 = word >> 27;
+ let rm = (word >> 12) & 0b111;
+
+ match f5 {
+ 0 => fadd_s(f_registers, rd, rs1, rs2),
+ 1 => fsub_s(f_registers, rd, rs1, rs2),
+ 2 => fmul_s(f_registers, rd, rs1, rs2),
+ 3 => fdiv_s(f_registers, rd, rs1, rs2),
+ 11 => fsqrt_s(f_registers, rd, rs1),
+ 4 => match rm {
+ 0 => fsgnj_s(f_registers, rd, rs1, rs2),
+ 1 => fsgnjn_s(f_registers, rd, rs1, rs2),
+ 2 => fsgnjx_s(f_registers, rd, rs1, rs2),
+ _ => panic!("Illegal instruction: {:x}", rm),
+ },
+ 5 => match rm {
+ 0 => fmin_s(f_registers, rd, rs1, rs2),
+ 1 => fmax_s(f_registers, rd, rs1, rs2),
+ _ => panic!("Illegal instruction: {:x}", rm),
+ },
+ 24 => {
+ fcvt_wu_s(registers, f_registers, rd, rs1);
+ }
+ 28 => {
+ match rm {
+ 0 => fmv_x_w(registers, f_registers, rd, rs1),
+ 1 => fclass_s(registers, f_registers, rd, rs1),
+ _ => panic!("Illegal instruction: {:x}", rm),
+ };
+ }
+ 20 => match rm {
+ 0 => feq_s(registers, f_registers, rd, rs1, rs2),
+ 1 => flt_s(registers, f_registers, rd, rs1, rs2),
+ 2 => fle_s(registers, f_registers, rd, rs1, rs2),
+ _ => panic!("Illegal instruction: {:x}", rm),
+ },
+
+ _ => panic!("Illegal instruction: {:x}", word),
+ }
+ }
+ 0b1010101 => {
+ let rd = ((word >> 7) & REGISTER_NAME_WIDTH) as usize;
+ let rs1 = ((word >> 15) & REGISTER_NAME_WIDTH) as usize;
+ fcvt_w_s(registers, f_registers, rd, rs1);
+ }
_ => panic!("Illegal instruction or todo: {:x}", word),
}