From 6bf5ccf7c82e0f5b037b6d6f9fdbd1f5aa2406a3 Mon Sep 17 00:00:00 2001 From: Benjamin Kyd Date: Thu, 20 Jul 2023 21:52:36 +0100 Subject: [PATCH] fixed "all" implementation bugs, can now run C! --- src/cpu/mod.rs | 6 ++-- src/ext/i/mod.rs | 32 +++++++++--------- test/Makefile | 9 +++-- test/c_test | Bin 5352 -> 5964 bytes test/c_test.bin | Bin 196 -> 112 bytes test/c_test.c | 22 ++++++------ test/c_test.hex | 22 +++++------- test/c_test.lst | 83 +++++++++++++++++----------------------------- test/c_test.map | 30 ++++++++--------- test/flatfile.lds | 11 ++++++ 10 files changed, 103 insertions(+), 112 deletions(-) mode change 100644 => 100755 test/c_test mode change 100644 => 100755 test/c_test.bin create mode 100644 test/flatfile.lds diff --git a/src/cpu/mod.rs b/src/cpu/mod.rs index 597b166..c5ffd37 100644 --- a/src/cpu/mod.rs +++ b/src/cpu/mod.rs @@ -57,8 +57,9 @@ impl CPU { self.state.pc = DRAM_BASE as rv32::Word; self.state.x[0] = 0x00000000; // x0 is tied to ground - self.state.x[2] = ram::DRAM_SIZE as u32; // x2 the addressable + self.state.x[2] = DRAM_BASE + ram::DRAM_SIZE as u32; // x2 the stack pointer println!("VM > CPU Initialisd with extensions {:?}", self.extensions); + self.dump_reg(); } pub fn get_pc(&self) -> rv32::Word { @@ -76,11 +77,12 @@ impl CPU { println!("VM > Fetched 0x{:08x}: 0x{:08x}", self.state.pc, inst); self.state.x[0] = 0x00000000; + self.state.pc = self.state.pc + rv32::WORD as u32; + self.instruction_decoder .borrow_mut() .decode_exec_inst(inst, &mut self.state)?; - self.state.pc = self.state.pc + rv32::WORD as u32; self.dump_reg(); } Ok(()) diff --git a/src/ext/i/mod.rs b/src/ext/i/mod.rs index 890ca87..02c0d81 100644 --- a/src/ext/i/mod.rs +++ b/src/ext/i/mod.rs @@ -74,7 +74,7 @@ impl Instruction for JAL { let offset = sext(inst.full_imm() << 1, 32); let pc = offset.wrapping_add(state.pc); state.x[inst.rd() as usize] = state.pc + rv32::WORD as u32; - state.pc = pc - 4; + state.pc = pc.wrapping_sub(rv32::WORD as u32); } } @@ -98,7 +98,7 @@ impl Instruction for JALR { let offset = sext(inst.full_imm(), 32); let pc = offset.wrapping_add(state.x[inst.rs1() as usize]); state.x[inst.rd() as usize] = state.pc + rv32::WORD as u32; - state.pc = pc - 4; + state.pc = pc.wrapping_sub(rv32::WORD as u32); } } @@ -272,12 +272,12 @@ impl Instruction for IMM { let rs1 = state.x[inst.rs1() as usize]; match inst.funct3() { - 0b000 => retval = rs1 + inst.sext_imm(), // addi + 0b000 => retval = rs1.wrapping_add(inst.sext_imm()), // addi 0b010 => retval = ((rs1 as i32) < (inst.sext_imm() as i32)) as u32, // slti 0b011 => retval = ((rs1 as u32) < (inst.sext_imm() as u32)) as u32, // sltiu - 0b100 => retval = rs1 ^ inst.sext_imm(), // xori - 0b110 => retval = rs1 | inst.sext_imm(), // ori - 0b111 => retval = rs1 & inst.sext_imm(), // andi + 0b100 => retval = rs1 ^ inst.sext_imm(), // xori + 0b110 => retval = rs1 | inst.sext_imm(), // ori + 0b111 => retval = rs1 & inst.sext_imm(), // andi _ => state.trap = 3, } @@ -309,14 +309,14 @@ impl Instruction for SHIFTI { let inst = unsafe { inst.R }; // fun7 is the L/A selector // rs2 is shamt let mut retval = 0; - let shamt = inst.rs2(); + let shamt = inst.rs2() as u32; let rs1 = state.x[inst.rs1() as usize]; match inst.funct3() { - 0b001 => retval = rs1 << shamt, //slli + 0b001 => retval = rs1.wrapping_shl(shamt), //slli 0b101 => match inst.funct7() { - 0b0000000 => retval = rs1 >> shamt, // srli - 0b0100000 => retval = ((rs1 as i32) >> shamt) as u32, // srai + 0b0000000 => retval = rs1.wrapping_shr(shamt), // srli + 0b0100000 => retval = (rs1 as i32).wrapping_shr(shamt) as u32, // srai _ => state.trap = 3, }, _ => state.trap = 3, @@ -348,17 +348,17 @@ impl Instruction for OP { match inst.funct3() { 0b000 => match inst.funct7() { - 0b0000000 => retval = rs1 + rs2, // add - 0b0100000 => retval = rs1 - rs2, // sub + 0b0000000 => retval = rs1.wrapping_add(rs2), // add + 0b0100000 => retval = rs1.wrapping_sub(rs2), // sub _ => state.trap = 3, }, - 0b001 => retval = rs1 << (rs2 & 0x1F), // sll + 0b001 => retval = rs1.wrapping_shl(rs2 & 0x1F), // sll 0b010 => retval = ((rs1 as i32) < (rs2 as i32)) as u32, // slt 0b011 => retval = ((rs1 as u32) < (rs2 as u32)) as u32, // sltu - 0b100 => retval = rs1 ^ rs2, // xor + 0b100 => retval = rs1 ^ rs2, // xor 0b101 => match inst.funct7() { - 0b0000000 => retval = rs1 >> (rs2 & 0x1F), // srl - 0b0100000 => retval = ((rs1 as i32) >> (rs2 & 0x1F)) as u32, // sra + 0b0000000 => retval = rs1.wrapping_shr(rs2 & 0x1F), // srl + 0b0100000 => retval = ((rs1 as i32).wrapping_shr(rs2 & 0x1F)) as u32, // sra _ => state.trap = 3, }, 0b110 => retval = rs1 | rs2, // or diff --git a/test/Makefile b/test/Makefile index 9454199..9030a76 100644 --- a/test/Makefile +++ b/test/Makefile @@ -1,17 +1,22 @@ TARGET=c_test GCC_PREFIX=riscv32-unknown-elf +CFLAGS:=-fno-stack-protector +CFLAGS+=-static-libgcc -fdata-sections -ffunction-sections +CFLAGS+=-g -O0 -march=rv32ia -mabi=ilp32 -static +LDFLAGS:= -T flatfile.lds -nostdlib + all: build assemble: - $(GCC_PREFIX)-gcc -Wl,-Ttext=0x0 -nostdlib -march=rv64i -mabi=lp64 -o $(TARGET) $(TARGET).c + $(GCC_PREFIX)-gcc -o $(TARGET) $(TARGET).c $(CFLAGS) $(LDFLAGS) $(GCC_PREFIX)-objdump -t $(TARGET) > $(TARGET).map $(GCC_PREFIX)-objdump -d -M no-aliases $(TARGET) > $(TARGET).lst $(GCC_PREFIX)-objcopy -O binary $(TARGET) $(TARGET).bin $(GCC_PREFIX)-objcopy -O ihex $(TARGET) $(TARGET).hex build: - $(GCC_PREFIX)-gcc -Wl,-Ttext=0x0 -nostdlib -march=rv64i -mabi=lp64 -o $(TARGET) $(TARGET).S + $(GCC_PREFIX)-gcc -o $(TARGET) $(TARGET).S $(CFLAGS) $(LDFLAGS) $(GCC_PREFIX)-objdump -t $(TARGET) > $(TARGET).map $(GCC_PREFIX)-objdump -d -M no-aliases $(TARGET) > $(TARGET).lst $(GCC_PREFIX)-objcopy -O binary $(TARGET) $(TARGET).bin diff --git a/test/c_test b/test/c_test old mode 100644 new mode 100755 index 4eb41af61dce7152a43880cfe1c6c28df36e541a..548d64ef2d01a0123ca1a395441c2f75be8b2cd4 GIT binary patch literal 5964 zcmeHLPj4GV6o0ehbrS5jPK;_&~Wq3~vb&jRFMhaH5#3$!L2h?X->a@ESA zc8Q+k@=07k&pBwHyOThcCQk|#OoP0;CGW2RR*n=1lK&$^D@ ztc>BT&&8ge=Ri??2K^jnHLBASJ%?Qx#)RVy!LwW+w%@;FY^`21R@>&P*)kfQ)pa-B z{oz_0Z87ql%`mXj%5edt_+Zcv{ zaBLBT7~Hc2R-)$yeuRE+tqo(P zzv@`muf5@{wXR-$HCZ&gV<1ITcmV7w&U_b11;vbGoDcuIu*#Wn0~D=p0PF(DM6Eq}iho7yo>zuScDp8&BchTL3VqAQ6STg}$;WH9#DlbR{bHAqJF9xz7;ytpcTT z^tU8jE6Ek{r}bT8lcF4rj}xtMCy1+KOo_tX!vNU|_aownQzZ&_9|P1=R&nYr*OY^r za3m)HV{5Wi-bmuTJQ9*lLqHC)}cL%b~kN;bLk}Xn*hcDbJ8aq z^*{PL_mk?oF9$V;ozJlx|3SI;onw%AoJYfXw07Zu;Ve4MR9;`dJHJ@VyY6kba4VNv zTE0HNl(+I$4vMq*^1c^1yTGQ=G|ZI0d#B*#TRHUpA^LDzaTciK_G6srv<*oJ?Kuqi z)=z}tLKu+SkWuy`nkM3Vmq#(O=E69GUSeOe8piQR$W8Q3od072e=mwB`;;+06MJ7t z&*lXDqY3e96i+_47WJ2X-=ZIi!-X3N%YlVG;JmietlB%g)$|&|^%pQw*(g3N^0iX= z!4~J}uT?6%w6zi1)ga)3uzdk_+iPI*EY{t&g$>+oY{O#@2eX3bbzxUg3xA-WNK3eT z0xYLlue%L2!W(1RLik?w8O|q%{eMmOkiPa*vPJZLhI_6kPdl}^Tt$cKC4Vv}za#aJ zi@aG<-@qj8>f#u(<=$@6o=)Pa&)8c}e-+Ap^dQ>l(L0`_Ad0-k=h6Q2@4&j55C%^N XYIw@IWq=+tuKr6@zaoK=PS*bhy(^eM diff --git a/test/c_test.bin b/test/c_test.bin old mode 100644 new mode 100755 index 684f65929775611de718b4619673cc7c7f54a934..25d8604f2974d8b9dfa05bff681c7f79d2fcf6ee GIT binary patch literal 112 zcmWe;Wc;VB*T^8u!pOA!Is?Px_Ul&4YG3|s7YDK3m6cV#{A*Tk`KPP|qL2K8@Lm3a y)G!12Ai3ll&lx7O3owAh@)-^Q*#-@rGf0p>;eqQV&B31dD}73q;TC_UA})@jpRwyW77oz|;fX!vu5>Q?p4UBhW3(AU6R3BValL diff --git a/test/c_test.c b/test/c_test.c index 5b93b77..8c7843b 100644 --- a/test/c_test.c +++ b/test/c_test.c @@ -1,12 +1,12 @@ -int fib(int n); - -int main() { - return fib(10); // Calculate the 10th fibonacci number. -} - -int fib(int n) { - if (n == 0 || n == 1) - return n; - else - return (fib(n - 1) + fib(n - 2)); +__attribute__((section(".start"))) int main() { + volatile register int x = 0xD3AD; + volatile register int y = 0x1234; + volatile register int temp = y; + y = x; + x = temp; + if (x > y) { + x = 1; + } else { + y = 3; + } } diff --git a/test/c_test.hex b/test/c_test.hex index 30f4ac5..4919cae 100644 --- a/test/c_test.hex +++ b/test/c_test.hex @@ -1,14 +1,10 @@ -:10000000130101FF23341100233081001304010187 -:100010001305A000EF00C00193070500138507003A -:100020008330810003340100130101016780000067 -:10003000130101FD2334110223308102233C91007E -:100040001304010393070500232EF4FC8327C4FD4A -:100050009B870700638A07008327C4FD1B8707006F -:10006000930710006316F7008327C4FD6F00000498 -:100070008327C4FD9B87F7FF9B8707001385070035 -:10008000EFF01FFB93070500938407008327C4FD4F -:100090009B87E7FF9B87070013850700EFF05FF959 -:1000A00093070500BB87F4009B87070013850700B3 -:1000B000833081020334010283348101130101037F -:0400C0006780000055 +:0200000480007A +:10000000130101FE232E810013040102B7D7000063 +:100010009387D73A2326F4FEB71700009387472328 +:100020002324F4FE832784FE2322F4FE8327C4FEC8 +:100030002324F4FE832744FE2326F4FE0327C4FE74 +:10004000832784FE63D8E700930710002326F4FE7D +:100050006F00C000930730002324F4FE93070000D4 +:10006000138507000324C10113010102678000000A +:040000058000000077 :00000001FF diff --git a/test/c_test.lst b/test/c_test.lst index 00ad8aa..102f67c 100644 --- a/test/c_test.lst +++ b/test/c_test.lst @@ -1,58 +1,35 @@ -c_test: file format elf64-littleriscv +c_test: file format elf32-littleriscv Disassembly of section .text: -0000000000000000
: - 0: ff010113 addi sp,sp,-16 - 4: 00113423 sd ra,8(sp) - 8: 00813023 sd s0,0(sp) - c: 01010413 addi s0,sp,16 - 10: 00a00513 addi a0,zero,10 - 14: 01c000ef jal ra,30 - 18: 00050793 addi a5,a0,0 - 1c: 00078513 addi a0,a5,0 - 20: 00813083 ld ra,8(sp) - 24: 00013403 ld s0,0(sp) - 28: 01010113 addi sp,sp,16 - 2c: 00008067 jalr zero,0(ra) - -0000000000000030 : - 30: fd010113 addi sp,sp,-48 - 34: 02113423 sd ra,40(sp) - 38: 02813023 sd s0,32(sp) - 3c: 00913c23 sd s1,24(sp) - 40: 03010413 addi s0,sp,48 - 44: 00050793 addi a5,a0,0 - 48: fcf42e23 sw a5,-36(s0) - 4c: fdc42783 lw a5,-36(s0) - 50: 0007879b addiw a5,a5,0 - 54: 00078a63 beq a5,zero,68 - 58: fdc42783 lw a5,-36(s0) - 5c: 0007871b addiw a4,a5,0 - 60: 00100793 addi a5,zero,1 - 64: 00f71663 bne a4,a5,70 - 68: fdc42783 lw a5,-36(s0) - 6c: 0400006f jal zero,ac - 70: fdc42783 lw a5,-36(s0) - 74: fff7879b addiw a5,a5,-1 - 78: 0007879b addiw a5,a5,0 - 7c: 00078513 addi a0,a5,0 - 80: fb1ff0ef jal ra,30 - 84: 00050793 addi a5,a0,0 - 88: 00078493 addi s1,a5,0 - 8c: fdc42783 lw a5,-36(s0) - 90: ffe7879b addiw a5,a5,-2 - 94: 0007879b addiw a5,a5,0 - 98: 00078513 addi a0,a5,0 - 9c: f95ff0ef jal ra,30 - a0: 00050793 addi a5,a0,0 - a4: 00f487bb addw a5,s1,a5 - a8: 0007879b addiw a5,a5,0 - ac: 00078513 addi a0,a5,0 - b0: 02813083 ld ra,40(sp) - b4: 02013403 ld s0,32(sp) - b8: 01813483 ld s1,24(sp) - bc: 03010113 addi sp,sp,48 - c0: 00008067 jalr zero,0(ra) +80000000
: +80000000: fe010113 addi sp,sp,-32 +80000004: 00812e23 sw s0,28(sp) +80000008: 02010413 addi s0,sp,32 +8000000c: 0000d7b7 lui a5,0xd +80000010: 3ad78793 addi a5,a5,941 # d3ad +80000014: fef42623 sw a5,-20(s0) +80000018: 000017b7 lui a5,0x1 +8000001c: 23478793 addi a5,a5,564 # 1234 +80000020: fef42423 sw a5,-24(s0) +80000024: fe842783 lw a5,-24(s0) +80000028: fef42223 sw a5,-28(s0) +8000002c: fec42783 lw a5,-20(s0) +80000030: fef42423 sw a5,-24(s0) +80000034: fe442783 lw a5,-28(s0) +80000038: fef42623 sw a5,-20(s0) +8000003c: fec42703 lw a4,-20(s0) +80000040: fe842783 lw a5,-24(s0) +80000044: 00e7d863 bge a5,a4,80000054 +80000048: 00100793 addi a5,zero,1 +8000004c: fef42623 sw a5,-20(s0) +80000050: 00c0006f jal zero,8000005c +80000054: 00300793 addi a5,zero,3 +80000058: fef42423 sw a5,-24(s0) +8000005c: 00000793 addi a5,zero,0 +80000060: 00078513 addi a0,a5,0 +80000064: 01c12403 lw s0,28(sp) +80000068: 02010113 addi sp,sp,32 +8000006c: 00008067 jalr zero,0(ra) diff --git a/test/c_test.map b/test/c_test.map index ad3349a..388189e 100644 --- a/test/c_test.map +++ b/test/c_test.map @@ -1,20 +1,20 @@ -c_test: file format elf64-littleriscv +c_test: file format elf32-littleriscv SYMBOL TABLE: -0000000000000000 l d .text 0000000000000000 .text -0000000000000000 l d .comment 0000000000000000 .comment -0000000000000000 l d .riscv.attributes 0000000000000000 .riscv.attributes -0000000000000000 l df *ABS* 0000000000000000 c_test.c -00000000000018c4 g *ABS* 0000000000000000 __global_pointer$ -00000000000010c4 g .text 0000000000000000 __SDATA_BEGIN__ -0000000000000000 *UND* 0000000000000000 _start -00000000000010c8 g .text 0000000000000000 __BSS_END__ -00000000000010c4 g .text 0000000000000000 __bss_start -0000000000000000 g F .text 0000000000000030 main -00000000000010c4 g .text 0000000000000000 __DATA_BEGIN__ -00000000000010c4 g .text 0000000000000000 _edata -00000000000010c8 g .text 0000000000000000 _end -0000000000000030 g F .text 0000000000000094 fib +80000000 l d .text 00000000 .text +00000000 l d .debug_info 00000000 .debug_info +00000000 l d .debug_abbrev 00000000 .debug_abbrev +00000000 l d .debug_aranges 00000000 .debug_aranges +00000000 l d .debug_rnglists 00000000 .debug_rnglists +00000000 l d .debug_line 00000000 .debug_line +00000000 l d .debug_str 00000000 .debug_str +00000000 l d .debug_line_str 00000000 .debug_line_str +00000000 l d .comment 00000000 .comment +00000000 l d .riscv.attributes 00000000 .riscv.attributes +00000000 l d .debug_frame 00000000 .debug_frame +00000000 l df *ABS* 00000000 c_test.c +00000000 *UND* 00000000 _start +80000000 g F .text 00000070 main diff --git a/test/flatfile.lds b/test/flatfile.lds new file mode 100644 index 0000000..467c96b --- /dev/null +++ b/test/flatfile.lds @@ -0,0 +1,11 @@ +ENTRY(_start) +SECTIONS { + .text 0x80000000 : { + *(.start); + *(.text); + *(.text.*) + } + .bss : { *(.bss); *(.bss.*) } + .data : { *(.data); *(.data.*) } + .rodata : { *(.rodata); *(.rodata.*) } +}