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:
| A | decode.h | | | 121 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| M | main.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;
}