commit 4e256a9cea6be3e08d06d1c63ab90e9cd4dd1824
parent 1b0c03d3ec03d206e74c17c7308f581f44332411
Author: Michail Konstantinos Dimopoulos <mk@mcdim.xyz>
Date: Fri, 4 Sep 2026 00:14:56 +0300
Fixed imm sign bug and disasm bugs
Diffstat:
3 files changed, 42 insertions(+), 16 deletions(-)
diff --git a/decode.h b/decode.h
@@ -14,23 +14,43 @@ opcode 0x33 0000011 loads
typedef struct {
uint8_t opcode;
uint8_t rd, rs1;
- uint16_t imm;
+ //uint16_t imm;
+ int32_t imm;
uint8_t funct3;
uint8_t funct7, inimm;
} itype_t;
-static inline void
+/*static inline void
decode_itype(itype_t *i, uint32_t inst)
{
i->rd = (uint8_t)((inst >> 7) & 31);
i->funct3 = (uint8_t)((inst >> 12) & 7);
i->rs1 = (uint8_t)((inst >> 15) & 31);
- i->imm = (uint16_t)((inst >> 20) & 2047);
+ //i->imm = (uint16_t)((inst >> 20) & 2047);
+ i->imm = (uint32_t)((inst >> 20) & 0xfff);
i->inimm = (uint8_t)(i->imm & 31);
i->funct7 = (uint8_t)((i->imm >> 5) & 127);
+}*/
+static inline void
+decode_itype(itype_t *i, uint32_t inst)
+{
+ uint32_t raw_imm = (inst >> 20) & UINT32_C(0xfff);
+
+ i->rd = (uint8_t)((inst >> 7) & UINT32_C(31));
+ i->funct3 = (uint8_t)((inst >> 12) & UINT32_C(7));
+ i->rs1 = (uint8_t)((inst >> 15) & UINT32_C(31));
+
+ i->inimm = (uint8_t)(raw_imm & UINT32_C(31));
+ i->funct7 = (uint8_t)((inst >> 25) & UINT32_C(127));
+
+ i->imm = (int32_t)raw_imm;
+
+ if ((raw_imm & UINT32_C(0x800)) != 0u)
+ i->imm -= INT32_C(0x1000);
}
+
/*
R-TYPE INSTRUCTION FORMAT
31 25 24 20 19 15 14 12 11 7 6 0
diff --git a/disasm.c b/disasm.c
@@ -27,7 +27,7 @@ static void disasm_itype(uint32_t inst) {
printf("slti");
break;
case 0x3:
- printf("sltui");
+ printf("sltiu");
break;
case 0x4:
printf("xori");
@@ -55,7 +55,7 @@ static void disasm_itype(uint32_t inst) {
printf("Illegal funct3\n");
return;
}
- printf(" x%d, %" PRIu8 ", %" PRIu8 "\n", i.rd, i.rs1, i.imm);
+ printf(" x%d, %" PRIu8 ", %" PRId32 "\n", i.rd, i.rs1, i.imm);
}
static void disasm_rtype(uint32_t inst) {
@@ -139,7 +139,7 @@ static void disasm_itype_loads(uint32_t inst) {
}
printf(" x%" PRIu32 ", %" PRId32 "(x%" PRIu32 ")",
- i.rd, (int32_t)(int16_t)i.imm, i.rs1);
+ i.rd, i.imm, i.rs1);
}
static void disasm_stype(uint32_t inst) {
@@ -209,7 +209,7 @@ static void disasm_itype_jalr(uint32_t inst) {
}
printf("x%" PRIu32 ", %" PRId32 "(x%" PRIu32 ")\n",
- i.rd, (int32_t)(int16_t)i.imm, i.rs1);
+ i.rd, i.imm, i.rs1);
}
@@ -256,9 +256,7 @@ disasm_itype_control(uint32_t inst)
} else {
puts("Illegal instruction");
return;
-
}
-
}
static void
diff --git a/main.c b/main.c
@@ -96,9 +96,10 @@ static void exec_itype(cpu_state_t *cpu, uint32_t inst, uint8_t *mem) {
decode_itype(&i, inst);
uint32_t x; uint32_t shamt;
+ uint32_t uimm = (uint32_t)i.imm;
switch(i.funct3) {
case 0x0:
- x = cpu->x[i.rs1]+i.imm;
+ x = cpu->x[i.rs1]+uimm;
break;
case 0x1:
if (i.funct7 == 0x00) {
@@ -113,19 +114,18 @@ static void exec_itype(cpu_state_t *cpu, uint32_t inst, uint8_t *mem) {
x = ((int32_t)cpu->x[i.rs1] < (int32_t)i.imm) ? 1 : 0;
break;
case 0x3:
- x = (cpu->x[i.rs1] < i.imm) ? 1 : 0;
+ x = (cpu->x[i.rs1] < uimm) ? 1 : 0;
break;
case 0x4:
- x = cpu->x[i.rs1]^i.imm;
+ x = cpu->x[i.rs1]^uimm;
break;
case 0x5:
+ shamt = i.imm & 31;
switch(i.funct7) {
case 0x00:
- shamt = i.imm & 31;
x = cpu->x[i.rs1] >> shamt;
break;
case 0x20:
- shamt = i.imm & 31;
x = (uint32_t)((int32_t)cpu->x[i.rs1] >> shamt);
break;
default:
@@ -134,10 +134,10 @@ static void exec_itype(cpu_state_t *cpu, uint32_t inst, uint8_t *mem) {
}
break;
case 0x6:
- x = cpu->x[i.rs1]|i.imm;
+ x = cpu->x[i.rs1]|uimm;
break;
case 0x7:
- x = cpu->x[i.rs1]&i.imm;
+ x = cpu->x[i.rs1]&uimm;
break;
default:
raise_trap(cpu, TRAP_ILLEGAL_INSTRUCTION, inst);
@@ -481,6 +481,7 @@ load_program(uint8_t *mem)
{
/* PROGRAM */
uint32_t arr[] = {
+/*
0x00500193, // addi x3, x0, 5
0x00600093, // addi x1, x0, 6
0xaaaaa3b7, // lui x7, 0xaaaaa -> rd:aaaaa000
@@ -488,6 +489,13 @@ load_program(uint8_t *mem)
0x00000013, // nop
0x0ff0000f, // fence
0x00100073, // ebreak
+*/
+ 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
};
size_t len = sizeof(arr) / sizeof(arr[0]);