Skip to content

Commit

Permalink
feat: Add elf parser and debug tools
Browse files Browse the repository at this point in the history
  • Loading branch information
howjmay committed Mar 2, 2024
1 parent 5e1e75b commit e4e9efa
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 17 deletions.
60 changes: 43 additions & 17 deletions src/cpu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,23 +23,23 @@ impl CPU {
return cpu;
}

fn fetch(self) -> u32 {
pub fn fetch(&self) -> u32 {
let instr: u32 = self.bus.load(self.pc, 32);
return instr;
}

fn execute(&mut self, instr: u32) {
pub fn execute(&mut self, instr: u32) {
let opcode = instr & 0x7f;
let funct3 = (instr >> 12) & 0x7;
let funct7 = (instr >> 25) & 0x7f;
self.xregs.regs[0] = 0; // x0 hardwired to 0 at each cycle

match instr {
match opcode {
LUI => exec_lui(self, instr),
AUIPC => exec_auipc(self, instr),
JAL => exec_jal(self, instr),
JALR => exec_jalr(self, instr),
B_TYPE => match funct7 {
B_TYPE => match funct3 {
BEQ => exec_beq(self, instr),
BNE => exec_bne(self, instr),
BLT => exec_blt(self, instr),
Expand Down Expand Up @@ -102,7 +102,23 @@ impl CPU {
}
},
FENCE => exec_fence(self, instr),
_ => panic!(),
CSR => match (funct3) {
ECALL | EBREAK => match imm_i(instr) {
0x0 => exec_ecall(self, instr),
0x1 => exec_ebreak(self, instr),
_ => (),
},
CSRRW => exec_csrrw(self, instr),
CSRRS => exec_csrrs(self, instr),
CSRRC => exec_csrrc(self, instr),
CSRRWI => exec_csrrwi(self, instr),
CSRRSI => exec_csrrsi(self, instr),
CSRRCI => exec_csrrci(self, instr),
_ => {
panic!("malformed CSR instruction");
}
},
_ => panic!("invalid instr {}", instr),
}
}
}
Expand All @@ -119,8 +135,8 @@ pub fn exec_auipc(cpu: &mut CPU, instr: u32) {
}
pub fn exec_jal(cpu: &mut CPU, instr: u32) {
let imm = imm_j(instr) as i32;
cpu.xregs.regs[rd(instr) as usize] = cpu.pc + 4;
cpu.pc = (cpu.pc as i32 + imm) as u32;
cpu.xregs.regs[rd(instr) as usize] = cpu.pc.wrapping_add(4);
cpu.pc = ((cpu.pc as i32).wrapping_add(imm)).wrapping_sub(4) as u32;
}
pub fn exec_jalr(cpu: &mut CPU, instr: u32) {
let imm = imm_i(instr) as i32;
Expand All @@ -131,38 +147,47 @@ pub fn exec_jalr(cpu: &mut CPU, instr: u32) {
pub fn exec_beq(cpu: &mut CPU, instr: u32) {
let imm = imm_b(instr) as i32;
if cpu.xregs.regs[rs1(instr) as usize] == cpu.xregs.regs[rs2(instr) as usize] {
cpu.pc = cpu.pc.wrapping_add(imm as u32).wrapping_sub(4);
cpu.pc = (cpu.pc as i32).wrapping_add(imm).wrapping_sub(4) as u32;
}
}
pub fn exec_bne(cpu: &mut CPU, instr: u32) {
let imm = imm_b(instr) as i32;
if cpu.xregs.regs[rs1(instr) as usize] != cpu.xregs.regs[rs2(instr) as usize] {
cpu.pc = cpu.pc.wrapping_add(imm as u32).wrapping_sub(4);
println!(
"cpu.xregs.regs[rs1(instr) as usize]: {}",
cpu.xregs.regs[rs1(instr) as usize]
);
println!(
"cpu.xregs.regs[rs2(instr) as usize]: {}",
cpu.xregs.regs[rs2(instr) as usize]
);
if cpu.xregs.regs[rs1(instr) as usize] as i64 != cpu.xregs.regs[rs2(instr) as usize] as i64 {
println!("IHIHI");
cpu.pc = (cpu.pc as i32).wrapping_add(imm).wrapping_sub(4) as u32;
}
}
pub fn exec_blt(cpu: &mut CPU, instr: u32) {
let imm = imm_b(instr) as i32;
if (cpu.xregs.regs[rs1(instr) as usize] as i32) < (cpu.xregs.regs[rs2(instr) as usize] as i32) {
cpu.pc = cpu.pc.wrapping_add(imm as u32).wrapping_sub(4);
if (cpu.xregs.regs[rs1(instr) as usize] as i64) < (cpu.xregs.regs[rs2(instr) as usize] as i64) {
cpu.pc = (cpu.pc as i32).wrapping_add(imm).wrapping_sub(4) as u32;
}
}
pub fn exec_bge(cpu: &mut CPU, instr: u32) {
let imm = imm_b(instr) as i32;
if (cpu.xregs.regs[rs1(instr) as usize] as i32) >= (cpu.xregs.regs[rs2(instr) as usize] as i32)
{
cpu.pc = cpu.pc.wrapping_add(imm as u32).wrapping_sub(4);
cpu.pc = (cpu.pc as i32).wrapping_add(imm).wrapping_sub(4) as u32;
}
}
pub fn exec_bltu(cpu: &mut CPU, instr: u32) {
let imm = imm_b(instr) as i32;
if cpu.xregs.regs[rs1(instr) as usize] < cpu.xregs.regs[rs2(instr) as usize] {
cpu.pc = cpu.pc.wrapping_add(imm as u32).wrapping_sub(4);
cpu.pc = (cpu.pc as i32).wrapping_add(imm).wrapping_sub(4) as u32;
}
}
pub fn exec_bgeu(cpu: &mut CPU, instr: u32) {
let imm = imm_b(instr) as i32;
if cpu.xregs.regs[rs1(instr) as usize] >= rs2(instr) {
cpu.pc = cpu.pc.wrapping_add(imm as u32).wrapping_sub(4);
if cpu.xregs.regs[rs1(instr) as usize] >= cpu.xregs.regs[rs2(instr) as usize] {
cpu.pc = (cpu.pc as i32).wrapping_add(imm).wrapping_sub(4) as u32;
}
}
pub fn exec_lb(cpu: &mut CPU, instr: u32) {
Expand Down Expand Up @@ -226,7 +251,8 @@ pub fn exec_sw(cpu: &mut CPU, instr: u32) {
}
pub fn exec_addi(cpu: &mut CPU, instr: u32) {
let imm = imm_i(instr);
cpu.xregs.regs[rd(instr) as usize] = cpu.xregs.regs[rs1(instr) as usize] + imm as u32;
cpu.xregs.regs[rd(instr) as usize] =
(cpu.xregs.regs[rs1(instr) as usize] as i32).wrapping_add(imm) as u32;
}
pub fn exec_slti(cpu: &mut CPU, instr: u32) {
let imm = imm_i(instr);
Expand Down
15 changes: 15 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,24 @@ struct Args {
file: String,
}

fn print_u32(input: Vec<u8>) {
for i in 0..input.len() {
println!()
}
}

fn main() {
let args = Args::parse();
let mut cpu = cpu::CPU::new();
let file_bin = files::read_file(&args.file);
println!("file_bin: {:x?}", file_bin);
cpu.bus.init_memory(file_bin);
let mut count = 0;
loop {
let instr = cpu.fetch();
println!("count: {}, cpu.pc: {}, instr: {:x}", count, cpu.pc, instr);
count += 1;
cpu.execute(instr);
cpu.pc += 4;
}
}
Binary file renamed tests/addi.bin → tests/rv32ui-p-add.bin
Binary file not shown.

0 comments on commit e4e9efa

Please sign in to comment.