feat add func call and rewrite codes
This commit is contained in:
139
test_rv_vm/ripes-vm.c
Normal file
139
test_rv_vm/ripes-vm.c
Normal file
@@ -0,0 +1,139 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
struct MiniRV32IMAState;
|
||||
void ecall_handler(struct MiniRV32IMAState *state);
|
||||
#define ECALL_HANDLER(state) ecall_handler(state)
|
||||
#define MINIRV32WARN( x... ) printf( x );
|
||||
#define MINIRV32_DECORATE static
|
||||
#define MINI_RV32_RAM_SIZE (32 * 1024 * 1024)
|
||||
#define MINIRV32_IMPLEMENTATION
|
||||
|
||||
#define MINIRV32_RAM_IMAGE_OFFSET 0x0
|
||||
#include "mini-rv32ima.h"
|
||||
|
||||
#define SYSCALL(num) (1025 + num)
|
||||
void ecall_handler(struct MiniRV32IMAState *state) {
|
||||
uint32_t a0 = REG(10);
|
||||
uint32_t a1 = REG(11);
|
||||
switch (state->regs[17]) // x17 | a7
|
||||
{
|
||||
case 1:
|
||||
// PrintInt
|
||||
printf("%d", a0);
|
||||
break;
|
||||
case 4:
|
||||
// PrintString
|
||||
printf("%s", a0);
|
||||
break;
|
||||
case 10:
|
||||
fprintf(stderr, "\nexit: %d\n", a0);
|
||||
exit(a0);
|
||||
case 93:
|
||||
fprintf(stderr, "\nmain return code: %d\n", a0);
|
||||
exit(a0);
|
||||
case SYSCALL(0):
|
||||
// getchar();
|
||||
REGSET(10, getchar());
|
||||
case SYSCALL(1):
|
||||
// putchar
|
||||
putchar(a0);
|
||||
|
||||
case SYSCALL(4):
|
||||
// input int
|
||||
scanf("%d", &a0);
|
||||
REGSET(10, a0);
|
||||
break;
|
||||
case SYSCALL(5):
|
||||
// input string
|
||||
scanf("%s", a0);
|
||||
REGSET(10, a0);
|
||||
break;
|
||||
default:
|
||||
MINIRV32WARN("Unhandled ECALL: %d\n", state->regs[17]);
|
||||
exit(1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
// gcc -DDEFAULT_FILE='\"flat.bin\"' .\ripes-vm.c -o rv32-vm.exe
|
||||
struct MiniRV32IMAState state;
|
||||
uint8_t *image = (uint8_t *)malloc(MINI_RV32_RAM_SIZE);
|
||||
|
||||
// 初始化状态
|
||||
memset(&state, 0, sizeof(state));
|
||||
state.pc = 0; // 程序计数器从0开始
|
||||
state.mstatus = 0x80000000; // 设置机器模式
|
||||
state.mtvec = 0x1000;
|
||||
state.mie = 0x7; // 启用所有中断
|
||||
|
||||
// 初始化内存
|
||||
memset(image, 0, MINI_RV32_RAM_SIZE);
|
||||
|
||||
#ifndef DEFAULT_FILE
|
||||
#define DEFAULT_FILE "../ccompiler/backend/test_rv.bin"
|
||||
#endif
|
||||
const char* filename = DEFAULT_FILE;
|
||||
// 加载 flatbin 文件
|
||||
if (argc == 2) {
|
||||
filename = argv[1];
|
||||
}
|
||||
|
||||
FILE *file = fopen(filename, "rb");
|
||||
if (!file) {
|
||||
fprintf(stderr, "Usage: %s <flatbin_file>\n", argv[0]);
|
||||
printf("Failed to open file %s\n", filename);
|
||||
return 1;
|
||||
}
|
||||
|
||||
fseek(file, 0, SEEK_END);
|
||||
long flen = ftell(file);
|
||||
fseek(file, 0, SEEK_SET);
|
||||
|
||||
if (flen > MINI_RV32_RAM_SIZE) {
|
||||
fprintf(stderr, "Flatbin file is too large\n");
|
||||
fclose(file);
|
||||
return 1;
|
||||
}
|
||||
|
||||
fread(image, flen, 1, file);
|
||||
fclose(file);
|
||||
|
||||
// 运行模拟器
|
||||
while (1) {
|
||||
int32_t ret = MiniRV32IMAStep(&state, image, MINIRV32_RAM_IMAGE_OFFSET, 0, 1);
|
||||
if (ret != 0) {
|
||||
printf("Exception or interrupt occurred at PC: %d\n", state.pc);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
free(image);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// static void DumpState( struct MiniRV32IMAState * core, uint8_t * ram_image )
|
||||
// {
|
||||
// uint32_t pc = core->pc;
|
||||
// uint32_t pc_offset = pc - MINIRV32_RAM_IMAGE_OFFSET;
|
||||
// uint32_t ir = 0;
|
||||
|
||||
// printf( "PC: %08x ", pc );
|
||||
// if( pc_offset >= 0 && pc_offset < ram_amt - 3 )
|
||||
// {
|
||||
// ir = *((uint32_t*)(&((uint8_t*)ram_image)[pc_offset]));
|
||||
// printf( "[0x%08x] ", ir );
|
||||
// }
|
||||
// else
|
||||
// printf( "[xxxxxxxxxx] " );
|
||||
// uint32_t * regs = core->regs;
|
||||
// printf( "Z:%08x ra:%08x sp:%08x gp:%08x tp:%08x t0:%08x t1:%08x t2:%08x s0:%08x s1:%08x a0:%08x a1:%08x a2:%08x a3:%08x a4:%08x a5:%08x ",
|
||||
// regs[0], regs[1], regs[2], regs[3], regs[4], regs[5], regs[6], regs[7],
|
||||
// regs[8], regs[9], regs[10], regs[11], regs[12], regs[13], regs[14], regs[15] );
|
||||
// printf( "a6:%08x a7:%08x s2:%08x s3:%08x s4:%08x s5:%08x s6:%08x s7:%08x s8:%08x s9:%08x s10:%08x s11:%08x t3:%08x t4:%08x t5:%08x t6:%08x\n",
|
||||
// regs[16], regs[17], regs[18], regs[19], regs[20], regs[21], regs[22], regs[23],
|
||||
// regs[24], regs[25], regs[26], regs[27], regs[28], regs[29], regs[30], regs[31] );
|
||||
// }
|
||||
Reference in New Issue
Block a user