commit c2e829caab204946155130c494312cf543871f68
parent 93a7993e757ab9660dcdb89239dd211a37754108
Author: Michail Konstantinos Dimopoulos <mk@mcdim.xyz>
Date: Sat, 21 Mar 2026 22:34:54 +0200
Load byte
Diffstat:
| M | main.c | | | 187 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- |
1 file changed, 181 insertions(+), 6 deletions(-)
diff --git a/main.c b/main.c
@@ -13,6 +13,13 @@ typedef struct {
uint8_t funct3, funct7;
} rtype_t;
+typedef struct {
+ uint8_t opcode;
+ uint8_t rd, rs1, imm;
+ uint8_t funct3;
+ uint8_t funct7, inimm;
+} itype_t;
+
void print_bin16(uint16_t x) {
for (int i = 15; i >= 0; i--) {
putchar((x >> i) & 1 ? '1' : '0');
@@ -33,14 +40,117 @@ void print_binless(uint32_t x, int a) {
}
/*
-R-TYPE INSTRUCTION DECODING
+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;
+
+ /**print**/
+ printf("f7 rs2 rs1 f3 rd opcode\n");
+ print_binless(i.imm, 11);
+ printf(" ");
+ print_binless(i.rs1, 5);
+ printf(" ");
+ print_binless(i.funct3, 3);
+ printf(" ");
+ print_binless(i.rd, 5);
+ printf("\nf7 in\n");
+ print_binless(i.funct7, 7);
+ printf(" ");
+ print_binless(i.inimm, 5);
+ printf("\n");
+ /*********/
+
+ uint32_t x;
+ uint32_t shamt;
+ switch(i.funct3) {
+ case 0x0:
+ printf("ADDI\n");
+ x = cpu->x[i.rs1]+i.imm;
+ break;
+ case 0x1:
+ if (i.funct7 != 0x00) {
+ printf("Shift logical left i\n");
+ shamt = i.imm & 31;
+ x = cpu->x[i.rs1] << shamt;
+ } else {
+ fprintf(stderr, "Illegal funct7\n");
+ return;
+ }
+ break;
+ case 0x2:
+ printf("Set less than i\n");
+ x = ((int32_t)cpu->x[i.rs1] < (int32_t)i.imm) ? 1 : 0;
+ break;
+ case 0x3:
+ printf("Set less than Ui\n");
+ x = (cpu->x[i.rs1] < i.imm) ? 1 : 0;
+ break;
+ case 0x4:
+ printf("XORi\n");
+ x = cpu->x[i.rs1]^i.imm;
+ break;
+ case 0x5:
+ switch(i.funct7) {
+ case 0x00:
+ printf("Shift logical right i\n");
+ shamt = i.imm & 31;
+ x = cpu->x[i.rs1] >> shamt;
+ break;
+ case 0x20:
+ printf("Shift arithm right i\n");
+ shamt = i.imm & 31;
+ x = (uint32_t)((int32_t)cpu->x[i.rs1] >> shamt);
+ break;
+ default:
+ fprintf(stderr, "Illegal funct7\n");
+ return;
+ }
+ break;
+ case 0x6:
+ printf("OR\n");
+ x = cpu->x[i.rs1]|i.imm;
+ break;
+ case 0x7:
+ printf("AND\n");
+ x = cpu->x[i.rs1]&i.imm;
+ break;
+ default:
+ fprintf(stderr, "Illegal funct3\n");
+ return;
+ }
+
+ printf("rs1:%u imm:%u rd:%u\n",cpu->x[i.rs1],i.imm,cpu->x[i.rd]);
+ if (i.rd != 0) {
+ cpu->x[i.rd] = x;
+ }
+
+ printf("rd:%u\n", cpu->x[i.rd]);
+}
+
+/*
+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) {
+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;
@@ -136,12 +246,58 @@ void exec_rtype(cpu_state_t *cpu, uint32_t inst) {
printf("rd:%u\n", cpu->x[r.rd]);
}
+/*
+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) {
+ 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;
+
+ /**print**/
+ printf("imm rs1 f3 rd opcode\n");
+ print_binless(i.imm, 11);
+ printf(" ");
+ print_binless(i.rs1, 5);
+ printf(" ");
+ print_binless(i.funct3, 3);
+ printf(" ");
+ print_binless(i.rd, 5);
+ printf("\n");
+ /*********/
+
+ int32_t x;
+ switch(i.funct3) {
+ case 0x0:
+ x = (int8_t)mem[i.imm+i.rs1];
+ break;
+ }
+
+ if (i.rd != 0) {
+ cpu->x[i.rd] = x;
+ }
+
+ printf("rd:%d\n", cpu->x[i.rd]);
+
+}
+
int main() {
/* function pointer dispatch */
- typedef void (*exec_fn)(cpu_state_t *, uint32_t inst);
+ typedef void (*exec_fn)(cpu_state_t *, uint32_t inst,
+ uint8_t *mem);
static exec_fn opcode_table[128];
opcode_table[0x33] = exec_rtype;
+ opcode_table[0x13] = exec_itype;
+ opcode_table[0x03] = exec_ltype;
/*opcode_table[0x13] = exec_rtype_imm;
opcode_table[0x03] = exec_load;
opcode_table[0x23] = exec_store;
@@ -172,7 +328,23 @@ int main() {
// f7 rs2 rs1 f3 rd opcode
// 0000000 00001 00010 100 00011 0110011
- //inst = 0x1141B3; /* XOR */
+ inst = 0x1141B3; /* XOR */
+
+ // imm rs1 f3 rd opcode
+ // 000000000101 00010 000 00011 0010011
+ inst = 0x510193; /* ADDi 5 */
+
+ // imm rs1 f3 rd opcode
+ // 000000000101 00010 111 00011 0010011
+ //inst = 0x517193; /* ANDi 101 */
+
+ // imm rs1 f3 rd opcode
+ // 000000000001 00010 101 00011 0010011
+ //inst = 0x115193; /* shift logical right i 1*/
+
+ // imm rs1 f3 rd opcode
+ // 011111111111 00000 000 00011 0000011
+ inst = 0x100183; /* LOAD Byte from address 0x3*/
print_bin32(inst);
printf("\n");
@@ -187,7 +359,10 @@ int main() {
cpu_state_t cpu;
cpu.x[1] = 51;
cpu.x[2] = 14;
-
+ uint8_t mem[2056] = {0};
+ for (int i=0; i<2056; i++) {
+ mem[i] = (uint8_t)i;
+ }
if (!fn) {
//illegal(NULL, inst);
@@ -195,7 +370,7 @@ int main() {
return EXIT_FAILURE;
}
- fn(&cpu,inst);
+ fn(&cpu,inst,mem);
return 0;
}