36f16b0cb8
Edit C code to reduce warnings from clang. Most warnings are for
implicit declarations of functions, but some warnings want me to add
parentheses or curly braces, or to cast arguments for printf().
Make a few other changes, like declaring float_cst() in h/con_float to
be static, and using C99 bool in ego/ra/makeitems.c and
ego/share/makecldef.c. Such changes don't silence warnings; I make
such changes while I silence warnings in the same file. In
float_cst(), rename parameter `str` to `float_str`, so it doesn't
share a name with the global variable `str`.
Remove `const` from `newmodule(const char *)` in mach/proto/as to
silence a warning. I wrongly added the `const` in d347207
.
For warnings about implicit declarations of functions, the fix is to
declare the function before calling it. For example, my OpenBSD
system needs <sys/wait.h> to declare wait().
In util/int, add "whatever.h" to declare more functions. Remove old
declarations from "mem.h", to prefer the newer declarations of the
same functions in "data.h" and "stack.h".
215 lines
4.1 KiB
C
215 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 "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*/
|
|
}
|
|
|