diff options
| author | Nathan Lee <me@nwlee.tech> | 2026-06-04 12:37:50 -0500 |
|---|---|---|
| committer | Nathan Lee <me@nwlee.tech> | 2026-06-04 12:37:50 -0500 |
| commit | 26c0e95d64b31bb2393cb7f5c18969d3d8475bda (patch) | |
| tree | 654b63ecf464a1ae66f8f0d688a86df079c55d4d /src | |
| parent | b31680496f402b50f3862be98f3637d007e263c3 (diff) | |
fix small issues with other I extension and move allocation to heap instead of stack
Diffstat (limited to 'src')
| -rw-r--r-- | src/main.rs | 42 |
1 files changed, 27 insertions, 15 deletions
diff --git a/src/main.rs b/src/main.rs index 8c69c20..0ad8162 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,9 +2,13 @@ use elf::ElfBytes; use elf::endian::AnyEndian; use std::io; use std::io::Write; +use std::process::exit; use std::sync::{LazyLock, Mutex}; -static MEMORY: LazyLock<Mutex<[u8; 64 * 1024 * 1024]>> = - LazyLock::new(|| Mutex::new([0u8; 64 * 1024 * 1024])); + +const MEMORY_SIZE: usize = 64 * 1024 * 1024; +static MEMORY: LazyLock<Mutex<Box<[u8]>>> = LazyLock::new(|| { + Mutex::new(vec![0u8; MEMORY_SIZE].into_boxed_slice()) +}); fn main() { let path = std::path::PathBuf::from("hi"); @@ -43,12 +47,14 @@ fn main() { } loop { - let mut memory = MEMORY.lock().expect("Unable to get memory"); - handle_instruction(&mut *memory, &mut registers, &mut pc); + { + let mut memory = MEMORY.lock().expect("Unable to get memory"); + handle_instruction(&mut *memory, &mut registers, &mut pc); + } } } -fn handle_instruction(memory: &mut [u8], registers: &mut [u32], pc: &mut u32) { +fn handle_instruction(memory: &mut Box<[u8]>, registers: &mut [u32], pc: &mut u32) { let word = u32::from_le_bytes([ memory[*pc as usize], memory[*pc as usize + 1], @@ -138,24 +144,24 @@ fn handle_instruction(memory: &mut [u8], registers: &mut [u32], pc: &mut u32) { let rd = ((word >> 7) & 0b11111) as usize; match f3 { - 0 => registers[rd] = registers[rs1] + imm, // addi + 0 => registers[rd] = registers[rs1].wrapping_add(imm), // addi 4 => registers[rd] = registers[rs1] ^ imm, // xori 6 => registers[rd] = registers[rs1] | imm, // ori 7 => registers[rd] = registers[rs1] & imm, // andi 1 => { - if (word >> 5) != 0 { + if (imm >> 5) != 0 { panic!("Illegal instruction: {:x}", word); } registers[rd] = registers[rs1] << (imm & 0b11111); // slli } 5 => { - if (word >> 5) != 0 { + if (imm >> 5) != 0 { panic!("Illegal instruction: {:x}", word); } if (imm >> 5) & 0b1111111 == 0 { registers[rd] = registers[rs1] >> (imm & 0b11111); // srli } else { - registers[rd] = ((registers[rs1] >> (imm & 0b11111)) as i32) as u32; // srai + registers[rd] = ((registers[rs1] as i32 >> (imm & 0b11111))) as u32; // srai } } 2 => { @@ -170,7 +176,7 @@ fn handle_instruction(memory: &mut [u8], registers: &mut [u32], pc: &mut u32) { } } 0b0000011 => { - let imm = word >> 20; + let imm = ((word as i32) >> 20) as u32; let f3 = (word >> 12) & 0b111; let rs1 = ((word >> 15) & 0b11111) as usize; @@ -189,7 +195,7 @@ fn handle_instruction(memory: &mut [u8], registers: &mut [u32], pc: &mut u32) { 2 => { let addr = (registers[rs1] + imm) as usize; let slice = memory.get(addr..addr + 4).unwrap(); - let number: u32 = slice.iter().fold(0u32, |acc, &n| (acc << 8) | n as u32); + let number: u32 = u32::from_le_bytes(slice.try_into().unwrap()); registers[rd] = number; // lw } 4 => registers[rd] = memory[(registers[rs1] + imm) as usize] as u32, // lbu @@ -208,7 +214,7 @@ fn handle_instruction(memory: &mut [u8], registers: &mut [u32], pc: &mut u32) { let rs1 = ((word >> 15) & 0b11111) as usize; let rs2 = ((word >> 20) & 0b11111) as usize; - let imm = (imm_high << 5) | imm_low; + let imm = ((((imm_high << 5) | imm_low) as i32) << 20 >> 20) as u32; match f3 { 0 => memory[(registers[rs1] + imm) as usize] = registers[rs2] as u8, // sb @@ -226,13 +232,17 @@ fn handle_instruction(memory: &mut [u8], registers: &mut [u32], pc: &mut u32) { }; } 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; + let imm = + (((word >> 31) & 0x1) << 12) + | (((word >> 7) & 0x1) << 11) + | (((word >> 25) & 0x3f) << 5) + | (((word >> 8) & 0xf) << 1); + + let imm = ((imm as i32) << 19 >> 19) as u32; match f3 { 0 => { @@ -317,6 +327,8 @@ fn handle_instruction(memory: &mut [u8], registers: &mut [u32], pc: &mut u32) { let len = registers[12] as usize; let total_bytes = &memory[buf..buf + len]; io::stdout().write(&total_bytes).unwrap(); + } else if registers[17] == 60 { + exit(registers[10] as i32); } } // ecall (ebreak not implemented) _ => panic!("Illegal instruction or todo: {:x}", word), |
