添加基础指令解析和运行
This commit is contained in:
238
cpu/riscv.c
238
cpu/riscv.c
@@ -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);
|
||||
}
|
||||
|
Reference in New Issue
Block a user