#include #include #include #include #include #include #include #include #include #include #include #include "asm.h" #include "cpu.h" #include "log.h" #include "mem.h" #include "opc.h" bool is_debug = false; size_t mem_size = 64 * 1024 * 1024; size_t reg_size = 0; static void usage(int rc) { fprintf(stderr, "Usage: risci [-dhi] \n"); exit(rc); } static void dump_registers(void) { fprintf(stderr, "REGISTER DUMP:\n"); for (size_t i = 0; i < reg_size; i++) fprintf(stderr, "\tr%zu = %"PRIu32"\n", i, GPR[i]); } static void read_program(const char *program) { struct stat sb; if (lstat(program, &sb) == -1) pdie("cannot stat program"); if (sb.st_size % 4) die("program does not align to op-code size of 4 bytes"); int pfd; if ((pfd = open(program, O_RDONLY)) == -1) pdie("could not open program"); /* initialize register file */ assert(read(pfd, ®_size, 4) == 4); reg_size += 4; GPR = calloc(reg_size, 4); /* initialize pseudo registers */ BP = reg_size - 3; SP = reg_size - 2; RV = reg_size - 1; GPR[BP] = GPR[SP] = mem_size; GPR[RV] = 0; assert(read(pfd, MEM, sb.st_size - 4) == sb.st_size - 4); memset(MEM + sb.st_size + 4, 0xFF, 4); } static uint32_t next_instruction(void) { uint32_t tmp; memcpy(&tmp, &MEM[IP], 4); return tmp; } int main(int argc, char *argv[]) { int ch; while ((ch = getopt(argc, argv, "dhm")) != -1) { switch (ch) { case 'd': is_debug = true; break; case 'h': usage(EXIT_SUCCESS); case 'm': mem_size = atoi(optarg) * 4; break; case '?': default: usage(EXIT_FAILURE); } } argc -= optind; argv += optind; /* reserve memory */ MEM = calloc(mem_size, sizeof(char)); /* load program from file */ if (argc < 1) usage(EXIT_FAILURE); read_program(argv[0]); /* reset program counter to first instruction */ IP = 0; /* start instruction loop */ while (1) { //dump_registers(); execute(next_instruction()); } /* not reached, program is terminated by signal traps from the cpu */ }