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:
| M | decode.h | | | 39 | ++++++++++++++++++++++++++++++++++----- |
| M | main.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;
}
/***/