添加基础指令解析和运行

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;\ _imm |= (_ins >> 25) << 5;\
} }
#define imm_csr(_ins,_imm) {\
_imm = (_ins >> 20) & 0xfff;\
}
// 解析指令 // 解析指令
int riscv_decode(riscv_t* riscv, uint32_t ins) { 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); ins_jalr(riscv, rs1, imm, rd);
break; break;
case opcode_beq: 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) { 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->rom_addr_base = rom_addr_base;
riscv->pc = 0; 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);
}

View File

@@ -23,9 +23,9 @@ CC = 'gcc'
# HEX = 'C:\\ARM_GCC\\bin\\arm-none-eabi-objcopy' + ' -O ihex' # HEX = 'C:\\ARM_GCC\\bin\\arm-none-eabi-objcopy' + ' -O ihex'
# BIN = 'C:\\ARM_GCC\\bin\\arm-none-eabi-objcopy' + ' -O binary -S' # BIN = 'C:\\ARM_GCC\\bin\\arm-none-eabi-objcopy' + ' -O binary -S'
CSRC = [] CSRC = ["main.c"]
CINC = ['-Isoft'] CINC = ['-Isoft',"-Icpu"]
CDEF = ["-DTEST","-DLINUX"] CDEF = ["-DTEST","-DLINUX"]
@@ -184,7 +184,8 @@ def build_target(src:list[str]):
def main(): def main():
global CSRC global CSRC
global ASRC global ASRC
CSRC+=find_type('.\\',['c','C']) CSRC+=find_type('.\\soft',['c','C'])
CSRC+=find_type('.\\cpu',['c','C'])
# ASRC+=find_type('./',['s','S','asm','ASM']) # ASRC+=find_type('./',['s','S','asm','ASM'])
if(not os.path.exists(BUILD_DIR)): if(not os.path.exists(BUILD_DIR)):

37
make_riscv.py Normal file
View File

@@ -0,0 +1,37 @@
import os
import sys
import time
CC="riscv64-unknown-elf-gcc"
OBJ="riscv64-unknown-elf-objcopy"
CFLAG=[
"-march=rv32i",
"-mabi=ilp32",
"-ffunction-sections",
"-fdata-sections",
"-ffast-math",
"-fno-common",
"-fno-builtin-printf",
"-Wall",
"-Werror",
"-g",
"-Os",
"-fno-omit-frame-pointer",
"-msave-restore"
]
SRC=[
"riscv/main.c"
]
TARGET="riscv"
if __name__ == "__main__":
os.system(f"{CC} {' '.join(CFLAG)} {' '.join(SRC)} -o {TARGET}.elf")
os.system(f"{OBJ} -O binary {TARGET}.elf {TARGET}.bin")

10
riscv/main.c Normal file
View File

@@ -0,0 +1,10 @@
int main()
{
int a=1;
int b=2;
int c=a+b;
return c;
}