+ ANSI C conversion
This commit is contained in:
parent
0df5d2f50b
commit
75909230c9
539
util/ass/ass00.c
539
util/ass/ass00.c
|
@ -1,5 +1,10 @@
|
||||||
|
#include <string.h>
|
||||||
|
#include <stddef.h>
|
||||||
#include "ass00.h"
|
#include "ass00.h"
|
||||||
#include "assex.h"
|
#include "assex.h"
|
||||||
|
#include "assci.h"
|
||||||
|
#include "asscm.h"
|
||||||
|
#include "assrl.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||||
|
@ -7,205 +12,289 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef NORCSID
|
char oflag;
|
||||||
static char rcs_id[] = "$Id$" ;
|
static int memflg;
|
||||||
#endif
|
|
||||||
|
/* Forward declarations. */
|
||||||
|
static siz_t* getsizes(char *);
|
||||||
|
static void getcore(void);
|
||||||
|
static void argument(char *);
|
||||||
|
static void flags(char *);
|
||||||
|
static void skipentry(void);
|
||||||
|
static void enmd_pro(void);
|
||||||
|
static void enmd_glo(void);
|
||||||
|
static void archive(void);
|
||||||
|
static void finish_up(void);
|
||||||
|
static void check_def(void);
|
||||||
|
|
||||||
|
static void c_print(void);
|
||||||
|
static void c_dprint(char *, char*);
|
||||||
|
|
||||||
|
/* External definitions */
|
||||||
|
void pass_3(void);
|
||||||
|
void pass_4(void);
|
||||||
|
void pass_5(void);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Main routine of EM1-assembler/loader
|
** Main routine of EM1-assembler/loader
|
||||||
*/
|
*/
|
||||||
|
|
||||||
main(argc, argv)
|
int main(int argc, char **argv)
|
||||||
int argc;
|
|
||||||
char **argv;
|
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Usage: ass [-[d][p][m][u][U]] [-s(s/m/l/x)] [ [file] [flag] ] ...
|
* Usage: ass [-[d][p][m][u][U]] [-s(s/m/l/x)] [ [file] [flag] ] ...
|
||||||
* The d flag can be repeated several times, resulting in more
|
* The d flag can be repeated several times, resulting in more
|
||||||
* debugging information.
|
* debugging information.
|
||||||
*/
|
*/
|
||||||
char workspace[6000] ;
|
char workspace[6000];
|
||||||
register char *cp ;
|
register char *cp;
|
||||||
register int argno ;
|
register int argno;
|
||||||
|
|
||||||
progname = argv[0];
|
progname = argv[0];
|
||||||
for ( cp=argv[0] ; *cp ; ) if ( *cp++ == '/' ) progname= cp;
|
for (cp = argv[0]; *cp;)
|
||||||
for ( argno=1 ; argno<argc ; argno++ ) {
|
if (*cp++ == '/')
|
||||||
if ( argv[argno][0] == '-' && LC(argv[argno][1]) == 's') {
|
progname = cp;
|
||||||
getsizes(&argv[argno][2]);
|
for (argno = 1; argno < argc; argno++)
|
||||||
break ;
|
{
|
||||||
|
if (argv[argno][0] == '-' && LC(argv[argno][1]) == 's')
|
||||||
|
{
|
||||||
|
oursize = getsizes(&argv[argno][2]);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* A piece of the interpreter's stack frame is used as
|
/* A piece of the interpreter's stack frame is used as
|
||||||
free area initially */
|
free area initially */
|
||||||
freearea( (area_t) workspace, (unsigned) sizeof workspace ) ;
|
freearea((area_t) workspace, (unsigned) sizeof workspace);
|
||||||
getcore();
|
getcore();
|
||||||
init_files();
|
init_files();
|
||||||
init_vars();
|
init_vars();
|
||||||
while ( --argc )
|
while (--argc)
|
||||||
argument(*++argv);
|
argument(*++argv);
|
||||||
finish_up();
|
finish_up();
|
||||||
exit(nerrors!=0);
|
exit(nerrors != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
getcore() {
|
static void getcore(void)
|
||||||
|
{
|
||||||
register siz_t *p;
|
register siz_t *p;
|
||||||
siz_t bytes;
|
siz_t bytes;
|
||||||
register unsigned n ;
|
register unsigned n;
|
||||||
register char *base ;
|
register char *base;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* xglobs[] should be located in front of mglobs[], see upd_reloc()
|
* xglobs[] should be located in front of mglobs[], see upd_reloc()
|
||||||
*/
|
*/
|
||||||
|
|
||||||
p = oursize; n = 0;
|
p = oursize;
|
||||||
|
n = 0;
|
||||||
n += (bytes.n_glab = p->n_glab * (sizeof *xglobs));
|
n += (bytes.n_glab = p->n_glab * (sizeof *xglobs));
|
||||||
n += (bytes.n_mlab = p->n_mlab * (sizeof *mglobs));
|
n += (bytes.n_mlab = p->n_mlab * (sizeof *mglobs));
|
||||||
n += (bytes.n_mproc = p->n_mproc * (sizeof *mprocs));
|
n += (bytes.n_mproc = p->n_mproc * (sizeof *mprocs));
|
||||||
n += (bytes.n_xproc = p->n_xproc * (sizeof *xprocs));
|
n += (bytes.n_xproc = p->n_xproc * (sizeof *xprocs));
|
||||||
n += (bytes.n_proc = p->n_proc * (sizeof *proctab));
|
n += (bytes.n_proc = p->n_proc * (sizeof *proctab));
|
||||||
base = getarea(n);
|
base = getarea(n);
|
||||||
zero(base,n);
|
memset(base, 0, n);
|
||||||
xglobs = gbp_cast base; base += bytes.n_glab;
|
xglobs = gbp_cast base;
|
||||||
mglobs = gbp_cast base; base += bytes.n_mlab;
|
base += bytes.n_glab;
|
||||||
mprocs = prp_cast base; base += bytes.n_mproc;
|
mglobs = gbp_cast base;
|
||||||
xprocs = prp_cast base; base += bytes.n_xproc;
|
base += bytes.n_mlab;
|
||||||
proctab = ptp_cast base; base += bytes.n_proc;
|
mprocs = prp_cast base;
|
||||||
|
base += bytes.n_mproc;
|
||||||
|
xprocs = prp_cast base;
|
||||||
|
base += bytes.n_xproc;
|
||||||
|
proctab = ptp_cast base;
|
||||||
|
base += bytes.n_proc;
|
||||||
}
|
}
|
||||||
|
|
||||||
getsizes(str) char *str; {
|
static siz_t* getsizes(char *str)
|
||||||
|
{
|
||||||
/*
|
/*
|
||||||
* accepts -ss (small), -sm (medium), -sl (large), -sx (extra large)
|
* accepts -ss (small), -sm (medium), -sl (large), -sx (extra large)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
switch(LC(*str)) {
|
switch (LC(*str))
|
||||||
default:error("bad size option %s",str);
|
{
|
||||||
case 's': oursize = &sizes[0]; break;
|
default:
|
||||||
case 'm': oursize = &sizes[1]; break;
|
error("bad size option %s", str);
|
||||||
case 'l': oursize = &sizes[2]; break;
|
case 's':
|
||||||
case 'x': oursize = &sizes[3]; break;
|
return &sizes[0];
|
||||||
|
break;
|
||||||
|
case 'm':
|
||||||
|
return &sizes[1];
|
||||||
|
break;
|
||||||
|
case 'l':
|
||||||
|
return &sizes[2];
|
||||||
|
break;
|
||||||
|
case 'x':
|
||||||
|
return &sizes[3];
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
char oflag;
|
/*
|
||||||
|
|
||||||
argument(arg) char *arg; {
|
|
||||||
register w;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This routine decides what to do with each argument.
|
* This routine decides what to do with each argument.
|
||||||
* It recognises flags and modules.
|
* It recognises flags and modules.
|
||||||
* Furthermore, it knows a library when it sees it and
|
* Furthermore, it knows a library when it sees it and
|
||||||
* call archive() to split it apart.
|
* call archive() to split it apart.
|
||||||
*/
|
*/
|
||||||
|
static void argument(char *arg)
|
||||||
|
{
|
||||||
|
register int w;
|
||||||
|
|
||||||
if (oflag) {
|
if (oflag)
|
||||||
|
{
|
||||||
eout = arg;
|
eout = arg;
|
||||||
oflag=0;
|
oflag = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(*arg == '-') {
|
if (*arg == '-')
|
||||||
|
{
|
||||||
flags(arg);
|
flags(arg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
curfile = arg; /* for error messages etc. */
|
curfile = arg; /* for error messages etc. */
|
||||||
if ((ifile = fopen(arg,"r")) == 0) {
|
if ((ifile = fopen(arg, "r")) == NULL)
|
||||||
error("can't open %s",arg);
|
{
|
||||||
|
error("can't open %s", arg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
inpoff = 2;
|
inpoff = 2;
|
||||||
if ((w = getu16()) == sp_magic )
|
if ((w = getu16()) == sp_magic)
|
||||||
read_compact();
|
read_compact();
|
||||||
else if (w == ARMAG || w == AALMAG) {
|
else if (w == ARMAG || w == AALMAG)
|
||||||
|
{
|
||||||
archmode = TRUE;
|
archmode = TRUE;
|
||||||
archive();
|
archive();
|
||||||
archmode = FALSE;
|
archmode = FALSE;
|
||||||
} else
|
}
|
||||||
error("%s: bad format",arg);
|
else
|
||||||
|
error("%s: bad format", arg);
|
||||||
if (fclose(ifile) == EOF)
|
if (fclose(ifile) == EOF)
|
||||||
;
|
{
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** process flag arguments
|
** process flag arguments
|
||||||
*/
|
*/
|
||||||
|
static void flags(char *arg)
|
||||||
static int memflg ;
|
|
||||||
|
|
||||||
flags(arg)
|
|
||||||
char *arg;
|
|
||||||
{
|
{
|
||||||
register char *argp;
|
register char *argp;
|
||||||
register on;
|
register int on;
|
||||||
|
|
||||||
argp = arg;
|
argp = arg;
|
||||||
while (*++argp)
|
while (*++argp)
|
||||||
{
|
{
|
||||||
switch(LC(*argp))
|
switch (LC(*argp))
|
||||||
{
|
{
|
||||||
case 'd': d_flag++;break;
|
case 'd':
|
||||||
case 'r': r_flag++;break;
|
d_flag++;
|
||||||
case 's': return ; /* s-flag is already scanned */
|
break;
|
||||||
|
case 'r':
|
||||||
|
r_flag++;
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
return; /* s-flag is already scanned */
|
||||||
#ifdef MEMUSE
|
#ifdef MEMUSE
|
||||||
case 'm': memflg++ ; break ;
|
case 'm':
|
||||||
|
memflg++;
|
||||||
|
break;
|
||||||
#endif
|
#endif
|
||||||
case 'p': ++procflag;break;
|
case 'p':
|
||||||
|
++procflag;
|
||||||
|
break;
|
||||||
#ifdef DUMP
|
#ifdef DUMP
|
||||||
case 'u': ++c_flag;break;
|
case 'u':
|
||||||
|
++c_flag;
|
||||||
|
break;
|
||||||
#endif
|
#endif
|
||||||
case 'o': ++oflag; break;
|
case 'o':
|
||||||
case 'w': ++wflag; break;
|
++oflag;
|
||||||
|
break;
|
||||||
|
case 'w':
|
||||||
|
++wflag;
|
||||||
|
break;
|
||||||
#ifdef JOHAN
|
#ifdef JOHAN
|
||||||
case 'j': ++jflag; break;
|
case 'j':
|
||||||
|
++jflag;
|
||||||
|
break;
|
||||||
#endif
|
#endif
|
||||||
case 'U': ++Uflag; break;
|
case 'U':
|
||||||
|
++Uflag;
|
||||||
|
break;
|
||||||
case '-':
|
case '-':
|
||||||
case '+':
|
case '+':
|
||||||
on = (*argp == '+');
|
on = (*argp == '+');
|
||||||
while (*++argp) switch(LC(*argp)) {
|
while (*++argp)
|
||||||
case 't': if (on) intflags |= 01;
|
switch (LC(*argp))
|
||||||
else intflags &= ~01;
|
{
|
||||||
|
case 't':
|
||||||
|
if (on)
|
||||||
|
intflags |= 01;
|
||||||
|
else
|
||||||
|
intflags &= ~01;
|
||||||
break;
|
break;
|
||||||
case 'p': if (on) intflags |= 02;
|
case 'p':
|
||||||
else intflags &= ~02;
|
if (on)
|
||||||
|
intflags |= 02;
|
||||||
|
else
|
||||||
|
intflags &= ~02;
|
||||||
break;
|
break;
|
||||||
case 'f': if (on) intflags |= 04;
|
case 'f':
|
||||||
else intflags &= ~04;
|
if (on)
|
||||||
|
intflags |= 04;
|
||||||
|
else
|
||||||
|
intflags &= ~04;
|
||||||
break;
|
break;
|
||||||
case 'c': if (on) intflags |= 010;
|
case 'c':
|
||||||
else intflags &= ~010;
|
if (on)
|
||||||
case 'e': if (on) intflags |= 040;
|
intflags |= 010;
|
||||||
else intflags &= ~040;
|
else
|
||||||
|
intflags &= ~010;
|
||||||
|
case 'e':
|
||||||
|
if (on)
|
||||||
|
intflags |= 040;
|
||||||
|
else
|
||||||
|
intflags &= ~040;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
error("bad interpreter option %s",argp);
|
error("bad interpreter option %s", argp);
|
||||||
}
|
}
|
||||||
--argp;
|
--argp;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
error("bad flag %s",argp);
|
error("bad flag %s", argp);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
do_proc() {
|
void do_proc(void)
|
||||||
|
{
|
||||||
/* One procedure has been read and will be processed.
|
/* One procedure has been read and will be processed.
|
||||||
*
|
*
|
||||||
* NOTE: The numbers of the passes, 1 3 4 and 5, are a remainder
|
* NOTE: The numbers of the passes, 1 3 4 and 5, are a remainder
|
||||||
* of ancient times.
|
* of ancient times.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
dump(1); if ( memflg>2 )memuse();
|
dump(1);
|
||||||
pass_3(); dump(3);
|
if (memflg > 2)
|
||||||
pass_4(); dump(4);
|
memuse();
|
||||||
pass_5(); if ( memflg>2 ) memuse() ;
|
pass_3();
|
||||||
endproc(); if ( memflg>1 ) memuse() ;
|
dump(3);
|
||||||
|
pass_4();
|
||||||
|
dump(4);
|
||||||
|
pass_5();
|
||||||
|
if (memflg > 2)
|
||||||
|
memuse();
|
||||||
|
endproc();
|
||||||
|
if (memflg > 1)
|
||||||
|
memuse();
|
||||||
}
|
}
|
||||||
|
|
||||||
archive() {
|
static void archive(void)
|
||||||
register i;
|
{
|
||||||
|
register int i;
|
||||||
register char *p;
|
register char *p;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -219,21 +308,26 @@ archive() {
|
||||||
* This is the only reason.
|
* This is the only reason.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
for(;;) {
|
for (;;)
|
||||||
if (unresolved == 0) { /* no use for this library anymore */
|
{
|
||||||
|
if (unresolved == 0)
|
||||||
|
{ /* no use for this library anymore */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
p = chp_cast &archhdr;
|
p = chp_cast &archhdr;
|
||||||
if ((i = fgetc(ifile))==EOF ) {
|
if ((i = fgetc(ifile)) == EOF)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
*p++ = i;
|
*p++ = i;
|
||||||
for (i=1;i< sizeof archhdr.ar_name; i++)
|
for (i = 1; i < sizeof archhdr.ar_name; i++)
|
||||||
*p++ = get8();
|
*p++ = get8();
|
||||||
for (i=0;i<8;i++) get8();
|
for (i = 0; i < 8; i++)
|
||||||
archhdr.ar_size= ((long)get16()<<16) ;
|
get8();
|
||||||
archhdr.ar_size+= getu16();
|
archhdr.ar_size = ((long) get16() << 16);
|
||||||
inpoff = 0; libeof = archhdr.ar_size;
|
archhdr.ar_size += getu16();
|
||||||
|
inpoff = 0;
|
||||||
|
libeof = archhdr.ar_size;
|
||||||
/*
|
/*
|
||||||
* UNIX archiveheader is read now, now process the contents
|
* UNIX archiveheader is read now, now process the contents
|
||||||
* of it. Note that recursive archives are not implemented.
|
* of it. Note that recursive archives are not implemented.
|
||||||
|
@ -241,29 +335,33 @@ archive() {
|
||||||
* The variable libeof is used by get8() to check
|
* The variable libeof is used by get8() to check
|
||||||
* whether or not we try to pass the library-boundary.
|
* whether or not we try to pass the library-boundary.
|
||||||
*/
|
*/
|
||||||
if ( getu16() == sp_magic ) {
|
if (getu16() == sp_magic)
|
||||||
|
{
|
||||||
read_compact();
|
read_compact();
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
error("bad archive entry");
|
error("bad archive entry");
|
||||||
skipentry();
|
skipentry();
|
||||||
libeof = 0;
|
libeof = 0;
|
||||||
} /* up to the next entry */
|
} /* up to the next entry */
|
||||||
}
|
}
|
||||||
|
|
||||||
skipentry() {
|
static void skipentry(void)
|
||||||
|
{
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* for some reason the rest of this library entry needs to be
|
* for some reason the rest of this library entry needs to be
|
||||||
* skipped. Do that now.
|
* skipped. Do that now.
|
||||||
*/
|
*/
|
||||||
while(inpoff<libeof)
|
while (inpoff < libeof)
|
||||||
get8();
|
get8();
|
||||||
if(odd(libeof)) /* archive entries are evensized */
|
if (odd(libeof)) /* archive entries are evensized */
|
||||||
if (fgetc(ifile) == EOF) /* except maybe the last one */
|
if (fgetc(ifile) == EOF) /* except maybe the last one */
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
init_vars() {
|
void init_vars(void)
|
||||||
|
{
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A small collection of variables is initialized.
|
* A small collection of variables is initialized.
|
||||||
|
@ -273,83 +371,86 @@ init_vars() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
init_files() {
|
void init_files(void)
|
||||||
|
{
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The temporary files on which text and data are kept
|
* The temporary files on which text and data are kept
|
||||||
* during assembly are set up here.
|
* during assembly are set up here.
|
||||||
*/
|
*/
|
||||||
#ifdef CPM
|
|
||||||
unlink("????????.$$$");
|
|
||||||
tfile=fopen("TFILE.$$$", "w");
|
|
||||||
dfile=fopen("DFILE.$$$", "w");
|
|
||||||
rtfile=fopen("RTFILE.$$$", "w");
|
|
||||||
rdfile=fopen("RDFILE.$$$", "w");
|
|
||||||
#else
|
|
||||||
/*
|
/*
|
||||||
* The function tmpfil() returns a file-descriptor
|
* The function tmpfil() returns a file-descriptor
|
||||||
* of a file that is valid for reading and writing.
|
* of a file that is valid for reading and writing.
|
||||||
* It has the nice property of generating truly unique names.
|
* It has the nice property of generating truly unique names.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
tfile=fdopen(tmpfil(),"w") ;
|
tfile = fopen(tmpfil(), "w+");
|
||||||
dfile=fdopen(tmpfil(),"w") ;
|
dfile = fopen(tmpfil(), "w+");
|
||||||
rtfile=fdopen(tmpfil(),"w") ;
|
rtfile = fopen(tmpfil(), "w+");
|
||||||
rdfile=fdopen(tmpfil(),"w") ;
|
rdfile = fopen(tmpfil(), "w+");
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
initproc() {
|
void initproc(void)
|
||||||
|
{
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Called at the start of assembly of every procedure.
|
* Called at the start of assembly of every procedure.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
stat_t *prevstate ;
|
stat_t *prevstate;
|
||||||
|
|
||||||
prevstate= pst_cast getarea(sizeof pstate) ;
|
prevstate = pst_cast getarea(sizeof pstate);
|
||||||
*prevstate= pstate ;
|
*prevstate = pstate;
|
||||||
pstate.s_prevstat= prevstate ;
|
pstate.s_prevstat = prevstate;
|
||||||
pstate.s_curpro= prp_cast 0 ;
|
pstate.s_curpro = prp_cast 0;
|
||||||
pstate.s_fline= lnp_cast 0 ;
|
pstate.s_fline = lnp_cast 0;
|
||||||
pstate.s_fdata= l_data ;
|
pstate.s_fdata = l_data;
|
||||||
pstate.s_locl = (locl_t (*)[])
|
pstate.s_locl = (locl_t (*)[]) getarea(
|
||||||
getarea(LOCLABSIZE * sizeof ((*(pstate.s_locl))[0]));
|
LOCLABSIZE * sizeof((*(pstate.s_locl))[0]));
|
||||||
zero(chp_cast pstate.s_locl,
|
memset(chp_cast pstate.s_locl, 0,
|
||||||
LOCLABSIZE * (unsigned) sizeof ((*(pstate.s_locl))[0]));
|
LOCLABSIZE * (unsigned) sizeof((*(pstate.s_locl))[0]));
|
||||||
if ( memflg>2 ) memuse() ;
|
if (memflg > 2)
|
||||||
|
memuse();
|
||||||
}
|
}
|
||||||
|
|
||||||
endproc() {
|
void endproc(void)
|
||||||
|
{
|
||||||
/* Throw the contents of the line and local label table away */
|
/* Throw the contents of the line and local label table away */
|
||||||
register line_t *lnp1;
|
register line_t *lnp1;
|
||||||
register locl_t *lbhead,*lbp,*lbp_next;
|
register locl_t *lbhead, *lbp, *lbp_next;
|
||||||
register kind ;
|
register int kind;
|
||||||
register stat_t *prevstate;
|
register stat_t *prevstate;
|
||||||
|
|
||||||
while ( lnp1= pstate.s_fline ) {
|
while ((lnp1 = pstate.s_fline) != NULL)
|
||||||
pstate.s_fline= lnp1->l_next ;
|
{
|
||||||
kind= lnp1->type1 ;
|
pstate.s_fline = lnp1->l_next;
|
||||||
if ( kind>VALLOW ) kind=VALLOW ;
|
kind = lnp1->type1;
|
||||||
freearea((area_t)lnp1,(unsigned)linesize[kind]) ;
|
if (kind > VALLOW)
|
||||||
|
kind = VALLOW;
|
||||||
|
freearea((area_t) lnp1, (unsigned) linesize[kind]);
|
||||||
}
|
}
|
||||||
prevstate= pstate.s_prevstat ;
|
prevstate = pstate.s_prevstat;
|
||||||
if ( prevstate!= pst_cast 0 ) {
|
if (prevstate != pst_cast 0)
|
||||||
for ( lbhead= *pstate.s_locl;
|
{
|
||||||
lbhead<&(*pstate.s_locl)[LOCLABSIZE] ; lbhead++ ) {
|
for (lbhead = *pstate.s_locl; lbhead < &(*pstate.s_locl)[LOCLABSIZE];
|
||||||
for ( lbp=lbhead->l_chain; lbp!= lbp_cast 0; lbp= lbp_next ) {
|
lbhead++)
|
||||||
lbp_next= lbp->l_chain;
|
{
|
||||||
freearea((area_t)lbp,(unsigned)sizeof *lbp) ;
|
for (lbp = lbhead->l_chain; lbp != lbp_cast 0; lbp = lbp_next)
|
||||||
|
{
|
||||||
|
lbp_next = lbp->l_chain;
|
||||||
|
freearea((area_t) lbp, (unsigned) sizeof *lbp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
freearea((area_t)(*pstate.s_locl),
|
freearea((area_t) (*pstate.s_locl),
|
||||||
LOCLABSIZE * (sizeof((*pstate.s_locl)[0])));
|
LOCLABSIZE * (sizeof((*pstate.s_locl)[0])));
|
||||||
pstate= *prevstate ;
|
pstate = *prevstate;
|
||||||
freearea((area_t)prevstate,(unsigned)sizeof *prevstate) ;
|
freearea((area_t) prevstate, (unsigned) sizeof *prevstate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
init_module() {
|
void init_module(void)
|
||||||
|
{
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Called at the start of every module.
|
* Called at the start of every module.
|
||||||
|
@ -360,7 +461,8 @@ init_module() {
|
||||||
mod_sizes = 0;
|
mod_sizes = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
end_module() {
|
void end_module(void)
|
||||||
|
{
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Finish a module.
|
* Finish a module.
|
||||||
|
@ -368,16 +470,18 @@ end_module() {
|
||||||
* and remembering of those that will live during assembly.
|
* and remembering of those that will live during assembly.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
align(wordsize) ;
|
align(wordsize);
|
||||||
set_mode(DATA_NUL);
|
set_mode(DATA_NUL);
|
||||||
dump(100);
|
dump(100);
|
||||||
enmd_pro();
|
enmd_pro();
|
||||||
enmd_glo();
|
enmd_glo();
|
||||||
if ( memflg ) memuse() ;
|
if (memflg)
|
||||||
|
memuse();
|
||||||
}
|
}
|
||||||
|
|
||||||
enmd_pro() {
|
static void enmd_pro(void)
|
||||||
register proc_t *p,*limit;
|
{
|
||||||
|
register proc_t *p, *limit;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check that all local procedures have been defined,
|
* Check that all local procedures have been defined,
|
||||||
|
@ -385,26 +489,29 @@ enmd_pro() {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
limit = &mprocs[oursize->n_mproc];
|
limit = &mprocs[oursize->n_mproc];
|
||||||
for (p=mprocs; p<limit; p++) {
|
for (p = mprocs; p < limit; p++)
|
||||||
|
{
|
||||||
if (p->p_name == 0)
|
if (p->p_name == 0)
|
||||||
continue;
|
continue;
|
||||||
if ((p->p_status&DEF)==0)
|
if ((p->p_status & DEF) == 0)
|
||||||
error("undefined local procedure '%s'",p->p_name);
|
error("undefined local procedure '%s'", p->p_name);
|
||||||
}
|
}
|
||||||
zero(chp_cast mprocs,(limit-mprocs)* (unsigned)sizeof *mprocs);
|
memset(chp_cast mprocs, 0, (limit - mprocs) * (unsigned ) sizeof *mprocs);
|
||||||
|
|
||||||
/* Clobber all flags indicating that external procedures
|
/* Clobber all flags indicating that external procedures
|
||||||
* were used in this module.
|
* were used in this module.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
limit = &xprocs[oursize->n_xproc];
|
limit = &xprocs[oursize->n_xproc];
|
||||||
for (p=xprocs; p<limit; p++) {
|
for (p = xprocs; p < limit; p++)
|
||||||
p->p_status &= ~EXT ;
|
{
|
||||||
|
p->p_status &= ~EXT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enmd_glo() {
|
static void enmd_glo(void)
|
||||||
register glob_t *mg,*xg,*limit;
|
{
|
||||||
|
register glob_t *mg, *xg, *limit;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Tougher then enmd_pro().
|
* Tougher then enmd_pro().
|
||||||
|
@ -420,36 +527,39 @@ enmd_glo() {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
limit = &mglobs[oursize->n_mlab];
|
limit = &mglobs[oursize->n_mlab];
|
||||||
for ( mg = mglobs; mg < limit; mg++) {
|
for (mg = mglobs; mg < limit; mg++)
|
||||||
|
{
|
||||||
if (mg->g_name == 0)
|
if (mg->g_name == 0)
|
||||||
continue;
|
continue;
|
||||||
if ((mg->g_status&(EXT|DEF))==0)
|
if ((mg->g_status & (EXT | DEF)) == 0)
|
||||||
error("undefined local symbol '%s'",glostring(mg));
|
error("undefined local symbol '%s'", glostring(mg));
|
||||||
if ((mg->g_status&EXT)==0)
|
if ((mg->g_status & EXT) == 0)
|
||||||
continue;
|
continue;
|
||||||
xg = xglolookup(mg->g_name,ENTERING);
|
xg = xglolookup(mg->g_name, ENTERING);
|
||||||
switch(xg->g_status&(EXT|DEF)) {
|
switch (xg->g_status & (EXT | DEF))
|
||||||
|
{
|
||||||
case 0: /* new symbol */
|
case 0: /* new symbol */
|
||||||
if((mg->g_status&DEF)==0)
|
if ((mg->g_status & DEF) == 0)
|
||||||
++unresolved;
|
++unresolved;
|
||||||
break;
|
break;
|
||||||
case EXT: /* already used but not defined */
|
case EXT: /* already used but not defined */
|
||||||
if(mg->g_status&DEF) {
|
if (mg->g_status & DEF)
|
||||||
|
{
|
||||||
--unresolved;
|
--unresolved;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
xg->g_status |= mg->g_status;
|
xg->g_status |= mg->g_status;
|
||||||
if (mg->g_status&DEF)
|
if (mg->g_status & DEF)
|
||||||
xg->g_val.g_addr = mg->g_val.g_addr;
|
xg->g_val.g_addr = mg->g_val.g_addr;
|
||||||
else
|
else
|
||||||
mg->g_val.g_gp = xg; /* used by upd_reloc */
|
mg->g_val.g_gp = xg; /* used by upd_reloc */
|
||||||
} /* up to the next symbol */
|
} /* up to the next symbol */
|
||||||
upd_reloc();
|
upd_reloc();
|
||||||
zero(chp_cast mglobs,(limit-mglobs)*(unsigned) sizeof *mglobs);
|
memset(chp_cast mglobs, 0, (limit - mglobs) * (unsigned ) sizeof *mglobs);
|
||||||
}
|
}
|
||||||
|
|
||||||
finish_up()
|
static void finish_up(void)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Almost done. Check for unresolved references,
|
* Almost done. Check for unresolved references,
|
||||||
|
@ -460,41 +570,55 @@ finish_up()
|
||||||
c_print();
|
c_print();
|
||||||
#endif
|
#endif
|
||||||
check_def();
|
check_def();
|
||||||
if ( nerrors==0 ) copyout();
|
if (nerrors == 0)
|
||||||
|
copyout();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DUMP
|
#ifdef DUMP
|
||||||
c_print() {
|
static void c_print(void)
|
||||||
if ( ! c_flag ) return ;
|
{
|
||||||
c_dprint("primary",opcnt1) ;
|
if (!c_flag)
|
||||||
c_dprint("secondary",opcnt2) ;
|
return;
|
||||||
c_dprint("extra long",opcnt3) ;
|
c_dprint("primary", opcnt1);
|
||||||
|
c_dprint("secondary", opcnt2);
|
||||||
|
c_dprint("extra long", opcnt3);
|
||||||
}
|
}
|
||||||
|
|
||||||
c_dprint(str,cnt) char *str,*cnt ; {
|
static void c_dprint(char *str, char* cnt)
|
||||||
register int first,curr ;
|
{
|
||||||
printf("unused %s opcodes\n",str) ;
|
register int first, curr;
|
||||||
for ( first= -1 , curr=0 ; curr<=256 ; curr++ ) {
|
printf("unused %s opcodes\n", str);
|
||||||
if ( curr==256 || cnt[curr] ) {
|
for (first = -1, curr = 0; curr <= 256; curr++)
|
||||||
if ( first!= -1 ) {
|
{
|
||||||
if ( first+1 == curr ) {
|
if (curr == 256 || cnt[curr])
|
||||||
printf("%3d\n",first ) ;
|
{
|
||||||
} else {
|
if (first != -1)
|
||||||
printf("%3d..%3d\n",first,curr-1) ;
|
{
|
||||||
|
if (first + 1 == curr)
|
||||||
|
{
|
||||||
|
printf("%3d\n", first);
|
||||||
}
|
}
|
||||||
first= -1 ;
|
else
|
||||||
|
{
|
||||||
|
printf("%3d..%3d\n", first, curr - 1);
|
||||||
}
|
}
|
||||||
} else {
|
first = -1;
|
||||||
if ( first== -1 ) first=curr ;
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (first == -1)
|
||||||
|
first = curr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
check_def() {
|
static void check_def(void)
|
||||||
|
{
|
||||||
register proc_t *p;
|
register proc_t *p;
|
||||||
register glob_t *g;
|
register glob_t *g;
|
||||||
register count;
|
register int count;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check for unresolved references.
|
* Check for unresolved references.
|
||||||
|
@ -504,25 +628,28 @@ check_def() {
|
||||||
* Every use of the symbols concerned is undefined.
|
* Every use of the symbols concerned is undefined.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (unresolved) {
|
if (unresolved)
|
||||||
|
{
|
||||||
printf("Unresolved references\n Procedures:\n");
|
printf("Unresolved references\n Procedures:\n");
|
||||||
count = oursize->n_xproc;
|
count = oursize->n_xproc;
|
||||||
for (p = xprocs; count--; p++)
|
for (p = xprocs; count--; p++)
|
||||||
if (p->p_name && (p->p_status&DEF)==0)
|
if (p->p_name && (p->p_status & DEF) == 0)
|
||||||
printf(" %s\n",p->p_name);
|
printf(" %s\n", p->p_name);
|
||||||
printf(" Data:\n");
|
printf(" Data:\n");
|
||||||
count = oursize->n_glab;
|
count = oursize->n_glab;
|
||||||
for (g = xglobs; count--; g++)
|
for (g = xglobs; count--; g++)
|
||||||
if (g->g_name && (g->g_status&DEF)==0)
|
if (g->g_name && (g->g_status & DEF) == 0)
|
||||||
printf(" %s\n",glostring(g));
|
printf(" %s\n", glostring(g));
|
||||||
if (! Uflag) nerrors++;
|
if (!Uflag)
|
||||||
|
nerrors++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ertrap() { /* trap routine to drain input in case of compile errors */
|
void ertrap(void)
|
||||||
|
{ /* trap routine to drain input in case of compile errors */
|
||||||
|
|
||||||
if (fileno(ifile)== 0)
|
if (ifile == stdin)
|
||||||
while (fgetc(ifile) != EOF)
|
while (fgetc(ifile) != EOF)
|
||||||
;
|
;
|
||||||
exit(1);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,15 +4,12 @@
|
||||||
*/
|
*/
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <unistd.h>
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include "em_spec.h"
|
||||||
#include <fcntl.h>
|
#include "as_spec.h"
|
||||||
#include <em_spec.h>
|
#include "em_flag.h"
|
||||||
#include <as_spec.h>
|
#include "arch.h"
|
||||||
#include <em_flag.h>
|
#include "local.h"
|
||||||
#include <arch.h>
|
|
||||||
#include <local.h>
|
|
||||||
|
|
||||||
#define RCS_ASS "$Id$"
|
#define RCS_ASS "$Id$"
|
||||||
|
|
||||||
|
|
536
util/ass/ass30.c
536
util/ass/ass30.c
|
@ -4,117 +4,163 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
#include "ass00.h"
|
#include "ass00.h"
|
||||||
#include "assex.h"
|
#include "assex.h"
|
||||||
|
#include "assci.h"
|
||||||
|
#include "asscm.h"
|
||||||
#include "ip_spec.h"
|
#include "ip_spec.h"
|
||||||
|
|
||||||
#ifndef NORCSID
|
short opt_line; /* max_line_no - # lines removed from end
|
||||||
static char rcs_id[] = "$Id$" ;
|
|
||||||
static char rcs_ip[] = RCS_IP ;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
short opt_line ; /* max_line_no - # lines removed from end
|
|
||||||
after perfoming exc's.
|
after perfoming exc's.
|
||||||
Used to estimate the distance in # of
|
Used to estimate the distance in # of
|
||||||
instructions.
|
instructions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* Forward declarations. */
|
||||||
|
static int valid(register line_t *);
|
||||||
|
static char *findfit(int, cons_t);
|
||||||
|
static char *findnop(int);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Determine the exact instruction length & format where possible, and the
|
** Determine the exact instruction length & format where possible, and the
|
||||||
** the upper and lower limits otherwise. Enter limits in labeltable
|
** the upper and lower limits otherwise. Enter limits in labeltable
|
||||||
*/
|
*/
|
||||||
pass_3()
|
void pass_3(void)
|
||||||
{
|
{
|
||||||
register line_t *lnp, *rev_lnp;
|
register line_t *lnp, *rev_lnp;
|
||||||
line_t *tmp_lnp;
|
line_t *tmp_lnp;
|
||||||
locl_t *lbp;
|
locl_t *lbp;
|
||||||
int min_l, max_l, min_bytes;
|
int min_l, max_l, min_bytes;
|
||||||
short last_line ;
|
short last_line;
|
||||||
short hol_err_line ;
|
short hol_err_line;
|
||||||
register insno ;
|
register int insno;
|
||||||
|
|
||||||
pass = 3;
|
pass = 3;
|
||||||
opt_line= line_num ; hol_err_line=0 ;
|
opt_line = line_num;
|
||||||
min_bytes = max_bytes = 0; rev_lnp= lnp_cast 0 ;
|
hol_err_line = 0;
|
||||||
for (lnp = pstate.s_fline ; lnp ; opt_line--, line_num-- ) {
|
min_bytes = max_bytes = 0;
|
||||||
pstate.s_fline= lnp;
|
rev_lnp = lnp_cast 0;
|
||||||
|
for (lnp = pstate.s_fline; lnp; opt_line--, line_num--)
|
||||||
|
{
|
||||||
|
pstate.s_fline = lnp;
|
||||||
insno = ctrunc(lnp->instr_num);
|
insno = ctrunc(lnp->instr_num);
|
||||||
switch( insno ) {
|
switch (insno)
|
||||||
case sp_fpseu :
|
{
|
||||||
last_line = line_num ;
|
case sp_fpseu:
|
||||||
line_num = lnp->ad.ad_ln.ln_first ;
|
last_line = line_num;
|
||||||
opt_line -= lnp->ad.ad_ln.ln_extra ;
|
line_num = lnp->ad.ad_ln.ln_first;
|
||||||
lnp->ad.ad_ln.ln_first= last_line ;
|
opt_line -= lnp->ad.ad_ln.ln_extra;
|
||||||
break ;
|
lnp->ad.ad_ln.ln_first = last_line;
|
||||||
case sp_ilb1 :
|
break;
|
||||||
|
case sp_ilb1:
|
||||||
lbp = lnp->ad.ad_lp;
|
lbp = lnp->ad.ad_lp;
|
||||||
lbp->l_defined = SEEN;
|
lbp->l_defined = SEEN;
|
||||||
lbp->l_min = min_bytes;
|
lbp->l_min = min_bytes;
|
||||||
lbp->l_max = max_bytes;
|
lbp->l_max = max_bytes;
|
||||||
break ;
|
break;
|
||||||
default:
|
default:
|
||||||
if ( lnp->type1==CONST && (em_flag[insno]&EM_PAR)==PAR_G ) {
|
if (lnp->type1 == CONST && (em_flag[insno] & EM_PAR) == PAR_G)
|
||||||
if (holbase != 0) {
|
{
|
||||||
if (lnp->ad.ad_i >= holsize) {
|
if (holbase != 0)
|
||||||
hol_err_line= line_num ;
|
{
|
||||||
|
if (lnp->ad.ad_i >= holsize)
|
||||||
|
{
|
||||||
|
hol_err_line = line_num;
|
||||||
}
|
}
|
||||||
lnp->ad.ad_i += holbase;
|
lnp->ad.ad_i += holbase;
|
||||||
}
|
}
|
||||||
} else
|
}
|
||||||
if ( lnp->type1>=VALLOW && (em_flag[insno]&EM_PAR)==PAR_G ) {
|
else if (lnp->type1 >= VALLOW && (em_flag[insno] & EM_PAR) == PAR_G)
|
||||||
if (holbase != 0) {
|
{
|
||||||
pstate.s_fline= lnp->l_next ;
|
if (holbase != 0)
|
||||||
newline(CONST) ;
|
{
|
||||||
pstate.s_fline->instr_num= insno ;
|
pstate.s_fline = lnp->l_next;
|
||||||
pstate.s_fline->ad.ad_i=
|
newline(CONST);
|
||||||
VAL1(lnp->type1)+holbase ;
|
pstate.s_fline->instr_num = insno;
|
||||||
freearea((area_t)lnp,
|
pstate.s_fline->ad.ad_i =
|
||||||
(unsigned)linesize[VALLOW]) ;
|
VAL1(lnp->type1) + holbase;
|
||||||
lnp= pstate.s_fline ;
|
freearea((area_t) lnp, (unsigned) linesize[VALLOW]);
|
||||||
if ( VAL1(lnp->type1) >= holsize) {
|
lnp = pstate.s_fline;
|
||||||
hol_err_line= line_num ;
|
if ( VAL1(lnp->type1) >= holsize)
|
||||||
|
{
|
||||||
|
hol_err_line = line_num;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( !valid(lnp) ) fatal("Invalid operand") ;
|
if (!valid(lnp))
|
||||||
|
fatal("Invalid operand");
|
||||||
|
|
||||||
determine_props(lnp, &min_l, &max_l);
|
determine_props(lnp, &min_l, &max_l);
|
||||||
min_bytes += min_l; max_bytes += max_l;
|
min_bytes += min_l;
|
||||||
break ;
|
max_bytes += max_l;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
tmp_lnp= lnp->l_next ;
|
tmp_lnp = lnp->l_next;
|
||||||
lnp->l_next= rev_lnp ; rev_lnp= lnp ;
|
lnp->l_next = rev_lnp;
|
||||||
lnp= tmp_lnp ;
|
rev_lnp = lnp;
|
||||||
|
lnp = tmp_lnp;
|
||||||
}
|
}
|
||||||
pstate.s_fline= rev_lnp ;
|
pstate.s_fline = rev_lnp;
|
||||||
if ( hol_err_line ) {
|
if (hol_err_line)
|
||||||
line_num= hol_err_line ;
|
{
|
||||||
werror("address exceeds holsize") ;
|
line_num = hol_err_line;
|
||||||
|
werror("address exceeds holsize");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int oplength(int flag)
|
||||||
|
{
|
||||||
|
int cnt;
|
||||||
|
|
||||||
|
cnt = 1;
|
||||||
|
if (flag & OPESC)
|
||||||
|
cnt++;
|
||||||
|
switch (flag & OPTYPE)
|
||||||
|
{
|
||||||
|
case OPNO:
|
||||||
|
case OPMINI:
|
||||||
|
break;
|
||||||
|
case OP8:
|
||||||
|
case OPSHORT:
|
||||||
|
cnt++;
|
||||||
|
break;
|
||||||
|
case OP16U:
|
||||||
|
case OP16:
|
||||||
|
cnt += 2;
|
||||||
|
break;
|
||||||
|
case OP32:
|
||||||
|
cnt += 5;
|
||||||
|
break;
|
||||||
|
case OP64:
|
||||||
|
cnt += 9;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return cnt;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Determine the format that should be used for each instruction,
|
** Determine the format that should be used for each instruction,
|
||||||
** depending on its offsets
|
** depending on its offsets
|
||||||
*/
|
*/
|
||||||
|
|
||||||
determine_props(lnp, min_len, max_len)
|
void determine_props(line_t *lnp, int *min_len, int *max_len)
|
||||||
line_t *lnp;
|
|
||||||
int *min_len, *max_len;
|
|
||||||
{
|
{
|
||||||
cons_t val ;
|
cons_t val;
|
||||||
register int insno ;
|
register int insno;
|
||||||
register char *f_off, *l_off ;
|
register char *f_off, *l_off;
|
||||||
char defined ;
|
char defined;
|
||||||
|
|
||||||
insno=ctrunc(lnp->instr_num) ;
|
insno = ctrunc(lnp->instr_num);
|
||||||
val=parval(lnp,&defined) ;
|
val = parval(lnp, &defined);
|
||||||
if ( !defined ) {
|
if (!defined)
|
||||||
switch(em_flag[insno]&EM_PAR) {
|
{
|
||||||
|
switch (em_flag[insno] & EM_PAR)
|
||||||
|
{
|
||||||
case PAR_NO:
|
case PAR_NO:
|
||||||
case PAR_W:
|
case PAR_W:
|
||||||
f_off = findnop(insno) ;
|
f_off = findnop(insno);
|
||||||
break ;
|
break;
|
||||||
case PAR_G:
|
case PAR_G:
|
||||||
/* We want the maximum address that is a multiple
|
/* We want the maximum address that is a multiple
|
||||||
of the wordsize.
|
of the wordsize.
|
||||||
|
@ -123,246 +169,270 @@ determine_props(lnp, min_len, max_len)
|
||||||
where intr is a instruction allowing parameters
|
where intr is a instruction allowing parameters
|
||||||
that are not a word multiple (PAR_G).
|
that are not a word multiple (PAR_G).
|
||||||
*/
|
*/
|
||||||
f_off = findfit(insno, maxadr&(~(wordsize-1))) ;
|
f_off = findfit(insno, maxadr & (~(wordsize - 1)));
|
||||||
break ;
|
break;
|
||||||
case PAR_B:
|
case PAR_B:
|
||||||
f_off = findfit(insno, (cons_t)0) ;
|
f_off = findfit(insno, (cons_t) 0);
|
||||||
l_off = findfit(insno, val ) ;
|
l_off = findfit(insno, val);
|
||||||
if ( f_off != l_off ) {
|
if (f_off != l_off)
|
||||||
*min_len=oplength(*f_off) ;
|
{
|
||||||
*max_len=oplength(*l_off) ;
|
*min_len = oplength(*f_off);
|
||||||
lnp->opoff = NO_OFF ;
|
*max_len = oplength(*l_off);
|
||||||
return ;
|
lnp->opoff = NO_OFF;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
break ;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
f_off = findfit(insno,val) ;
|
|
||||||
}
|
}
|
||||||
lnp->opoff = f_off ;
|
else
|
||||||
*min_len = *max_len = oplength(*f_off) ;
|
{
|
||||||
|
f_off = findfit(insno, val);
|
||||||
|
}
|
||||||
|
lnp->opoff = f_off;
|
||||||
|
*min_len = *max_len = oplength(*f_off);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *findfit(instr,val) int instr ; cons_t val ; {
|
static char *findfit(int instr, cons_t val)
|
||||||
register char *currc,*endc ;
|
{
|
||||||
int found, flags, number ;
|
register char *currc, *endc;
|
||||||
char *opc ;
|
int found, flags, number;
|
||||||
|
char *opc;
|
||||||
|
|
||||||
endc = opindex[instr+1] ;
|
endc = opindex[instr + 1];
|
||||||
for ( currc=opindex[instr], found=0 ;
|
for (currc = opindex[instr], found = 0; !found && currc < endc; currc++)
|
||||||
!found && currc<endc ; currc++ ) {
|
{
|
||||||
opc = currc ;
|
opc = currc;
|
||||||
flags=ctrunc(*currc++) ;
|
flags = ctrunc(*currc++);
|
||||||
switch ( flags&OPTYPE ) {
|
switch (flags & OPTYPE)
|
||||||
case OPNO :
|
{
|
||||||
continue ;
|
case OPNO:
|
||||||
case OPMINI :
|
continue;
|
||||||
case OPSHORT :
|
case OPMINI:
|
||||||
number=ctrunc(*++currc) ;
|
case OPSHORT:
|
||||||
|
number = ctrunc(*++currc);
|
||||||
}
|
}
|
||||||
found = opfit(flags, number, val, em_flag[instr]&EM_PAR ) ;
|
found = opfit(flags, number, val, em_flag[instr] & EM_PAR);
|
||||||
}
|
}
|
||||||
if ( !found ) fatal("Cannot find interpreter opcode") ;
|
if (!found)
|
||||||
return opc ;
|
fatal("Cannot find interpreter opcode");
|
||||||
|
return opc;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *findnop(instr) int instr ; {
|
static char* findnop(int instr)
|
||||||
register char *currc,*endc ;
|
{
|
||||||
|
register char *currc, *endc;
|
||||||
|
|
||||||
endc = opindex[instr+1] ;
|
endc = opindex[instr + 1];
|
||||||
for ( currc=opindex[instr] ; currc<endc ; currc++ ) {
|
for (currc = opindex[instr]; currc < endc; currc++)
|
||||||
switch ( ctrunc(*currc)&OPTYPE ) {
|
{
|
||||||
case OPNO :
|
switch ( ctrunc(*currc) & OPTYPE)
|
||||||
return currc ;
|
{
|
||||||
case OPSHORT :
|
case OPNO:
|
||||||
case OPMINI :
|
return currc;
|
||||||
currc++ ;
|
case OPSHORT:
|
||||||
|
case OPMINI:
|
||||||
|
currc++;
|
||||||
}
|
}
|
||||||
currc++ ;
|
currc++;
|
||||||
}
|
}
|
||||||
fatal("Cannot find interpreter opcode") ;
|
fatal("Cannot find interpreter opcode");
|
||||||
/* NOTREACHED */
|
/* NOTREACHED */
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int opfit(flag,number,val,i_flag)
|
int opfit(int flag, int number, cons_t val, int i_flag)
|
||||||
int i_flag,flag,number ; cons_t val ; {
|
{
|
||||||
/* Number is invalid if flag does not contain MINI or SHORT */
|
/* Number is invalid if flag does not contain MINI or SHORT */
|
||||||
switch ( flag&OPRANGE ) {
|
switch (flag & OPRANGE)
|
||||||
case OP_POS :
|
{
|
||||||
if ( val<0 ) return 0 ;
|
case OP_POS:
|
||||||
break ;
|
if (val < 0)
|
||||||
case OP_NEG :
|
return 0;
|
||||||
if ( val>=0 ) return 0 ;
|
break;
|
||||||
break ;
|
case OP_NEG:
|
||||||
|
if (val >= 0)
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if ( flag&OPWORD ) {
|
if (flag & OPWORD)
|
||||||
if ( val%wordsize ) return 0 ;
|
{
|
||||||
val /= wordsize ;
|
if (val % wordsize)
|
||||||
|
return 0;
|
||||||
|
val /= wordsize;
|
||||||
}
|
}
|
||||||
if ( flag&OPNZ ) {
|
if (flag & OPNZ)
|
||||||
if ( val==0 ) return 0 ;
|
{
|
||||||
val-- ;
|
if (val == 0)
|
||||||
|
return 0;
|
||||||
|
val--;
|
||||||
}
|
}
|
||||||
switch ( flag&OPTYPE ) {
|
switch (flag & OPTYPE)
|
||||||
case OPMINI :
|
{
|
||||||
if ( val<0 ) val = -1-val ;
|
case OPMINI:
|
||||||
return val>=0 && val<number ;
|
if (val < 0)
|
||||||
case OPSHORT :
|
val = -1 - val;
|
||||||
if ( val<0 ) val = -1-val ;
|
return val >= 0 && val < number;
|
||||||
return val>=0 && val<number*256 ;
|
case OPSHORT:
|
||||||
|
if (val < 0)
|
||||||
|
val = -1 - val;
|
||||||
|
return val >= 0 && val < number * 256;
|
||||||
case OP16U:
|
case OP16U:
|
||||||
return val>=0 && val<=65535L &&
|
return val >= 0 && val <= 65535L && (i_flag != PAR_G || val <= maxadr);
|
||||||
( i_flag!=PAR_G || val<=maxadr ) ;
|
case OP16:
|
||||||
case OP16 :
|
return val >= -32768 && val <= 32767;
|
||||||
return val>= -32768 && val<=32767 ;
|
case OP32:
|
||||||
case OP32 :
|
return TRUE;
|
||||||
return TRUE ;
|
default:
|
||||||
default :
|
fatal("illegal OPTYPE value");
|
||||||
fatal("illegal OPTYPE value") ;
|
return -1;
|
||||||
/* NOTREACHED */
|
/* NOTREACHED */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int oplength(flag) int flag ; {
|
|
||||||
int cnt ;
|
|
||||||
|
|
||||||
cnt=1 ;
|
|
||||||
if ( flag&OPESC ) cnt++ ;
|
|
||||||
switch( flag&OPTYPE ) {
|
|
||||||
case OPNO :
|
|
||||||
case OPMINI : break ;
|
|
||||||
case OP8 :
|
|
||||||
case OPSHORT : cnt++ ; break ;
|
|
||||||
case OP16U:
|
|
||||||
case OP16 : cnt+=2 ; break ;
|
|
||||||
case OP32 : cnt+=5 ; break ;
|
|
||||||
case OP64 : cnt+=9 ; break ;
|
|
||||||
}
|
|
||||||
return cnt ;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** return estimation of value of parameter
|
** return estimation of value of parameter
|
||||||
*/
|
*/
|
||||||
cons_t parval(lnp,defined)
|
cons_t parval(line_t *lnp, char *defined)
|
||||||
line_t *lnp;
|
|
||||||
char *defined;
|
|
||||||
{
|
{
|
||||||
register int type;
|
register int type;
|
||||||
register locl_t *lbp;
|
register locl_t *lbp;
|
||||||
register glob_t *gbp;
|
register glob_t *gbp;
|
||||||
cons_t offs ;
|
cons_t offs;
|
||||||
|
|
||||||
*defined = TRUE ;
|
*defined = TRUE;
|
||||||
type = lnp->type1;
|
type = lnp->type1;
|
||||||
switch(type) {
|
switch (type)
|
||||||
default: if ( type>=VALLOW && type<=VALHIGH )
|
{
|
||||||
return VAL1(type) ;
|
default:
|
||||||
|
if (type >= VALLOW && type <= VALHIGH)
|
||||||
|
return VAL1(type);
|
||||||
error("bad type during parval");
|
error("bad type during parval");
|
||||||
break;
|
break;
|
||||||
case CONST:
|
case CONST:
|
||||||
return(lnp->ad.ad_i);
|
return (lnp->ad.ad_i);
|
||||||
case GLOSYM:
|
case GLOSYM:
|
||||||
case GLOOFF:
|
case GLOOFF:
|
||||||
if ( type!=GLOOFF) {
|
if (type != GLOOFF)
|
||||||
|
{
|
||||||
gbp = lnp->ad.ad_gp;
|
gbp = lnp->ad.ad_gp;
|
||||||
offs= 0 ;
|
offs = 0;
|
||||||
} else {
|
|
||||||
gbp =lnp->ad.ad_df.df_gp ;
|
|
||||||
offs=lnp->ad.ad_df.df_i ;
|
|
||||||
}
|
}
|
||||||
if(gbp->g_status&DEF)
|
else
|
||||||
return(gbp->g_val.g_addr+offs);
|
{
|
||||||
else {
|
gbp = lnp->ad.ad_df.df_gp;
|
||||||
*defined = FALSE ;
|
offs = lnp->ad.ad_df.df_i;
|
||||||
return offs ;
|
}
|
||||||
|
if (gbp->g_status & DEF)
|
||||||
|
return (gbp->g_val.g_addr + offs);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*defined = FALSE;
|
||||||
|
return offs;
|
||||||
}
|
}
|
||||||
case LOCSYM:
|
case LOCSYM:
|
||||||
lbp = lnp->ad.ad_lp;
|
lbp = lnp->ad.ad_lp;
|
||||||
switch(pass) {
|
switch (pass)
|
||||||
default:error("bad pass in parval");
|
{
|
||||||
|
default:
|
||||||
|
error("bad pass in parval");
|
||||||
case 3:
|
case 3:
|
||||||
*defined = FALSE;
|
*defined = FALSE;
|
||||||
switch(lbp->l_defined) {
|
switch (lbp->l_defined)
|
||||||
default : fatal("Illegal local label") ;
|
{
|
||||||
case NO :
|
default:
|
||||||
error("Undefined local label") ;
|
fatal("Illegal local label");
|
||||||
lbp->l_defined= NOTPRESENT ;
|
case NO:
|
||||||
|
error("Undefined local label");
|
||||||
|
lbp->l_defined = NOTPRESENT;
|
||||||
case NOTPRESENT:
|
case NOTPRESENT:
|
||||||
return max_bytes;
|
return max_bytes;
|
||||||
case SEEN :
|
case SEEN:
|
||||||
return max_bytes - lbp->l_min ;
|
return max_bytes - lbp->l_min;
|
||||||
case YES :
|
case YES:
|
||||||
/* l_min contains line_num
|
/* l_min contains line_num
|
||||||
adjusted for exc's.
|
adjusted for exc's.
|
||||||
*/
|
*/
|
||||||
return (lbp->l_min - opt_line -1 ) * maxinsl ;
|
return (lbp->l_min - opt_line - 1) * maxinsl;
|
||||||
}
|
}
|
||||||
case 4: if(lbp->l_defined == YES)
|
case 4:
|
||||||
return(lbp->l_min-prog_size-maxinsl);
|
if (lbp->l_defined == YES)
|
||||||
return max_bytes - lbp->l_max- prog_size;
|
return (lbp->l_min - prog_size - maxinsl);
|
||||||
case 5: if (lbp->l_defined == YES )
|
return max_bytes - lbp->l_max - prog_size;
|
||||||
return lbp->l_min ;
|
case 5:
|
||||||
*defined = FALSE ;
|
if (lbp->l_defined == YES)
|
||||||
break ;
|
return lbp->l_min;
|
||||||
|
*defined = FALSE;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MISSING:
|
case MISSING:
|
||||||
*defined = FALSE ;
|
*defined = FALSE;
|
||||||
break;
|
break;
|
||||||
case PROCNAME:
|
case PROCNAME:
|
||||||
return(lnp->ad.ad_pp->p_num);
|
return (lnp->ad.ad_pp->p_num);
|
||||||
}
|
}
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
int valid(lnp) register line_t *lnp ; {
|
|
||||||
cons_t val ;
|
|
||||||
int type ;
|
|
||||||
|
|
||||||
type = lnp->type1 ;
|
static int valid(register line_t *lnp)
|
||||||
if ( type>=VALLOW && type<=VALHIGH ) {
|
{
|
||||||
val= VAL1(type) ;
|
cons_t val;
|
||||||
type= CONST ;
|
int type;
|
||||||
} else if ( type==CONST ) val = lnp->ad.ad_i ;
|
|
||||||
switch ( em_flag[ctrunc(lnp->instr_num)]&EM_PAR ) {
|
type = lnp->type1;
|
||||||
|
if (type >= VALLOW && type <= VALHIGH)
|
||||||
|
{
|
||||||
|
val = VAL1(type);
|
||||||
|
type = CONST;
|
||||||
|
}
|
||||||
|
else if (type == CONST)
|
||||||
|
val = lnp->ad.ad_i;
|
||||||
|
switch (em_flag[ctrunc(lnp->instr_num)] & EM_PAR)
|
||||||
|
{
|
||||||
case PAR_NO:
|
case PAR_NO:
|
||||||
return type==MISSING ;
|
return type == MISSING;
|
||||||
case PAR_C:
|
case PAR_C:
|
||||||
if ( type!=CONST ) return FALSE;
|
if (type != CONST)
|
||||||
if ( val>maxint && val<=maxunsig ) {
|
return FALSE;
|
||||||
lnp->ad.ad_i = val -maxunsig -1 ;
|
if (val > maxint && val <= maxunsig)
|
||||||
|
{
|
||||||
|
lnp->ad.ad_i = val - maxunsig - 1;
|
||||||
}
|
}
|
||||||
return TRUE ;
|
return TRUE;
|
||||||
case PAR_D:
|
case PAR_D:
|
||||||
if ( type!=CONST ) return FALSE;
|
if (type != CONST)
|
||||||
if ( val>maxdint && val<=maxdunsig ) {
|
return FALSE;
|
||||||
lnp->ad.ad_i = val -maxdunsig -1 ;
|
if (val > maxdint && val <= maxdunsig)
|
||||||
|
{
|
||||||
|
lnp->ad.ad_i = val - maxdunsig - 1;
|
||||||
}
|
}
|
||||||
return TRUE ;
|
return TRUE;
|
||||||
case PAR_L:
|
case PAR_L:
|
||||||
case PAR_F:
|
case PAR_F:
|
||||||
return type==CONST ;
|
return type == CONST;
|
||||||
case PAR_N:
|
case PAR_N:
|
||||||
return type==CONST && val>=0 ;
|
return type == CONST && val >= 0;
|
||||||
case PAR_G:
|
case PAR_G:
|
||||||
return type==CONST || type==GLOSYM || type==GLOOFF ;
|
return type == CONST || type == GLOSYM || type == GLOOFF;
|
||||||
case PAR_W:
|
case PAR_W:
|
||||||
if ( type==MISSING ) return TRUE ;
|
if (type == MISSING)
|
||||||
|
return TRUE;
|
||||||
case PAR_S:
|
case PAR_S:
|
||||||
return type==CONST && val>0 && val%wordsize==0 ;
|
return type == CONST && val > 0 && val % wordsize == 0;
|
||||||
case PAR_Z:
|
case PAR_Z:
|
||||||
return type==CONST && val>=0 && val%wordsize==0 ;
|
return type == CONST && val >= 0 && val % wordsize == 0;
|
||||||
case PAR_O:
|
case PAR_O:
|
||||||
return type==CONST && val>=0 &&
|
return type == CONST && val >= 0
|
||||||
( val >= wordsize ? val%wordsize : wordsize%val ) == 0 ;
|
&& (val >= wordsize ? val % wordsize : wordsize % val) == 0;
|
||||||
case PAR_P:
|
case PAR_P:
|
||||||
return type==PROCNAME ;
|
return type == PROCNAME;
|
||||||
case PAR_B:
|
case PAR_B:
|
||||||
return type==LOCSYM ;
|
return type == LOCSYM;
|
||||||
case PAR_R:
|
case PAR_R:
|
||||||
return type==CONST && val>=0 && val<=3 ;
|
return type == CONST && val >= 0 && val <= 3;
|
||||||
default:
|
default:
|
||||||
fatal("Unknown parameter type") ;
|
fatal("Unknown parameter type");
|
||||||
|
return -1;
|
||||||
/* NOTREACHED */
|
/* NOTREACHED */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,15 +7,13 @@
|
||||||
#include "ass00.h"
|
#include "ass00.h"
|
||||||
#include "assex.h"
|
#include "assex.h"
|
||||||
|
|
||||||
#ifndef NORCSID
|
|
||||||
static char rcs_id[] = "$Id$" ;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Make scans to do final assignment of instruction sizes & formats
|
** Make scans to do final assignment of instruction sizes & formats
|
||||||
** to those not already done. assign final values to labels
|
** to those not already done. assign final values to labels
|
||||||
*/
|
*/
|
||||||
pass_4()
|
void pass_4(void)
|
||||||
{
|
{
|
||||||
register line_t *lnp;
|
register line_t *lnp;
|
||||||
register locl_t *lbp;
|
register locl_t *lbp;
|
||||||
|
|
|
@ -6,19 +6,21 @@
|
||||||
|
|
||||||
#include "ass00.h"
|
#include "ass00.h"
|
||||||
#include "assex.h"
|
#include "assex.h"
|
||||||
|
#include "assrl.h"
|
||||||
#include "ip_spec.h"
|
#include "ip_spec.h"
|
||||||
|
|
||||||
#ifndef NORCSID
|
|
||||||
static char rcs_id[] = "$Id$" ;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Pass 5 of EM1 assembler/loader
|
** Pass 5 of EM1 assembler/loader
|
||||||
** Fix reloc tables
|
** Fix reloc tables
|
||||||
** Write out code
|
** Write out code
|
||||||
*/
|
*/
|
||||||
|
|
||||||
pass_5() {
|
static void patchcase(void);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void pass_5(void)
|
||||||
|
{
|
||||||
register line_t *lnp;
|
register line_t *lnp;
|
||||||
cons_t off1;
|
cons_t off1;
|
||||||
char defined ;
|
char defined ;
|
||||||
|
@ -78,14 +80,15 @@ pass_5() {
|
||||||
|
|
||||||
} /* end pass_5 */
|
} /* end pass_5 */
|
||||||
|
|
||||||
genop(startc,value,i_flag) char *startc ; cons_t value ; int i_flag ; {
|
|
||||||
char *currc ;
|
|
||||||
register flag ;
|
|
||||||
char opc ;
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Real code generation.
|
* Real code generation.
|
||||||
*/
|
*/
|
||||||
|
void genop(char *startc,cons_t value,int i_flag)
|
||||||
|
{
|
||||||
|
char *currc ;
|
||||||
|
register int flag ;
|
||||||
|
char opc ;
|
||||||
|
|
||||||
currc= startc ;
|
currc= startc ;
|
||||||
flag = ctrunc(*currc++);
|
flag = ctrunc(*currc++);
|
||||||
|
@ -161,11 +164,12 @@ genop(startc,value,i_flag) char *startc ; cons_t value ; int i_flag ; {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
patchcase() {
|
static void patchcase(void)
|
||||||
|
{
|
||||||
register relc_t *r;
|
register relc_t *r;
|
||||||
register locl_t *k;
|
register locl_t *k;
|
||||||
|
|
||||||
if ( r= pstate.s_fdata ) {
|
if ( (r= pstate.s_fdata) ) {
|
||||||
r= r->r_next ;
|
r= r->r_next ;
|
||||||
} else {
|
} else {
|
||||||
r= f_data ;
|
r= f_data ;
|
||||||
|
|
278
util/ass/ass60.c
278
util/ass/ass60.c
|
@ -8,61 +8,73 @@
|
||||||
#include "assex.h"
|
#include "assex.h"
|
||||||
#include "ip_spec.h"
|
#include "ip_spec.h"
|
||||||
|
|
||||||
#ifndef NORCSID
|
|
||||||
static char rcs_id[] = "$Id$" ;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef DUMP
|
#ifdef DUMP
|
||||||
static char *typestr[] =
|
static char *typestr[] =
|
||||||
{"missing","const","procname","glosym","locsym","glosym+off","pseudo"};
|
{ "missing", "const", "procname", "glosym", "locsym", "glosym+off", "pseudo" };
|
||||||
static char *labstr[] = {"EMPTY","no","yes","seen","notpresent"};
|
static char *labstr[] =
|
||||||
static char formstr[] = { 'm','s','-','1','2','4','8' };
|
{ "EMPTY", "no", "yes", "seen", "notpresent" };
|
||||||
static char *r_data[] = { "null","glob","head","loc","adr" };
|
static char formstr[] =
|
||||||
|
{ 'm', 's', '-', '1', '2', '4', '8' };
|
||||||
|
static char *r_data[] =
|
||||||
|
{ "null", "glob", "head", "loc", "adr" };
|
||||||
|
|
||||||
cons_t nicepr(typ,ap) addr_u *ap; {
|
cons_t nicepr(int typ, addr_u *ap)
|
||||||
|
{
|
||||||
register proc_t *pl;
|
register proc_t *pl;
|
||||||
|
|
||||||
switch (typ) {
|
switch (typ)
|
||||||
|
{
|
||||||
case CONST:
|
case CONST:
|
||||||
return(ap->ad_i);
|
return (ap->ad_i);
|
||||||
case LOCSYM:
|
case LOCSYM:
|
||||||
return(int_cast ap->ad_lp);
|
return (int_cast ap->ad_lp);
|
||||||
case GLOOFF:
|
case GLOOFF:
|
||||||
return(ap->ad_df.df_gp - mglobs);
|
return (ap->ad_df.df_gp - mglobs);
|
||||||
case GLOSYM:
|
case GLOSYM:
|
||||||
return(ap->ad_gp - mglobs);
|
return (ap->ad_gp - mglobs);
|
||||||
case PROCNAME:
|
case PROCNAME:
|
||||||
pl = ap->ad_pp;;
|
pl = ap->ad_pp;
|
||||||
if (pl->p_status&EXT)
|
;
|
||||||
return((pl-xprocs)+1000);
|
if (pl->p_status & EXT)
|
||||||
|
return ((pl - xprocs) + 1000);
|
||||||
else
|
else
|
||||||
return(pl-mprocs);
|
return (pl - mprocs);
|
||||||
default:
|
default:
|
||||||
if ( typ>=VALLOW && typ<=VALHIGH ) return VAL1(typ) ;
|
if (typ >= VALLOW && typ <= VALHIGH)
|
||||||
break ;
|
return VAL1(typ);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return(0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *pflags(flg) int flg ; {
|
char *pflags(int flg)
|
||||||
static char res[9] ;
|
{
|
||||||
register char *cp ;
|
static char res[9];
|
||||||
|
register char *cp;
|
||||||
|
|
||||||
cp=res ;
|
cp = res;
|
||||||
if ( flg&OPESC ) *cp++ = 'e' ;
|
if (flg & OPESC)
|
||||||
switch ( flg&OPRANGE ) {
|
*cp++ = 'e';
|
||||||
case OP_NEG : *cp++ = 'N' ; break ;
|
switch (flg & OPRANGE)
|
||||||
case OP_POS : *cp++ = 'P' ; break ;
|
{
|
||||||
|
case OP_NEG:
|
||||||
|
*cp++ = 'N';
|
||||||
|
break;
|
||||||
|
case OP_POS:
|
||||||
|
*cp++ = 'P';
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if ( flg&OPWORD ) *cp++ = 'w' ;
|
if (flg & OPWORD)
|
||||||
if ( flg&OPNZ ) *cp++ = 'o' ;
|
*cp++ = 'w';
|
||||||
*cp++ = formstr[flg&OPTYPE] ;
|
if (flg & OPNZ)
|
||||||
*cp++ = 0 ;
|
*cp++ = 'o';
|
||||||
return res ;
|
*cp++ = formstr[flg & OPTYPE];
|
||||||
|
*cp++ = 0;
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void dump(int n)
|
||||||
dump(n)
|
|
||||||
{
|
{
|
||||||
register glob_t *gb;
|
register glob_t *gb;
|
||||||
register line_t *ln;
|
register line_t *ln;
|
||||||
|
@ -71,27 +83,32 @@ dump(n)
|
||||||
proc_t *pl;
|
proc_t *pl;
|
||||||
int i;
|
int i;
|
||||||
int insno;
|
int insno;
|
||||||
extern char em_mnem[][4] ;
|
extern char em_mnem[][4];
|
||||||
|
|
||||||
if (d_flag==0) return;
|
if (d_flag == 0)
|
||||||
if ( (n==0 && d_flag) || (n==4 && d_flag>=2) || (n<100 && d_flag>=3) ) {
|
return;
|
||||||
printf("\nEM1-assembler ***** pass %1d complete:\n",n);
|
if ((n == 0 && d_flag) || (n == 4 && d_flag >= 2)
|
||||||
printf("current size %ld\n",prog_size) ;
|
|| (n < 100 && d_flag >= 3))
|
||||||
printf(" %9.9s%9.9s%14.14s%8.8s%8.8s\n", "instr_nr",
|
{
|
||||||
"type1","addr1","length","format");
|
printf("\nEM1-assembler ***** pass %1d complete:\n", n);
|
||||||
for (ln = pstate.s_fline ; ln ;
|
printf("current size %ld\n", prog_size);
|
||||||
ln = ln->l_next, n>=3 || n==0 ? i++ : i-- ) {
|
printf(" %9.9s%9.9s%14.14s%8.8s%8.8s\n", "instr_nr", "type1", "addr1",
|
||||||
insno = ctrunc(ln->instr_num) ;
|
"length", "format");
|
||||||
if ( insno==sp_fpseu ) {
|
for (ln = pstate.s_fline; ln;
|
||||||
i= ln->ad.ad_ln.ln_first ;
|
ln = ln->l_next, n >= 3 || n == 0 ? i++ : i--)
|
||||||
continue ;
|
{
|
||||||
|
insno = ctrunc(ln->instr_num);
|
||||||
|
if (insno == sp_fpseu)
|
||||||
|
{
|
||||||
|
i = ln->ad.ad_ln.ln_first;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
printf("%4d ",i) ;
|
printf("%4d ", i);
|
||||||
switch(insno) {
|
switch (insno)
|
||||||
|
{
|
||||||
default:
|
default:
|
||||||
printf(
|
printf(" %3.3s", em_mnem[insno]);
|
||||||
" %3.3s",em_mnem[insno]) ;
|
break;
|
||||||
break ;
|
|
||||||
case sp_ilb1:
|
case sp_ilb1:
|
||||||
printf("l ");
|
printf("l ");
|
||||||
break;
|
break;
|
||||||
|
@ -100,105 +117,118 @@ if ( (n==0 && d_flag) || (n==4 && d_flag>=2) || (n<100 && d_flag>=3) ) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
printf(" %9.9s%14ld",
|
printf(" %9.9s%14ld",
|
||||||
typestr[ln->type1<VALLOW ? ln->type1 : CONST],
|
typestr[ln->type1 < VALLOW ? ln->type1 : CONST],
|
||||||
nicepr(ln->type1,&ln->ad)) ;
|
nicepr(ln->type1, &ln->ad));
|
||||||
if ( ln->opoff != NO_OFF )
|
if (ln->opoff != NO_OFF)
|
||||||
printf("%5d %.6s",
|
printf("%5d %.6s", oplength(*(ln->opoff)),
|
||||||
oplength(*(ln->opoff)),pflags(*(ln->opoff)));
|
pflags(*(ln->opoff)));
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
printf("\n %8s%8s%8s%8s%8s\n","labnum","labid","minval","maxval",
|
printf("\n %8s%8s%8s%8s%8s\n", "labnum", "labid", "minval", "maxval",
|
||||||
"defined");
|
"defined");
|
||||||
for ( i = 0, lbhead= *pstate.s_locl ; i<LOCLABSIZE ; lbhead++,i++) {
|
for (i = 0, lbhead = *pstate.s_locl; i < LOCLABSIZE; lbhead++, i++)
|
||||||
if ( lbhead->l_defined!=EMPTY ) printf("%4d\n",i);
|
{
|
||||||
for (lbp= lbhead; lbp != lbp_cast 0; lbp= lbp->l_chain) {
|
if (lbhead->l_defined != EMPTY)
|
||||||
if (lbp->l_defined!=EMPTY)
|
printf("%4d\n", i);
|
||||||
|
for (lbp = lbhead; lbp != lbp_cast 0; lbp = lbp->l_chain)
|
||||||
|
{
|
||||||
|
if (lbp->l_defined != EMPTY)
|
||||||
printf(" %8d%8d%8d%8d %-s\n",
|
printf(" %8d%8d%8d%8d %-s\n",
|
||||||
lbp->l_hinum*LOCLABSIZE + i,
|
lbp->l_hinum * LOCLABSIZE + i,
|
||||||
int_cast lbp,lbp->l_min,
|
int_cast lbp, lbp->l_min, lbp->l_max,
|
||||||
lbp->l_max, labstr[lbp->l_defined]);
|
labstr[(unsigned char)lbp->l_defined]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( ( (n==0 || n>=100) && d_flag) || (n<=1 && d_flag>=2) ) {
|
if (((n == 0 || n >= 100) && d_flag) || (n <= 1 && d_flag >= 2))
|
||||||
if ( n==0 || n==100 ) {
|
{
|
||||||
printf("File %s",curfile) ;
|
if (n == 0 || n == 100)
|
||||||
if ( archmode ) printf("(%.14s)",archhdr.ar_name);
|
{
|
||||||
printf(" :\n\n") ;
|
printf("File %s", curfile);
|
||||||
|
if (archmode)
|
||||||
|
printf("(%.14s)", archhdr.ar_name);
|
||||||
|
printf(" :\n\n");
|
||||||
}
|
}
|
||||||
printf("Local data labels:\n");
|
printf("Local data labels:\n");
|
||||||
printf(
|
printf("\n\t%8.8s %8.8s %8.8s\n", "g_name", "g_status", "g_addr");
|
||||||
"\n\t%8.8s %8.8s %8.8s\n","g_name","g_status","g_addr");
|
for (gb = mglobs, i = 0; gb < &mglobs[oursize->n_mlab]; gb++, i++)
|
||||||
for (gb = mglobs,i = 0;gb < &mglobs[oursize->n_mlab]; gb++, i++)
|
if (gb->g_name[0] != 0)
|
||||||
if (gb->g_name[0] != 0) {
|
{
|
||||||
printf("%5d\t%8.6s",i,gb->g_name);
|
printf("%5d\t%8.6s", i, gb->g_name);
|
||||||
printf(" %8o %8ld\n",gb->g_status,gb->g_val.g_addr);
|
printf(" %8o %8ld\n", gb->g_status, gb->g_val.g_addr);
|
||||||
}
|
}
|
||||||
printf("\n\nGlobal data labels\n");
|
printf("\n\nGlobal data labels\n");
|
||||||
printf("\n\t%8.8s %8.8s %8.8s\n",
|
printf("\n\t%8.8s %8.8s %8.8s\n", "g_name", "g_status", "g_addr");
|
||||||
"g_name","g_status","g_addr");
|
for (gb = xglobs, i = 0; gb < &xglobs[oursize->n_glab]; gb++, i++)
|
||||||
for (gb = xglobs,i = 0;gb < &xglobs[oursize->n_glab]; gb++, i++)
|
if (gb->g_name != 0)
|
||||||
if (gb->g_name != 0) {
|
{
|
||||||
printf("%5d\t%8.6s",i,gb->g_name);
|
printf("%5d\t%8.6s", i, gb->g_name);
|
||||||
printf(" %8o %8ld\n",gb->g_status,gb->g_val.g_addr);
|
printf(" %8o %8ld\n", gb->g_status, gb->g_val.g_addr);
|
||||||
}
|
}
|
||||||
printf("\n\nLocal procedures\n");
|
printf("\n\nLocal procedures\n");
|
||||||
printf("\n\t%8.8s%8s%8s\t%8s%8s\n",
|
printf("\n\t%8.8s%8s%8s\t%8s%8s\n", "name", "status", "num", "off",
|
||||||
"name","status","num","off","locals");
|
"locals");
|
||||||
for (pl=mprocs;pl< &mprocs[oursize->n_mproc]; pl++)
|
for (pl = mprocs; pl < &mprocs[oursize->n_mproc]; pl++)
|
||||||
if (pl->p_name) {
|
if (pl->p_name)
|
||||||
printf("%4d\t%-8s%8o%8d",
|
{
|
||||||
pl-mprocs,pl->p_name,pl->p_status,pl->p_num);
|
printf("%4d\t%-8s%8o%8d", pl - mprocs, pl->p_name, pl->p_status,
|
||||||
if (pl->p_status&DEF)
|
pl->p_num);
|
||||||
printf("\t%8ld%8ld",proctab[pl->p_num].pr_off,
|
if (pl->p_status & DEF)
|
||||||
|
printf("\t%8ld%8ld", proctab[pl->p_num].pr_off,
|
||||||
proctab[pl->p_num].pr_loc);
|
proctab[pl->p_num].pr_loc);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
printf("\nGlobal procedures\n");
|
printf("\nGlobal procedures\n");
|
||||||
printf("\n\t%8s%8s%8s\t%8s%8s\n",
|
printf("\n\t%8s%8s%8s\t%8s%8s\n", "name", "status", "num", "off",
|
||||||
"name","status","num","off","locals");
|
"locals");
|
||||||
for (pl=xprocs;pl< &xprocs[oursize->n_xproc]; pl++)
|
for (pl = xprocs; pl < &xprocs[oursize->n_xproc]; pl++)
|
||||||
if (pl->p_name) {
|
if (pl->p_name)
|
||||||
printf("%4d\t%-8s%8o%8d",
|
{
|
||||||
pl-xprocs,pl->p_name,pl->p_status,pl->p_num);
|
printf("%4d\t%-8s%8o%8d", pl - xprocs, pl->p_name, pl->p_status,
|
||||||
if (pl->p_status&DEF)
|
pl->p_num);
|
||||||
printf("\t%8ld%8ld",proctab[pl->p_num].pr_off,
|
if (pl->p_status & DEF)
|
||||||
|
printf("\t%8ld%8ld", proctab[pl->p_num].pr_off,
|
||||||
proctab[pl->p_num].pr_loc);
|
proctab[pl->p_num].pr_loc);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
if ( r_flag ) {
|
if (r_flag)
|
||||||
register relc_t *rl ;
|
{
|
||||||
printf("\nData relocation\n") ;
|
register relc_t *rl;
|
||||||
printf("\n\t%10s %10s %10s\n","offset","type","value");
|
printf("\nData relocation\n");
|
||||||
for ( rl=f_data ; rl ; rl= rl->r_next ) {
|
printf("\n\t%10s %10s %10s\n", "offset", "type", "value");
|
||||||
printf("\t%10ld %10s ",rl->r_off,r_data[rl->r_typ]);
|
for (rl = f_data; rl; rl = rl->r_next)
|
||||||
switch(rl->r_typ) {
|
{
|
||||||
|
printf("\t%10ld %10s ", rl->r_off, r_data[rl->r_typ]);
|
||||||
|
switch (rl->r_typ)
|
||||||
|
{
|
||||||
case RELADR:
|
case RELADR:
|
||||||
case RELHEAD:
|
case RELHEAD:
|
||||||
printf("%10ld\n",rl->r_val.rel_i) ;
|
printf("%10ld\n", rl->r_val.rel_i);
|
||||||
break ;
|
break;
|
||||||
case RELGLO:
|
case RELGLO:
|
||||||
printf("%8.8s\n",rl->r_val.rel_gp->g_name) ;
|
printf("%8.8s\n", rl->r_val.rel_gp->g_name);
|
||||||
break ;
|
break;
|
||||||
case RELLOC:
|
case RELLOC:
|
||||||
printf("%10d\n",rl->r_val.rel_lp) ;
|
printf("%10d\n", rl->r_val.rel_lp);
|
||||||
break ;
|
break;
|
||||||
case RELNULL:
|
case RELNULL:
|
||||||
printf("\n"); break ;
|
printf("\n");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
printf("\n\nText relocation\n") ;
|
printf("\n\nText relocation\n");
|
||||||
printf("\n\t%10s %10s %10s\n","offset","flags","value");
|
printf("\n\t%10s %10s %10s\n", "offset", "flags", "value");
|
||||||
for ( rl=f_text; rl ; rl= rl->r_next ) {
|
for (rl = f_text; rl; rl = rl->r_next)
|
||||||
printf("\t%10ld %10s ",
|
{
|
||||||
rl->r_off,pflags(opchoice[rl->r_typ&~RELMNS])) ;
|
printf("\t%10ld %10s ", rl->r_off,
|
||||||
if ( rl->r_typ&RELMNS )
|
pflags(opchoice[rl->r_typ & ~RELMNS]));
|
||||||
printf("%10ld\n",rl->r_val.rel_i) ;
|
if (rl->r_typ & RELMNS)
|
||||||
else printf("\n") ;
|
printf("%10ld\n", rl->r_val.rel_i);
|
||||||
|
else
|
||||||
|
printf("\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -4,12 +4,11 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <stddef.h>
|
||||||
#include "ass00.h"
|
#include "ass00.h"
|
||||||
#include "assex.h"
|
#include "assex.h"
|
||||||
|
#include "asscm.h"
|
||||||
#ifndef NORCSID
|
|
||||||
static char rcs_id[] = "$Id$" ;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** utilities of EM1-assembler/loader
|
** utilities of EM1-assembler/loader
|
||||||
|
@ -17,15 +16,16 @@ static char rcs_id[] = "$Id$" ;
|
||||||
|
|
||||||
static int globstep;
|
static int globstep;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* glohash returns an index in table and leaves a stepsize in globstep
|
* glohash returns an index in table and leaves a stepsize in globstep
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
static int glohash(char *aname ,int size)
|
||||||
static int glohash(aname,size) char *aname; {
|
{
|
||||||
register char *p;
|
register char *p;
|
||||||
register i;
|
register int i;
|
||||||
register sum;
|
register int sum;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Computes a hash-value from a string.
|
* Computes a hash-value from a string.
|
||||||
|
@ -44,17 +44,19 @@ static int glohash(aname,size) char *aname; {
|
||||||
* return index in labeltable
|
* return index in labeltable
|
||||||
*/
|
*/
|
||||||
|
|
||||||
glob_t *glo2lookup(name,status) char *name; {
|
glob_t *glo2lookup(char *name ,int status)
|
||||||
|
{
|
||||||
return(glolookup(name,status,mglobs,oursize->n_mlab));
|
return(glolookup(name,status,mglobs,oursize->n_mlab));
|
||||||
}
|
}
|
||||||
|
|
||||||
glob_t *xglolookup(name,status) char *name; {
|
glob_t *xglolookup(char *name,int status)
|
||||||
|
{
|
||||||
|
|
||||||
return(glolookup(name,status,xglobs,oursize->n_glab));
|
return(glolookup(name,status,xglobs,oursize->n_glab));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void findext(g) glob_t *g ; {
|
static void findext(glob_t *g)
|
||||||
|
{
|
||||||
glob_t *x;
|
glob_t *x;
|
||||||
|
|
||||||
x = xglolookup(g->g_name,ENTERING);
|
x = xglolookup(g->g_name,ENTERING);
|
||||||
|
@ -65,19 +67,10 @@ static void findext(g) glob_t *g ; {
|
||||||
g->g_status |= EXT;
|
g->g_status |= EXT;
|
||||||
}
|
}
|
||||||
|
|
||||||
glob_t *glolookup(name,status,table,size)
|
/*
|
||||||
char *name; /* name */
|
|
||||||
int status; /* kind of lookup */
|
|
||||||
glob_t *table; /* which table to use */
|
|
||||||
int size; /* size for hash */
|
|
||||||
{
|
|
||||||
register glob_t *g;
|
|
||||||
register rem,j;
|
|
||||||
int new;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* lookup global symbol name in specified table.
|
* lookup global symbol name in specified table.
|
||||||
* Various actions are taken depending on status.
|
* Various actions are taken depending on status
|
||||||
|
* parameter.
|
||||||
*
|
*
|
||||||
* DEFINING:
|
* DEFINING:
|
||||||
* Lookup or enter the symbol, check for mult. def.
|
* Lookup or enter the symbol, check for mult. def.
|
||||||
|
@ -92,6 +85,12 @@ int size; /* size for hash */
|
||||||
* ENTERING:
|
* ENTERING:
|
||||||
* Lookup or enter the symbol, don't check
|
* Lookup or enter the symbol, don't check
|
||||||
*/
|
*/
|
||||||
|
glob_t *glolookup(char *name,int status,glob_t *table, int size)
|
||||||
|
{
|
||||||
|
register glob_t *g;
|
||||||
|
register int rem,j;
|
||||||
|
int new;
|
||||||
|
|
||||||
|
|
||||||
rem = glohash(name,size);
|
rem = glohash(name,size);
|
||||||
j = 0; new=0;
|
j = 0; new=0;
|
||||||
|
@ -150,9 +149,18 @@ int size; /* size for hash */
|
||||||
return(g);
|
return(g);
|
||||||
}
|
}
|
||||||
|
|
||||||
locl_t *loclookup(an,status) {
|
/*
|
||||||
|
* lookup local label by number and return the
|
||||||
|
* label definition if found.
|
||||||
|
*
|
||||||
|
* DEFINING:
|
||||||
|
* Lookup or enter the symbol, check for mult. def.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
locl_t *loclookup(unsigned int an,int status)
|
||||||
|
{
|
||||||
register locl_t *lbp,*l_lbp;
|
register locl_t *lbp,*l_lbp;
|
||||||
register unsigned num;
|
register unsigned int num;
|
||||||
char hinum;
|
char hinum;
|
||||||
|
|
||||||
if ( !pstate.s_locl ) fatal("label outside procedure");
|
if ( !pstate.s_locl ) fatal("label outside procedure");
|
||||||
|
@ -188,11 +196,7 @@ locl_t *loclookup(an,status) {
|
||||||
return(lbp);
|
return(lbp);
|
||||||
}
|
}
|
||||||
|
|
||||||
proc_t *prolookup(name,status) char *name; {
|
/*
|
||||||
register proc_t *p;
|
|
||||||
register pstat;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Look up a procedure name according to status
|
* Look up a procedure name according to status
|
||||||
*
|
*
|
||||||
* PRO_OCC: Occurrence
|
* PRO_OCC: Occurrence
|
||||||
|
@ -208,6 +212,11 @@ proc_t *prolookup(name,status) char *name; {
|
||||||
* The EXT bit in this table indicates the the name is used
|
* The EXT bit in this table indicates the the name is used
|
||||||
* as external in this module.
|
* as external in this module.
|
||||||
*/
|
*/
|
||||||
|
proc_t *prolookup(char *name,int status)
|
||||||
|
{
|
||||||
|
register proc_t *p= NULL;
|
||||||
|
register int pstat = 0;
|
||||||
|
|
||||||
|
|
||||||
switch(status) {
|
switch(status) {
|
||||||
case PRO_OCC:
|
case PRO_OCC:
|
||||||
|
@ -281,18 +290,15 @@ proc_t *prolookup(name,status) char *name; {
|
||||||
return(enterproc(name,pstat,p));
|
return(enterproc(name,pstat,p));
|
||||||
}
|
}
|
||||||
|
|
||||||
proc_t *searchproc(name,table,size)
|
/*
|
||||||
char *name;
|
|
||||||
proc_t *table;
|
|
||||||
int size;
|
|
||||||
{
|
|
||||||
register proc_t *p;
|
|
||||||
register rem,j;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* return a pointer into table to the place where the procedure
|
* return a pointer into table to the place where the procedure
|
||||||
* name is or should be if in the table.
|
* name is or should be if in the table.
|
||||||
*/
|
*/
|
||||||
|
proc_t *searchproc(char *name,proc_t *table,int size)
|
||||||
|
{
|
||||||
|
register proc_t *p;
|
||||||
|
register int rem,j;
|
||||||
|
|
||||||
|
|
||||||
rem = glohash(name,size);
|
rem = glohash(name,size);
|
||||||
j = 0;
|
j = 0;
|
||||||
|
@ -307,13 +313,7 @@ proc_t *searchproc(name,table,size)
|
||||||
return(p);
|
return(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
proc_t *enterproc(name,status,place)
|
/*
|
||||||
char *name;
|
|
||||||
char status;
|
|
||||||
proc_t *place; {
|
|
||||||
register proc_t *p;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Enter the procedure name into the table at place place.
|
* Enter the procedure name into the table at place place.
|
||||||
* Place had better be computed by searchproc().
|
* Place had better be computed by searchproc().
|
||||||
*
|
*
|
||||||
|
@ -325,6 +325,9 @@ proc_t *place; {
|
||||||
* Two local procedures with the same name in different
|
* Two local procedures with the same name in different
|
||||||
* modules have different numbers.
|
* modules have different numbers.
|
||||||
*/
|
*/
|
||||||
|
proc_t *enterproc(char *name,int status,proc_t *place)
|
||||||
|
{
|
||||||
|
register proc_t *p;
|
||||||
|
|
||||||
p=place;
|
p=place;
|
||||||
p->p_name = (char *) getarea((unsigned) (strlen(name) + 1));
|
p->p_name = (char *) getarea((unsigned) (strlen(name) + 1));
|
||||||
|
|
180
util/ass/ass80.c
180
util/ass/ass80.c
|
@ -6,28 +6,19 @@
|
||||||
|
|
||||||
#include "ass00.h"
|
#include "ass00.h"
|
||||||
#include "assex.h"
|
#include "assex.h"
|
||||||
#include <em_path.h>
|
#include "assrl.h"
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
#include "system.h"
|
||||||
|
|
||||||
#ifndef NORCSID
|
|
||||||
static char rcs_id[] = "$Id$" ;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* this file contains several library routines.
|
* this file contains several library routines.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
zero(area,length) char *area; unsigned length ; {
|
static char filename[L_tmpnam];
|
||||||
register char *p;
|
|
||||||
register n;
|
|
||||||
/*
|
|
||||||
* Clear area of length bytes.
|
|
||||||
*/
|
|
||||||
if ((n=length)==0)
|
|
||||||
return;
|
|
||||||
p = area;
|
|
||||||
do *p++=0; while (--n);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* VARARGS1 */
|
/* VARARGS1 */
|
||||||
static void pr_error(const char* string1, va_list ap) {
|
static void pr_error(const char* string1, va_list ap) {
|
||||||
|
@ -60,7 +51,8 @@ void error(const char* string1, ...)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* VARARGS1 */
|
/* VARARGS1 */
|
||||||
void werror(const char* string1, ...) {
|
void werror(const char* string1, ...)
|
||||||
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
if ( wflag ) return ;
|
if ( wflag ) return ;
|
||||||
|
|
||||||
|
@ -69,57 +61,44 @@ void werror(const char* string1, ...) {
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
fatal(s) char *s; {
|
void fatal(char *s)
|
||||||
|
{
|
||||||
/*
|
/*
|
||||||
* handle fatal errors
|
* handle fatal errors
|
||||||
*/
|
*/
|
||||||
error("Fatal error: %s",s);
|
error("Fatal error: %s",s);
|
||||||
dump(0);
|
dump(0);
|
||||||
exit(-1);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef CPM
|
|
||||||
FILE *frewind(f) FILE *f ; {
|
|
||||||
/* Rewind a file open for writing and open it for reading */
|
|
||||||
/* Assumption, file descriptor is r/w */
|
|
||||||
register FILE *tmp ;
|
|
||||||
tmp=fdopen(dup(fileno(f)),"r");
|
|
||||||
fclose(f);
|
|
||||||
rewind(tmp);
|
|
||||||
return tmp ;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int xgetc(af) register FILE *af; {
|
|
||||||
|
int xgetc(register FILE *af)
|
||||||
|
{
|
||||||
register int nextc;
|
register int nextc;
|
||||||
/*
|
|
||||||
* read next character; fatal if there isn't one
|
|
||||||
*/
|
|
||||||
nextc=fgetc(af) ;
|
nextc=fgetc(af) ;
|
||||||
if ( feof(af) )
|
if ( feof(af) )
|
||||||
fatal("unexpected end of file");
|
fatal("unexpected end of file");
|
||||||
return nextc ;
|
return nextc ;
|
||||||
}
|
}
|
||||||
|
|
||||||
xputc(c,af) register FILE *af; {
|
void xputc(int c,register FILE *af)
|
||||||
/* output one character and scream if it gives an error */
|
{
|
||||||
fputc(c,af) ;
|
fputc(c,af) ;
|
||||||
if ( ferror(af) ) fatal("write error") ;
|
if ( ferror(af) ) fatal("write error") ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
putblk(stream,from,amount)
|
void putblk(register FILE *stream,register char *from, register int amount)
|
||||||
register FILE *stream; register char *from ; register int amount ; {
|
{
|
||||||
|
|
||||||
for ( ; amount-- ; from++ ) {
|
for ( ; amount-- ; from++ ) {
|
||||||
fputc(*from,stream) ;
|
fputc(*from,stream) ;
|
||||||
if ( ferror(stream) ) fatal("write error") ;
|
if ( ferror(stream) ) fatal("write error") ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int getblk(stream,from,amount)
|
int getblk(register FILE *stream, register char *from, register int amount)
|
||||||
register FILE *stream; register char *from ; register int amount ; {
|
{
|
||||||
|
|
||||||
for ( ; amount-- ; from++ ) {
|
for ( ; amount-- ; from++ ) {
|
||||||
*from = fgetc(stream) ;
|
*from = fgetc(stream) ;
|
||||||
if ( feof(stream) ) return 1 ;
|
if ( feof(stream) ) return 1 ;
|
||||||
|
@ -127,7 +106,8 @@ int getblk(stream,from,amount)
|
||||||
return 0 ;
|
return 0 ;
|
||||||
}
|
}
|
||||||
|
|
||||||
xput16(w,f) FILE *f; {
|
void xput16(int w,FILE *f)
|
||||||
|
{
|
||||||
/*
|
/*
|
||||||
* two times xputc
|
* two times xputc
|
||||||
*/
|
*/
|
||||||
|
@ -135,19 +115,22 @@ xput16(w,f) FILE *f; {
|
||||||
xputc(w>>8,f);
|
xputc(w>>8,f);
|
||||||
}
|
}
|
||||||
|
|
||||||
xputarb(l,w,f) int l ; cons_t w ; FILE *f ; {
|
void xputarb(int l,cons_t w, FILE* f)
|
||||||
|
{
|
||||||
while ( l-- ) {
|
while ( l-- ) {
|
||||||
xputc( int_cast w,f) ;
|
xputc( int_cast w,f) ;
|
||||||
w >>=8 ;
|
w >>=8 ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
put8(n) {
|
void put8(int n)
|
||||||
|
{
|
||||||
xputc(n,tfile);
|
xputc(n,tfile);
|
||||||
textoff++;
|
textoff++;
|
||||||
}
|
}
|
||||||
|
|
||||||
put16(n) {
|
void put16(int n)
|
||||||
|
{
|
||||||
/*
|
/*
|
||||||
* note reversed order of bytes.
|
* note reversed order of bytes.
|
||||||
* this is done for faster interpretation.
|
* this is done for faster interpretation.
|
||||||
|
@ -157,16 +140,19 @@ put16(n) {
|
||||||
textoff += 2;
|
textoff += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
put32(n) cons_t n ; {
|
void put32(cons_t n)
|
||||||
|
{
|
||||||
put16( int_cast (n>>16)) ;
|
put16( int_cast (n>>16)) ;
|
||||||
put16( int_cast n) ;
|
put16( int_cast n) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
put64(n) cons_t n ; {
|
void put64(cons_t n)
|
||||||
|
{
|
||||||
fatal("put64 called") ;
|
fatal("put64 called") ;
|
||||||
}
|
}
|
||||||
|
|
||||||
int xget8() {
|
int xget8(void)
|
||||||
|
{
|
||||||
/*
|
/*
|
||||||
* Read one byte from ifile.
|
* Read one byte from ifile.
|
||||||
*/
|
*/
|
||||||
|
@ -176,7 +162,8 @@ int xget8() {
|
||||||
return fgetc(ifile) ;
|
return fgetc(ifile) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned get8() {
|
unsigned int get8(void)
|
||||||
|
{
|
||||||
register int nextc;
|
register int nextc;
|
||||||
/*
|
/*
|
||||||
* Read one byte from ifile.
|
* Read one byte from ifile.
|
||||||
|
@ -191,16 +178,17 @@ unsigned get8() {
|
||||||
return nextc ;
|
return nextc ;
|
||||||
}
|
}
|
||||||
|
|
||||||
cons_t xgetarb(l,f) int l; FILE *f ; {
|
cons_t xgetarb(int l,FILE *f)
|
||||||
|
{
|
||||||
cons_t val ;
|
cons_t val ;
|
||||||
register int shift ;
|
register int shift ;
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
shift=0 ; val=0 ;
|
shift=0 ; val=0 ;
|
||||||
while ( l-- ) {
|
while ( l-- ) {
|
||||||
// val += ((cons_t)(c = ctrunc(xgetc(f))))<<shift ;
|
/* val += ((cons_t)(c = ctrunc(xgetc(f))))<<shift ;
|
||||||
// Bug here: shifts with too large shift counts
|
Bug here: shifts with too large shift counts
|
||||||
// get unspecified results. --Ceriel
|
get unspecified results. --Ceriel */
|
||||||
c = ctrunc(xgetc(f));
|
c = ctrunc(xgetc(f));
|
||||||
if (shift < 8 * sizeof(cons_t)) {
|
if (shift < 8 * sizeof(cons_t)) {
|
||||||
val += ((cons_t)c)<<shift ;
|
val += ((cons_t)c)<<shift ;
|
||||||
|
@ -216,7 +204,8 @@ cons_t xgetarb(l,f) int l; FILE *f ; {
|
||||||
return val ;
|
return val ;
|
||||||
}
|
}
|
||||||
|
|
||||||
ext8(b) {
|
void ext8(int b)
|
||||||
|
{
|
||||||
/*
|
/*
|
||||||
* Handle one byte of data.
|
* Handle one byte of data.
|
||||||
*/
|
*/
|
||||||
|
@ -224,55 +213,56 @@ ext8(b) {
|
||||||
xputc(b,dfile);
|
xputc(b,dfile);
|
||||||
}
|
}
|
||||||
|
|
||||||
extword(w) cons_t w ; {
|
void extword(cons_t w)
|
||||||
|
{
|
||||||
/* Assemble the word constant w.
|
/* Assemble the word constant w.
|
||||||
* NOTE: The bytes are written low to high.
|
* NOTE: The bytes are written low to high.
|
||||||
*/
|
*/
|
||||||
register i ;
|
register int i ;
|
||||||
for ( i=wordsize ; i-- ; ) {
|
for ( i=wordsize ; i-- ; ) {
|
||||||
ext8( int_cast w) ;
|
ext8( int_cast w) ;
|
||||||
w >>= 8 ;
|
w >>= 8 ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extarb(size,value) int size ; long value ; {
|
void extarb(int size, long value)
|
||||||
|
{
|
||||||
/* Assemble the 'size' constant value.
|
/* Assemble the 'size' constant value.
|
||||||
* The bytes are again written low to high.
|
* The bytes are again written low to high.
|
||||||
*/
|
*/
|
||||||
register i ;
|
register int i ;
|
||||||
for ( i=size ; i-- ; ) {
|
for ( i=size ; i-- ; ) {
|
||||||
ext8( int_cast value ) ;
|
ext8( int_cast value ) ;
|
||||||
value >>=8 ;
|
value >>=8 ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extadr(a) cons_t a ; {
|
void extadr(cons_t a)
|
||||||
/* Assemble the word constant a.
|
{
|
||||||
|
/* Assemble the pointer constant a.
|
||||||
* NOTE: The bytes are written low to high.
|
* NOTE: The bytes are written low to high.
|
||||||
*/
|
*/
|
||||||
register i ;
|
register int i ;
|
||||||
for ( i=ptrsize ; i-- ; ) {
|
for ( i=ptrsize ; i-- ; ) {
|
||||||
ext8( int_cast a) ;
|
ext8( int_cast a) ;
|
||||||
a >>= 8 ;
|
a >>= 8 ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
xputa(a,f) cons_t a ; FILE *f ; {
|
void xputa(cons_t a,FILE* f)
|
||||||
/* Assemble the pointer constant a.
|
{
|
||||||
* NOTE: The bytes are written low to high.
|
|
||||||
*/
|
register int i ;
|
||||||
register i ;
|
|
||||||
for ( i=ptrsize ; i-- ; ) {
|
for ( i=ptrsize ; i-- ; ) {
|
||||||
xputc( int_cast a,f) ;
|
xputc( int_cast a,f) ;
|
||||||
a >>= 8 ;
|
a >>= 8 ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cons_t xgeta(f) FILE *f ; {
|
cons_t xgeta(FILE* f)
|
||||||
/* Read the pointer constant a.
|
{
|
||||||
* NOTE: The bytes were written low to high.
|
|
||||||
*/
|
register int i, shift ;
|
||||||
register i, shift ;
|
|
||||||
cons_t val ;
|
cons_t val ;
|
||||||
val = 0 ; shift=0 ;
|
val = 0 ; shift=0 ;
|
||||||
for ( i=ptrsize ; i-- ; ) {
|
for ( i=ptrsize ; i-- ; ) {
|
||||||
|
@ -282,14 +272,16 @@ cons_t xgeta(f) FILE *f ; {
|
||||||
return val ;
|
return val ;
|
||||||
}
|
}
|
||||||
|
|
||||||
int icount(size) {
|
int icount(int size)
|
||||||
|
{
|
||||||
int amount ;
|
int amount ;
|
||||||
amount=(dataoff-lastoff)/size ;
|
amount=(dataoff-lastoff)/size ;
|
||||||
if ( amount>MAXBYTE) fatal("Descriptor overflow");
|
if ( amount>MAXBYTE) fatal("Descriptor overflow");
|
||||||
return amount ;
|
return amount ;
|
||||||
}
|
}
|
||||||
|
|
||||||
set_mode(mode) {
|
void set_mode(int mode)
|
||||||
|
{
|
||||||
|
|
||||||
if (datamode==mode) { /* in right mode already */
|
if (datamode==mode) { /* in right mode already */
|
||||||
switch ( datamode ) {
|
switch ( datamode ) {
|
||||||
|
@ -389,40 +381,12 @@ set_mode(mode) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef CPM
|
|
||||||
int tmpfil() {
|
char* tmpfil(void)
|
||||||
register char *fname, *cpname ;
|
{
|
||||||
static char sfname[] = "tmp.00000";
|
if (sys_tmpnam(filename)==NULL)
|
||||||
register fildes,pid;
|
{
|
||||||
static char name[80] = TMP_DIR ;
|
fatal("Cannot create temporary filename.");
|
||||||
int count;
|
|
||||||
/*
|
|
||||||
* This procedure returns a file-descriptor of a temporary
|
|
||||||
* file valid for reading and writing.
|
|
||||||
* After closing the tmpfil-descriptor the file is lost
|
|
||||||
* Calling this routine frees the program from generating uniqe names.
|
|
||||||
*/
|
|
||||||
fname = sfname+4;
|
|
||||||
count = 10;
|
|
||||||
pid = getpid();
|
|
||||||
while (pid!=0) {
|
|
||||||
*fname++ = (pid&07) + '0';
|
|
||||||
pid >>= 3;
|
|
||||||
}
|
}
|
||||||
*fname = 0;
|
return filename;
|
||||||
for ( fname=name ; *fname ; fname++ ) ;
|
|
||||||
cpname=sfname ;
|
|
||||||
while ( *fname++ = *cpname++ ) ;
|
|
||||||
do {
|
|
||||||
fname = name;
|
|
||||||
if ((fildes = creat(fname, 0600)) < 0)
|
|
||||||
if ((fildes = creat(fname=sfname, 0600)) < 0)
|
|
||||||
return(-1);
|
|
||||||
if (close(fildes) < 0)
|
|
||||||
;
|
|
||||||
} while((fildes = open(fname, 2)) < 0 && count--);
|
|
||||||
if (unlink(fname) < 0)
|
|
||||||
;
|
|
||||||
return(fildes);
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
1145
util/ass/assci.c
1145
util/ass/assci.c
File diff suppressed because it is too large
Load diff
20
util/ass/assci.h
Normal file
20
util/ass/assci.h
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
/* Copyright (c) 2019 ACK Project.
|
||||||
|
* See the copyright notice in the ACK home directory,
|
||||||
|
* in the file "Copyright".
|
||||||
|
*
|
||||||
|
* Created on: 2019-03-12
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef ASSCI_H_
|
||||||
|
#define ASSCI_H_
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* read module in compact EM1 code and fill in the table in memory
|
||||||
|
* with all the specified data as a linked list.
|
||||||
|
*/
|
||||||
|
void read_compact(void);
|
||||||
|
void newline(int type);
|
||||||
|
void align(int size);
|
||||||
|
|
||||||
|
#endif /* ASSCI_H_ */
|
146
util/ass/asscm.c
146
util/ass/asscm.c
|
@ -16,116 +16,132 @@
|
||||||
Free blocks with a size smaller then the administration cannot
|
Free blocks with a size smaller then the administration cannot
|
||||||
exist.
|
exist.
|
||||||
The algorithm is first fit.
|
The algorithm is first fit.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "ass00.h"
|
#include "ass00.h"
|
||||||
|
#include "assex.h"
|
||||||
#ifndef NORCSID
|
#include "asscm.h"
|
||||||
static char rcs_id[] = "$Id$" ;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef MEMUSE
|
#ifdef MEMUSE
|
||||||
static unsigned m_used = 0 ;
|
static unsigned m_used = 0;
|
||||||
static unsigned m_free = 0 ;
|
static unsigned m_free = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct freeblock {
|
struct freeblock
|
||||||
struct freeblock *f_next ;
|
{
|
||||||
unsigned f_size ;
|
struct freeblock *f_next;
|
||||||
} ;
|
unsigned f_size;
|
||||||
|
};
|
||||||
|
|
||||||
static struct freeblock freexx[2] = {
|
static struct freeblock freexx[2] =
|
||||||
{ freexx, 0 },
|
{
|
||||||
{ freexx+1, 0 }
|
{ freexx, 0 },
|
||||||
} ;
|
{ freexx + 1, 0 } };
|
||||||
|
|
||||||
#define freehead freexx[1]
|
#define freehead freexx[1]
|
||||||
|
|
||||||
#define CHUNK 2048 /* Smallest chunk to be gotten from UNIX */
|
#define CHUNK 2048 /* Smallest chunk to be gotten from UNIX */
|
||||||
|
|
||||||
area_t getarea(size) unsigned size ; {
|
area_t getarea(unsigned int size)
|
||||||
register struct freeblock *c_ptr,*l_ptr ;
|
{
|
||||||
register char *ptr ;
|
register struct freeblock *c_ptr, *l_ptr;
|
||||||
unsigned rqsize ;
|
register char *ptr;
|
||||||
|
unsigned rqsize;
|
||||||
|
|
||||||
size = ((size + (sizeof(int) - 1)) / sizeof(int)) * sizeof(int);
|
size = ((size + (sizeof(int) - 1)) / sizeof(int)) * sizeof(int);
|
||||||
#ifdef MEMUSE
|
#ifdef MEMUSE
|
||||||
m_used += size ;
|
m_used += size;
|
||||||
m_free -= size ;
|
m_free -= size;
|
||||||
#endif
|
#endif
|
||||||
for(;;) {
|
for (;;)
|
||||||
for ( l_ptr= &freehead, c_ptr= freehead.f_next ;
|
{
|
||||||
c_ptr!= &freehead ; c_ptr = c_ptr->f_next ) {
|
for (l_ptr = &freehead, c_ptr= freehead.f_next;
|
||||||
if ( size==c_ptr->f_size ) {
|
c_ptr!= &freehead; c_ptr = c_ptr->f_next )
|
||||||
l_ptr->f_next= c_ptr->f_next ;
|
{
|
||||||
return (area_t) c_ptr ;
|
if ( size==c_ptr->f_size )
|
||||||
|
{
|
||||||
|
l_ptr->f_next= c_ptr->f_next;
|
||||||
|
return (area_t) c_ptr;
|
||||||
}
|
}
|
||||||
if ( size+sizeof freehead <= c_ptr->f_size ) {
|
if ( size+sizeof freehead <= c_ptr->f_size )
|
||||||
c_ptr->f_size -= size ;
|
{
|
||||||
return (area_t) ((char *) c_ptr + c_ptr->f_size) ;
|
c_ptr->f_size -= size;
|
||||||
|
return (area_t) ((char *) c_ptr + c_ptr->f_size);
|
||||||
}
|
}
|
||||||
l_ptr = c_ptr ;
|
l_ptr = c_ptr;
|
||||||
}
|
}
|
||||||
rqsize = size<CHUNK ? CHUNK : size ;
|
rqsize = size<CHUNK ? CHUNK : size;
|
||||||
for(;;){
|
for(;;)
|
||||||
ptr = malloc( rqsize ) ;
|
{
|
||||||
if ( ptr ) break ; /* request succesfull */
|
ptr = malloc( rqsize );
|
||||||
rqsize /= 2 ;
|
if ( ptr ) break; /* request succesfull */
|
||||||
rqsize -= rqsize%sizeof (int) ;
|
rqsize /= 2;
|
||||||
if ( rqsize < sizeof freehead ) {
|
rqsize -= rqsize%sizeof (int);
|
||||||
fatal("Out of memory") ;
|
if ( rqsize < sizeof freehead )
|
||||||
|
{
|
||||||
|
fatal("Out of memory");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
freearea((area_t)ptr,rqsize) ;
|
freearea((area_t)ptr,rqsize);
|
||||||
#ifdef MEMUSE
|
#ifdef MEMUSE
|
||||||
m_used += rqsize ;
|
m_used += rqsize;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
/* NOTREACHED */
|
/* NOTREACHED */
|
||||||
}
|
}
|
||||||
|
|
||||||
freearea(ptr,size) register area_t ptr ; unsigned size ; {
|
void freearea(register area_t ptr, unsigned int size)
|
||||||
register struct freeblock *c_ptr, *l_ptr ;
|
{
|
||||||
|
register struct freeblock *c_ptr, *l_ptr;
|
||||||
|
|
||||||
size = ((size + (sizeof(int) - 1)) / sizeof(int)) * sizeof(int);
|
size = ((size + (sizeof(int) - 1)) / sizeof(int)) * sizeof(int);
|
||||||
#ifdef MEMUSE
|
#ifdef MEMUSE
|
||||||
m_free += size ;
|
m_free += size;
|
||||||
m_used -= size ;
|
m_used -= size;
|
||||||
#endif
|
#endif
|
||||||
for ( l_ptr= &freehead, c_ptr=freehead.f_next ;
|
for (l_ptr = &freehead, c_ptr=freehead.f_next;
|
||||||
c_ptr!= &freehead ; c_ptr= c_ptr->f_next ) {
|
c_ptr!= &freehead; c_ptr= c_ptr->f_next )
|
||||||
if ( (area_t)c_ptr>ptr ) break ;
|
{
|
||||||
l_ptr= c_ptr ;
|
if ( (area_t)c_ptr>ptr ) break;
|
||||||
|
l_ptr= c_ptr;
|
||||||
}
|
}
|
||||||
/* now insert between l_ptr and c_ptr */
|
/* now insert between l_ptr and c_ptr */
|
||||||
/* Beware they may both point to freehead */
|
/* Beware they may both point to freehead */
|
||||||
|
|
||||||
#ifdef MEMUSE
|
#ifdef MEMUSE
|
||||||
if ( ((char *)l_ptr)+l_ptr->f_size> (char *)ptr && (char *)l_ptr<=(char *)ptr )
|
if (((char *) l_ptr) + l_ptr->f_size > (char *) ptr
|
||||||
fatal("Double freed") ;
|
&& (char *) l_ptr <= (char *) ptr)
|
||||||
if ( ((char *)ptr)+size > (char *)c_ptr && (char *)ptr<=(char *)c_ptr )
|
fatal("Double freed");
|
||||||
fatal("Frreed double") ;
|
if (((char *) ptr) + size > (char *) c_ptr
|
||||||
|
&& (char *) ptr <= (char *) c_ptr)
|
||||||
|
fatal("Frreed double");
|
||||||
#endif
|
#endif
|
||||||
/* Is the block before this one adjacent ? */
|
/* Is the block before this one adjacent ? */
|
||||||
if ( ((char *)l_ptr) + l_ptr->f_size == (char *) ptr ) {
|
if (((char *) l_ptr) + l_ptr->f_size == (char *) ptr)
|
||||||
l_ptr->f_size += size ; /* yes */
|
{
|
||||||
} else {
|
l_ptr->f_size += size;
|
||||||
|
/* yes */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
/* No, create an entry */
|
/* No, create an entry */
|
||||||
((struct freeblock *)ptr)->f_next = c_ptr ;
|
((struct freeblock *) ptr)->f_next = c_ptr;
|
||||||
((struct freeblock *)ptr)->f_size = size ;
|
((struct freeblock *) ptr)->f_size = size;
|
||||||
l_ptr->f_next = (struct freeblock *)ptr ;
|
l_ptr->f_next = (struct freeblock *) ptr;
|
||||||
l_ptr = (struct freeblock *)ptr ;
|
l_ptr = (struct freeblock *) ptr;
|
||||||
}
|
}
|
||||||
/* Are the two entries adjacent ? */
|
/* Are the two entries adjacent ? */
|
||||||
if ( (char *)l_ptr + l_ptr->f_size == (char *) c_ptr ) {
|
if ((char *) l_ptr + l_ptr->f_size == (char *) c_ptr)
|
||||||
|
{
|
||||||
/* the two entries are adjacent */
|
/* the two entries are adjacent */
|
||||||
l_ptr->f_next = c_ptr->f_next ;
|
l_ptr->f_next = c_ptr->f_next;
|
||||||
l_ptr->f_size += c_ptr->f_size ;
|
l_ptr->f_size += c_ptr->f_size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MEMUSE
|
#ifdef MEMUSE
|
||||||
memuse() {
|
void memuse(void)
|
||||||
printf("Free %7u, Used %7u, Total %7u\n",m_free,m_used,m_free+m_used);
|
{
|
||||||
|
printf("Free %7u, Used %7u, Total %7u\n", m_free, m_used, m_free + m_used);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
22
util/ass/asscm.h
Normal file
22
util/ass/asscm.h
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
/* Copyright (c) 2019 ACK Project.
|
||||||
|
* See the copyright notice in the ACK home directory,
|
||||||
|
* in the file "Copyright".
|
||||||
|
*
|
||||||
|
* Created on: 2019-03-12
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef ASSCM_H_
|
||||||
|
#define ASSCM_H_
|
||||||
|
|
||||||
|
/* Allocates an area of "size" bytes in memory
|
||||||
|
* and returns a pointer to this area.
|
||||||
|
*/
|
||||||
|
area_t getarea(unsigned int size);
|
||||||
|
/* Frees an area of memory of "size" bytes. */
|
||||||
|
void freearea(register area_t ptr, unsigned int size);
|
||||||
|
|
||||||
|
#ifdef MEMUSE
|
||||||
|
void memuse(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* ASSCM_H_ */
|
|
@ -5,11 +5,6 @@
|
||||||
#include "ass00.h"
|
#include "ass00.h"
|
||||||
#include "assex.h"
|
#include "assex.h"
|
||||||
|
|
||||||
#ifndef NORCSID
|
|
||||||
static char rcs_id[] = "$Id$" ;
|
|
||||||
static char rcs_ass[]= RCS_ASS ;
|
|
||||||
static char rcs_ex[] = RCS_EX ;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* global data
|
* global data
|
||||||
|
|
145
util/ass/assex.h
145
util/ass/assex.h
|
@ -6,7 +6,7 @@
|
||||||
* global data
|
* global data
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define RCS_EX "$Id$"
|
#include <stdio.h>
|
||||||
|
|
||||||
extern int wordsize;
|
extern int wordsize;
|
||||||
extern int ptrsize;
|
extern int ptrsize;
|
||||||
|
@ -122,31 +122,126 @@ extern char *opindex[] ;
|
||||||
extern char opchoice[] ;
|
extern char opchoice[] ;
|
||||||
extern int maxinsl ;
|
extern int maxinsl ;
|
||||||
|
|
||||||
/*
|
/* Generate temporary filename. Fatal error in case of error. */
|
||||||
* types of value returning routines
|
extern char *tmpfil(void);
|
||||||
|
|
||||||
|
|
||||||
|
/* Read next byte from "af" file, fatal error if there isn't one. */
|
||||||
|
extern int xgetc(register FILE *af);
|
||||||
|
/* Read a value of length "l" bytes from file "f",
|
||||||
|
* fatal error if cannot be read.
|
||||||
*/
|
*/
|
||||||
#ifndef CPM
|
extern cons_t xgetarb(int l,FILE *f);
|
||||||
extern int tmpfil();
|
/* Read the pointer constant a from file "f".
|
||||||
extern FILE *frewind();
|
* NOTE: The bytes were written low to high (little-endian).
|
||||||
#endif
|
*/
|
||||||
extern int xgetc();
|
extern cons_t xgeta(FILE* f);
|
||||||
extern unsigned get8();
|
|
||||||
extern int get16();
|
|
||||||
extern cons_t get32();
|
|
||||||
extern cons_t xgeta();
|
/* Output one byte into file "af" and fatal error if it gives an error */
|
||||||
extern cons_t parval();
|
extern void xputc(int c,register FILE *af);
|
||||||
extern cons_t valsize();
|
/* Output a 16-bit value into file "f" in little-endian, fatal error if it gives an error. */
|
||||||
extern cons_t xgetarb();
|
extern void xput16(int w,FILE *f);
|
||||||
|
/* Output a value of "l" bytes into file "f" and fatal error if it gives an error. */
|
||||||
|
extern void xputarb(int l,cons_t w, FILE* f);
|
||||||
|
/* Assemble the pointer constant a into file "f".
|
||||||
|
* NOTE: The bytes are written low to high (little-endian).
|
||||||
|
*/
|
||||||
|
extern void xputa(cons_t a,FILE* f);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Write a byte value into the code temporary file. */
|
||||||
|
extern void put8(int n);
|
||||||
|
/* Write a 16-bit value into the code temporary file. */
|
||||||
|
extern void put16(int n);
|
||||||
|
/* Write a 32-bit value into the code temporary file. */
|
||||||
|
extern void put32(cons_t n);
|
||||||
|
/* Write a 64-bit value into the code temporary file. */
|
||||||
|
extern void put64(cons_t n);
|
||||||
|
|
||||||
|
|
||||||
|
/* Read a byte from the input file, return EOF upon error of EOF */
|
||||||
|
extern int xget8(void);
|
||||||
|
/* Read a byte from the input file, fatal error upon error or EOF. */
|
||||||
|
extern unsigned int get8(void);
|
||||||
|
/* Read a signed 16-bit value from the input file. Raise
|
||||||
|
* a fatal error upon error or end of stream.
|
||||||
|
*/
|
||||||
|
extern int get16(void);
|
||||||
|
/* Read an unsigned 16-bit value from the input file. Raise
|
||||||
|
* a fatal error upon error or end of stream.
|
||||||
|
*/
|
||||||
|
extern int getu16(void);
|
||||||
|
/* Read a 32-bit value from the input file. Raise
|
||||||
|
* a fatal error upon error or end of stream.
|
||||||
|
*/
|
||||||
|
extern cons_t get32(void);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Write a byte to the data file. */
|
||||||
|
extern void ext8(int b);
|
||||||
|
/* Write a 16-bit value to the data file.
|
||||||
|
* The value is written from low to high (little-endian)
|
||||||
|
*/
|
||||||
|
extern void extword(cons_t w);
|
||||||
|
/* Write "value" of "size" bytes to the data file. The bytes
|
||||||
|
* are written low to high.
|
||||||
|
*/
|
||||||
|
extern void extarb(int size, long value);
|
||||||
|
/* Write pointer "a". The bytes are
|
||||||
|
* written from low to high to the data file.
|
||||||
|
*/
|
||||||
|
extern void extadr(cons_t a);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Returns the opcode length in bytes */
|
||||||
|
extern int oplength(int);
|
||||||
|
extern void genop(char *,cons_t,int );
|
||||||
|
|
||||||
|
extern void putblk(register FILE *stream,register char *from, register int amount);
|
||||||
|
extern int getblk(register FILE *stream, register char *from, register int amount);
|
||||||
|
|
||||||
|
|
||||||
|
extern void set_mode(int mode);
|
||||||
|
|
||||||
|
/* Dump current information to screen if dump flag is enabled. */
|
||||||
|
void dump(int n);
|
||||||
|
|
||||||
|
/*
|
||||||
extern char *findnop();
|
extern char *findnop();
|
||||||
extern char *findfit();
|
extern char *findfit();
|
||||||
extern glob_t *glolookup();
|
|
||||||
extern glob_t *glo2lookup();
|
*/
|
||||||
extern glob_t *xglolookup();
|
extern glob_t *glolookup(char *name,int status,glob_t *table, int size);
|
||||||
extern locl_t *loclookup();
|
extern proc_t *searchproc(char *name,proc_t *table,int size);
|
||||||
extern proc_t *prolookup();
|
extern glob_t *glo2lookup(char *name ,int status);
|
||||||
extern proc_t *enterproc();
|
extern glob_t *xglolookup(char *name,int status);
|
||||||
extern proc_t *searchproc();
|
extern proc_t *prolookup(char *name,int status);
|
||||||
extern relc_t *text_reloc();
|
extern locl_t *loclookup(unsigned int an,int status);
|
||||||
extern relc_t *data_reloc();
|
extern proc_t *enterproc(char *name,int status,proc_t *place);
|
||||||
extern area_t getarea();
|
extern cons_t parval(line_t *lnp,char *defined);
|
||||||
|
|
||||||
|
|
||||||
|
extern void determine_props(line_t *lnp, int *min_len, int *max_len);
|
||||||
|
extern int opfit(int flag,int number,cons_t val,int i_flag);
|
||||||
|
|
||||||
|
extern void initproc(void);
|
||||||
|
extern void endproc(void);
|
||||||
|
extern void init_files(void);
|
||||||
|
extern void init_module(void);
|
||||||
|
extern void end_module(void);
|
||||||
|
extern void do_proc(void);
|
||||||
|
extern void ertrap(void);
|
||||||
|
extern void init_vars(void);
|
||||||
|
|
||||||
|
extern void error(const char* string1, ...);
|
||||||
|
extern void werror(const char* string1, ...);
|
||||||
|
extern void fatal(char *s);
|
||||||
|
|
||||||
|
|
||||||
|
|
334
util/ass/assrl.c
334
util/ass/assrl.c
|
@ -4,12 +4,13 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
#include "ass00.h"
|
#include "ass00.h"
|
||||||
#include "assex.h"
|
#include "assex.h"
|
||||||
|
#include "asscm.h"
|
||||||
|
#include "assrl.h"
|
||||||
|
|
||||||
|
|
||||||
#ifndef NORCSID
|
|
||||||
static char rcs_id[] = "$Id$" ;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define COPYFINAL 1
|
#define COPYFINAL 1
|
||||||
#define COPYTEMP 0
|
#define COPYTEMP 0
|
||||||
|
@ -18,10 +19,12 @@ static char rcs_id[] = "$Id$" ;
|
||||||
* collection of routines to deal with relocation business
|
* collection of routines to deal with relocation business
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void dataprocess();
|
|
||||||
void textprocess();
|
static void dataprocess(FILE *, FILE *);
|
||||||
relc_t *
|
static void textprocess(FILE *, FILE *);
|
||||||
text_reloc(glosym,off,typ) glob_t *glosym; FOFFSET off ; int typ ; {
|
|
||||||
|
relc_t * text_reloc(glob_t *glosym, FOFFSET off, int typ)
|
||||||
|
{
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* prepare the relocation that has to be done at text-offset off
|
* prepare the relocation that has to be done at text-offset off
|
||||||
|
@ -33,48 +36,55 @@ text_reloc(glosym,off,typ) glob_t *glosym; FOFFSET off ; int typ ; {
|
||||||
* into the one in xglobs[] later.
|
* into the one in xglobs[] later.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
register relc_t *nxtextreloc ;
|
register relc_t *nxtextreloc;
|
||||||
|
|
||||||
nxtextreloc= rlp_cast getarea(sizeof *nxtextreloc) ;
|
nxtextreloc = rlp_cast getarea(sizeof *nxtextreloc);
|
||||||
if ( !f_text ) {
|
if (!f_text)
|
||||||
f_text= nxtextreloc ;
|
{
|
||||||
} else {
|
f_text = nxtextreloc;
|
||||||
l_text->r_next= nxtextreloc ;
|
|
||||||
}
|
}
|
||||||
nxtextreloc->r_next= rlp_cast 0 ;
|
else
|
||||||
l_text= nxtextreloc ;
|
{
|
||||||
|
l_text->r_next = nxtextreloc;
|
||||||
|
}
|
||||||
|
nxtextreloc->r_next = rlp_cast 0;
|
||||||
|
l_text = nxtextreloc;
|
||||||
nxtextreloc->r_off = off;
|
nxtextreloc->r_off = off;
|
||||||
nxtextreloc->r_val.rel_gp = glosym;
|
nxtextreloc->r_val.rel_gp = glosym;
|
||||||
nxtextreloc->r_typ = typ; /* flags of instruction */
|
nxtextreloc->r_typ = typ; /* flags of instruction */
|
||||||
return(nxtextreloc);
|
return (nxtextreloc);
|
||||||
}
|
}
|
||||||
|
|
||||||
relc_t *
|
relc_t * data_reloc(char *arg ,FOFFSET off, int typ)
|
||||||
data_reloc(arg,off,typ) char *arg ; FOFFSET off ; int typ ; {
|
{
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Same as above.
|
* Same as above.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
register relc_t *nxdatareloc ;
|
register relc_t *nxdatareloc;
|
||||||
|
|
||||||
nxdatareloc= rlp_cast getarea(sizeof *nxdatareloc) ;
|
nxdatareloc = rlp_cast getarea(sizeof *nxdatareloc);
|
||||||
if ( !f_data ) {
|
if (!f_data)
|
||||||
f_data= nxdatareloc ;
|
{
|
||||||
} else {
|
f_data = nxdatareloc;
|
||||||
l_data->r_next= nxdatareloc ;
|
|
||||||
}
|
}
|
||||||
nxdatareloc->r_next= rlp_cast 0 ;
|
else
|
||||||
l_data= nxdatareloc ;
|
{
|
||||||
|
l_data->r_next = nxdatareloc;
|
||||||
|
}
|
||||||
|
nxdatareloc->r_next = rlp_cast 0;
|
||||||
|
l_data = nxdatareloc;
|
||||||
nxdatareloc->r_off = off;
|
nxdatareloc->r_off = off;
|
||||||
nxdatareloc->r_val.rel_lp = lbp_cast arg;
|
nxdatareloc->r_val.rel_lp = lbp_cast arg;
|
||||||
nxdatareloc->r_typ = typ;
|
nxdatareloc->r_typ = typ;
|
||||||
return(nxdatareloc);
|
return (nxdatareloc);
|
||||||
}
|
}
|
||||||
|
|
||||||
copyout() {
|
void copyout(void)
|
||||||
register i;
|
{
|
||||||
int remtext ;
|
register int i;
|
||||||
|
int remtext;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Make the e.out file that looks as follows:
|
* Make the e.out file that looks as follows:
|
||||||
|
@ -113,145 +123,158 @@ copyout() {
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
remtext = textbytes%wordsize ;
|
remtext = textbytes % wordsize;
|
||||||
if ( remtext != 0 ) remtext = wordsize-remtext ;
|
if (remtext != 0)
|
||||||
|
remtext = wordsize - remtext;
|
||||||
|
|
||||||
if ((ifile = fopen(eout,"w")) == 0 )
|
if ((ifile = fopen(eout, "w")) == 0)
|
||||||
fatal("can't create e.out");
|
fatal("can't create e.out");
|
||||||
#ifdef CPM
|
|
||||||
fclose(tfile); tfile=fopen("TFILE.$$$", "r");
|
|
||||||
fclose(dfile); dfile=fopen("DFILE.$$$", "r");
|
|
||||||
#else
|
|
||||||
tfile=frewind(tfile);
|
|
||||||
dfile=frewind(dfile);
|
|
||||||
#endif
|
|
||||||
xput16(as_magic,ifile);
|
|
||||||
xput16(intflags,ifile);
|
|
||||||
xput16(unresolved,ifile);
|
|
||||||
xput16(VERSION,ifile);
|
|
||||||
xput16(wordsize,ifile);
|
|
||||||
xput16(ptrsize,ifile);
|
|
||||||
xput16(0,ifile);
|
|
||||||
xput16(0,ifile);
|
|
||||||
xputa(textbytes+remtext ,ifile);
|
|
||||||
xputa((cons_t)datablocks,ifile);
|
|
||||||
xputa((cons_t)procnum,ifile);
|
|
||||||
xputa((cons_t)searchproc(MAIN,xprocs,oursize->n_xproc)->p_num,
|
|
||||||
ifile);
|
|
||||||
xputa((cons_t)sourcelines,ifile);
|
|
||||||
xputa((cons_t)databytes,ifile);
|
|
||||||
xputa((cons_t)0,ifile);
|
|
||||||
xputa((cons_t)0,ifile);
|
|
||||||
|
|
||||||
textprocess(tfile,ifile);
|
rewind(tfile);
|
||||||
while ( remtext-- ) xputc(0,ifile) ;
|
rewind(dfile);
|
||||||
|
|
||||||
dataprocess(dfile,ifile);
|
xput16(as_magic, ifile);
|
||||||
for (i=0;i<procnum;i++) {
|
xput16(intflags, ifile);
|
||||||
xputarb(ptrsize,proctab[i].pr_loc,ifile);
|
xput16(unresolved, ifile);
|
||||||
xputarb(ptrsize,proctab[i].pr_off,ifile);
|
xput16(VERSION, ifile);
|
||||||
|
xput16(wordsize, ifile);
|
||||||
|
xput16(ptrsize, ifile);
|
||||||
|
xput16(0, ifile);
|
||||||
|
xput16(0, ifile);
|
||||||
|
xputa(textbytes + remtext, ifile);
|
||||||
|
xputa((cons_t) datablocks, ifile);
|
||||||
|
xputa((cons_t) procnum, ifile);
|
||||||
|
xputa((cons_t) searchproc(MAIN, xprocs, oursize->n_xproc)->p_num, ifile);
|
||||||
|
xputa((cons_t) sourcelines, ifile);
|
||||||
|
xputa((cons_t) databytes, ifile);
|
||||||
|
xputa((cons_t) 0, ifile);
|
||||||
|
xputa((cons_t) 0, ifile);
|
||||||
|
|
||||||
|
textprocess(tfile, ifile);
|
||||||
|
while (remtext--)
|
||||||
|
xputc(0, ifile);
|
||||||
|
|
||||||
|
dataprocess(dfile, ifile);
|
||||||
|
for (i = 0; i < procnum; i++)
|
||||||
|
{
|
||||||
|
xputarb(ptrsize, proctab[i].pr_loc, ifile);
|
||||||
|
xputarb(ptrsize, proctab[i].pr_off, ifile);
|
||||||
}
|
}
|
||||||
if ( fclose(ifile)==EOF ) ;
|
if (fclose(ifile) == EOF)
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
void dataprocess(f1,f2) FILE *f1,*f2; {
|
static void dataprocess(FILE *f1, FILE *outf)
|
||||||
|
{
|
||||||
relc_t datareloc;
|
relc_t datareloc;
|
||||||
FOFFSET i;
|
FOFFSET i;
|
||||||
register ieof ;
|
register int ieof;
|
||||||
|
|
||||||
#ifdef CPM
|
rewind(rdfile);
|
||||||
fclose(rdfile); rdfile=fopen("RDFILE.$$$", "r");
|
ieof = getblk(rdfile, (char *) (&datareloc.r_off),
|
||||||
#else
|
sizeof datareloc - sizeof datareloc.r_next);
|
||||||
rdfile=frewind(rdfile) ;
|
for (i = 0; i < dataoff && !ieof; i++)
|
||||||
#endif
|
{
|
||||||
ieof=getblk(rdfile,(char *)(&datareloc.r_off),
|
if (i == datareloc.r_off)
|
||||||
sizeof datareloc - sizeof datareloc.r_next) ;
|
{
|
||||||
for (i=0 ; i<dataoff && !ieof ; i++) {
|
switch (datareloc.r_typ)
|
||||||
if (i==datareloc.r_off) {
|
{
|
||||||
switch(datareloc.r_typ) {
|
|
||||||
case RELADR:
|
case RELADR:
|
||||||
xputa(xgeta(f1)+datareloc.r_val.rel_i,f2) ;
|
xputa(xgeta(f1) + datareloc.r_val.rel_i, outf);
|
||||||
i += ptrsize-1 ;
|
i += ptrsize - 1;
|
||||||
break ;
|
break;
|
||||||
case RELGLO:
|
case RELGLO:
|
||||||
if (datareloc.r_val.rel_gp->g_status&DEF) {
|
if (datareloc.r_val.rel_gp->g_status & DEF)
|
||||||
xputa(xgeta(f1)+
|
{
|
||||||
datareloc.r_val.rel_gp->g_val.g_addr,
|
xputa(xgeta(f1) + datareloc.r_val.rel_gp->g_val.g_addr, outf);
|
||||||
f2);
|
i += ptrsize - 1;
|
||||||
i+= ptrsize-1 ;
|
break;
|
||||||
break ;
|
|
||||||
}
|
}
|
||||||
if ( unresolved == 0 )
|
if (unresolved == 0)
|
||||||
fatal("Definition botch") ;
|
fatal("Definition botch");
|
||||||
case RELHEAD:
|
case RELHEAD:
|
||||||
xputc((int)(xgetc(f1)+datareloc.r_val.rel_i),
|
xputc((int) (xgetc(f1) + datareloc.r_val.rel_i), outf);
|
||||||
f2);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fatal("Bad r_typ in dataprocess");
|
fatal("Bad r_typ in dataprocess");
|
||||||
}
|
}
|
||||||
ieof=getblk(rdfile,(char *)(&datareloc.r_off),
|
ieof = getblk(rdfile, (char *) (&datareloc.r_off),
|
||||||
sizeof datareloc - sizeof datareloc.r_next) ;
|
sizeof datareloc - sizeof datareloc.r_next);
|
||||||
} else
|
|
||||||
xputc(xgetc(f1),f2);
|
|
||||||
}
|
}
|
||||||
for ( ; i<dataoff ; i++ ) xputc(xgetc(f1),f2) ;
|
else
|
||||||
if ( !ieof && !getblk(rdfile,(char *)&datareloc,1) )
|
xputc(xgetc(f1), outf);
|
||||||
fatal("data relocation botch") ;
|
}
|
||||||
|
for (; i < dataoff; i++)
|
||||||
|
xputc(xgetc(f1), outf);
|
||||||
|
if (!ieof && !getblk(rdfile, (char *) &datareloc, 1))
|
||||||
|
fatal("data relocation botch");
|
||||||
}
|
}
|
||||||
|
|
||||||
void textprocess(f1,f2) FILE *f1,*f2; {
|
static void textprocess(FILE *f1, FILE *outf)
|
||||||
|
{
|
||||||
relc_t textreloc;
|
relc_t textreloc;
|
||||||
cons_t n;
|
cons_t n;
|
||||||
FOFFSET i;
|
FOFFSET i;
|
||||||
FILE *otfile ;
|
FILE *otfile;
|
||||||
int insl ; register int ieof ;
|
int insl;
|
||||||
char *op_curr ;
|
register int ieof;
|
||||||
register FOFFSET keep ;
|
char *op_curr;
|
||||||
|
register FOFFSET keep;
|
||||||
|
|
||||||
#ifdef CPM
|
rewind(rtfile);
|
||||||
fclose(rtfile); rtfile=fopen("RTFILE.$$$", "r");
|
keep = textoff;
|
||||||
#else
|
textoff = 0;
|
||||||
rtfile=frewind(rtfile) ;
|
otfile = tfile;
|
||||||
#endif
|
tfile = outf;
|
||||||
keep = textoff ; textoff=0 ; otfile=tfile ; tfile=f2 ;
|
|
||||||
/* This redirects the output of genop */
|
/* This redirects the output of genop */
|
||||||
ieof=getblk(rtfile,(char *)(&textreloc.r_off),
|
ieof = getblk(rtfile, (char *) (&textreloc.r_off),
|
||||||
sizeof textreloc - sizeof textreloc.r_next) ;
|
sizeof textreloc - sizeof textreloc.r_next);
|
||||||
for(i=0;i<keep && !ieof ;i++) {
|
for (i = 0; i < keep && !ieof; i++)
|
||||||
if( i == textreloc.r_off ) {
|
{
|
||||||
if (textreloc.r_typ&RELMNS) {
|
if (i == textreloc.r_off)
|
||||||
n=textreloc.r_val.rel_i;
|
{
|
||||||
} else {
|
if (textreloc.r_typ & RELMNS)
|
||||||
if (textreloc.r_val.rel_gp->g_status&DEF) {
|
{
|
||||||
n=textreloc.r_val.rel_gp->g_val.g_addr;
|
n = textreloc.r_val.rel_i;
|
||||||
} else {
|
}
|
||||||
if ( unresolved==0 )
|
else
|
||||||
fatal("Definition botch") ;
|
{
|
||||||
xputc(xgetc(f1),f2) ;
|
if (textreloc.r_val.rel_gp->g_status & DEF)
|
||||||
ieof=getblk(rtfile,(char *)(&textreloc.r_off),
|
{
|
||||||
sizeof textreloc-sizeof textreloc.r_next);
|
n = textreloc.r_val.rel_gp->g_val.g_addr;
|
||||||
continue ;
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (unresolved == 0)
|
||||||
|
fatal("Definition botch");
|
||||||
|
xputc(xgetc(f1), outf);
|
||||||
|
ieof = getblk(rtfile, (char *) (&textreloc.r_off),
|
||||||
|
sizeof textreloc - sizeof textreloc.r_next);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
op_curr = &opchoice[textreloc.r_typ& ~RELMNS] ;
|
op_curr = &opchoice[textreloc.r_typ & ~RELMNS];
|
||||||
insl = oplength(*op_curr) ;
|
insl = oplength(*op_curr);
|
||||||
genop(op_curr, n+xgetarb(insl,f1), PAR_G);
|
genop(op_curr, n + xgetarb(insl, f1), PAR_G);
|
||||||
i += insl-1 ;
|
i += insl - 1;
|
||||||
ieof=getblk(rtfile,(char *)(&textreloc.r_off),
|
ieof = getblk(rtfile, (char *) (&textreloc.r_off),
|
||||||
sizeof textreloc - sizeof textreloc.r_next) ;
|
sizeof textreloc - sizeof textreloc.r_next);
|
||||||
} else {
|
}
|
||||||
xputc(xgetc(f1),f2) ;
|
else
|
||||||
|
{
|
||||||
|
xputc(xgetc(f1), outf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for ( ; i<keep ; i++ ) xputc(xgetc(f1),f2) ;
|
for (; i < keep; i++)
|
||||||
if ( !ieof && !getblk(rtfile,(char *)&textreloc,1) )
|
xputc(xgetc(f1), outf);
|
||||||
fatal("text relocation botch") ;
|
if (!ieof && !getblk(rtfile, (char *) &textreloc, 1))
|
||||||
textoff = keep ;
|
fatal("text relocation botch");
|
||||||
tfile = otfile ;
|
textoff = keep;
|
||||||
|
tfile = otfile;
|
||||||
}
|
}
|
||||||
|
|
||||||
upd_reloc() {
|
void upd_reloc(void)
|
||||||
|
{
|
||||||
register relc_t *p;
|
register relc_t *p;
|
||||||
register glob_t *gbp;
|
register glob_t *gbp;
|
||||||
|
|
||||||
|
@ -264,28 +287,37 @@ upd_reloc() {
|
||||||
* see also getcore()
|
* see also getcore()
|
||||||
*/
|
*/
|
||||||
|
|
||||||
while ( p= f_text ) {
|
while ( (p = f_text) != NULL)
|
||||||
gbp= p->r_val.rel_gp ;
|
{
|
||||||
if( gbp->g_status&DEF ) {
|
gbp = p->r_val.rel_gp;
|
||||||
|
if (gbp->g_status & DEF)
|
||||||
|
{
|
||||||
p->r_typ |= RELMNS;
|
p->r_typ |= RELMNS;
|
||||||
p->r_val.rel_i = gbp->g_val.g_addr;
|
p->r_val.rel_i = gbp->g_val.g_addr;
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
p->r_val.rel_gp = gbp->g_val.g_gp;
|
p->r_val.rel_gp = gbp->g_val.g_gp;
|
||||||
putblk(rtfile,(char *)(&(p->r_off)),sizeof *p - sizeof p) ;
|
putblk(rtfile, (char *) (&(p->r_off)), sizeof *p - sizeof p);
|
||||||
f_text= p->r_next ; freearea( (area_t) p , sizeof *p ) ;
|
f_text = p->r_next;
|
||||||
|
freearea((area_t) p, sizeof *p);
|
||||||
}
|
}
|
||||||
|
|
||||||
while( p= f_data ) {
|
while ( (p = f_data) != NULL)
|
||||||
if (p->r_typ == RELGLO) {
|
{
|
||||||
gbp= p->r_val.rel_gp ;
|
if (p->r_typ == RELGLO)
|
||||||
if(gbp->g_status&DEF) {
|
{
|
||||||
|
gbp = p->r_val.rel_gp;
|
||||||
|
if (gbp->g_status & DEF)
|
||||||
|
{
|
||||||
p->r_typ = RELADR;
|
p->r_typ = RELADR;
|
||||||
p->r_val.rel_i = gbp->g_val.g_addr;
|
p->r_val.rel_i = gbp->g_val.g_addr;
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
p->r_val.rel_gp = gbp->g_val.g_gp;
|
p->r_val.rel_gp = gbp->g_val.g_gp;
|
||||||
}
|
}
|
||||||
putblk(rdfile,(char *)(&(p->r_off)),sizeof *p - sizeof p) ;
|
putblk(rdfile, (char *) (&(p->r_off)), sizeof *p - sizeof p);
|
||||||
f_data= p->r_next ; freearea( (area_t) p , sizeof *p ) ;
|
f_data = p->r_next;
|
||||||
|
freearea((area_t) p, sizeof *p);
|
||||||
}
|
}
|
||||||
l_data= rlp_cast 0 ;
|
l_data = rlp_cast 0;
|
||||||
}
|
}
|
||||||
|
|
21
util/ass/assrl.h
Normal file
21
util/ass/assrl.h
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
/* Copyright (c) 2019 ACK Project.
|
||||||
|
* See the copyright notice in the ACK home directory,
|
||||||
|
* in the file "Copyright".
|
||||||
|
*
|
||||||
|
* Created on: 2019-03-13
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef ASSRL_H_
|
||||||
|
#define ASSRL_H_
|
||||||
|
|
||||||
|
/* Generates an e.out file from the the temporary code file "tfile" and
|
||||||
|
* data temporary "dfile" file. Output the data to "ifile".
|
||||||
|
*/
|
||||||
|
void copyout(void);
|
||||||
|
/* Update the relocation entries and place them into "rtfile" and "rdfile". */
|
||||||
|
void upd_reloc(void);
|
||||||
|
|
||||||
|
relc_t * data_reloc(char *arg ,FOFFSET off, int typ);
|
||||||
|
relc_t * text_reloc(glob_t *glosym, FOFFSET off, int typ);
|
||||||
|
|
||||||
|
#endif /* ASSRL_H_ */
|
|
@ -36,7 +36,7 @@ cprogram {
|
||||||
"modules/src/em_data+lib",
|
"modules/src/em_data+lib",
|
||||||
--"modules/src/data+lib",
|
--"modules/src/data+lib",
|
||||||
--"modules/src/object+lib",
|
--"modules/src/object+lib",
|
||||||
--"modules/src/system+lib",
|
"modules/src/system+lib",
|
||||||
"./ass*.h",
|
"./ass*.h",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,7 +64,7 @@ produced code the only messages to expect are "Out of memory"
|
||||||
or of the
|
or of the
|
||||||
form: Overflow in XXXX. The latter can usually be cured by giving
|
form: Overflow in XXXX. The latter can usually be cured by giving
|
||||||
a -sx flag,
|
a -sx flag,
|
||||||
the former means the program is too big, dimishing
|
the former means the program is too big, diminishing
|
||||||
the size of very large procedures can sometimes help.
|
the size of very large procedures can sometimes help.
|
||||||
The most likely errors, however, are unresolved references,
|
The most likely errors, however, are unresolved references,
|
||||||
probably caused by the omission of a library argument.
|
probably caused by the omission of a library argument.
|
||||||
|
|
|
@ -6,471 +6,646 @@
|
||||||
|
|
||||||
#include "ip_spec.h"
|
#include "ip_spec.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <string.h>
|
||||||
#include <em_spec.h>
|
#include <em_spec.h>
|
||||||
#include <em_flag.h>
|
#include <em_flag.h>
|
||||||
|
|
||||||
#ifndef NORCSID
|
|
||||||
static char rcs_id[] = "$Id$" ;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* This program reads the human readable interpreter specification
|
/* This program reads the human readable interpreter specification
|
||||||
and produces a efficient machine representation that can be
|
and produces a efficient machine representation that can be
|
||||||
translated by a C-compiler.
|
translated by a C-compiler.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define NOTAB 600 /* The max no of interpreter specs */
|
#define NOTAB 600 /* The max no of interpreter specs */
|
||||||
#define ESCAP 256
|
#define ESCAP 256
|
||||||
|
|
||||||
struct opform intable[NOTAB] ;
|
struct opform intable[NOTAB];
|
||||||
struct opform *lastform = intable-1 ;
|
struct opform *lastform = intable - 1;
|
||||||
|
|
||||||
int nerror = 0 ;
|
int nerror = 0;
|
||||||
int atend = 0 ;
|
int atend = 0;
|
||||||
int line = 1 ;
|
int line = 1;
|
||||||
int maxinsl= 0 ;
|
int maxinsl = 0;
|
||||||
|
|
||||||
extern char em_mnem[][4] ;
|
extern char em_mnem[][4];
|
||||||
char esca[] = "escape" ;
|
char esca[] = "escape";
|
||||||
#define ename(no) ((no)==ESCAP?esca:em_mnem[(no)])
|
#define ename(no) ((no)==ESCAP?esca:em_mnem[(no)])
|
||||||
|
|
||||||
extern char em_flag[] ;
|
extern char em_flag[];
|
||||||
|
|
||||||
main(argc,argv) char **argv ; {
|
|
||||||
if ( argc>1 ) {
|
/* Forward declarations */
|
||||||
if ( freopen(argv[1],"r",stdin)==NULL) {
|
static int readchar(void);
|
||||||
fatal("Cannot open %s",argv[1]) ;
|
static void pushback(int);
|
||||||
|
static void readin(void);
|
||||||
|
static char *ident(void);
|
||||||
|
static int getmnem(char *);
|
||||||
|
static void writeout(void);
|
||||||
|
static void checkall(void);
|
||||||
|
static void chkc(int, int, int);
|
||||||
|
static void ckop(int, int, int, int);
|
||||||
|
static int oplength(struct opform *);
|
||||||
|
static void check(int);
|
||||||
|
static int decflag(char *);
|
||||||
|
int compare(const void *, const void *);
|
||||||
|
|
||||||
|
static void error(char *format, ...);
|
||||||
|
static void mess(char *format, ...);
|
||||||
|
static void fatal(char *format, ...);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
if (argc > 1)
|
||||||
|
{
|
||||||
|
if (freopen(argv[1], "r", stdin) == NULL)
|
||||||
|
{
|
||||||
|
fatal("Cannot open %s", argv[1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( argc>2 ) {
|
if (argc > 2)
|
||||||
if ( freopen(argv[2],"w",stdout)==NULL) {
|
{
|
||||||
fatal("Cannot create %s",argv[2]) ;
|
if (freopen(argv[2], "w", stdout) == NULL)
|
||||||
|
{
|
||||||
|
fatal("Cannot create %s", argv[2]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( argc>3 ) {
|
if (argc > 3)
|
||||||
fatal("%s [ file [ file ] ]",argv[0]) ;
|
{
|
||||||
|
fatal("%s [ file [ file ] ]", argv[0]);
|
||||||
}
|
}
|
||||||
atend=0 ;
|
atend = 0;
|
||||||
readin();
|
readin();
|
||||||
atend=1 ;
|
atend = 1;
|
||||||
checkall();
|
checkall();
|
||||||
if ( nerror==0 ) {
|
if (nerror == 0)
|
||||||
|
{
|
||||||
writeout();
|
writeout();
|
||||||
}
|
}
|
||||||
exit(nerror);
|
exit(nerror);
|
||||||
}
|
}
|
||||||
|
|
||||||
readin() {
|
static void readin(void)
|
||||||
register struct opform *nextform ;
|
{
|
||||||
char *ident();
|
register struct opform *nextform;
|
||||||
char *firstid ;
|
char *firstid;
|
||||||
register maxl ;
|
register int maxl;
|
||||||
|
|
||||||
maxl = 0 ;
|
maxl = 0;
|
||||||
for ( nextform=intable ;
|
for (nextform = intable; !feof(stdin) && nextform < &intable[NOTAB];)
|
||||||
!feof(stdin) && nextform<&intable[NOTAB] ; ) {
|
{
|
||||||
firstid=ident() ;
|
firstid = ident();
|
||||||
if ( *firstid=='\n' || feof(stdin) ) continue ;
|
if (*firstid == '\n' || feof(stdin))
|
||||||
lastform=nextform ;
|
continue;
|
||||||
nextform->i_opcode = getmnem(firstid) ;
|
lastform = nextform;
|
||||||
nextform->i_flag = decflag(ident()) ;
|
nextform->i_opcode = getmnem(firstid);
|
||||||
switch ( nextform->i_flag&OPTYPE ) {
|
nextform->i_flag = decflag(ident());
|
||||||
|
switch (nextform->i_flag & OPTYPE)
|
||||||
|
{
|
||||||
case OPMINI:
|
case OPMINI:
|
||||||
case OPSHORT:
|
case OPSHORT:
|
||||||
nextform->i_num = atoi(ident()) ;
|
nextform->i_num = atoi(ident());
|
||||||
break ;
|
break;
|
||||||
}
|
}
|
||||||
nextform->i_low = atoi(ident()) ;
|
nextform->i_low = atoi(ident());
|
||||||
if ( *ident()!='\n' ) {
|
if (*ident() != '\n')
|
||||||
int c ;
|
{
|
||||||
|
int c;
|
||||||
error("End of line expected");
|
error("End of line expected");
|
||||||
while ( (c=readchar())!='\n' && c!=EOF ) ;
|
while ((c = readchar()) != '\n' && c != EOF)
|
||||||
|
;
|
||||||
}
|
}
|
||||||
if ( oplength(nextform)>maxl ) maxl=oplength(nextform) ;
|
if (oplength(nextform) > maxl)
|
||||||
nextform++ ;
|
maxl = oplength(nextform);
|
||||||
|
nextform++;
|
||||||
}
|
}
|
||||||
if ( !feof(stdin) ) fatal("Internal table too small") ;
|
if (!feof(stdin))
|
||||||
maxinsl = maxl ;
|
fatal("Internal table too small");
|
||||||
|
maxinsl = maxl;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *ident() {
|
static char *ident(void)
|
||||||
|
{
|
||||||
/* skip spaces and tabs, anything up to space,tab or eof is
|
/* skip spaces and tabs, anything up to space,tab or eof is
|
||||||
a identifier.
|
a identifier.
|
||||||
Anything from # to end-of-line is an end-of-line.
|
Anything from # to end-of-line is an end-of-line.
|
||||||
End-of-line is an identifier all by itself.
|
End-of-line is an identifier all by itself.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static char array[200] ;
|
static char array[200];
|
||||||
register int c ;
|
register int c;
|
||||||
register char *cc ;
|
register char *cc;
|
||||||
|
|
||||||
do {
|
do
|
||||||
c=readchar() ;
|
{
|
||||||
} while ( c==' ' || c=='\t' ) ;
|
c = readchar();
|
||||||
for ( cc=array ; cc<&array[(sizeof array) - 1] ; cc++ ) {
|
} while (c == ' ' || c == '\t');
|
||||||
if ( c=='#' ) {
|
for (cc = array; cc < &array[(sizeof array) - 1]; cc++)
|
||||||
do {
|
{
|
||||||
c=readchar();
|
if (c == '#')
|
||||||
} while ( c!='\n' && c!=EOF ) ;
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
c = readchar();
|
||||||
|
} while (c != '\n' && c != EOF);
|
||||||
}
|
}
|
||||||
*cc = c ;
|
*cc = c;
|
||||||
if ( c=='\n' && cc==array ) break ;
|
if (c == '\n' && cc == array)
|
||||||
c=readchar() ;
|
break;
|
||||||
if ( c=='\n' ) {
|
c = readchar();
|
||||||
pushback(c) ;
|
if (c == '\n')
|
||||||
break ;
|
{
|
||||||
|
pushback(c);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if ( c==' ' || c=='\t' || c==EOF ) break ;
|
if (c == ' ' || c == '\t' || c == EOF)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
*++cc=0 ;
|
*++cc = 0;
|
||||||
return array ;
|
return array;
|
||||||
}
|
}
|
||||||
|
|
||||||
int getmnem(str) char *str ; {
|
static int getmnem(char *str)
|
||||||
char (*ptr)[4] ;
|
{
|
||||||
|
char (*ptr)[4];
|
||||||
|
|
||||||
for ( ptr = em_mnem ; *ptr<= &em_mnem[sp_lmnem-sp_fmnem][0] ; ptr++ ) {
|
for (ptr = em_mnem; *ptr <= &em_mnem[sp_lmnem - sp_fmnem][0]; ptr++)
|
||||||
if ( strcmp(*ptr,str)==0 ) return (ptr-em_mnem) ;
|
{
|
||||||
|
if (strcmp(*ptr, str) == 0)
|
||||||
|
return (ptr - em_mnem);
|
||||||
}
|
}
|
||||||
error("Illegal mnemonic") ;
|
error("Illegal mnemonic");
|
||||||
return 0 ;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
error(str,a1,a2,a3,a4,a5,a6) /* VARARGS1 */ char *str ; {
|
/* VARARGS1 */
|
||||||
if ( !atend ) fprintf(stderr,"line %d: ",line) ;
|
static void error(char *format, ...)
|
||||||
fprintf(stderr,str,a1,a2,a3,a4,a5,a6) ;
|
{
|
||||||
fprintf(stderr,"\n");
|
va_list argptr;
|
||||||
nerror++ ;
|
if (!atend)
|
||||||
|
fprintf(stderr, "line %d: ", line);
|
||||||
|
va_start(argptr, format);
|
||||||
|
vfprintf(stderr, format, argptr);
|
||||||
|
va_end(argptr);
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
nerror++;
|
||||||
}
|
}
|
||||||
|
|
||||||
mess(str,a1,a2,a3,a4,a5,a6) /* VARARGS1 */ char *str ; {
|
/* VARARGS1 */
|
||||||
if ( !atend ) fprintf(stderr,"line %d: ",line) ;
|
static void mess(char *format, ...)
|
||||||
fprintf(stderr,str,a1,a2,a3,a4,a5,a6) ;
|
{
|
||||||
fprintf(stderr,"\n");
|
va_list argptr;
|
||||||
|
if (!atend)
|
||||||
|
fprintf(stderr, "line %d: ", line);
|
||||||
|
va_start(argptr, format);
|
||||||
|
vfprintf(stderr, format, argptr);
|
||||||
|
va_end(argptr);
|
||||||
|
fprintf(stderr, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
fatal(str,a1,a2,a3,a4,a5,a6) /* VARARGS1 */ char *str ; {
|
/* VARARGS1 */
|
||||||
error(str,a1,a2,a3,a4,a5,a6) ;
|
static void fatal(char *format, ...)
|
||||||
exit(1) ;
|
{
|
||||||
|
va_list argptr;
|
||||||
|
if (!atend)
|
||||||
|
fprintf(stderr, "line %d: ", line);
|
||||||
|
va_start(argptr, format);
|
||||||
|
vfprintf(stderr, format, argptr);
|
||||||
|
va_end(argptr);
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define ILLGL -1
|
#define ILLGL -1
|
||||||
|
|
||||||
check(val) int val ; {
|
static void check(int val)
|
||||||
if ( val!=ILLGL ) error("Illegal flag combination") ;
|
{
|
||||||
|
if (val != ILLGL)
|
||||||
|
error("Illegal flag combination");
|
||||||
}
|
}
|
||||||
|
|
||||||
int decflag(str) char *str ; {
|
static int decflag(char *str)
|
||||||
int type ;
|
{
|
||||||
int escape ;
|
int type;
|
||||||
int range ;
|
int escape;
|
||||||
int wordm ;
|
int range;
|
||||||
int notzero ;
|
int wordm;
|
||||||
|
int notzero;
|
||||||
|
|
||||||
type=escape=range=wordm=notzero= ILLGL ;
|
type = escape = range = wordm = notzero = ILLGL;
|
||||||
while ( *str ) switch ( *str++ ) {
|
while (*str)
|
||||||
case 'm' :
|
switch (*str++)
|
||||||
check(type) ; type=OPMINI ; break ;
|
{
|
||||||
case 's' :
|
case 'm':
|
||||||
check(type) ; type=OPSHORT ; break ;
|
check(type);
|
||||||
case '-' :
|
type = OPMINI;
|
||||||
check(type) ; type=OPNO ; break ;
|
break;
|
||||||
case '1' :
|
case 's':
|
||||||
check(type) ; type=OP8 ; break ;
|
check(type);
|
||||||
case '2' :
|
type = OPSHORT;
|
||||||
check(type) ; type=OP16 ; break ;
|
break;
|
||||||
case '4' :
|
case '-':
|
||||||
check(type) ; type=OP32 ; break ;
|
check(type);
|
||||||
case '8' :
|
type = OPNO;
|
||||||
check(type) ; type=OP64 ; break ;
|
break;
|
||||||
|
case '1':
|
||||||
|
check(type);
|
||||||
|
type = OP8;
|
||||||
|
break;
|
||||||
|
case '2':
|
||||||
|
check(type);
|
||||||
|
type = OP16;
|
||||||
|
break;
|
||||||
|
case '4':
|
||||||
|
check(type);
|
||||||
|
type = OP32;
|
||||||
|
break;
|
||||||
|
case '8':
|
||||||
|
check(type);
|
||||||
|
type = OP64;
|
||||||
|
break;
|
||||||
case 'u':
|
case 'u':
|
||||||
check(type) ; type=OP16U ; break ;
|
check(type);
|
||||||
case 'e' :
|
type = OP16U;
|
||||||
check(escape) ; escape=0 ; break ;
|
break;
|
||||||
case 'N' :
|
case 'e':
|
||||||
check(range) ; range= 2 ; break ;
|
check(escape);
|
||||||
case 'P' :
|
escape = 0;
|
||||||
check(range) ; range= 1 ; break ;
|
break;
|
||||||
case 'w' :
|
case 'N':
|
||||||
check(wordm) ; wordm=0 ; break ;
|
check(range);
|
||||||
case 'o' :
|
range = 2;
|
||||||
check(notzero) ; notzero=0 ; break ;
|
break;
|
||||||
default :
|
case 'P':
|
||||||
error("Unknown flag") ;
|
check(range);
|
||||||
|
range = 1;
|
||||||
|
break;
|
||||||
|
case 'w':
|
||||||
|
check(wordm);
|
||||||
|
wordm = 0;
|
||||||
|
break;
|
||||||
|
case 'o':
|
||||||
|
check(notzero);
|
||||||
|
notzero = 0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
error("Unknown flag");
|
||||||
}
|
}
|
||||||
if ( type==ILLGL ) error("Type must be specified") ;
|
if (type == ILLGL)
|
||||||
switch ( type ) {
|
error("Type must be specified");
|
||||||
case OP64 :
|
switch (type)
|
||||||
case OP32 :
|
{
|
||||||
if ( escape!=ILLGL ) error("Conflicting escapes") ;
|
case OP64:
|
||||||
escape=ILLGL ;
|
case OP32:
|
||||||
case OP16 :
|
if (escape != ILLGL)
|
||||||
case OP16U :
|
error("Conflicting escapes");
|
||||||
case OP8 :
|
escape = ILLGL;
|
||||||
case OPSHORT :
|
case OP16:
|
||||||
case OPNO :
|
case OP16U:
|
||||||
if ( notzero!=ILLGL ) mess("Improbable OPNZ") ;
|
case OP8:
|
||||||
if ( type==OPNO && range!=ILLGL ) {
|
case OPSHORT:
|
||||||
mess("No operand in range") ;
|
case OPNO:
|
||||||
|
if (notzero != ILLGL)
|
||||||
|
mess("Improbable OPNZ");
|
||||||
|
if (type == OPNO && range != ILLGL)
|
||||||
|
{
|
||||||
|
mess("No operand in range");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( escape!=ILLGL ) type|=OPESC ;
|
if (escape != ILLGL)
|
||||||
if ( wordm!=ILLGL ) type|=OPWORD ;
|
type |= OPESC;
|
||||||
switch ( range) {
|
if (wordm != ILLGL)
|
||||||
case ILLGL : type|=OP_BOTH ;
|
type |= OPWORD;
|
||||||
if ( type==OPMINI || type==OPSHORT )
|
switch (range)
|
||||||
error("Minies and shorties must have P or N") ;
|
{
|
||||||
break ;
|
case ILLGL:
|
||||||
case 1 : type|=OP_POS ; break ;
|
type |= OP_BOTH;
|
||||||
case 2 : type|=OP_NEG ; break ;
|
if (type == OPMINI || type == OPSHORT)
|
||||||
|
error("Minies and shorties must have P or N");
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
type |= OP_POS;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
type |= OP_NEG;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if ( notzero!=ILLGL ) type|=OPNZ ;
|
if (notzero != ILLGL)
|
||||||
return type ;
|
type |= OPNZ;
|
||||||
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
writeout() {
|
static void writeout(void)
|
||||||
register struct opform *next ;
|
{
|
||||||
int elem[sp_lmnem-sp_fmnem+1+1] ;
|
register struct opform *next;
|
||||||
|
int elem[sp_lmnem - sp_fmnem + 1 + 1];
|
||||||
/* for each op points to first of descr. */
|
/* for each op points to first of descr. */
|
||||||
register int i,currop ;
|
register int i, currop;
|
||||||
int nch ;
|
int nch;
|
||||||
int compare() ;
|
|
||||||
|
|
||||||
qsort(intable,(lastform-intable)+1,sizeof intable[0],compare) ;
|
qsort(intable, (lastform - intable) + 1, sizeof intable[0], compare);
|
||||||
|
|
||||||
printf("int\tmaxinsl\t= %d ;\n",maxinsl) ;
|
printf("int\tmaxinsl\t= %d ;\n", maxinsl);
|
||||||
currop= -1 ; nch=0 ;
|
currop = -1;
|
||||||
printf("char opchoice[] = {\n") ;
|
nch = 0;
|
||||||
for (next=intable ; next<=lastform ; next++ ) {
|
printf("char opchoice[] = {\n");
|
||||||
if ( (next->i_opcode&0377)!=currop ) {
|
for (next = intable; next <= lastform; next++)
|
||||||
for ( currop++ ;
|
{
|
||||||
currop<(next->i_opcode&0377) ; currop++ ) {
|
if ((next->i_opcode & 0377) != currop)
|
||||||
elem[currop]= nch ;
|
{
|
||||||
error("Missing opcode %s",em_mnem[currop]) ;
|
for (currop++; currop < (next->i_opcode & 0377); currop++)
|
||||||
|
{
|
||||||
|
elem[currop] = nch;
|
||||||
|
error("Missing opcode %s", em_mnem[currop]);
|
||||||
}
|
}
|
||||||
elem[currop]= nch ;
|
elem[currop] = nch;
|
||||||
}
|
}
|
||||||
printf("%d, %d,",next->i_flag&0377,next->i_low&0377) ;
|
printf("%d, %d,", next->i_flag & 0377, next->i_low & 0377);
|
||||||
nch+=2 ;
|
nch += 2;
|
||||||
switch ( next->i_flag&OPTYPE ) {
|
switch (next->i_flag & OPTYPE)
|
||||||
case OPMINI :
|
{
|
||||||
case OPSHORT :
|
case OPMINI:
|
||||||
printf("%d,",next->i_num&0377) ; nch++ ;
|
case OPSHORT:
|
||||||
|
printf("%d,", next->i_num & 0377);
|
||||||
|
nch++;
|
||||||
}
|
}
|
||||||
printf("\n") ;
|
printf("\n");
|
||||||
}
|
}
|
||||||
for ( currop++ ; currop<=sp_lmnem-sp_fmnem ; currop++ ) {
|
for (currop++; currop <= sp_lmnem - sp_fmnem; currop++)
|
||||||
elem[currop]= nch ;
|
{
|
||||||
error("Missing opcode %s",em_mnem[currop]) ;
|
elem[currop] = nch;
|
||||||
|
error("Missing opcode %s", em_mnem[currop]);
|
||||||
}
|
}
|
||||||
elem[sp_lmnem-sp_fmnem+1]=nch ;
|
elem[sp_lmnem - sp_fmnem + 1] = nch;
|
||||||
printf("0 } ;\n\nchar *opindex[] = {\n");
|
printf("0 } ;\n\nchar *opindex[] = {\n");
|
||||||
for ( i=0 ; i<=sp_lmnem-sp_fmnem+1 ; i++ ) {
|
for (i = 0; i <= sp_lmnem - sp_fmnem + 1; i++)
|
||||||
printf(" &opchoice[%d], /* %d = %s */\n",elem[i], i, em_mnem[i]) ;
|
{
|
||||||
|
printf(" &opchoice[%d], /* %d = %s */\n", elem[i], i, em_mnem[i]);
|
||||||
}
|
}
|
||||||
printf("} ;\n") ;
|
printf("} ;\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
int compare(a,b) struct opform *a,*b ; {
|
int compare(const void *a1, const void *b1)
|
||||||
if ( a->i_opcode!=b->i_opcode ) {
|
{
|
||||||
return (a->i_opcode&0377)-(b->i_opcode&0377) ;
|
struct opform *a = (struct opform *)(a1);
|
||||||
|
struct opform *b = (struct opform *)(b1);
|
||||||
|
|
||||||
|
if (a->i_opcode != b->i_opcode)
|
||||||
|
{
|
||||||
|
return (a->i_opcode & 0377) - (b->i_opcode & 0377);
|
||||||
}
|
}
|
||||||
return oplength(a)-oplength(b) ;
|
return oplength(a) - oplength(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
int oplength(a) struct opform *a ; {
|
static int oplength(struct opform *a)
|
||||||
int cnt ;
|
{
|
||||||
|
int cnt;
|
||||||
|
|
||||||
cnt=1 ;
|
cnt = 1;
|
||||||
if ( a->i_flag&OPESC ) cnt++ ;
|
if (a->i_flag & OPESC)
|
||||||
switch( a->i_flag&OPTYPE ) {
|
cnt++;
|
||||||
case OPNO :
|
switch (a->i_flag & OPTYPE)
|
||||||
case OPMINI : break ;
|
{
|
||||||
case OP8 :
|
case OPNO:
|
||||||
case OPSHORT : cnt++ ; break ;
|
case OPMINI:
|
||||||
case OP16U :
|
break;
|
||||||
case OP16 : cnt+=2 ; break ;
|
case OP8:
|
||||||
case OP32 : cnt+=5 ; break ;
|
case OPSHORT:
|
||||||
case OP64 : cnt+=9 ; break ;
|
cnt++;
|
||||||
|
break;
|
||||||
|
case OP16U:
|
||||||
|
case OP16:
|
||||||
|
cnt += 2;
|
||||||
|
break;
|
||||||
|
case OP32:
|
||||||
|
cnt += 5;
|
||||||
|
break;
|
||||||
|
case OP64:
|
||||||
|
cnt += 9;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return cnt ;
|
return cnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ----------- checking --------------*/
|
/* ----------- checking --------------*/
|
||||||
|
|
||||||
int ecodes[256],codes[256],lcodes[256] ;
|
int ecodes[256], codes[256], lcodes[256];
|
||||||
|
|
||||||
#define NMNEM (sp_lmnem-sp_fmnem+1)
|
#define NMNEM (sp_lmnem-sp_fmnem+1)
|
||||||
#define MUST 1
|
#define MUST 1
|
||||||
#define MAY 2
|
#define MAY 2
|
||||||
#define FORB 3
|
#define FORB 3
|
||||||
|
|
||||||
char negc[NMNEM], zc[NMNEM], posc[NMNEM] ;
|
char negc[NMNEM], zc[NMNEM], posc[NMNEM];
|
||||||
|
|
||||||
checkall() {
|
static void checkall(void)
|
||||||
register i,flag ;
|
{
|
||||||
register struct opform *next ;
|
register int i, flag;
|
||||||
int opc,low ;
|
register struct opform *next;
|
||||||
|
int opc, low;
|
||||||
|
|
||||||
for ( i=0 ; i<NMNEM ; i++ ) negc[i]=zc[i]=posc[i]=0 ;
|
for (i = 0; i < NMNEM; i++)
|
||||||
for ( i=0 ; i<256 ; i++ ) lcodes[i]= codes[i]= ecodes[i]= -1 ;
|
negc[i] = zc[i] = posc[i] = 0;
|
||||||
codes[254]=codes[255]=ESCAP;
|
for (i = 0; i < 256; i++)
|
||||||
|
lcodes[i] = codes[i] = ecodes[i] = -1;
|
||||||
|
codes[254] = codes[255] = ESCAP;
|
||||||
|
|
||||||
atend=0 ; line=0 ;
|
atend = 0;
|
||||||
for ( next=intable ; next<=lastform ; next++ ) {
|
line = 0;
|
||||||
line++ ;
|
for (next = intable; next <= lastform; next++)
|
||||||
flag = next->i_flag&0377 ;
|
{
|
||||||
opc = next->i_opcode&0377 ;
|
line++;
|
||||||
low = next->i_low&0377 ;
|
flag = next->i_flag & 0377;
|
||||||
chkc(flag,low,opc) ;
|
opc = next->i_opcode & 0377;
|
||||||
switch(flag&OPTYPE) {
|
low = next->i_low & 0377;
|
||||||
case OPNO : zc[opc]++ ; break ;
|
chkc(flag, low, opc);
|
||||||
case OPMINI :
|
switch (flag & OPTYPE)
|
||||||
case OPSHORT :
|
{
|
||||||
for ( i=1 ; i<((next->i_num)&0377) ; i++ ) {
|
case OPNO:
|
||||||
chkc(flag,low+i,opc) ;
|
zc[opc]++;
|
||||||
|
break;
|
||||||
|
case OPMINI:
|
||||||
|
case OPSHORT:
|
||||||
|
for (i = 1; i < ((next->i_num) & 0377); i++)
|
||||||
|
{
|
||||||
|
chkc(flag, low + i, opc);
|
||||||
}
|
}
|
||||||
if ( !(em_flag[opc]&PAR_G) &&
|
if (!(em_flag[opc] & PAR_G) && (flag & OPRANGE) == OP_BOTH)
|
||||||
(flag&OPRANGE)==OP_BOTH) {
|
{
|
||||||
mess("Mini's and shorties should have P or N");
|
mess("Mini's and shorties should have P or N");
|
||||||
}
|
}
|
||||||
break ;
|
break;
|
||||||
case OP8 :
|
case OP8:
|
||||||
error("OP8 is removed") ;
|
error("OP8 is removed");
|
||||||
break ;
|
break;
|
||||||
case OP16 :
|
case OP16:
|
||||||
if ( flag&OP_NEG )
|
if (flag & OP_NEG)
|
||||||
negc[opc]++ ;
|
negc[opc]++;
|
||||||
else if ( flag&OP_POS )
|
else if (flag & OP_POS)
|
||||||
posc[opc]++ ;
|
posc[opc]++;
|
||||||
break ;
|
break;
|
||||||
case OP16U :
|
case OP16U:
|
||||||
case OP32 :
|
case OP32:
|
||||||
case OP64 :
|
case OP64:
|
||||||
break ;
|
break;
|
||||||
default :
|
default:
|
||||||
error("Illegal type") ;
|
error("Illegal type");
|
||||||
break ;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
atend=1 ;
|
atend = 1;
|
||||||
for ( i=0 ; i<256 ; i++ ) if ( codes[i]== -1 ) {
|
for (i = 0; i < 256; i++)
|
||||||
mess("interpreter opcode %d not used",i) ;
|
if (codes[i] == -1)
|
||||||
|
{
|
||||||
|
mess("interpreter opcode %d not used", i);
|
||||||
}
|
}
|
||||||
for ( opc=0 ; opc<NMNEM ; opc++ ) {
|
for (opc = 0; opc < NMNEM; opc++)
|
||||||
switch(em_flag[opc]&EM_PAR) {
|
{
|
||||||
case PAR_NO :
|
switch (em_flag[opc] & EM_PAR)
|
||||||
ckop(opc,MUST,FORB,FORB) ;
|
{
|
||||||
break ;
|
case PAR_NO:
|
||||||
|
ckop(opc, MUST, FORB, FORB);
|
||||||
|
break;
|
||||||
case PAR_C:
|
case PAR_C:
|
||||||
case PAR_D:
|
case PAR_D:
|
||||||
case PAR_F:
|
case PAR_F:
|
||||||
case PAR_B:
|
case PAR_B:
|
||||||
ckop(opc,FORB,MAY,MAY) ;
|
ckop(opc, FORB, MAY, MAY);
|
||||||
break ;
|
break;
|
||||||
case PAR_N:
|
case PAR_N:
|
||||||
case PAR_G:
|
case PAR_G:
|
||||||
case PAR_S:
|
case PAR_S:
|
||||||
case PAR_Z:
|
case PAR_Z:
|
||||||
case PAR_O:
|
case PAR_O:
|
||||||
case PAR_P:
|
case PAR_P:
|
||||||
ckop(opc,FORB,MAY,FORB) ;
|
ckop(opc, FORB, MAY, FORB);
|
||||||
break ;
|
break;
|
||||||
case PAR_R:
|
case PAR_R:
|
||||||
ckop(opc,FORB,MAY,FORB) ;
|
ckop(opc, FORB, MAY, FORB);
|
||||||
break ;
|
break;
|
||||||
case PAR_L:
|
case PAR_L:
|
||||||
ckop(opc,FORB,MUST,MUST) ;
|
ckop(opc, FORB, MUST, MUST);
|
||||||
break ;
|
break;
|
||||||
case PAR_W:
|
case PAR_W:
|
||||||
ckop(opc,MUST,MAY,FORB) ;
|
ckop(opc, MUST, MAY, FORB);
|
||||||
break ;
|
break;
|
||||||
default :
|
default:
|
||||||
error("Unknown instruction type of %s",ename(opc)) ;
|
error("Unknown instruction type of %s", ename(opc));
|
||||||
break ;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
chkc(flag,icode,emc) {
|
static void chkc(int flag, int icode, int emc)
|
||||||
if ( flag&OPESC ) {
|
{
|
||||||
if ( ecodes[icode]!=-1 ) {
|
if (flag & OPESC)
|
||||||
mess("Escaped opcode %d used by %s and %s",
|
{
|
||||||
icode,ename(emc),ename(ecodes[icode])) ;
|
if (ecodes[icode] != -1)
|
||||||
|
{
|
||||||
|
mess("Escaped opcode %d used by %s and %s", icode, ename(emc),
|
||||||
|
ename(ecodes[icode]));
|
||||||
}
|
}
|
||||||
ecodes[icode]=emc;
|
ecodes[icode] = emc;
|
||||||
} else switch ( flag&OPTYPE ) {
|
}
|
||||||
|
else
|
||||||
|
switch (flag & OPTYPE)
|
||||||
|
{
|
||||||
default:
|
default:
|
||||||
if ( codes[icode]!=-1 ) {
|
if (codes[icode] != -1)
|
||||||
mess("Opcode %d used by %s and %s",
|
{
|
||||||
icode,ename(emc),ename(codes[icode])) ;
|
mess("Opcode %d used by %s and %s", icode, ename(emc),
|
||||||
|
ename(codes[icode]));
|
||||||
}
|
}
|
||||||
codes[icode]=emc;
|
codes[icode] = emc;
|
||||||
break ;
|
break;
|
||||||
case OP32:
|
case OP32:
|
||||||
case OP64:
|
case OP64:
|
||||||
if ( lcodes[icode]!=-1 ) {
|
if (lcodes[icode] != -1)
|
||||||
mess("Long opcode %d used by %s and %s",
|
{
|
||||||
icode,ename(emc),ename(codes[icode])) ;
|
mess("Long opcode %d used by %s and %s", icode, ename(emc),
|
||||||
|
ename(codes[icode]));
|
||||||
}
|
}
|
||||||
lcodes[icode]=emc;
|
lcodes[icode] = emc;
|
||||||
break ;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ckop(emc,zf,pf,nf) {
|
static void ckop(int emc, int zf, int pf, int nf)
|
||||||
if ( zc[emc]>1 ) mess("More then one OPNO for %s",ename(emc)) ;
|
{
|
||||||
if ( posc[emc]>1 ) mess("More then one OP16(pos) for %s",ename(emc)) ;
|
if (zc[emc] > 1)
|
||||||
if ( negc[emc]>1 ) mess("More then one OP16(neg) for %s",ename(emc)) ;
|
mess("More then one OPNO for %s", ename(emc));
|
||||||
switch(zf) {
|
if (posc[emc] > 1)
|
||||||
|
mess("More then one OP16(pos) for %s", ename(emc));
|
||||||
|
if (negc[emc] > 1)
|
||||||
|
mess("More then one OP16(neg) for %s", ename(emc));
|
||||||
|
switch (zf)
|
||||||
|
{
|
||||||
case MUST:
|
case MUST:
|
||||||
if ( zc[emc]==0 ) mess("No OPNO for %s",ename(emc)) ;
|
if (zc[emc] == 0)
|
||||||
break ;
|
mess("No OPNO for %s", ename(emc));
|
||||||
|
break;
|
||||||
case FORB:
|
case FORB:
|
||||||
if ( zc[emc]==1 ) mess("Forbidden OPNO for %s",ename(emc)) ;
|
if (zc[emc] == 1)
|
||||||
break ;
|
mess("Forbidden OPNO for %s", ename(emc));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
switch(pf) {
|
switch (pf)
|
||||||
|
{
|
||||||
case MUST:
|
case MUST:
|
||||||
if ( posc[emc]==0 ) mess("No OP16(pos) for %s",ename(emc)) ;
|
if (posc[emc] == 0)
|
||||||
break ;
|
mess("No OP16(pos) for %s", ename(emc));
|
||||||
|
break;
|
||||||
case FORB:
|
case FORB:
|
||||||
if ( posc[emc]==1 )
|
if (posc[emc] == 1)
|
||||||
mess("Forbidden OP16(pos) for %s",ename(emc)) ;
|
mess("Forbidden OP16(pos) for %s", ename(emc));
|
||||||
break ;
|
break;
|
||||||
}
|
}
|
||||||
switch(nf) {
|
switch (nf)
|
||||||
|
{
|
||||||
case MUST:
|
case MUST:
|
||||||
if ( negc[emc]==0 ) mess("No OP16(neg) for %s",ename(emc)) ;
|
if (negc[emc] == 0)
|
||||||
break ;
|
mess("No OP16(neg) for %s", ename(emc));
|
||||||
|
break;
|
||||||
case FORB:
|
case FORB:
|
||||||
if ( negc[emc]==1 )
|
if (negc[emc] == 1)
|
||||||
mess("Forbidden OP16(neg) for %s",ename(emc)) ;
|
mess("Forbidden OP16(neg) for %s", ename(emc));
|
||||||
break ;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pushchar ;
|
static int pushchar;
|
||||||
static int pushf ;
|
static int pushf;
|
||||||
|
|
||||||
int readchar() {
|
static int readchar(void)
|
||||||
int c ;
|
{
|
||||||
|
int c;
|
||||||
|
|
||||||
if ( pushf ) {
|
if (pushf)
|
||||||
pushf=0 ;
|
{
|
||||||
c = pushchar ;
|
pushf = 0;
|
||||||
} else {
|
c = pushchar;
|
||||||
if ( feof(stdin) ) return EOF ;
|
|
||||||
c=getc(stdin) ;
|
|
||||||
}
|
}
|
||||||
if ( c=='\n' ) line++ ;
|
else
|
||||||
return c ;
|
{
|
||||||
|
if (feof(stdin))
|
||||||
|
return EOF;
|
||||||
|
c = getc(stdin);
|
||||||
|
}
|
||||||
|
if (c == '\n')
|
||||||
|
line++;
|
||||||
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
pushback(c) {
|
static void pushback(int c)
|
||||||
if ( pushf ) {
|
{
|
||||||
fatal("Double pushback") ;
|
if (pushf)
|
||||||
|
{
|
||||||
|
fatal("Double pushback");
|
||||||
}
|
}
|
||||||
pushf++ ;
|
pushf++;
|
||||||
pushchar=c ;
|
pushchar = c;
|
||||||
if ( c=='\n' ) line-- ;
|
if (c == '\n')
|
||||||
|
line--;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue