rvemu

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

commit 2960ee19a669a70430c0ccdb7b21ec3b2f4f5729
parent 0cc9916509027b5af4690f39d4c1ba10f9b49d5e
Author: Michail Konstantinos Dimopoulos <mk@mcdim.xyz>
Date:   Sat,  5 Sep 2026 20:09:29 +0300

Fixed jal decoding

Diffstat:
Mdecode.h | 15++++++++++++---
Mdisasm.c | 4++--
Mexec.c | 8++------
Mexec.h | 2+-
Mmain.c | 75+++++++++++++++++++--------------------------------------------------------
Mrtests.c | 34+++++++++++++++++++++++++++++++++-
6 files changed, 69 insertions(+), 69 deletions(-)

diff --git a/decode.h b/decode.h @@ -150,20 +150,29 @@ opcode 0x6f 1101111 jal typedef struct { uint8_t opcode; uint8_t rd; - uint32_t imm; + int32_t imm; } jtype_t; static inline void decode_jtype(jtype_t *j, uint32_t inst) { - j->rd = (uint8_t)((inst >> 7) & 0x1f); + j->rd = (uint8_t)((inst >> 7) & 0x1f); uint8_t imm_19_12 = (uint8_t)((inst >> 12) & 0xff); uint8_t imm_11 = (uint8_t)((inst >> 20) & 1); uint16_t imm_10_1 = (uint16_t)((inst >> 21) & 0x3ff); uint8_t imm_20 = (uint8_t)((inst >> 31) & 1); - j->imm = (uint32_t)(imm_19_12 | imm_11 | imm_10_1 | imm_20); + uint32_t raw = (int32_t)(uint32_t)(imm_19_12 << 12 | + imm_11 << 11 | + imm_10_1 << 1| + imm_20 << 20); + j->imm = (int32_t)raw; + + /* extend sign */ + if ((raw & UINT32_C(0x100000)) != 0u) + j->imm -= INT32_C(0x200000); + } /* diff --git a/disasm.c b/disasm.c @@ -208,7 +208,7 @@ static void disasm_itype_jalr(uint32_t inst) { return; } - printf("x%" PRIu32 ", %" PRId32 "(x%" PRIu32 ")\n", + printf("jalr x%" PRIu32 ", %" PRId32 "(x%" PRIu32 ")\n", i.rd, i.imm, i.rs1); } @@ -217,7 +217,7 @@ static void disasm_jtype(uint32_t inst) { jtype_t j; decode_jtype(&j, inst); - printf("x%" PRIu32 ", %" PRId32 "\n", + printf("jal x%" PRIu32 ", %" PRId32 "\n", j.rd, (int32_t)j.imm); } diff --git a/exec.c b/exec.c @@ -376,10 +376,6 @@ static void exec_jtype(cpu_state_t *cpu, uint32_t inst, uint8_t *mem) { jtype_t j; decode_jtype(&j, inst); - uint32_t x; - x = cpu->pc + 4; - cpu->pc += j.imm; - uint32_t target; trap_cause_t cause = get_valid_branch_target(cpu->pc, (int32_t)j.imm, @@ -389,11 +385,11 @@ static void exec_jtype(cpu_state_t *cpu, uint32_t inst, uint8_t *mem) { return; } - cpu->pc = target; - if (j.rd != 0) { + uint32_t x = cpu->pc + 4; cpu->x[j.rd] = x; } + cpu->pc = target; } static void diff --git a/exec.h b/exec.h @@ -3,7 +3,7 @@ #include "trap.h" -#define MEMSIZE 2052 +#define MEMSIZE 4128 typedef enum { CPU_RUNNING = 0, diff --git a/main.c b/main.c @@ -19,62 +19,25 @@ load_program(uint8_t *mem) { /* program */ uint32_t arr[] = { -/* - 0xfff00093, // addi x1, x0, -1 - 0xfff04113, // xori x2, x0, -1 - 0xfff06193, // ori x3, x0, -1 - 0xfff17213, // andi x4, x2, -1 - 0xfff02293, // slti x5, x0, -1 - 0xfff03313 // sltiu x6, x0, -1 -*/ -/* - 0xfff00093, // li ra,-1 - 0xfff04113, // not sp,zero - 0xfff06193, // ori gp,zero,-1 - 0xfff17213, // andi tp,sp,-1 - 0xfff02293, // slti t0,zero,-1 - 0xfff03313, // sltiu t1,zero,-1 - 0x00100073 // ebreak -*/ -/* - 0x00700513, // addi x10, x0, 7 - 0x00451513, // slli x10, x10, 4 - 0x00d50513, // addi x10, x10, 13 - 0x05554513, // xori x10, x10, 0x55 - 0xff750513, // addi x10, x10, -9 - 0x00100073 // ebreak -*/ -0x10000593, //li a1,256 -0xfff00513, //li a0,-1 -0x00a58023, //sb a0,0(a1) -0x0005c503, //lbu a0,0(a1) -0x00150513, //addi a0,a0,1 -0x00a59123, //sh a0,2(a1) -0x00259503, //lh a0,2(a1) -0xeff50513, //addi a0,a0,-257 -0x00a58223, //sb a0,4(a1) -0x00458503, //lb a0,4(a1) -0x00a59323, //sh a0,6(a1) -0x00659503, //lh a0,6(a1) -0x0065d503, //lhu a0,6(a1) -0x00150513, //addi a0,a0,1 -0x00a5a423, //sw a0,8(a1) -0x00000513, //li a0,0 -0x0085a503, //lw a0,8(a1) -0x00000593, //li a1,0 -0x00100073 //ebreak -/* - 0x00200093, // addi x1, x0, 2 - 0x00000113, // addi x2, x0, 0 - 0x05c00193, // addi x3, x0, 0x5c - 0x00110113, // addi x2, x2, 1 - 0x0021a023, // sw x2, 0(x3) - 0x00418193, // addi x3, x3, 4 - 0xfff08093, // addi x1, x1, -1 - 0xfe0098e3, // bne x1, x0, -16 - 0x00100073 // ebreak -*/ - + 0x10000593, //li a1,256 + 0xfff00513, //li a0,-1 + 0x00a58023, //sb a0,0(a1) + 0x0005c503, //lbu a0,0(a1) + 0x00150513, //addi a0,a0,1 + 0x00a59123, //sh a0,2(a1) + 0x00259503, //lh a0,2(a1) + 0xeff50513, //addi a0,a0,-257 + 0x00a58223, //sb a0,4(a1) + 0x00458503, //lb a0,4(a1) + 0x00a59323, //sh a0,6(a1) + 0x00659503, //lh a0,6(a1) + 0x0065d503, //lhu a0,6(a1) + 0x00150513, //addi a0,a0,1 + 0x00a5a423, //sw a0,8(a1) + 0x00000513, //li a0,0 + 0x0085a503, //lw a0,8(a1) + 0x00000593, //li a1,0 + 0x00100073 //ebreak }; size_t len = sizeof(arr) / sizeof(arr[0]); diff --git a/rtests.c b/rtests.c @@ -187,7 +187,39 @@ test_t tests[] = { .mem_len = 12, } }, - + { + .name = "Fibonacci sequence", + .program = { + 0x01400513, //li a0,20 + 0x00000293, //li t0,0 + 0x00100313, //li t1,1 + 0x00000393, //li t2,0 + 0x00a38c63, //beq t2,a0,28 <done> + 0x00628e33, //add t3,t0,t1 + 0x00030293, //mv t0,t1 + 0x000e0313, //mv t1,t3 + 0x00138393, //addi t2,t2,1 + 0xfedff06f, //j 10 <loop> + 0x00028513, //mv a0,t0 + 0x00100073, //ebreak + }, + .program_len = 12, + .exp = { + .x = { + [5] = 0x1a6d, + [6] = 0x2ac2, + [7] = 0x14, + [10] = 0x1a6d, + [28] = 0x2ac2, + }, + .x_check_mask = ((UINT32_C(1) << 5) | + (UINT32_C(1) << 6) | + (UINT32_C(1) << 7) | + (UINT32_C(1) << 10) | + (UINT32_C(1) << 28)), + .pc = 0x2c, + } + }, }; static void