添加基础指令解析和运行

This commit is contained in:
2025-04-17 00:04:59 +08:00
parent 5aec6bced8
commit be8c08f176
4 changed files with 288 additions and 4 deletions

View File

@@ -457,6 +457,9 @@ void ins_xori(riscv_t* riscv, int rs1, int imm, int rd) {
_imm |= (_ins >> 25) << 5;\
}
#define imm_csr(_ins,_imm) {\
_imm = (_ins >> 20) & 0xfff;\
}
// 解析指令
int riscv_decode(riscv_t* riscv, uint32_t ins) {
@@ -488,8 +491,179 @@ int riscv_decode(riscv_t* riscv, uint32_t ins) {
ins_jalr(riscv, rs1, imm, rd);
break;
case opcode_beq:
imm_b_type(ins, imm);
switch(funct3) {
case 0x0:
ins_beq(riscv, rs2, rs1, imm);
break;
case 0x1:
ins_bne(riscv, rs2, rs1, imm);
break;
case 0x4:
ins_blt(riscv, rs2, rs1, imm);
break;
case 0x5:
ins_bge(riscv, rs2, rs1, imm);
break;
case 0x6:
ins_bltu(riscv, rs2, rs1, imm);
break;
case 0x7:
ins_bgeu(riscv, rs2, rs1, imm);
break;
default:
break;
}
break;
case opcode_lb:
imm_i_type(imm, ins);
switch (funct3)
{
case 0x0:
ins_lb(riscv, rs1, imm, rd);
break;
case 0x1:
ins_lh(riscv, rs1, imm, rd);
break;
case 0x2:
ins_lw(riscv, rs1, imm, rd);
break;
case 0x4:
ins_lbu(riscv, rs1, imm, rd);
break;
case 0x5:
ins_lhu(riscv, rs1, imm, rd);
break;
default:
break;
}
break;
case opcode_sb:
switch(funct3){
case 0x0:
ins_sb(riscv, rs2, rs1, imm);
break;
case 0x1:
ins_sh(riscv, rs2, rs1, imm);
break;
case 0x2:
ins_sw(riscv, rs2, rs1, imm);
break;
default:
break;
}
break;
case opcode_addi:
imm_i_type(ins,imm);
switch (funct3)
{
case 0x0:
ins_addi(riscv, rs1, imm, rd);
break;
case 0x2:
ins_slti(riscv, rs1, imm, rd);
break;
case 0x3:
ins_sltiu(riscv, rs1, imm, rd);
break;
case 0x4:
ins_xori(riscv, rs1, imm, rd);
break;
case 0x6:
ins_ori(riscv, rs1, imm, rd);
break;
case 0x7:
ins_andi(riscv, rs1, imm, rd);
break;
case 0x1:
imm = imm&0x1f;
ins_slli(riscv, rs1, imm, rd);
break;
case 0x5:
imm = imm&0x1f;
if(funct7 == 0x20){
ins_srai(riscv, rs1, imm, rd);
}else{
ins_srli(riscv, rs1, imm, rd);
}
break;
default:
break;
}
break;
case opcode_add:
switch (funct3)
{
case 0x0:
if(funct7 == 0x20){
ins_sub(riscv, rs2, rs1, rd);
}else{
ins_add(riscv, rs2, rs1, rd);
}
break;
case 0x1:
ins_sll(riscv, rs2, rs1, rd);
break;
case 0x2:
ins_slt(riscv, rs2, rs1, rd);
break;
case 0x3:
ins_sltu(riscv, rs2, rs1, rd);
break;
case 0x4:
ins_xor(riscv, rs2, rs1, rd);
break;
case 0x5:
if (funct7 == 0x20) {
ins_sra(riscv, rs2, rs1, rd);
}else{
ins_srl(riscv, rs2, rs1, rd);
}
break;
case 0x6:
ins_or(riscv, rs2, rs1, rd);
break;
case 0x7:
ins_and(riscv, rs2, rs1, rd);
break;
default:
break;
}
break;
case opcode_ecall:
imm_csr(ins,imm);
switch (funct3)
{
case 0x0:
ins_ebreak(riscv);
break;
case 0x1:
ins_csrrw(riscv, rs1, rd, imm);
break;
case 0x2:
ins_csrrs(riscv, rs1, rd, imm);
break;
case 0x3:
ins_csrrc(riscv, rs1, rd, imm);
break;
case 0x5:
// rs1 保存的是zimm 值
ins_csrrwi(riscv, rs1, rd, imm);
break;
case 0x6:
ins_csrrsi(riscv, rs1, rd, imm);
break;
case 0x7:
ins_csrrci(riscv, rs1, rd, imm);
break;
default:
break;
}
break;
default:
break;
}
return 0;
}
int riscv_init(riscv_t* riscv, uint32_t* rom, uint32_t rom_addr_base, uint32_t rom_size) {
@@ -498,3 +672,65 @@ int riscv_init(riscv_t* riscv, uint32_t* rom, uint32_t rom_addr_base, uint32_t r
riscv->rom_addr_base = rom_addr_base;
riscv->pc = 0;
}
int riscv_run(riscv_t* riscv) {
int ret = 0;
while(1) {
uint32_t instr = riscv->rom[riscv->pc >> 2];
riscv->pc += 4;
if(riscv->pc >= riscv->rom_addr_base + riscv->rom_size){
printf("riscv run out of rom");
break;
}
ret=riscv_decode(riscv, instr);
if(ret){
break;
}
}
printf("riscv run end\n");
}
#include "stdio.h"
#include "stdlib.h"
#include "errno.h"
long get_file_size(FILE *stream)
{
long file_size = -1;
long cur_offset = ftell(stream); // 获取当前偏移位置
if (cur_offset == -1) {
printf("ftell failed :%s\n", strerror(errno));
return -1;
}
if (fseek(stream, 0, SEEK_END) != 0) { // 移动文件指针到文件末尾
printf("fseek failed: %s\n", strerror(errno));
return -1;
}
file_size = ftell(stream); // 获取此时偏移值,即文件大小
if (file_size == -1) {
printf("ftell failed :%s\n", strerror(errno));
}
if (fseek(stream, cur_offset, SEEK_SET) != 0) { // 将文件指针恢复初始位置
printf("fseek failed: %s\n", strerror(errno));
return -1;
}
return file_size;
}
int thread_fun(void* t)
{
riscv_t riscv={0};
FILE *file=fopen("riscv.bin", "rb" );
if(file==NULL)
{
printf("open file error\n");
return -1;
}
riscv.rom_size=get_file_size(file);
riscv.rom=calloc((riscv.rom_size+3)/4,4);
fread(riscv.rom, 1, riscv.rom_size, file);
fclose(file);
riscv_init(&riscv,riscv.rom,0x80000000,riscv.rom_size);
}