rvemu

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

commit 5b14406c061bd7ba6193feba733e2eb8650598bc
parent b6f38b53eb40e2eab52f93ca2b5bd2a5f1a27aa9
Author: Michail Konstantinos Dimopoulos <mk@mcdim.xyz>
Date:   Thu, 27 Aug 2026 15:12:09 +0300

Decoding helpers on decode.h

Diffstat:
Adecode.h | 121+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mmain.c | 152++++++++++++++-----------------------------------------------------------------
2 files changed, 147 insertions(+), 126 deletions(-)

diff --git a/decode.h b/decode.h @@ -0,0 +1,121 @@ +#ifndef DECODE +#define DECODE + +/* +I-TYPE INSTRUCTION FORMAT +31 20 19 15 14 12 11 7 6 0 ++---------------------+--------+--------+---------+--------+ +| imm[11:0] | rs1 | funct3 | rd | opcode | ++---------------------+--------+--------+---------+--------+ +opcode 0x13 0010011 immediates +opcode 0x33 0000011 loads +*/ + +typedef struct { + uint8_t opcode; + uint8_t rd, rs1; + uint16_t imm; + uint8_t funct3; + uint8_t funct7, inimm; +} itype_t; + +static inline void +decode_itype(itype_t *i, uint32_t inst) +{ + i->rd = (inst >> 7) & 31; + i->funct3 = (inst >> 12) & 7; + i->rs1 = (inst >> 15) & 31; + i->imm = (inst >> 20) & 2047; + + i->inimm = i->imm & 31; + i->funct7 = (i->imm >> 5) & 127; +} + +/* +R-TYPE INSTRUCTION FORMAT +31 25 24 20 19 15 14 12 11 7 6 0 ++------------+--------+--------+--------+---------+--------+ +| funct7 | rs2 | rs1 | funct3 | rd | opcode | ++------------+--------+--------+--------+---------+--------+ +opcode 0x33 0110011 +*/ + +typedef struct { + uint8_t opcode; + uint8_t rd, rs1, rs2; + uint8_t funct3, funct7; +} rtype_t; + +static inline void +decode_rtype(rtype_t *r, uint32_t inst) +{ + r->rd = (inst >> 7) & 31; + r->funct3 = (inst >> 12) & 7; + r->rs1 = (inst >> 15) & 31; + r->rs2 = (inst >> 20) & 31; + r->funct7 = (inst >> 25) & 127; +} + +/* +S-TYPE INSTRUCTION FORMAT +31 25 24 20 19 15 14 12 11 7 6 0 ++------------+--------+--------+--------+---------+--------+ +| imm[11:0] | rs2 | rs1 | funct3 |imm[4:0] | opcode | ++------------+--------+--------+--------+---------+--------+ +opcode 0x33 0100011 +*/ + +typedef struct { + uint8_t opcode; + uint8_t rs1, rs2; + uint16_t imm; + uint8_t funct3; +} stype_t; + +static inline void +decode_stype(stype_t *s, uint32_t inst) +{ + uint32_t imm_11_5 = (inst >> 25) & 127; + uint32_t imm_4_0 = (inst >> 7) & 31; + s->imm = (imm_4_0) | (imm_11_5 << 5); + + s->funct3 = (inst >> 12) & 7; + s->rs1 = (inst >> 15) & 31; + s->rs2 = (inst >> 20) & 31; +} + +/* +B-TYPE INSTRUCTION FORMAT +31 25 24 20 19 15 14 12 11 7 6 0 ++---------------+--------+--------+--------+------------+--------+ +| imm[12|10:5] | rs2 | rs1 | funct3 |imm[4:1|11] | opcode | ++---------------+--------+--------+--------+------------+--------+ +opcode 0x63 1100011 +*/ +typedef struct { + uint8_t opcode; + uint8_t rs1, rs2; + int16_t imm; + uint8_t funct3; +} btype_t; + +static inline void +decode_btype(btype_t *b, uint32_t inst) +{ + uint32_t imm_10_5 = (inst >> 25) & 63; + uint32_t imm_11 = (inst >> 7) & 1; + uint32_t imm_4_1 = (inst >> 8) & 15; + uint32_t imm_12 = (inst >> 31) & 1; + + uint32_t raw_imm = (imm_12 << 12) | (imm_11 << 11) | + (imm_10_5 << 5) | (imm_4_1 << 1); + if (raw_imm & (1U << 12)) + raw_imm |= 0xffffe000U; + b->imm = (int32_t)raw_imm; + + b->funct3 = (inst >> 12) & 7; + b->rs1 = (inst >> 15) & 31; + b->rs2 = (inst >> 20) & 31; +} + +#endif diff --git a/main.c b/main.c @@ -4,6 +4,8 @@ #include <stdlib.h> #include <string.h> +#include "decode.h" + #define MEMSIZE 2052 @@ -12,34 +14,6 @@ typedef struct { uint32_t pc; } cpu_state_t; -typedef struct { - uint8_t opcode; - uint8_t rd, rs1, rs2; - uint8_t funct3, funct7; -} rtype_t; - -typedef struct { - uint8_t opcode; - uint8_t rd, rs1; - uint16_t imm; - uint8_t funct3; - uint8_t funct7, inimm; -} itype_t; - -typedef struct { - uint8_t opcode; - uint8_t rs1, rs2; - uint16_t imm; - uint8_t funct3; -} stype_t; - -typedef struct { - uint8_t opcode; - uint8_t rs1, rs2; - int16_t imm; - uint8_t funct3; -} btype_t; - void print_bin16(uint16_t x) { for (int i = 15; i >= 0; i--) { putchar((x >> i) & 1 ? '1' : '0'); @@ -76,25 +50,10 @@ static int32_t get_valid_branch_target(uint32_t pc, int32_t offset, uint32_t *ta return 0; } -/* -I-TYPE INSTRUCTION FORMAT -31 20 19 15 14 12 11 7 6 0 -+---------------------+--------+--------+---------+--------+ -| imm[11:0] | rs1 | funct3 | rd | opcode | -+---------------------+--------+--------+---------+--------+ -opcode 0x13 0010011 -*/ - void exec_itype(cpu_state_t *cpu, uint32_t inst, uint8_t *mem) { printf("TYPE I\n"); itype_t i; - i.rd = (inst >> 7) & 31; - i.funct3 = (inst >> 12) & 7; - i.rs1 = (inst >> 15) & 31; - i.imm = (inst >> 20) & 2047; - - i.inimm = i.imm & 31; - i.funct7 = (i.imm >> 5) & 127; + decode_itype(&i, inst); /**print**/ printf("f7 rs2 rs1 f3 rd opcode\n"); @@ -181,22 +140,10 @@ void exec_itype(cpu_state_t *cpu, uint32_t inst, uint8_t *mem) { cpu->pc += 4; } -/* -R-TYPE INSTRUCTION FORMAT -31 25 24 20 19 15 14 12 11 7 6 0 -+------------+--------+--------+--------+---------+--------+ -| funct7 | rs2 | rs1 | funct3 | rd | opcode | -+------------+--------+--------+--------+---------+--------+ -opcode 0x33 0110011 -*/ void exec_rtype(cpu_state_t *cpu, uint32_t inst, uint8_t *mem) { printf("TYPE R\n"); rtype_t r; - r.rd = (inst >> 7) & 31; - r.funct3 = (inst >> 12) & 7; - r.rs1 = (inst >> 15) & 31; - r.rs2 = (inst >> 20) & 31; - r.funct7 = (inst >> 25) & 127; + decode_rtype(&r, inst); /**print**/ printf("f7 rs2 rs1 f3 rd opcode\n"); @@ -286,21 +233,10 @@ void exec_rtype(cpu_state_t *cpu, uint32_t inst, uint8_t *mem) { cpu->pc += 4; } -/* -I-TYPE INSTRUCTION FORMAT (LOAD) -31 25 24 20 19 15 14 12 11 7 6 0 -+------------+--------+--------+--------+---------+--------+ -| funct7 | rs2 | rs1 | funct3 | rd | opcode | -+------------+--------+--------+--------+---------+--------+ -opcode 0x33 0000011 -*/ -void exec_ltype(cpu_state_t *cpu, uint32_t inst, uint8_t *mem) { +void exec_itype_loads(cpu_state_t *cpu, uint32_t inst, uint8_t *mem) { printf("TYPE L\n"); itype_t i; - i.rd = (inst >> 7) & 31; - i.funct3 = (inst >> 12) & 7; - i.rs1 = (inst >> 15) & 31; - i.imm = (inst >> 20) & 2047; + decode_itype(&i, inst); /**print**/ printf("imm rs1 f3 rd opcode\n"); @@ -363,29 +299,16 @@ void exec_ltype(cpu_state_t *cpu, uint32_t inst, uint8_t *mem) { } -/* -S-TYPE INSTRUCTION FORMAT -31 25 24 20 19 15 14 12 11 7 6 0 -+------------+--------+--------+--------+---------+--------+ -| imm[11:0] | rs2 | rs1 | funct3 |imm[4:0] | opcode | -+------------+--------+--------+--------+---------+--------+ -opcode 0x33 0100011 -*/ void exec_stype(cpu_state_t *cpu, uint32_t inst, uint8_t *mem) { printf("TYPE S\n"); stype_t s; - - uint32_t imm_11_5 = (inst >> 25) & 127; - uint32_t imm_4_0 = (inst >> 7) & 31; - s.imm = (imm_4_0) | (imm_11_5 << 5); - - s.funct3 = (inst >> 12) & 7; - s.rs1 = (inst >> 15) & 31; - s.rs2 = (inst >> 20) & 31; + decode_stype(&s, inst); printf("\nimm:%x\n", s.imm); /**print**/ + /*for printing, not needed*/uint32_t imm_11_5 = (inst >> 25) & 127; + /*for printing, not needed*/uint32_t imm_4_0 = (inst >> 7) & 31; printf("imm rs2 rs1 f3 imm opcode\n"); printf("[11:5] [4:0]\n"); print_binless(imm_11_5, 7); @@ -440,52 +363,29 @@ void exec_stype(cpu_state_t *cpu, uint32_t inst, uint8_t *mem) { cpu->pc += 4; } -/* -B-TYPE INSTRUCTION FORMAT -31 25 24 20 19 15 14 12 11 7 6 0 -+---------------+--------+--------+--------+------------+--------+ -| imm[12|10:5] | rs2 | rs1 | funct3 |imm[4:1|11] | opcode | -+---------------+--------+--------+--------+------------+--------+ -opcode 0x63 1100011 -*/ void exec_btype(cpu_state_t *cpu, uint32_t inst, uint8_t *mem) { (void)mem; /* suppressing unused parameters warning */ printf("TYPE B\n"); btype_t b; + decode_btype(&b, inst); - uint32_t imm_10_5 = (inst >> 25) & 63; - uint32_t imm_11 = (inst >> 7) & 1; - uint32_t imm_4_1 = (inst >> 8) & 15; - uint32_t imm_12 = (inst >> 31) & 1; - - /**/uint32_t raw_imm = (imm_12 << 12) | (imm_11 << 11) | (imm_10_5 << 5) | (imm_4_1 << 1); - /**/if (raw_imm & (1U << 12)) - /**/ raw_imm |= 0xffffe000U; - //b.imm = (int32_t)(0 | (imm_4_1 << 1) | (imm_10_5 << 5) | (imm_11 << 11) | (imm_12 << 12)); - b.imm = (int32_t)raw_imm; - - b.funct3 = (inst >> 12) & 7; - b.rs1 = (inst >> 15) & 31; - b.rs2 = (inst >> 20) & 31; - - /**/printf("imm: %" PRId32 "\n", b.imm); - printf("\nimm:%x\n", b.imm); + printf("imm: %" PRId32 "\n", b.imm); /**print**/ - printf("imm rs2 rs1 f3 imm opcode\n"); - printf("[12|10:5] [4:1|11]\n"); - print_binless(imm_12, 1); - print_binless(imm_10_5, 6); - printf(" "); - print_binless(b.rs2, 5); - printf(" "); - print_binless(b.rs1, 5); - printf(" "); - print_binless(b.funct3, 3); - printf(" "); - print_binless(imm_4_1, 4); - print_binless(imm_11, 1); - printf("\n"); + //printf("imm rs2 rs1 f3 imm opcode\n"); + //printf("[12|10:5] [4:1|11]\n"); + //print_binless(imm_12, 1); + //print_binless(imm_10_5, 6); + //printf(" "); + //print_binless(b.rs2, 5); + //printf(" "); + //print_binless(b.rs1, 5); + //printf(" "); + //print_binless(b.funct3, 3); + //printf(" "); + //print_binless(imm_4_1, 4); + //print_binless(imm_11, 1); + //printf("\n"); /*********/ int jump = 0; @@ -589,7 +489,7 @@ init_opcode_table(void) { opcode_table[0x33] = exec_rtype; opcode_table[0x13] = exec_itype; - opcode_table[0x03] = exec_ltype; + opcode_table[0x03] = exec_itype_loads; opcode_table[0x23] = exec_stype; opcode_table[0x63] = exec_btype; }