compiler

Unnamed Compiled Systems Language Project
git clone http://frotz.net/git/compiler.git
Log | Files | Refs

r5e.c (2442B)


      1 #include <stdio.h>
      2 #include <unistd.h>
      3 #include <fcntl.h>
      4 #include <string.h>
      5 
      6 #include "risc5emu.h"
      7 
      8 int main(int argc, char** argv) {
      9 	bool trace = false;
     10 	bool no_cycle_limit = false;
     11 	const char* fn = NULL;
     12 	int args = 0;
     13 
     14 	while (argc > 1) {
     15 		if (!strcmp(argv[1], "--")) {
     16 			args = argc - 2;
     17 			argv += 2;
     18 			break;
     19 		} else if (!strcmp(argv[1], "-n")) {
     20 			no_cycle_limit = true;
     21 		} else if (!strcmp(argv[1], "-t")) {
     22 			trace = true;
     23 		} else if (argv[1][0] == '-') {
     24 			fprintf(stderr, "r5e: unknown option: %s\n", argv[1]);
     25 			return -1;
     26 		} else {
     27 			if (fn != NULL) {
     28 				fprintf(stderr, "r5e: multiple images not supported\n");
     29 				return -1;
     30 			}
     31 			fn = argv[1];
     32 		}
     33 		argc--;
     34 		argv++;
     35 	}
     36 
     37 	if (fn == NULL) {
     38 		fprintf(stderr,
     39 "usage: r5e <options>* <binary> [ -- <arg>* ]\n"
     40 "\n"
     41 "options:   -n    no cycle limit (run forever)\n"
     42 "           -t    trace execution\n"
     43 "\n"
     44 "args:      passed on to emulated program\n"
     45 );
     46 		return -1;
     47 	}
     48 
     49 	risc_t *r = risc_new(false);
     50 
     51 	// load image
     52 	int fd = open(fn, O_RDONLY);
     53 	if (fd < 0) {
     54 		fprintf(stderr, "r5e: cannot open: %s\n", fn);
     55 		return -1;
     56 	}
     57 	unsigned n = 0;
     58 	uint32_t w;
     59 	while (read(fd, &w, sizeof(w)) == 4) {
     60 		risc_store_word(r, n, w);
     61 		n += 4;
     62 	}
     63 
     64 	// setup entry environment
     65 	uint32_t sp = 0x100000;
     66 
     67 	// exit shim
     68 	sp -= 16;
     69 	uint32_t lr = sp;
     70 	risc_store_word(r, lr+0, 0x51000000); // mov r1, 0xffff0000
     71 	risc_store_word(r, lr+4, 0xa0100100); // stw r0, [r1, 256]
     72 	risc_store_word(r, lr+8, 0xe7ffffff); // b .
     73 	// point LR at shim
     74 	risc_set_register(r, 15, lr);
     75 
     76 	// r0/r1 is an [][]byte of commandline args
     77 	uint32_t r0 = 0;
     78 	uint32_t r1 = 0;
     79 	if (args) {
     80 		sp -= args * 8;
     81 		uint32_t p = sp;
     82 		r0 = p;
     83 		r1 = args;
     84 		while (args > 0) {
     85 			fprintf(stderr, "E %s\n", argv[0]);
     86 			uint32_t n = strlen(argv[0]);
     87 			sp -= (n + 3) & (~3);
     88 			for (uint32_t i = 0; i < n; i++) {
     89 				risc_store_byte(r, sp + i, argv[0][i]);
     90 			}
     91 			risc_store_word(r, p+0, sp);
     92 			risc_store_word(r, p+4, n);
     93 			p += 8;
     94 			args--;
     95 			argv++;
     96 		}
     97 	}
     98 	risc_set_register(r, 0, r0);
     99 	risc_set_register(r, 1, r1);
    100 
    101 	// set SP
    102 	risc_set_register(r, 14, sp);
    103 
    104 	if (trace) {
    105 		risc_trace(r, true);
    106 		printf("                    SP = %08x\n", sp);
    107 		printf("                    LR = %08x (exit shim)\n", lr);
    108 		printf("                    R0 = %08x **argv\n", r0);
    109 		printf("                    R1 = %08x argc\n", r1);
    110 	}
    111 
    112 	do {
    113 		risc_run(r, 100000000);
    114 	} while (no_cycle_limit);
    115 
    116 	return 0;
    117 }