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