rvemu

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

commit e2aa4903fefda539540b4dc39619291196c02159
parent 01f7641b70f741df2279b57364a784bded02bb0b
Author: Michail Konstantinos Dimopoulos <mk@mcdim.xyz>
Date:   Wed,  2 Sep 2026 00:13:57 +0300

Added lui, auipc, fixed jal decoding

Diffstat:
Mdecode.h | 39++++++++++++++++++++++++++++++++++-----
Mmain.c | 54+++++++++++++++++++++++++++++++++++++++++++++++++-----
2 files changed, 83 insertions(+), 10 deletions(-)

diff --git a/decode.h b/decode.h @@ -122,22 +122,51 @@ decode_btype(btype_t *b, uint32_t inst) J-TYPE INSTRUCTION FORMAT 31 12 11 7 6 0 +---------------------------------------+---------+--------+ -| imm[31:12] | rd | opcode | +| imm[20|10:1|11|19:12] | rd | opcode | +---------------------------------------+---------+--------+ -opcode 0x13 0010011 immediates +opcode 0x6f 1101111 jal */ typedef struct { uint8_t opcode; - uint8_t rd, rs1; + uint8_t rd; uint32_t imm; } jtype_t; static inline void decode_jtype(jtype_t *j, uint32_t inst) { - j->rd = (uint8_t)((inst >> 7) & 31); - j->imm = (uint32_t)((inst >> 11) & 0xfffff); + 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); +} + +/* +U-TYPE INSTRUCTION FORMAT +31 11 7 6 0 ++---------------------------------------+---------+--------+ +| imm[31:12] | rd | opcode | ++---------------------------------------+---------+--------+ +opcode 0x37 0110111 lui +opcode 0x17 0010111 auipc +*/ + +typedef struct { + uint8_t opcode; + uint8_t rd; + uint32_t imm; +} utype_t; + +static inline void +decode_utype(utype_t *u, uint32_t inst) +{ + u->rd = (uint8_t)((inst >> 7) & 31); + u->imm = (uint32_t)((inst >> 12) & 0xfffff); } #endif diff --git a/main.c b/main.c @@ -72,8 +72,7 @@ static void exec_itype(cpu_state_t *cpu, uint32_t inst, uint8_t *mem) { printf("\n"); /*********/ - uint32_t x; - uint32_t shamt; + uint32_t x; uint32_t shamt; switch(i.funct3) { case 0x0: printf("ADDI\n"); @@ -495,7 +494,7 @@ static void exec_jtype(cpu_state_t *cpu, uint32_t inst, uint8_t *mem) { x = cpu->pc + 4; cpu->pc += j.imm; - printf("rs1:%u imm:%u rd:%u\n",cpu->x[j.rs1],j.imm,cpu->x[j.rd]); + printf("imm:%u rd:%u\n",j.imm,cpu->x[j.rd]); if (j.rd != 0) { /* TODO: calculate & check addr */ cpu->x[j.rd] = x; @@ -504,6 +503,48 @@ static void exec_jtype(cpu_state_t *cpu, uint32_t inst, uint8_t *mem) { printf("rd:%u\n", cpu->x[j.rd]); } +static void exec_utype(cpu_state_t *cpu, uint32_t inst, uint8_t *mem) { + (void)mem; /* suppressing unused parameters warning */ + printf("TYPE U\n"); + utype_t u; + decode_utype(&u, inst); + + /**print**/ + printf("imm rd opcode\n"); + print_binless(u.imm, 20); + printf(" "); + print_binless(u.rd, 5); + printf("\n"); + /*********/ + + cpu->x[u.rd] = u.imm << 12; + cpu->pc += 4; + + printf("rd:%u\n", cpu->x[u.rd]); + printf("rd:%x\n", cpu->x[u.rd]); +} + +static void exec_utype_auipc(cpu_state_t *cpu, uint32_t inst, uint8_t *mem) { + (void)mem; /* suppressing unused parameters warning */ + printf("TYPE U\n"); + utype_t u; + decode_utype(&u, inst); + + /**print**/ + printf("imm rd opcode\n"); + print_binless(u.imm, 20); + printf(" "); + print_binless(u.rd, 5); + printf("\n"); + /*********/ + + cpu->x[u.rd] = cpu->pc + (u.imm << 12); + cpu->pc += 4; + + printf("rd:%u\n", cpu->x[u.rd]); + printf("rd:%x\n", cpu->x[u.rd]); +} + static void load_program(uint8_t *mem) { @@ -519,8 +560,9 @@ load_program(uint8_t *mem) uint32_t arr[] = { 0x00500193, // addi x3, x0, 5 0x00600093, // addi x1, x0, 6 - 0x00118263, // beq x3, x1. +4 - 0xfe728ae3 // beq x5, x7, -12 -> addr 0 + 0xaaaaa3b7, // lui x7, 0xaaaaa -> rd:aaaaa000 + //0xfe728ae3 // beq x5, x7, -12 -> addr 0 + 0x1397 // auipc x7 0x1 -> rd 1008 }; size_t len = sizeof(arr) / sizeof(arr[0]); @@ -563,6 +605,8 @@ init_opcode_table(void) opcode_table[0x23] = exec_stype; opcode_table[0x63] = exec_btype; opcode_table[0x6f] = exec_jtype; + opcode_table[0x37] = exec_utype; + opcode_table[0x17] = exec_utype_auipc; } /***/