Commit Diff


commit - 1029a1177da1c59d6d27ba7c5dd653202c0ce313
commit + c8a2c51f80c364d04ff8b86b55c8fa0444ab1391
blob - /dev/null
blob + dd689e20d4964ff3c5f13cea619551d57872c0e8 (mode 644)
--- /dev/null
+++ rvvm/rvhart.c
@@ -0,0 +1,86 @@
+#include <err.h>
+#include <stdint.h>
+
+#include "rvhart.h"
+#include "rvram.h"
+
+struct rv_instr
+rv_decode(uint32_t word)
+{
+	struct rv_instr	i;
+
+	i		= {0};
+	i.opcode	= word & 0x7f;
+	i.rd		= (word >> 7) & 0x1f;
+	i.rs1		= (word >> 15) & 0x1f;
+	i.rs2		= (word >> 20) & 0x1f;
+	i.funct3	= (word >> 12) & 0x7;
+	i.funct7	= (word >> 25) & 0x7f;
+	
+	switch (i.opcode) {
+	case 0x33:
+		i.fmt	= R_FMT;
+		break;
+	case 0x13:
+	case 0x03:
+	case 0x67:
+	case 0x73:
+		i.fmt	= I_FMT;
+		i.imm	= SE(word >> 20, 12);
+		break;
+	case 0x23:
+		i.fmt	= S_FMT;
+		i.imm	= SE((((word >> 25) & 0x7f) << 5) | ((word >> 7) & 0x1f), 12);
+		break;
+	case 0x63:
+		i.fmt	= B_FMT;
+		i.imm	= SE(((word & 0x80000000) >> 19) |
+				((word & 0x00000080) << 4) |
+				((word & 0x7e000000) >> 20) |
+				((word & 0x00000f00) >> 7),
+				13);
+		break;
+	case 0x37:
+	case 0x17:
+		i.fmt	= U_FMT;
+		i.imm	= SE(word >> 12, 20) << 12;
+		break;
+	case 0x6f:
+		i.fmt	= J_FMT;
+		i.imm	= SE(((word & 0x80000000) >> 11) |
+				(word & 0x000ff000) |
+				((word & 0x00100000) >> 9) |
+				((word & 0x7fe00000) >> 20),
+				21);
+		break;
+	default:
+		err(1, "rv_decode(): unknown opcode %x", i.opcode);
+	}
+	
+	return (i);
+}
+
+void
+rv_execute(struct rv_hart *h, struct rv_ram *m, struct rv_instr i)
+{
+	uint64_t 	next_pc = h->pc + RV_STEP_SIZE;
+
+	switch (i.opcode) {
+		// TODO: Implement execution logic.
+	default:
+		err(1, "rv_execute(): unknown opcode %x", i.opcode);
+	}
+	
+	h->rfile[0]	= 0;
+	h->pc		= next_pc;
+}
+
+void
+rv_step(struct rv_hart *h, struct rv_ram *m) {
+	uint32_t	word;
+	struct rv_instr	i;
+	
+	word	= (uint32_t)rv_ram_read(m, h->pc);
+	i 	= rv_decode(word);
+	rv_execute(h, i);
+}
blob - /dev/null
blob + dc3aee9e339cb3ba5f080fc76655ebe2ce253379 (mode 644)
--- /dev/null
+++ rvvm/rvhart.h
@@ -0,0 +1,41 @@
+#ifndef _RVHART_H_
+#define _RVHART_H_
+
+#include <stdint.h>
+
+#include "rvram.h"
+
+#define RV_RFILE_SIZE	32
+#define RV_STEP_SIZE	4
+
+#define SE(val, bits) (((int64_t)(val) << (64 - (bits))) >> (64 - (bits)))
+
+enum rv_instrfmt {
+	R_FMT,
+	I_FMT,
+	S_FMT,
+	B_FMT,
+	U_FMT,
+	J_FMT
+};
+
+struct rv_instr {
+	enum rv_instrfmt	fmt;
+	uint8_t			opcode;
+	uint8_t			rd;
+	uint8_t			rs1;
+	uint8_t			rs2;
+	uint8_t			funct3;
+	uint8_t			funct7;
+	int64_t			imm;
+};
+
+struct rv_hart {
+	uint64_t pc;
+	uint64_t rfile[RV_RFILE_SIZE];
+};
+
+struct rv_instr	rv_decode(uint32_t word);
+void		rv_execute(struct rv_hart *h, struct rv_ram *m, struct rv_instr i);
+void		rv_step(struct rv_hart *h, struct rv_ram *m);
+#endif