ack/util/int/main.c
George Koehler 777d0abb00 Add util/int/switch.h to declare do_instr() and Do???()
Use switch.h to reduce warnings from clang about implicit declarations
of functions.  I used `grep ... do_*.c | sed ... | sort`, and some
manual editing, to make the big list of Do???() functions.
2019-10-30 18:36:55 -04:00

216 lines
4.1 KiB
C

/*
Main loop
*/
/* $Id$ */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <setjmp.h>
#include <em_abs.h>
#include "e.out.h"
#include "logging.h"
#include "nofloat.h"
#include "global.h"
#include "log.h"
#include "io.h"
#include "trap.h"
#include "warn.h"
#include "text.h"
#include "read.h"
#include "opcode.h"
#include "m_sigtrp.h"
#include "rsb.h"
#include "switch.h"
#include "whatever.h"
char mess_file[64] = "int.mess"; /* name of message file */
jmp_buf trapbuf;
char *prog_name;
int running; /* set if EM machine is running */
size maxstack; /* if set, max stack size */
size maxheap; /* if set, max heap size */
#ifdef LOGGING
extern long inr; /* from log.c */
#endif /* LOGGING */
PRIVATE char *dflt_av[] = {"e.out", 0}; /* default arguments */
/** Check dynamically that the interpreter can run on the target machine. */
static void check_requirements(char *name)
{
/* Verify that shift right supported signed shifts. According to ISO C90,
* this is not mandatory, we should not support it here!
*/
int shrv = -4;
if ((shrv >> 1) != -2)
{
fprintf(stderr,
"%s compiled with compiler that does not support signed right shifts. Aborted.",
name);
exit(1);
}
}
int main(int argc, char *argv[])
{
register int i;
register int nosetjmp = 1;
int must_disassemble = 0;
int must_tally = 0;
prog_name = argv[0];
check_requirements(prog_name);
/* Initialize the EM machine */
PreIgnMask = 0;
FRALimit = FRALIMIT;
for (i = 1; i < argc; i++) {
if (*(argv[i]) == '-') {
switch (*(argv[i] + 1)) {
case 'd': /* disassembly */
must_disassemble = 1;
break;
case 'h': /* limit heap size */
maxheap = atol(argv[i] + 2);
break;
case 'I': /* IgnMask pre-setting */
if (atoi(argv[i] + 2) < 16)
PreIgnMask = BIT(atoi(argv[i] + 2));
break;
case 'm': /* messagefile name override */
strcpy(mess_file, argv[i] + 2);
break;
case 'r': /* FRALimit override */
FRALimit = atoi(argv[i] + 2);
break;
case 's': /* limit stack size */
maxstack = atol(argv[i] + 2);
break;
case 't': /* switch on tallying */
must_tally= 1;
break;
case 'W': /* disable warning */
set_wmask(atoi(argv[i] + 2));
break;
default:
fprintf(stderr,
"%s: bad option: %s\n",
prog_name,
argv[i]
);
exit(1);
}
}
#ifdef LOGGING
else if (logarg(argv[i])) {
/* interesting for the logging machine */
}
#endif /* LOGGING */
else break;
}
#ifdef LOGGING
/* Initialize the logging machine */
init_log();
#endif /* LOGGING */
if (argc > i)
init(argc - i, argv + i);
else
init(1, dflt_av);
/* Text dump only? */
if (must_disassemble) {
message(
"text segment disassembly produced; program was not run");
disassemble();
close_down(0);
}
/* Analyse FLAGS word */
if (FLAGS&FB_TEST)
must_test = 1;
if ((FLAGS&FB_PROFILE) || (FLAGS&FB_FLOW) || (FLAGS&FB_COUNT))
must_tally = 1;
#ifdef NOFLOAT
if (FLAGS&FB_REALS)
warning(WFLUSED);
#endif /* NOFLOAT */
if (FLAGS&FB_EXTRA)
warning(WEXTRIGN);
/* Call first procedure */
running = 1; /* start the machine */
OnTrap = TR_HALT; /* default trap handling */
call(ENTRY, RSB_STP);
/* Run the machine */
while (running) {
#ifdef LOGGING
inr++;
if (must_log && inr >= log_start) {
/* log this instruction */
logging = 1;
}
#endif /* LOGGING */
LOG(("@x9 PC = %lu OPCODE = %lu", PC,
btol(text_loc(PC)) < SECONDARY ?
btol(text_loc(PC)) :
btol(text_loc(PC)) + btol(text_loc(PC+1))
));
newPC(PC); /* just check for validity */
do_instr(nextPCbyte()); /* here it happens */
if (must_tally) {
tally();
}
if (signalled) {
/* a signal has come in during this instruction */
LOG(("@t1 signal %d caught by EM machine", signalled));
trap_signal();
}
if (nosetjmp) {
/* entry point after a trap occurred */
setjmp(trapbuf);
nosetjmp = 0;
}
#ifdef LOGGING
log_eoi();
#endif /* LOGGING */
}
if (must_tally) {
out_tally();
}
if (ES_def == DEFINED) {
message("program exits with status %ld", ES);
close_down((int) ES);
}
else {
message("program exits with undefined status");
close_down(0);
}
/*NOTREACHED*/
}