添加基础指令解析和运行
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;\
|
_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);
|
||||||
|
}
|
||||||
|
7
make.py
7
make.py
@@ -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
37
make_riscv.py
Normal 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
10
riscv/main.c
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
int a=1;
|
||||||
|
int b=2;
|
||||||
|
int c=a+b;
|
||||||
|
return c;
|
||||||
|
}
|
Reference in New Issue
Block a user