diff --git a/Makefile b/Makefile index 114c80a..4a78d2c 100644 --- a/Makefile +++ b/Makefile @@ -1,15 +1,23 @@ -SRCS = $(wildcard tests/*.s) +SRCS = $(wildcard tests/*.s tests/*.c) PROGS = $(patsubst %.s,%.bin,$(SRCS)) +C_PROGS = $(patsubst %.c,%.bin,$(SRCS)) .PHONY: test test: test_files cargo t -test_files: $(PROGS) +test_files: $(PROGS) $(C_PROGS) %.bin: %.s riscv64-unknown-elf-gcc -Wl,-Ttext=0x0 -nostdlib -o $@ $< riscv64-unknown-elf-objcopy -O binary $@ $@ + +%.s: %.c + riscv64-unknown-elf-gcc -S $< -o $@ + +.PHONY: clean +clean: + rm -rf tests/*.bin diff --git a/README.md b/README.md index 0b9626b..1eea7b9 100644 --- a/README.md +++ b/README.md @@ -1 +1,10 @@ +
+ +# Rysk + +
+ + +A RISC-V emulator made in Rust. + Work in progress. diff --git a/src/cpu.rs b/src/cpu.rs index c8cf873..9b6ba4e 100644 --- a/src/cpu.rs +++ b/src/cpu.rs @@ -122,30 +122,37 @@ impl Cpu { match funct3 { 0x0 => { // lb + debug!("LB"); self.regs[rd] = self.bus.load(addr, 8)? as i8 as i64 as u64; } 0x1 => { // lh + debug!("LH"); self.regs[rd] = self.bus.load(addr, 16)? as i16 as i64 as u64; } 0x2 => { // lw + debug!("LW"); self.regs[rd] = self.bus.load(addr, 32)? as i32 as i64 as u64; } 0x3 => { // ld + debug!("LD"); self.regs[rd] = self.bus.load(addr, 64)? as i64 as u64; } 0x4 => { // lbu + debug!("LBU"); self.regs[rd] = self.bus.load(addr, 8)?; } 0x5 => { // lhu + debug!("LHU"); self.regs[rd] = self.bus.load(addr, 16)?; } 0x6 => { // lwu + debug!("LWU"); self.regs[rd] = self.bus.load(addr, 32)?; } _ => Err(())?, @@ -274,7 +281,29 @@ impl Cpu { _ => Err(())?, } } - + 0b0110111 => { + // LUI + let imm32 = (inst & 0xfffff000) as i32 as i64 as u64; + tracing::Span::current().record("imm", imm32); + debug!("LUI"); + self.regs[rd] = imm32; + } + 0b0010111 => { + // AUIPC + let imm32 = (inst & 0xfffff000) as i32 as i64 as u64; + tracing::Span::current().record("imm", imm32); + debug!("AUIPC"); + } + 0b1101111 => { + // JAL + // imm[20|10:1|11|19:12] = inst[31|30:21|20|19:12] + let imm = (((inst & 0x80000000) as i32 as i64 >> 11) as u64) // imm[20] + | (inst & 0xff000) // imm[19:12] + | ((inst >> 9) & 0x800) // imm[11] + | ((inst >> 20) & 0x7fe); // imm[10:1] + self.regs[rd] = self.pc; + self.pc = self.pc.wrapping_add(imm).wrapping_sub(4); + } 0x73 => { // csr let csr_addr = ((inst & 0xfff00000) >> 20) as usize; diff --git a/tests/.gitignore b/tests/.gitignore index 2b71e25..c4f41bf 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -4,3 +4,4 @@ !*.bin !*.s !*.rs +!*.c diff --git a/tests/fib.bin b/tests/fib.bin new file mode 100755 index 0000000..684f659 Binary files /dev/null and b/tests/fib.bin differ diff --git a/tests/fib.c b/tests/fib.c new file mode 100644 index 0000000..f4ae45d --- /dev/null +++ b/tests/fib.c @@ -0,0 +1,12 @@ +int fib(int n); + +int main() { + return fib(10); +} + +int fib(int n) { + if (n == 0 || n == 1) + return n; + else + return (fib(n-1) + fib(n-2)); +}