commit 2960ee19a669a70430c0ccdb7b21ec3b2f4f5729
parent 0cc9916509027b5af4690f39d4c1ba10f9b49d5e
Author: Michail Konstantinos Dimopoulos <mk@mcdim.xyz>
Date: Sat, 5 Sep 2026 20:09:29 +0300
Fixed jal decoding
Diffstat:
| M | decode.h | | | 15 | ++++++++++++--- |
| M | disasm.c | | | 4 | ++-- |
| M | exec.c | | | 8 | ++------ |
| M | exec.h | | | 2 | +- |
| M | main.c | | | 75 | +++++++++++++++++++-------------------------------------------------------- |
| M | rtests.c | | | 34 | +++++++++++++++++++++++++++++++++- |
6 files changed, 69 insertions(+), 69 deletions(-)
diff --git a/decode.h b/decode.h
@@ -150,20 +150,29 @@ opcode 0x6f 1101111 jal
typedef struct {
uint8_t opcode;
uint8_t rd;
- uint32_t imm;
+ int32_t imm;
} jtype_t;
static inline void
decode_jtype(jtype_t *j, uint32_t inst)
{
- j->rd = (uint8_t)((inst >> 7) & 0x1f);
+ 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);
+ uint32_t raw = (int32_t)(uint32_t)(imm_19_12 << 12 |
+ imm_11 << 11 |
+ imm_10_1 << 1|
+ imm_20 << 20);
+ j->imm = (int32_t)raw;
+
+ /* extend sign */
+ if ((raw & UINT32_C(0x100000)) != 0u)
+ j->imm -= INT32_C(0x200000);
+
}
/*
diff --git a/disasm.c b/disasm.c
@@ -208,7 +208,7 @@ static void disasm_itype_jalr(uint32_t inst) {
return;
}
- printf("x%" PRIu32 ", %" PRId32 "(x%" PRIu32 ")\n",
+ printf("jalr x%" PRIu32 ", %" PRId32 "(x%" PRIu32 ")\n",
i.rd, i.imm, i.rs1);
}
@@ -217,7 +217,7 @@ static void disasm_jtype(uint32_t inst) {
jtype_t j;
decode_jtype(&j, inst);
- printf("x%" PRIu32 ", %" PRId32 "\n",
+ printf("jal x%" PRIu32 ", %" PRId32 "\n",
j.rd, (int32_t)j.imm);
}
diff --git a/exec.c b/exec.c
@@ -376,10 +376,6 @@ static void exec_jtype(cpu_state_t *cpu, uint32_t inst, uint8_t *mem) {
jtype_t j;
decode_jtype(&j, inst);
- uint32_t x;
- x = cpu->pc + 4;
- cpu->pc += j.imm;
-
uint32_t target;
trap_cause_t cause = get_valid_branch_target(cpu->pc,
(int32_t)j.imm,
@@ -389,11 +385,11 @@ static void exec_jtype(cpu_state_t *cpu, uint32_t inst, uint8_t *mem) {
return;
}
- cpu->pc = target;
-
if (j.rd != 0) {
+ uint32_t x = cpu->pc + 4;
cpu->x[j.rd] = x;
}
+ cpu->pc = target;
}
static void
diff --git a/exec.h b/exec.h
@@ -3,7 +3,7 @@
#include "trap.h"
-#define MEMSIZE 2052
+#define MEMSIZE 4128
typedef enum {
CPU_RUNNING = 0,
diff --git a/main.c b/main.c
@@ -19,62 +19,25 @@ load_program(uint8_t *mem)
{
/* program */
uint32_t arr[] = {
-/*
- 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
-*/
-/*
- 0xfff00093, // li ra,-1
- 0xfff04113, // not sp,zero
- 0xfff06193, // ori gp,zero,-1
- 0xfff17213, // andi tp,sp,-1
- 0xfff02293, // slti t0,zero,-1
- 0xfff03313, // sltiu t1,zero,-1
- 0x00100073 // ebreak
-*/
-/*
- 0x00700513, // addi x10, x0, 7
- 0x00451513, // slli x10, x10, 4
- 0x00d50513, // addi x10, x10, 13
- 0x05554513, // xori x10, x10, 0x55
- 0xff750513, // addi x10, x10, -9
- 0x00100073 // ebreak
-*/
-0x10000593, //li a1,256
-0xfff00513, //li a0,-1
-0x00a58023, //sb a0,0(a1)
-0x0005c503, //lbu a0,0(a1)
-0x00150513, //addi a0,a0,1
-0x00a59123, //sh a0,2(a1)
-0x00259503, //lh a0,2(a1)
-0xeff50513, //addi a0,a0,-257
-0x00a58223, //sb a0,4(a1)
-0x00458503, //lb a0,4(a1)
-0x00a59323, //sh a0,6(a1)
-0x00659503, //lh a0,6(a1)
-0x0065d503, //lhu a0,6(a1)
-0x00150513, //addi a0,a0,1
-0x00a5a423, //sw a0,8(a1)
-0x00000513, //li a0,0
-0x0085a503, //lw a0,8(a1)
-0x00000593, //li a1,0
-0x00100073 //ebreak
-/*
- 0x00200093, // addi x1, x0, 2
- 0x00000113, // addi x2, x0, 0
- 0x05c00193, // addi x3, x0, 0x5c
- 0x00110113, // addi x2, x2, 1
- 0x0021a023, // sw x2, 0(x3)
- 0x00418193, // addi x3, x3, 4
- 0xfff08093, // addi x1, x1, -1
- 0xfe0098e3, // bne x1, x0, -16
- 0x00100073 // ebreak
-*/
-
+ 0x10000593, //li a1,256
+ 0xfff00513, //li a0,-1
+ 0x00a58023, //sb a0,0(a1)
+ 0x0005c503, //lbu a0,0(a1)
+ 0x00150513, //addi a0,a0,1
+ 0x00a59123, //sh a0,2(a1)
+ 0x00259503, //lh a0,2(a1)
+ 0xeff50513, //addi a0,a0,-257
+ 0x00a58223, //sb a0,4(a1)
+ 0x00458503, //lb a0,4(a1)
+ 0x00a59323, //sh a0,6(a1)
+ 0x00659503, //lh a0,6(a1)
+ 0x0065d503, //lhu a0,6(a1)
+ 0x00150513, //addi a0,a0,1
+ 0x00a5a423, //sw a0,8(a1)
+ 0x00000513, //li a0,0
+ 0x0085a503, //lw a0,8(a1)
+ 0x00000593, //li a1,0
+ 0x00100073 //ebreak
};
size_t len = sizeof(arr) / sizeof(arr[0]);
diff --git a/rtests.c b/rtests.c
@@ -187,7 +187,39 @@ test_t tests[] = {
.mem_len = 12,
}
},
-
+ {
+ .name = "Fibonacci sequence",
+ .program = {
+ 0x01400513, //li a0,20
+ 0x00000293, //li t0,0
+ 0x00100313, //li t1,1
+ 0x00000393, //li t2,0
+ 0x00a38c63, //beq t2,a0,28 <done>
+ 0x00628e33, //add t3,t0,t1
+ 0x00030293, //mv t0,t1
+ 0x000e0313, //mv t1,t3
+ 0x00138393, //addi t2,t2,1
+ 0xfedff06f, //j 10 <loop>
+ 0x00028513, //mv a0,t0
+ 0x00100073, //ebreak
+ },
+ .program_len = 12,
+ .exp = {
+ .x = {
+ [5] = 0x1a6d,
+ [6] = 0x2ac2,
+ [7] = 0x14,
+ [10] = 0x1a6d,
+ [28] = 0x2ac2,
+ },
+ .x_check_mask = ((UINT32_C(1) << 5) |
+ (UINT32_C(1) << 6) |
+ (UINT32_C(1) << 7) |
+ (UINT32_C(1) << 10) |
+ (UINT32_C(1) << 28)),
+ .pc = 0x2c,
+ }
+ },
};
static void