rvemu

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

commit 4e256a9cea6be3e08d06d1c63ab90e9cd4dd1824
parent 1b0c03d3ec03d206e74c17c7308f581f44332411
Author: Michail Konstantinos Dimopoulos <mk@mcdim.xyz>
Date:   Fri,  4 Sep 2026 00:14:56 +0300

Fixed imm sign bug and disasm bugs

Diffstat:
Mdecode.h | 26+++++++++++++++++++++++---
Mdisasm.c | 10++++------
Mmain.c | 22+++++++++++++++-------
3 files changed, 42 insertions(+), 16 deletions(-)

diff --git a/decode.h b/decode.h @@ -14,23 +14,43 @@ opcode 0x33 0000011 loads typedef struct { uint8_t opcode; uint8_t rd, rs1; - uint16_t imm; + //uint16_t imm; + int32_t imm; uint8_t funct3; uint8_t funct7, inimm; } itype_t; -static inline void +/*static inline void decode_itype(itype_t *i, uint32_t inst) { i->rd = (uint8_t)((inst >> 7) & 31); i->funct3 = (uint8_t)((inst >> 12) & 7); i->rs1 = (uint8_t)((inst >> 15) & 31); - i->imm = (uint16_t)((inst >> 20) & 2047); + //i->imm = (uint16_t)((inst >> 20) & 2047); + i->imm = (uint32_t)((inst >> 20) & 0xfff); i->inimm = (uint8_t)(i->imm & 31); i->funct7 = (uint8_t)((i->imm >> 5) & 127); +}*/ +static inline void +decode_itype(itype_t *i, uint32_t inst) +{ + uint32_t raw_imm = (inst >> 20) & UINT32_C(0xfff); + + i->rd = (uint8_t)((inst >> 7) & UINT32_C(31)); + i->funct3 = (uint8_t)((inst >> 12) & UINT32_C(7)); + i->rs1 = (uint8_t)((inst >> 15) & UINT32_C(31)); + + i->inimm = (uint8_t)(raw_imm & UINT32_C(31)); + i->funct7 = (uint8_t)((inst >> 25) & UINT32_C(127)); + + i->imm = (int32_t)raw_imm; + + if ((raw_imm & UINT32_C(0x800)) != 0u) + i->imm -= INT32_C(0x1000); } + /* R-TYPE INSTRUCTION FORMAT 31 25 24 20 19 15 14 12 11 7 6 0 diff --git a/disasm.c b/disasm.c @@ -27,7 +27,7 @@ static void disasm_itype(uint32_t inst) { printf("slti"); break; case 0x3: - printf("sltui"); + printf("sltiu"); break; case 0x4: printf("xori"); @@ -55,7 +55,7 @@ static void disasm_itype(uint32_t inst) { printf("Illegal funct3\n"); return; } - printf(" x%d, %" PRIu8 ", %" PRIu8 "\n", i.rd, i.rs1, i.imm); + printf(" x%d, %" PRIu8 ", %" PRId32 "\n", i.rd, i.rs1, i.imm); } static void disasm_rtype(uint32_t inst) { @@ -139,7 +139,7 @@ static void disasm_itype_loads(uint32_t inst) { } printf(" x%" PRIu32 ", %" PRId32 "(x%" PRIu32 ")", - i.rd, (int32_t)(int16_t)i.imm, i.rs1); + i.rd, i.imm, i.rs1); } static void disasm_stype(uint32_t inst) { @@ -209,7 +209,7 @@ static void disasm_itype_jalr(uint32_t inst) { } printf("x%" PRIu32 ", %" PRId32 "(x%" PRIu32 ")\n", - i.rd, (int32_t)(int16_t)i.imm, i.rs1); + i.rd, i.imm, i.rs1); } @@ -256,9 +256,7 @@ disasm_itype_control(uint32_t inst) } else { puts("Illegal instruction"); return; - } - } static void diff --git a/main.c b/main.c @@ -96,9 +96,10 @@ static void exec_itype(cpu_state_t *cpu, uint32_t inst, uint8_t *mem) { decode_itype(&i, inst); uint32_t x; uint32_t shamt; + uint32_t uimm = (uint32_t)i.imm; switch(i.funct3) { case 0x0: - x = cpu->x[i.rs1]+i.imm; + x = cpu->x[i.rs1]+uimm; break; case 0x1: if (i.funct7 == 0x00) { @@ -113,19 +114,18 @@ static void exec_itype(cpu_state_t *cpu, uint32_t inst, uint8_t *mem) { x = ((int32_t)cpu->x[i.rs1] < (int32_t)i.imm) ? 1 : 0; break; case 0x3: - x = (cpu->x[i.rs1] < i.imm) ? 1 : 0; + x = (cpu->x[i.rs1] < uimm) ? 1 : 0; break; case 0x4: - x = cpu->x[i.rs1]^i.imm; + x = cpu->x[i.rs1]^uimm; break; case 0x5: + shamt = i.imm & 31; switch(i.funct7) { case 0x00: - shamt = i.imm & 31; x = cpu->x[i.rs1] >> shamt; break; case 0x20: - shamt = i.imm & 31; x = (uint32_t)((int32_t)cpu->x[i.rs1] >> shamt); break; default: @@ -134,10 +134,10 @@ static void exec_itype(cpu_state_t *cpu, uint32_t inst, uint8_t *mem) { } break; case 0x6: - x = cpu->x[i.rs1]|i.imm; + x = cpu->x[i.rs1]|uimm; break; case 0x7: - x = cpu->x[i.rs1]&i.imm; + x = cpu->x[i.rs1]&uimm; break; default: raise_trap(cpu, TRAP_ILLEGAL_INSTRUCTION, inst); @@ -481,6 +481,7 @@ 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 @@ -488,6 +489,13 @@ load_program(uint8_t *mem) 0x00000013, // nop 0x0ff0000f, // fence 0x00100073, // ebreak +*/ + 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 }; size_t len = sizeof(arr) / sizeof(arr[0]);