commit 4446e4fbe7569a37b01c06a28e26ef64c45c6e8c
Author: Michail Konstantinos Dimopoulos <mk@mcdim.xyz>
Date: Mon, 16 Mar 2026 23:49:55 +0200
Initial commit
Diffstat:
| A | Makefile | | | 2 | ++ |
| A | config.h | | | 2 | ++ |
| A | main.c | | | 167 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
3 files changed, 171 insertions(+), 0 deletions(-)
diff --git a/Makefile b/Makefile
@@ -0,0 +1,2 @@
+all:
+ gcc main.c
diff --git a/config.h b/config.h
@@ -0,0 +1,2 @@
+#define MEM_SIZE (32 * 1024 * 1024)
+
diff --git a/main.c b/main.c
@@ -0,0 +1,167 @@
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+typedef struct {
+ uint32_t x[32]; /* general purpose registers */
+ uint32_t pc;
+} cpu_state_t;
+
+typedef struct {
+ uint8_t opcode;
+ uint8_t rd, rs1, rs2;
+ uint8_t funct3, funct7;
+} rtype_t;
+
+void print_bin16(uint16_t x) {
+ for (int i = 15; i >= 0; i--) {
+ putchar((x >> i) & 1 ? '1' : '0');
+ /*if (i % 4 == 0) putchar(' '); grouping */
+ }
+}
+
+void print_bin32(uint32_t x) {
+ for (int i = 31; i >= 0; i--) {
+ putchar((x >> i) & 1 ? '1' : '0');
+ }
+}
+
+void print_binless(uint32_t x, int a) {
+ for (int i = a-1; i >= 0; i--) {
+ putchar((x >> i) & 1 ? '1' : '0');
+ }
+}
+
+/*
+R-TYPE INSTRUCTION DECODING
+31 25 24 20 19 15 14 12 11 7 6 0
++------------+--------+--------+--------+---------+--------+
+| funct7 | rs2 | rs1 | funct3 | rd | opcode |
++------------+--------+--------+--------+---------+--------+
+opcode 0x33 0110011
+*/
+void exec_op(cpu_state_t *cpu, uint32_t inst) {
+ 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;
+
+ /* print */
+ printf("f7 rs2 rs1 f3 rd opcode\n");
+ print_binless(r.funct7, 7);
+ printf(" ");
+ print_binless(r.rs2, 5);
+ printf(" ");
+ print_binless(r.rs1, 5);
+ printf(" ");
+ print_binless(r.funct3, 3);
+ printf(" ");
+ print_binless(r.rd, 5);
+ printf("\n");
+
+ /* */
+
+ switch(r.funct3) {
+ case 0x0:
+ printf("HI\n\n");
+ switch(r.funct7) {
+ case 0x00:
+ printf("ADD\n");
+ printf("rs1:%d\nrs2:%d\nrd:%d\n",cpu->x[r.rs1],cpu->x[r.rs2],cpu->x[r.rd]);
+
+ int x = cpu->x[r.rs1]+cpu->x[r.rs2];
+
+ printf("%d\n", x);
+
+ if (r.rd != 0) {
+ cpu->x[r.rd] = x;
+ }
+
+ printf("rd:%d\n", cpu->x[r.rd]);
+
+ break;
+ case 0x20:
+ printf("SUB\n");
+ printf("rs1:%d\nrs2:%d\nrd:%d\n",cpu->x[r.rs1],cpu->x[r.rs2],cpu->x[r.rd]);
+
+ x = cpu->x[r.rs1]-cpu->x[r.rs2];
+
+ if (r.rd != 0) {
+ cpu->x[r.rd] = x;
+ }
+
+ printf("rd:%d\n", cpu->x[r.rd]);
+ break;
+ }
+ break;
+ case 0x4:
+ printf("XOR\n");
+ break;
+ case 0x6:
+ printf("OR\n");
+ break;
+ case 0x7:
+ printf("AND\n");
+ printf("rs1:%d\nrs2:%d\nrd:%d",cpu->x[r.rs1],cpu->x[r.rs2],cpu->x[r.rd]);
+
+ int x = r.rs1&r.rs2;
+ printf("%d\n", x);
+ break;
+ }
+}
+
+int main() {
+
+ /* function pointer dispatch */
+ typedef void (*exec_fn)(cpu_state_t *, uint32_t inst);
+ static exec_fn opcode_table[128];
+ opcode_table[0x33] = exec_op;
+ /*opcode_table[0x13] = exec_op_imm;
+ opcode_table[0x03] = exec_load;
+ opcode_table[0x23] = exec_store;
+ opcode_table[0x63] = exec_branch;
+ opcode_table[0x73] = exec_system;*/
+
+
+ /*0000000111110000011100000110011*/
+ //uint32_t inst = 0x01F07033;
+ /*0000000111110000000000000110011*/
+ uint32_t inst = 0x01F00033;
+
+ // f7 rs2 rs1 f3 rd opcode
+ // 0000000 00001 00010 000 00000 0110011
+ inst = 0x00110033;
+
+ // f7 rs2 rs1 f3 rd opcode
+ // 0100000 00001 00010 000 00011 0110011
+ //inst = 0x401101B3;
+
+ print_bin32(inst);
+ printf("\n");
+
+ /* decode instruction */
+ uint16_t opcode = inst & 127;
+ printf("opcode:");
+ printf("\n");
+ print_bin16(opcode);
+ printf("\n");
+
+ exec_fn fn = opcode_table[opcode];
+ cpu_state_t cpu;
+ cpu.x[1] = 5;
+ cpu.x[2] = 14;
+
+
+ if (!fn) {
+ //illegal(NULL, inst);
+ fprintf(stderr, "Illegal opcode\n");
+ return EXIT_FAILURE;
+ }
+
+ fn(&cpu,inst);
+
+ return 0;
+}