rvemu

RISC-V RV32I execution engine
git clone git://mcdim.xyz/revemu.git
Log | Files | Refs

commit bcb8d4b9f6383baa8d150ef73f79e67280049a29
parent 2573410cb02d2f261c9d8b0c7422e0353c994af2
Author: Michail Konstantinos Dimopoulos <mk@mcdim.xyz>
Date:   Thu,  3 Sep 2026 20:06:31 +0300

Added ebreak and ecall

Diffstat:
MMakefile | 7-------
Mdisasm.c | 26++++++++++++++++++++++++++
Mmain.c | 41++++++++++++++++++++++++++++++++++-------
Mtrap.h | 2+-
4 files changed, 61 insertions(+), 15 deletions(-)

diff --git a/Makefile b/Makefile @@ -4,10 +4,3 @@ all: -Wconversion -Wsign-conversion \ -Wshadow -Wstrict-prototypes \ -Wmissing-prototypes -Wformat=2 - -disasm: - gcc -g disasm.c \ - -Wall -Wextra -Wpedantic \ - -Wconversion -Wsign-conversion \ - -Wshadow -Wstrict-prototypes \ - -Wmissing-prototypes -Wformat=2 diff --git a/disasm.c b/disasm.c @@ -236,6 +236,31 @@ static void disasm_utype_auipc(uint32_t inst) { printf("auipc x%" PRIu8 ", 0x%05" PRIx32 "\n", u.rd, u.imm); } +static void +disasm_itype_control(uint32_t inst) +{ + itype_t i; + decode_itype(&i, inst); + + if (i.funct3 != 0x0) { + puts("Illegal instruction"); + return; + } + + if (i.imm == 0x0) { + puts("ecall"); + return; + } else if (i.imm == 0x1) { + puts("ebreak"); + return; + } else { + puts("Illegal instruction"); + return; + + } + +} + typedef void (*disasm_fn)(uint32_t inst); static disasm_fn opcode_table[128]; @@ -247,6 +272,7 @@ init_opcode_table(void) opcode_table[0x13] = disasm_itype; opcode_table[0x03] = disasm_itype_loads; opcode_table[0x67] = disasm_itype_jalr; + opcode_table[0x73] = disasm_itype_control; opcode_table[0x23] = disasm_stype; opcode_table[0x63] = disasm_btype; opcode_table[0x6f] = disasm_jtype; diff --git a/main.c b/main.c @@ -434,15 +434,40 @@ exec_utype_auipc(cpu_state_t *cpu, uint32_t inst, uint8_t *mem) { } static void +exec_itype_control(cpu_state_t *cpu, uint32_t inst, uint8_t *mem) +{ + (void)mem; /* suppressing unused parameters warning */ + itype_t i; + decode_itype(&i, inst); + + if (i.funct3 != 0x0) { + raise_trap(cpu, TRAP_ILLEGAL_INSTRUCTION, inst); + return; + } + + if (i.imm == 0x0) { + raise_trap(cpu, TRAP_ECALL, inst); + return; + } else if (i.imm == 0x1) { + raise_trap(cpu, TRAP_EBREAK, inst); + return; + } else { + raise_trap(cpu, TRAP_ILLEGAL_INSTRUCTION, inst); + return; + } + +} + +static void load_program(uint8_t *mem) { /* PROGRAM */ uint32_t arr[] = { - 0x00500193, // addi x3, x0, 5 - 0x00600093, // addi x1, x0, 6 - 0xaaaaa3b7, // lui x7, 0xaaaaa -> rd:aaaaa000 - //0xfe728ae3 // beq x5, x7, -12 -> addr 0 - 0x1397 // auipc x7 0x1 -> rd 1008 + 0x00500193, // addi x3, x0, 5 + 0x00600093, // addi x1, x0, 6 + 0xaaaaa3b7, // lui x7, 0xaaaaa -> rd:aaaaa000 + 0x00001397, // auipc x7 0x1 -> rd 1008 + 0x00100073, // ebreak }; size_t len = sizeof(arr) / sizeof(arr[0]); @@ -482,6 +507,7 @@ init_opcode_table(void) opcode_table[0x13] = exec_itype; opcode_table[0x03] = exec_itype_loads; opcode_table[0x67] = exec_itype_jalr; + opcode_table[0x73] = exec_itype_control; opcode_table[0x23] = exec_stype; opcode_table[0x63] = exec_btype; opcode_table[0x6f] = exec_jtype; @@ -525,10 +551,12 @@ int main() { raise_trap(&cpu, TRAP_ILLEGAL_INSTRUCTION, inst); } + fn(&cpu,inst,mem); + if (cpu.status == CPU_TRAPPED) { printf("CPU trapped\n"); switch(cpu.trap.cause) { - case TRAP_BREAKPOINT: + case TRAP_EBREAK: printf("Code reached breakpoint\n"); break; case TRAP_ECALL: @@ -551,7 +579,6 @@ int main() { return EXIT_FAILURE; } - fn(&cpu,inst,mem); } else if (strncmp(line, "r", 1) == 0 || strncmp(line, "registers", 9) == 0) { diff --git a/trap.h b/trap.h @@ -3,7 +3,7 @@ typedef enum { TRAP_NONE = 0, - TRAP_BREAKPOINT, + TRAP_EBREAK, TRAP_ECALL, TRAP_ILLEGAL_INSTRUCTION, TRAP_INSTRUCTION_MISALIGNED,