commit - b7739ce0610723e174431f433a6335f33dec04d9
commit + 5c19b3855c296bea828f9a37a10af99a2c39d54f
blob - 961761d22ce8fd4748b57645c841b5e25eaefceb
blob + 13211d74922c5f7de1a85008c82b8d5d6fd7b254
--- rvvm/rvhandler.c
+++ rvvm/rvhandler.c
#include <stdint.h>
#include <stdio.h>
+#include "rvhart.h"
#include "rvhandler.h"
void
-exec_addi(struct rv_hart *h, struct rv_instr i)
+exec_addi(struct rv_hart *h, struct rv_ram *m, struct rv_instr i)
{
+ (void)m;
h->rfile[i.rd] = h->rfile[i.rs1] + i.imm;
}
void
-exec_andi(struct rv_hart *h, struct rv_instr i)
+exec_andi(struct rv_hart *h, struct rv_ram *m, struct rv_instr i)
{
+ (void)m;
h->rfile[i.rd] = h->rfile[i.rs1] & i.imm;
}
void
-exec_ori(struct rv_hart *h, struct rv_instr i)
+exec_ori(struct rv_hart *h, struct rv_ram *m, struct rv_instr i)
{
+ (void)m;
h->rfile[i.rd] = h->rfile[i.rs1] | i.imm;
}
void
-exec_xori(struct rv_hart *h, struct rv_instr i)
+exec_xori(struct rv_hart *h, struct rv_ram *m, struct rv_instr i)
{
+ (void)m;
h->rfile[i.rd] = h->rfile[i.rs1] ^ i.imm;
}
void
-exec_add(struct rv_hart *h, struct rv_instr i)
+exec_add(struct rv_hart *h, struct rv_ram *m, struct rv_instr i)
{
+ (void)m;
h->rfile[i.rd] = h->rfile[i.rs1] + h->rfile[i.rs2];
}
void
-exec_sub(struct rv_hart *h, struct rv_instr i)
+exec_sub(struct rv_hart *h, struct rv_ram *m, struct rv_instr i)
{
+ (void)m;
h->rfile[i.rd] = h->rfile[i.rs1] - h->rfile[i.rs2];
}
void
-exec_and(struct rv_hart *h, struct rv_instr i)
+exec_and(struct rv_hart *h, struct rv_ram *m, struct rv_instr i)
{
+ (void)m;
h->rfile[i.rd] = h->rfile[i.rs1] & h->rfile[i.rs2];
}
void
-exec_addiw(struct rv_hart *h, struct rv_instr i)
+exec_addiw(struct rv_hart *h, struct rv_ram *m, struct rv_instr i)
{
+ (void)m;
int32_t r;
r = (int32_t)h->rfile[i.rs1] + (int32_t)i.imm;
}
void
-exec_addw(struct rv_hart *h, struct rv_instr i)
+exec_addw(struct rv_hart *h, struct rv_ram *m, struct rv_instr i)
{
+ (void)m;
int32_t r;
r = (int32_t)h->rfile[i.rs1] + (int32_t)h->rfile[i.rs2];
}
void
-exec_beq(struct rv_hart *h, struct rv_instr i)
+exec_beq(struct rv_hart *h, struct rv_ram *m, struct rv_instr i)
{
+ (void)m;
if (h->rfile[i.rs1] == h->rfile[i.rs2])
h->next_pc = h->pc + i.imm;
}
void
-exec_bnq(struct rv_hart *h, struct rv_instr i)
+exec_bnq(struct rv_hart *h, struct rv_ram *m, struct rv_instr i)
{
+ (void)m;
if (h->rfile[i.rs1] != h->rfile[i.rs2])
h->next_pc = h->pc + i.imm;
}
void
-exec_ld(struct rv_hart *h, struct rv_instr i)
+exec_ld(struct rv_hart *h, struct rv_ram *m, struct rv_instr i)
{
- (void)h; (void)i;
+ (void)m; (void)h; (void)i;
}
void
-exec_lw(struct rv_hart *h, struct rv_instr i)
+exec_lw(struct rv_hart *h, struct rv_ram *m, struct rv_instr i)
{
- (void)h; (void)i;
+ (void)m; (void)h; (void)i;
}
void
-exec_sd(struct rv_hart *h, struct rv_instr i)
+exec_sd(struct rv_hart *h, struct rv_ram *m, struct rv_instr i)
{
- (void)h; (void)i;
+ (void)m; (void)h; (void)i;
}
void
-exec_sw(struct rv_hart *h, struct rv_instr i)
+exec_sw(struct rv_hart *h, struct rv_ram *m, struct rv_instr i)
{
- (void)h; (void)i;
+ (void)m; (void)h; (void)i;
}
void
-exec_ecall(struct rv_hart *h, struct rv_instr i)
+exec_ecall(struct rv_hart *h, struct rv_ram *m, struct rv_instr i)
{
- (void)h; (void)i;
+ (void)m; (void)h; (void)i;
}
+
+void exec_lui(struct rv_hart *h, struct rv_ram *m, struct rv_instr i) { (void)m; h->rfile[i.rd] = i.imm; }
+void exec_auipc(struct rv_hart *h, struct rv_ram *m, struct rv_instr i) { (void)m; h->rfile[i.rd] = h->pc + i.imm; }
+void exec_jal(struct rv_hart *h, struct rv_ram *m, struct rv_instr i) { (void)m; h->rfile[i.rd] = h->pc + 4; h->next_pc = h->pc + i.imm; }
+
+void exec_jalr(struct rv_hart *h, struct rv_ram *m, struct rv_instr i) {
+ (void)m;
+ uint64_t target = (h->rfile[i.rs1] + i.imm) & ~1ULL;
+ h->rfile[i.rd] = h->pc + 4;
+ h->next_pc = target;
+}
+
+void exec_bne(struct rv_hart *h, struct rv_ram *m, struct rv_instr i) {
+ (void)m;
+ if (h->rfile[i.rs1] != h->rfile[i.rs2]) h->next_pc = h->pc + i.imm;
+}
+
+void exec_xor(struct rv_hart *h, struct rv_ram *m, struct rv_instr i) { (void)m; h->rfile[i.rd] = h->rfile[i.rs1] ^ h->rfile[i.rs2]; }
+void exec_or(struct rv_hart *h, struct rv_ram *m, struct rv_instr i) { (void)m; h->rfile[i.rd] = h->rfile[i.rs1] | h->rfile[i.rs2]; }
+
+void exec_slli(struct rv_hart *h, struct rv_ram *m, struct rv_instr i) { (void)m; h->rfile[i.rd] = h->rfile[i.rs1] << (i.imm & 0x3F); }
+void exec_srli(struct rv_hart *h, struct rv_ram *m, struct rv_instr i) { (void)m; h->rfile[i.rd] = h->rfile[i.rs1] >> (i.imm & 0x3F); }
+void exec_srai(struct rv_hart *h, struct rv_ram *m, struct rv_instr i) {
+ (void)m;
+ h->rfile[i.rd] = (int64_t)h->rfile[i.rs1] >> (i.imm & 0x3F);
+}
+
+const rv_handler rv_handler_lookup_table[512] = {
+ [RV_IDX(0, 0x13, 0x0)] = exec_addi,
+ [RV_IDX(0, 0x13, 0x4)] = exec_xori,
+ [RV_IDX(0, 0x13, 0x6)] = exec_ori,
+ [RV_IDX(0, 0x13, 0x7)] = exec_andi,
+ [RV_IDX(0, 0x13, 0x1)] = exec_slli,
+ [RV_IDX(0, 0x13, 0x5)] = exec_srli,
+ [RV_IDX(1, 0x13, 0x5)] = exec_srai,
+
+ [RV_IDX(0, 0x33, 0x0)] = exec_add,
+ [RV_IDX(1, 0x33, 0x0)] = exec_sub,
+ [RV_IDX(0, 0x33, 0x7)] = exec_and,
+ [RV_IDX(0, 0x33, 0x6)] = exec_or,
+ [RV_IDX(0, 0x33, 0x4)] = exec_xor,
+
+ [RV_IDX(0, 0x63, 0x0)] = exec_beq,
+ [RV_IDX(0, 0x63, 0x1)] = exec_bne,
+
+ [RV_IDX(0, 0x03, 0x3)] = exec_ld,
+ [RV_IDX(0, 0x23, 0x3)] = exec_sd,
+
+ [RV_IDX(0, 0x37, 0x0)] = exec_lui,
+ [RV_IDX(0, 0x17, 0x0)] = exec_auipc,
+ [RV_IDX(0, 0x6f, 0x0)] = exec_jal,
+ [RV_IDX(0, 0x67, 0x0)] = exec_jalr,
+};
blob - 11683da307fb8ee7a22722c04b0658b12abed16b
blob + 9cb884469fb1bc6e9fddad00e207fe9ff9c80813
--- rvvm/rvhandler.h
+++ rvvm/rvhandler.h
#ifndef _RVHANDLER_H_
#define _RVHANDLER_H_
+#include "rvhart.h"
+#include "rvram.h"
+
typedef void (*rv_handler)(struct rv_hart *h, struct rv_ram *m, struct rv_instr i);
#define RV_IDX(funct7_bit, opcode, funct3) ((((uint16_t)(funct7_bit)) << 8) | (((opcode) >> 2) << 3) | (funct3))
-void exec_addi(struct rv_hart *h, struct rv_instr i);
-void exec_xori(struct rv_hart *h, struct rv_instr i);
-void exec_ori(struct rv_hart *h, struct rv_instr i);
-void exec_andi(struct rv_hart *h, struct rv_instr i);
-void exec_slli(struct rv_hart *h, struct rv_instr i);
-void exec_srli(struct rv_hart *h, struct rv_instr i);
-void exec_srai(struct rv_hart *h, struct rv_instr i);
+void exec_addi(struct rv_hart *h, struct rv_ram *m, struct rv_instr i);
+void exec_xori(struct rv_hart *h, struct rv_ram *m, struct rv_instr i);
+void exec_ori(struct rv_hart *h, struct rv_ram *m, struct rv_instr i);
+void exec_andi(struct rv_hart *h, struct rv_ram *m, struct rv_instr i);
+void exec_slli(struct rv_hart *h, struct rv_ram *m, struct rv_instr i);
+void exec_srli(struct rv_hart *h, struct rv_ram *m, struct rv_instr i);
+void exec_srai(struct rv_hart *h, struct rv_ram *m, struct rv_instr i);
-void exec_add(struct rv_hart *h, struct rv_instr i);
-void exec_sub(struct rv_hart *h, struct rv_instr i);
-void exec_and(struct rv_hart *h, struct rv_instr i);
-void exec_or(struct rv_hart *h, struct rv_instr i);
-void exec_xor(struct rv_hart *h, struct rv_instr i);
+void exec_add(struct rv_hart *h, struct rv_ram *m, struct rv_instr i);
+void exec_sub(struct rv_hart *h, struct rv_ram *m, struct rv_instr i);
+void exec_and(struct rv_hart *h, struct rv_ram *m, struct rv_instr i);
+void exec_or(struct rv_hart *h, struct rv_ram *m, struct rv_instr i);
+void exec_xor(struct rv_hart *h, struct rv_ram *m, struct rv_instr i);
-void exec_beq(struct rv_hart *h, struct rv_instr i);
-void exec_bne(struct rv_hart *h, struct rv_instr i);
+void exec_beq(struct rv_hart *h, struct rv_ram *m, struct rv_instr i);
+void exec_bne(struct rv_hart *h, struct rv_ram *m, struct rv_instr i);
-void exec_ld(struct rv_hart *h, struct rv_instr i);
-void exec_sd(struct rv_hart *h, struct rv_instr i);
+void exec_ld(struct rv_hart *h, struct rv_ram *m, struct rv_instr i);
+void exec_sd(struct rv_hart *h, struct rv_ram *m, struct rv_instr i);
-void exec_lui(struct rv_hart *h, struct rv_instr i);
-void exec_auipc(struct rv_hart *h, struct rv_instr i);
-void exec_jal(struct rv_hart *h, struct rv_instr i);
-void exec_jalr(struct rv_hart *h, struct rv_instr i);
+void exec_lui(struct rv_hart *h, struct rv_ram *m, struct rv_instr i);
+void exec_auipc(struct rv_hart *h, struct rv_ram *m, struct rv_instr i);
+void exec_jal(struct rv_hart *h, struct rv_ram *m, struct rv_instr i);
+void exec_jalr(struct rv_hart *h, struct rv_ram *m, struct rv_instr i);
-static const rv_handler rv_handler_lookup_table[512] = {
- [RV_IDX(0, 0x13, 0x0)] = exec_addi,
- [RV_IDX(0, 0x13, 0x4)] = exec_xori,
- [RV_IDX(0, 0x13, 0x6)] = exec_ori,
- [RV_IDX(0, 0x13, 0x7)] = exec_andi,
- [RV_IDX(0, 0x13, 0x1)] = exec_slli,
- [RV_IDX(0, 0x13, 0x5)] = exec_srli,
- [RV_IDX(1, 0x13, 0x5)] = exec_srai,
-
- [RV_IDX(0, 0x33, 0x0)] = exec_add,
- [RV_IDX(1, 0x33, 0x0)] = exec_sub,
- [RV_IDX(0, 0x33, 0x7)] = exec_and,
- [RV_IDX(0, 0x33, 0x6)] = exec_or,
- [RV_IDX(0, 0x33, 0x4)] = exec_xor,
-
- [RV_IDX(0, 0x63, 0x0)] = exec_beq,
- [RV_IDX(0, 0x63, 0x1)] = exec_bne,
-
- [RV_IDX(0, 0x03, 0x3)] = exec_ld,
- [RV_IDX(0, 0x23, 0x3)] = exec_sd,
-
- [RV_IDX(0, 0x37, 0x0)] = exec_lui,
- [RV_IDX(0, 0x17, 0x0)] = exec_auipc,
- [RV_IDX(0, 0x6f, 0x0)] = exec_jal,
- [RV_IDX(0, 0x67, 0x0)] = exec_jalr,
-};
+extern const rv_handler rv_handler_lookup_table[512];
#endif
blob - 51a56ec2de32959b9d7afa52c129b70dc937538b
blob + af7e3c0f80d9c5a2f936c884b6916daaca484060
--- rvvm/rvhart.c
+++ rvvm/rvhart.c
funct7_bit = (i.funct7 >> 5) & 0x1;
idx = (funct7_bit << 8) | ((i.opcode >> 2) << 3) | i.funct3;
- handler = jump_table[idx];
+ handler = rv_handler_lookup_table[idx];
h->next_pc = h->pc + RV_STEP_SIZE;
- if (rv_handler_lookup_table[idx])
- rv_handler_lookup_table[idx](h, i);
+ if (handler)
+ handler(h, m, i);
else
errx(1, "rv_execute(): unknown instruction: op=0x%x, funct3=0x%x", i.opcode, i.funct3);