diff options
| author | Nathan Lee <me@nwlee.tech> | 2026-06-03 20:44:26 -0500 |
|---|---|---|
| committer | Nathan Lee <me@nwlee.tech> | 2026-06-03 20:44:26 -0500 |
| commit | c14dd3e17fc41669b95d6cda80ff028f319420b7 (patch) | |
| tree | 0c7f2faab7d74dee5d78bf4cc1157b0bc2991d3a /src | |
| parent | 32bdfd563dbcb262e5417bbb5a2afccbd15b803b (diff) | |
finish B-type instructions
this commit may overlap with the previous one due to an amendment.
Diffstat (limited to 'src')
| -rw-r--r-- | src/main.rs | 66 |
1 files changed, 58 insertions, 8 deletions
diff --git a/src/main.rs b/src/main.rs index 8aacb63..8974330 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,6 +2,7 @@ use elf::ElfBytes; use elf::endian::AnyEndian; use std::io; use std::io::Write; +use std::path::Component::ParentDir; use std::sync::{LazyLock, Mutex}; const ABI: [&str; 32] = [ @@ -51,17 +52,16 @@ fn main() { loop { let mut memory = MEMORY.lock().expect("Unable to get memory"); - handle_instruction(&mut *memory, &mut registers, pc); - pc += 4; + handle_instruction(&mut *memory, &mut registers, &mut pc); } } -fn handle_instruction(memory: &mut [u8], registers: &mut [u32], pc: u32) { +fn handle_instruction(memory: &mut [u8], registers: &mut [u32], pc: &mut u32) { let word = u32::from_le_bytes([ - memory[pc as usize], - memory[pc as usize + 1], - memory[pc as usize + 2], - memory[pc as usize + 3], + memory[*pc as usize], + memory[*pc as usize + 1], + memory[*pc as usize + 2], + memory[*pc as usize + 3], ]); let opcode = word & 0x7f; match opcode { @@ -192,7 +192,55 @@ fn handle_instruction(memory: &mut [u8], registers: &mut [u32], pc: u32) { _ => panic!("Illegal instruction: {:x}", word), }; } - 0b1100011 => println!("B-type (todo)"), + 0b1100011 => { + let imm_low = (word >> 7) & 0b11111; + let imm_high = (word >> 25) & 0b1111111; + let f3 = (word >> 12) & 0b111; + let rs1 = ((word >> 15) & 0b11111) as usize; + let rs2 = ((word >> 20) & 0b11111) as usize; + + let imm = (imm_high << 5) | imm_low; + + match f3 { + 0 => { + if registers[rs1] == registers[rs2] { + *pc += imm; + } + return; + }, // beq + 1 => { + if registers[rs1] != registers[rs2] { + *pc += imm; + } + return; + }, // bne + 4 => { + if (registers[rs1] as i32) < (registers[rs2] as i32) { + *pc += imm; + } + return; + }, // blt + 5 => { + if (registers[rs1] as i32) >= (registers[rs2] as i32) { + *pc += imm; + } + return; + }, // bge + 6 => { + if (registers[rs1] < registers[rs2]) { + *pc += imm; + } + return; + }, // bltu + 7 => { + if (registers[rs1] >= registers[rs2]) { + *pc += imm; + } + return; + }, // bgeu + _ => panic!("Illegal instruction: {:x}", word) + } + }, 0b1101111 => println!("J-type (todo)"), 0b1100111 => println!("jalr"), 0b0110111 => { @@ -223,4 +271,6 @@ fn handle_instruction(memory: &mut [u8], registers: &mut [u32], pc: u32) { } _ => panic!("Illegal instruction or todo: {:x}", word), } + + *pc += 4; } |
