+ ANSI C conversion

This commit is contained in:
carl 2019-03-17 22:41:25 +08:00
parent 0df5d2f50b
commit 75909230c9
19 changed files with 2748 additions and 1984 deletions

View file

@ -1,5 +1,10 @@
#include <string.h>
#include <stddef.h>
#include "ass00.h" #include "ass00.h"
#include "assex.h" #include "assex.h"
#include "assci.h"
#include "asscm.h"
#include "assrl.h"
/* /*
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
@ -7,205 +12,289 @@
* *
*/ */
#ifndef NORCSID char oflag;
static char rcs_id[] = "$Id$" ; static int memflg;
#endif
/* Forward declarations. */
static siz_t* getsizes(char *);
static void getcore(void);
static void argument(char *);
static void flags(char *);
static void skipentry(void);
static void enmd_pro(void);
static void enmd_glo(void);
static void archive(void);
static void finish_up(void);
static void check_def(void);
static void c_print(void);
static void c_dprint(char *, char*);
/* External definitions */
void pass_3(void);
void pass_4(void);
void pass_5(void);
/* /*
** Main routine of EM1-assembler/loader ** Main routine of EM1-assembler/loader
*/ */
main(argc, argv) int main(int argc, char **argv)
int argc;
char **argv;
{ {
/* /*
* Usage: ass [-[d][p][m][u][U]] [-s(s/m/l/x)] [ [file] [flag] ] ... * Usage: ass [-[d][p][m][u][U]] [-s(s/m/l/x)] [ [file] [flag] ] ...
* The d flag can be repeated several times, resulting in more * The d flag can be repeated several times, resulting in more
* debugging information. * debugging information.
*/ */
char workspace[6000] ; char workspace[6000];
register char *cp ; register char *cp;
register int argno ; register int argno;
progname = argv[0]; progname = argv[0];
for ( cp=argv[0] ; *cp ; ) if ( *cp++ == '/' ) progname= cp; for (cp = argv[0]; *cp;)
for ( argno=1 ; argno<argc ; argno++ ) { if (*cp++ == '/')
if ( argv[argno][0] == '-' && LC(argv[argno][1]) == 's') { progname = cp;
getsizes(&argv[argno][2]); for (argno = 1; argno < argc; argno++)
break ; {
if (argv[argno][0] == '-' && LC(argv[argno][1]) == 's')
{
oursize = getsizes(&argv[argno][2]);
break;
} }
} }
/* A piece of the interpreter's stack frame is used as /* A piece of the interpreter's stack frame is used as
free area initially */ free area initially */
freearea( (area_t) workspace, (unsigned) sizeof workspace ) ; freearea((area_t) workspace, (unsigned) sizeof workspace);
getcore(); getcore();
init_files(); init_files();
init_vars(); init_vars();
while ( --argc ) while (--argc)
argument(*++argv); argument(*++argv);
finish_up(); finish_up();
exit(nerrors!=0); exit(nerrors != 0);
} }
getcore() { static void getcore(void)
{
register siz_t *p; register siz_t *p;
siz_t bytes; siz_t bytes;
register unsigned n ; register unsigned n;
register char *base ; register char *base;
/* /*
* xglobs[] should be located in front of mglobs[], see upd_reloc() * xglobs[] should be located in front of mglobs[], see upd_reloc()
*/ */
p = oursize; n = 0; p = oursize;
n = 0;
n += (bytes.n_glab = p->n_glab * (sizeof *xglobs)); n += (bytes.n_glab = p->n_glab * (sizeof *xglobs));
n += (bytes.n_mlab = p->n_mlab * (sizeof *mglobs)); n += (bytes.n_mlab = p->n_mlab * (sizeof *mglobs));
n += (bytes.n_mproc = p->n_mproc * (sizeof *mprocs)); n += (bytes.n_mproc = p->n_mproc * (sizeof *mprocs));
n += (bytes.n_xproc = p->n_xproc * (sizeof *xprocs)); n += (bytes.n_xproc = p->n_xproc * (sizeof *xprocs));
n += (bytes.n_proc = p->n_proc * (sizeof *proctab)); n += (bytes.n_proc = p->n_proc * (sizeof *proctab));
base = getarea(n); base = getarea(n);
zero(base,n); memset(base, 0, n);
xglobs = gbp_cast base; base += bytes.n_glab; xglobs = gbp_cast base;
mglobs = gbp_cast base; base += bytes.n_mlab; base += bytes.n_glab;
mprocs = prp_cast base; base += bytes.n_mproc; mglobs = gbp_cast base;
xprocs = prp_cast base; base += bytes.n_xproc; base += bytes.n_mlab;
proctab = ptp_cast base; base += bytes.n_proc; mprocs = prp_cast base;
base += bytes.n_mproc;
xprocs = prp_cast base;
base += bytes.n_xproc;
proctab = ptp_cast base;
base += bytes.n_proc;
} }
getsizes(str) char *str; { static siz_t* getsizes(char *str)
{
/* /*
* accepts -ss (small), -sm (medium), -sl (large), -sx (extra large) * accepts -ss (small), -sm (medium), -sl (large), -sx (extra large)
*/ */
switch(LC(*str)) { switch (LC(*str))
default:error("bad size option %s",str); {
case 's': oursize = &sizes[0]; break; default:
case 'm': oursize = &sizes[1]; break; error("bad size option %s", str);
case 'l': oursize = &sizes[2]; break; case 's':
case 'x': oursize = &sizes[3]; break; return &sizes[0];
break;
case 'm':
return &sizes[1];
break;
case 'l':
return &sizes[2];
break;
case 'x':
return &sizes[3];
break;
} }
} }
char oflag;
argument(arg) char *arg; {
register w;
/*
* This routine decides what to do with each argument.
* It recognises flags and modules.
* Furthermore, it knows a library when it sees it and
* call archive() to split it apart.
*/
if (oflag) {
eout = arg;
oflag=0;
return;
}
if(*arg == '-') {
flags(arg);
return;
}
curfile = arg; /* for error messages etc. */
if ((ifile = fopen(arg,"r")) == 0) {
error("can't open %s",arg);
return;
}
inpoff = 2;
if ((w = getu16()) == sp_magic )
read_compact();
else if (w == ARMAG || w == AALMAG) {
archmode = TRUE;
archive();
archmode = FALSE;
} else
error("%s: bad format",arg);
if (fclose(ifile) == EOF)
;
}
/* /*
** process flag arguments * This routine decides what to do with each argument.
*/ * It recognises flags and modules.
* Furthermore, it knows a library when it sees it and
static int memflg ; * call archive() to split it apart.
*/
flags(arg) static void argument(char *arg)
char *arg;
{ {
register char *argp; register int w;
register on;
if (oflag)
{
eout = arg;
oflag = 0;
return;
}
if (*arg == '-')
{
flags(arg);
return;
}
curfile = arg; /* for error messages etc. */
if ((ifile = fopen(arg, "r")) == NULL)
{
error("can't open %s", arg);
return;
}
inpoff = 2;
if ((w = getu16()) == sp_magic)
read_compact();
else if (w == ARMAG || w == AALMAG)
{
archmode = TRUE;
archive();
archmode = FALSE;
}
else
error("%s: bad format", arg);
if (fclose(ifile) == EOF)
{
}
}
/*
** process flag arguments
*/
static void flags(char *arg)
{
register char *argp;
register int on;
argp = arg; argp = arg;
while (*++argp) while (*++argp)
{ {
switch(LC(*argp)) switch (LC(*argp))
{ {
case 'd': d_flag++;break; case 'd':
case 'r': r_flag++;break; d_flag++;
case 's': return ; /* s-flag is already scanned */ break;
case 'r':
r_flag++;
break;
case 's':
return; /* s-flag is already scanned */
#ifdef MEMUSE #ifdef MEMUSE
case 'm': memflg++ ; break ; case 'm':
memflg++;
break;
#endif #endif
case 'p': ++procflag;break; case 'p':
++procflag;
break;
#ifdef DUMP #ifdef DUMP
case 'u': ++c_flag;break; case 'u':
++c_flag;
break;
#endif #endif
case 'o': ++oflag; break; case 'o':
case 'w': ++wflag; break; ++oflag;
break;
case 'w':
++wflag;
break;
#ifdef JOHAN #ifdef JOHAN
case 'j': ++jflag; break; case 'j':
++jflag;
break;
#endif #endif
case 'U': ++Uflag; break; case 'U':
case '-': ++Uflag;
case '+': break;
on = (*argp == '+'); case '-':
while (*++argp) switch(LC(*argp)) { case '+':
case 't': if (on) intflags |= 01; on = (*argp == '+');
else intflags &= ~01; while (*++argp)
break; switch (LC(*argp))
case 'p': if (on) intflags |= 02; {
else intflags &= ~02; case 't':
break; if (on)
case 'f': if (on) intflags |= 04; intflags |= 01;
else intflags &= ~04; else
break; intflags &= ~01;
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);
}
--argp;
break;
default:
error("bad flag %s",argp);
break; break;
case 'p':
if (on)
intflags |= 02;
else
intflags &= ~02;
break;
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;
break;
default:
error("bad interpreter option %s", argp);
}
--argp;
break;
default:
error("bad flag %s", argp);
break;
} }
} }
} }
do_proc() { void do_proc(void)
{
/* One procedure has been read and will be processed. /* One procedure has been read and will be processed.
* *
* NOTE: The numbers of the passes, 1 3 4 and 5, are a remainder * NOTE: The numbers of the passes, 1 3 4 and 5, are a remainder
* of ancient times. * of ancient times.
*/ */
dump(1); if ( memflg>2 )memuse(); dump(1);
pass_3(); dump(3); if (memflg > 2)
pass_4(); dump(4); memuse();
pass_5(); if ( memflg>2 ) memuse() ; pass_3();
endproc(); if ( memflg>1 ) memuse() ; dump(3);
pass_4();
dump(4);
pass_5();
if (memflg > 2)
memuse();
endproc();
if (memflg > 1)
memuse();
} }
archive() { static void archive(void)
register i; {
register int i;
register char *p; register char *p;
/* /*
@ -219,21 +308,26 @@ archive() {
* This is the only reason. * This is the only reason.
*/ */
for(;;) { for (;;)
if (unresolved == 0) { /* no use for this library anymore */ {
if (unresolved == 0)
{ /* no use for this library anymore */
return; return;
} }
p = chp_cast &archhdr; p = chp_cast &archhdr;
if ((i = fgetc(ifile))==EOF ) { if ((i = fgetc(ifile)) == EOF)
{
return; return;
} }
*p++ = i; *p++ = i;
for (i=1;i< sizeof archhdr.ar_name; i++) for (i = 1; i < sizeof archhdr.ar_name; i++)
*p++ = get8(); *p++ = get8();
for (i=0;i<8;i++) get8(); for (i = 0; i < 8; i++)
archhdr.ar_size= ((long)get16()<<16) ; get8();
archhdr.ar_size+= getu16(); archhdr.ar_size = ((long) get16() << 16);
inpoff = 0; libeof = archhdr.ar_size; archhdr.ar_size += getu16();
inpoff = 0;
libeof = archhdr.ar_size;
/* /*
* UNIX archiveheader is read now, now process the contents * UNIX archiveheader is read now, now process the contents
* of it. Note that recursive archives are not implemented. * of it. Note that recursive archives are not implemented.
@ -241,29 +335,33 @@ archive() {
* The variable libeof is used by get8() to check * The variable libeof is used by get8() to check
* whether or not we try to pass the library-boundary. * whether or not we try to pass the library-boundary.
*/ */
if ( getu16() == sp_magic ) { if (getu16() == sp_magic)
{
read_compact(); read_compact();
} else }
else
error("bad archive entry"); error("bad archive entry");
skipentry(); skipentry();
libeof = 0; libeof = 0;
} /* up to the next entry */ } /* up to the next entry */
} }
skipentry() { static void skipentry(void)
{
/* /*
* for some reason the rest of this library entry needs to be * for some reason the rest of this library entry needs to be
* skipped. Do that now. * skipped. Do that now.
*/ */
while(inpoff<libeof) while (inpoff < libeof)
get8(); get8();
if(odd(libeof)) /* archive entries are evensized */ if (odd(libeof)) /* archive entries are evensized */
if (fgetc(ifile) == EOF) /* except maybe the last one */ if (fgetc(ifile) == EOF) /* except maybe the last one */
; ;
} }
init_vars() { void init_vars(void)
{
/* /*
* A small collection of variables is initialized. * A small collection of variables is initialized.
@ -273,94 +371,98 @@ init_vars() {
} }
init_files() { void init_files(void)
{
/* /*
* The temporary files on which text and data are kept * The temporary files on which text and data are kept
* during assembly are set up here. * during assembly are set up here.
*/ */
#ifdef CPM
unlink("????????.$$$");
tfile=fopen("TFILE.$$$", "w");
dfile=fopen("DFILE.$$$", "w");
rtfile=fopen("RTFILE.$$$", "w");
rdfile=fopen("RDFILE.$$$", "w");
#else
/* /*
* The function tmpfil() returns a file-descriptor * The function tmpfil() returns a file-descriptor
* of a file that is valid for reading and writing. * of a file that is valid for reading and writing.
* It has the nice property of generating truly unique names. * It has the nice property of generating truly unique names.
*/ */
tfile=fdopen(tmpfil(),"w") ; tfile = fopen(tmpfil(), "w+");
dfile=fdopen(tmpfil(),"w") ; dfile = fopen(tmpfil(), "w+");
rtfile=fdopen(tmpfil(),"w") ; rtfile = fopen(tmpfil(), "w+");
rdfile=fdopen(tmpfil(),"w") ; rdfile = fopen(tmpfil(), "w+");
#endif
} }
initproc() { void initproc(void)
{
/* /*
* Called at the start of assembly of every procedure. * Called at the start of assembly of every procedure.
*/ */
stat_t *prevstate ; stat_t *prevstate;
prevstate= pst_cast getarea(sizeof pstate) ; prevstate = pst_cast getarea(sizeof pstate);
*prevstate= pstate ; *prevstate = pstate;
pstate.s_prevstat= prevstate ; pstate.s_prevstat = prevstate;
pstate.s_curpro= prp_cast 0 ; pstate.s_curpro = prp_cast 0;
pstate.s_fline= lnp_cast 0 ; pstate.s_fline = lnp_cast 0;
pstate.s_fdata= l_data ; pstate.s_fdata = l_data;
pstate.s_locl = (locl_t (*)[]) pstate.s_locl = (locl_t (*)[]) getarea(
getarea(LOCLABSIZE * sizeof ((*(pstate.s_locl))[0])); LOCLABSIZE * sizeof((*(pstate.s_locl))[0]));
zero(chp_cast pstate.s_locl, memset(chp_cast pstate.s_locl, 0,
LOCLABSIZE * (unsigned) sizeof ((*(pstate.s_locl))[0])); LOCLABSIZE * (unsigned) sizeof((*(pstate.s_locl))[0]));
if ( memflg>2 ) memuse() ; if (memflg > 2)
memuse();
} }
endproc() { void endproc(void)
{
/* Throw the contents of the line and local label table away */ /* Throw the contents of the line and local label table away */
register line_t *lnp1; register line_t *lnp1;
register locl_t *lbhead,*lbp,*lbp_next; register locl_t *lbhead, *lbp, *lbp_next;
register kind ; register int kind;
register stat_t *prevstate; register stat_t *prevstate;
while ( lnp1= pstate.s_fline ) { while ((lnp1 = pstate.s_fline) != NULL)
pstate.s_fline= lnp1->l_next ; {
kind= lnp1->type1 ; pstate.s_fline = lnp1->l_next;
if ( kind>VALLOW ) kind=VALLOW ; kind = lnp1->type1;
freearea((area_t)lnp1,(unsigned)linesize[kind]) ; if (kind > VALLOW)
kind = VALLOW;
freearea((area_t) lnp1, (unsigned) linesize[kind]);
} }
prevstate= pstate.s_prevstat ; prevstate = pstate.s_prevstat;
if ( prevstate!= pst_cast 0 ) { if (prevstate != pst_cast 0)
for ( lbhead= *pstate.s_locl; {
lbhead<&(*pstate.s_locl)[LOCLABSIZE] ; lbhead++ ) { for (lbhead = *pstate.s_locl; lbhead < &(*pstate.s_locl)[LOCLABSIZE];
for ( lbp=lbhead->l_chain; lbp!= lbp_cast 0; lbp= lbp_next ) { lbhead++)
lbp_next= lbp->l_chain; {
freearea((area_t)lbp,(unsigned)sizeof *lbp) ; for (lbp = lbhead->l_chain; lbp != lbp_cast 0; lbp = lbp_next)
{
lbp_next = lbp->l_chain;
freearea((area_t) lbp, (unsigned) sizeof *lbp);
} }
} }
freearea((area_t)(*pstate.s_locl), freearea((area_t) (*pstate.s_locl),
LOCLABSIZE * (sizeof((*pstate.s_locl)[0]))); LOCLABSIZE * (sizeof((*pstate.s_locl)[0])));
pstate= *prevstate ; pstate = *prevstate;
freearea((area_t)prevstate,(unsigned)sizeof *prevstate) ; freearea((area_t) prevstate, (unsigned) sizeof *prevstate);
} }
} }
init_module() { void init_module(void)
{
/* /*
* Called at the start of every module. * Called at the start of every module.
*/ */
holbase = 0; holbase = 0;
line_num = 1; line_num = 1;
mod_sizes = 0; mod_sizes = 0;
} }
end_module() { void end_module(void)
{
/* /*
* Finish a module. * Finish a module.
@ -368,16 +470,18 @@ end_module() {
* and remembering of those that will live during assembly. * and remembering of those that will live during assembly.
*/ */
align(wordsize) ; align(wordsize);
set_mode(DATA_NUL); set_mode(DATA_NUL);
dump(100); dump(100);
enmd_pro(); enmd_pro();
enmd_glo(); enmd_glo();
if ( memflg ) memuse() ; if (memflg)
memuse();
} }
enmd_pro() { static void enmd_pro(void)
register proc_t *p,*limit; {
register proc_t *p, *limit;
/* /*
* Check that all local procedures have been defined, * Check that all local procedures have been defined,
@ -385,26 +489,29 @@ enmd_pro() {
*/ */
limit = &mprocs[oursize->n_mproc]; limit = &mprocs[oursize->n_mproc];
for (p=mprocs; p<limit; p++) { for (p = mprocs; p < limit; p++)
{
if (p->p_name == 0) if (p->p_name == 0)
continue; continue;
if ((p->p_status&DEF)==0) if ((p->p_status & DEF) == 0)
error("undefined local procedure '%s'",p->p_name); error("undefined local procedure '%s'", p->p_name);
} }
zero(chp_cast mprocs,(limit-mprocs)* (unsigned)sizeof *mprocs); memset(chp_cast mprocs, 0, (limit - mprocs) * (unsigned ) sizeof *mprocs);
/* Clobber all flags indicating that external procedures /* Clobber all flags indicating that external procedures
* were used in this module. * were used in this module.
*/ */
limit = &xprocs[oursize->n_xproc]; limit = &xprocs[oursize->n_xproc];
for (p=xprocs; p<limit; p++) { for (p = xprocs; p < limit; p++)
p->p_status &= ~EXT ; {
p->p_status &= ~EXT;
} }
} }
enmd_glo() { static void enmd_glo(void)
register glob_t *mg,*xg,*limit; {
register glob_t *mg, *xg, *limit;
/* /*
* Tougher then enmd_pro(). * Tougher then enmd_pro().
@ -420,36 +527,39 @@ enmd_glo() {
*/ */
limit = &mglobs[oursize->n_mlab]; limit = &mglobs[oursize->n_mlab];
for ( mg = mglobs; mg < limit; mg++) { for (mg = mglobs; mg < limit; mg++)
{
if (mg->g_name == 0) if (mg->g_name == 0)
continue; continue;
if ((mg->g_status&(EXT|DEF))==0) if ((mg->g_status & (EXT | DEF)) == 0)
error("undefined local symbol '%s'",glostring(mg)); error("undefined local symbol '%s'", glostring(mg));
if ((mg->g_status&EXT)==0) if ((mg->g_status & EXT) == 0)
continue; continue;
xg = xglolookup(mg->g_name,ENTERING); xg = xglolookup(mg->g_name, ENTERING);
switch(xg->g_status&(EXT|DEF)) { switch (xg->g_status & (EXT | DEF))
case 0: /* new symbol */ {
if((mg->g_status&DEF)==0) case 0: /* new symbol */
if ((mg->g_status & DEF) == 0)
++unresolved; ++unresolved;
break; break;
case EXT: /* already used but not defined */ case EXT: /* already used but not defined */
if(mg->g_status&DEF) { if (mg->g_status & DEF)
{
--unresolved; --unresolved;
} }
break; break;
} }
xg->g_status |= mg->g_status; xg->g_status |= mg->g_status;
if (mg->g_status&DEF) if (mg->g_status & DEF)
xg->g_val.g_addr = mg->g_val.g_addr; xg->g_val.g_addr = mg->g_val.g_addr;
else else
mg->g_val.g_gp = xg; /* used by upd_reloc */ mg->g_val.g_gp = xg; /* used by upd_reloc */
} /* up to the next symbol */ } /* up to the next symbol */
upd_reloc(); upd_reloc();
zero(chp_cast mglobs,(limit-mglobs)*(unsigned) sizeof *mglobs); memset(chp_cast mglobs, 0, (limit - mglobs) * (unsigned ) sizeof *mglobs);
} }
finish_up() static void finish_up(void)
{ {
/* /*
* Almost done. Check for unresolved references, * Almost done. Check for unresolved references,
@ -460,41 +570,55 @@ finish_up()
c_print(); c_print();
#endif #endif
check_def(); check_def();
if ( nerrors==0 ) copyout(); if (nerrors == 0)
copyout();
} }
#ifdef DUMP #ifdef DUMP
c_print() { static void c_print(void)
if ( ! c_flag ) return ; {
c_dprint("primary",opcnt1) ; if (!c_flag)
c_dprint("secondary",opcnt2) ; return;
c_dprint("extra long",opcnt3) ; c_dprint("primary", opcnt1);
c_dprint("secondary", opcnt2);
c_dprint("extra long", opcnt3);
} }
c_dprint(str,cnt) char *str,*cnt ; { static void c_dprint(char *str, char* cnt)
register int first,curr ; {
printf("unused %s opcodes\n",str) ; register int first, curr;
for ( first= -1 , curr=0 ; curr<=256 ; curr++ ) { printf("unused %s opcodes\n", str);
if ( curr==256 || cnt[curr] ) { for (first = -1, curr = 0; curr <= 256; curr++)
if ( first!= -1 ) { {
if ( first+1 == curr ) { if (curr == 256 || cnt[curr])
printf("%3d\n",first ) ; {
} else { if (first != -1)
printf("%3d..%3d\n",first,curr-1) ; {
if (first + 1 == curr)
{
printf("%3d\n", first);
} }
first= -1 ; else
{
printf("%3d..%3d\n", first, curr - 1);
}
first = -1;
} }
} else { }
if ( first== -1 ) first=curr ; else
{
if (first == -1)
first = curr;
} }
} }
} }
#endif #endif
check_def() { static void check_def(void)
{
register proc_t *p; register proc_t *p;
register glob_t *g; register glob_t *g;
register count; register int count;
/* /*
* Check for unresolved references. * Check for unresolved references.
@ -504,25 +628,28 @@ check_def() {
* Every use of the symbols concerned is undefined. * Every use of the symbols concerned is undefined.
*/ */
if (unresolved) { if (unresolved)
{
printf("Unresolved references\n Procedures:\n"); printf("Unresolved references\n Procedures:\n");
count = oursize->n_xproc; count = oursize->n_xproc;
for (p = xprocs; count--; p++) for (p = xprocs; count--; p++)
if (p->p_name && (p->p_status&DEF)==0) if (p->p_name && (p->p_status & DEF) == 0)
printf(" %s\n",p->p_name); printf(" %s\n", p->p_name);
printf(" Data:\n"); printf(" Data:\n");
count = oursize->n_glab; count = oursize->n_glab;
for (g = xglobs; count--; g++) for (g = xglobs; count--; g++)
if (g->g_name && (g->g_status&DEF)==0) if (g->g_name && (g->g_status & DEF) == 0)
printf(" %s\n",glostring(g)); printf(" %s\n", glostring(g));
if (! Uflag) nerrors++; if (!Uflag)
nerrors++;
} }
} }
ertrap() { /* trap routine to drain input in case of compile errors */ void ertrap(void)
{ /* trap routine to drain input in case of compile errors */
if (fileno(ifile)== 0) if (ifile == stdin)
while (fgetc(ifile) != EOF) while (fgetc(ifile) != EOF)
; ;
exit(1); exit(EXIT_FAILURE);
} }

View file

@ -4,15 +4,12 @@
*/ */
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <unistd.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include "em_spec.h"
#include <fcntl.h> #include "as_spec.h"
#include <em_spec.h> #include "em_flag.h"
#include <as_spec.h> #include "arch.h"
#include <em_flag.h> #include "local.h"
#include <arch.h>
#include <local.h>
#define RCS_ASS "$Id$" #define RCS_ASS "$Id$"

View file

@ -4,365 +4,435 @@
* *
*/ */
#include <stddef.h>
#include "ass00.h" #include "ass00.h"
#include "assex.h" #include "assex.h"
#include "assci.h"
#include "asscm.h"
#include "ip_spec.h" #include "ip_spec.h"
#ifndef NORCSID short opt_line; /* max_line_no - # lines removed from end
static char rcs_id[] = "$Id$" ; after perfoming exc's.
static char rcs_ip[] = RCS_IP ; Used to estimate the distance in # of
#endif instructions.
*/
/* Forward declarations. */
static int valid(register line_t *);
static char *findfit(int, cons_t);
static char *findnop(int);
short opt_line ; /* max_line_no - # lines removed from end
after perfoming exc's.
Used to estimate the distance in # of
instructions.
*/
/* /*
** Determine the exact instruction length & format where possible, and the ** Determine the exact instruction length & format where possible, and the
** the upper and lower limits otherwise. Enter limits in labeltable ** the upper and lower limits otherwise. Enter limits in labeltable
*/ */
pass_3() void pass_3(void)
{ {
register line_t *lnp, *rev_lnp; register line_t *lnp, *rev_lnp;
line_t *tmp_lnp; line_t *tmp_lnp;
locl_t *lbp; locl_t *lbp;
int min_l, max_l, min_bytes; int min_l, max_l, min_bytes;
short last_line ; short last_line;
short hol_err_line ; short hol_err_line;
register insno ; register int insno;
pass = 3; pass = 3;
opt_line= line_num ; hol_err_line=0 ; opt_line = line_num;
min_bytes = max_bytes = 0; rev_lnp= lnp_cast 0 ; hol_err_line = 0;
for (lnp = pstate.s_fline ; lnp ; opt_line--, line_num-- ) { min_bytes = max_bytes = 0;
pstate.s_fline= lnp; rev_lnp = lnp_cast 0;
for (lnp = pstate.s_fline; lnp; opt_line--, line_num--)
{
pstate.s_fline = lnp;
insno = ctrunc(lnp->instr_num); insno = ctrunc(lnp->instr_num);
switch( insno ) { switch (insno)
case sp_fpseu : {
last_line = line_num ; case sp_fpseu:
line_num = lnp->ad.ad_ln.ln_first ; last_line = line_num;
opt_line -= lnp->ad.ad_ln.ln_extra ; line_num = lnp->ad.ad_ln.ln_first;
lnp->ad.ad_ln.ln_first= last_line ; opt_line -= lnp->ad.ad_ln.ln_extra;
break ; lnp->ad.ad_ln.ln_first = last_line;
case sp_ilb1 : break;
case sp_ilb1:
lbp = lnp->ad.ad_lp; lbp = lnp->ad.ad_lp;
lbp->l_defined = SEEN; lbp->l_defined = SEEN;
lbp->l_min = min_bytes; lbp->l_min = min_bytes;
lbp->l_max = max_bytes; lbp->l_max = max_bytes;
break ; break;
default: default:
if ( lnp->type1==CONST && (em_flag[insno]&EM_PAR)==PAR_G ) { if (lnp->type1 == CONST && (em_flag[insno] & EM_PAR) == PAR_G)
if (holbase != 0) { {
if (lnp->ad.ad_i >= holsize) { if (holbase != 0)
hol_err_line= line_num ; {
} if (lnp->ad.ad_i >= holsize)
lnp->ad.ad_i += holbase; {
} hol_err_line = line_num;
} else }
if ( lnp->type1>=VALLOW && (em_flag[insno]&EM_PAR)==PAR_G ) { lnp->ad.ad_i += holbase;
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 ( !valid(lnp) ) fatal("Invalid operand") ; {
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");
determine_props(lnp, &min_l, &max_l); determine_props(lnp, &min_l, &max_l);
min_bytes += min_l; max_bytes += max_l; min_bytes += min_l;
break ; max_bytes += max_l;
break;
} }
tmp_lnp= lnp->l_next ; tmp_lnp = lnp->l_next;
lnp->l_next= rev_lnp ; rev_lnp= lnp ; lnp->l_next = rev_lnp;
lnp= tmp_lnp ; rev_lnp = lnp;
lnp = tmp_lnp;
} }
pstate.s_fline= rev_lnp ; pstate.s_fline = rev_lnp;
if ( hol_err_line ) { if (hol_err_line)
line_num= hol_err_line ; {
werror("address exceeds holsize") ; line_num = hol_err_line;
werror("address exceeds holsize");
} }
} }
int oplength(int flag)
{
int cnt;
cnt = 1;
if (flag & OPESC)
cnt++;
switch (flag & OPTYPE)
{
case OPNO:
case OPMINI:
break;
case OP8:
case OPSHORT:
cnt++;
break;
case OP16U:
case OP16:
cnt += 2;
break;
case OP32:
cnt += 5;
break;
case OP64:
cnt += 9;
break;
}
return cnt;
}
/* /*
** Determine the format that should be used for each instruction, ** Determine the format that should be used for each instruction,
** depending on its offsets ** depending on its offsets
*/ */
determine_props(lnp, min_len, max_len) void determine_props(line_t *lnp, int *min_len, int *max_len)
line_t *lnp;
int *min_len, *max_len;
{ {
cons_t val ; cons_t val;
register int insno ; register int insno;
register char *f_off, *l_off ; register char *f_off, *l_off;
char defined ; char defined;
insno=ctrunc(lnp->instr_num) ; insno = ctrunc(lnp->instr_num);
val=parval(lnp,&defined) ; val = parval(lnp, &defined);
if ( !defined ) { if (!defined)
switch(em_flag[insno]&EM_PAR) { {
switch (em_flag[insno] & EM_PAR)
{
case PAR_NO: case PAR_NO:
case PAR_W: case PAR_W:
f_off = findnop(insno) ; f_off = findnop(insno);
break ; break;
case PAR_G: case PAR_G:
/* We want the maximum address that is a multiple /* We want the maximum address that is a multiple
of the wordsize. of the wordsize.
Assumption: there is no shortie for Assumption: there is no shortie for
intr max_word_multiple intr max_word_multiple
where intr is a instruction allowing parameters where intr is a instruction allowing parameters
that are not a word multiple (PAR_G). that are not a word multiple (PAR_G).
*/ */
f_off = findfit(insno, maxadr&(~(wordsize-1))) ; f_off = findfit(insno, maxadr & (~(wordsize - 1)));
break ; break;
case PAR_B: case PAR_B:
f_off = findfit(insno, (cons_t)0) ; f_off = findfit(insno, (cons_t) 0);
l_off = findfit(insno, val ) ; l_off = findfit(insno, val);
if ( f_off != l_off ) { if (f_off != l_off)
*min_len=oplength(*f_off) ; {
*max_len=oplength(*l_off) ; *min_len = oplength(*f_off);
lnp->opoff = NO_OFF ; *max_len = oplength(*l_off);
return ; lnp->opoff = NO_OFF;
return;
} }
break ; break;
} }
} else {
f_off = findfit(insno,val) ;
} }
lnp->opoff = f_off ; else
*min_len = *max_len = oplength(*f_off) ; {
f_off = findfit(insno, val);
}
lnp->opoff = f_off;
*min_len = *max_len = oplength(*f_off);
} }
char *findfit(instr,val) int instr ; cons_t val ; { static char *findfit(int instr, cons_t val)
register char *currc,*endc ; {
int found, flags, number ; register char *currc, *endc;
char *opc ; int found, flags, number;
char *opc;
endc = opindex[instr+1] ; endc = opindex[instr + 1];
for ( currc=opindex[instr], found=0 ; for (currc = opindex[instr], found = 0; !found && currc < endc; currc++)
!found && currc<endc ; currc++ ) { {
opc = currc ; opc = currc;
flags=ctrunc(*currc++) ; flags = ctrunc(*currc++);
switch ( flags&OPTYPE ) { switch (flags & OPTYPE)
case OPNO : {
continue ; case OPNO:
case OPMINI : continue;
case OPSHORT : case OPMINI:
number=ctrunc(*++currc) ; case OPSHORT:
number = ctrunc(*++currc);
} }
found = opfit(flags, number, val, em_flag[instr]&EM_PAR ) ; found = opfit(flags, number, val, em_flag[instr] & EM_PAR);
} }
if ( !found ) fatal("Cannot find interpreter opcode") ; if (!found)
return opc ; fatal("Cannot find interpreter opcode");
return opc;
} }
char *findnop(instr) int instr ; { static char* findnop(int instr)
register char *currc,*endc ; {
register char *currc, *endc;
endc = opindex[instr+1] ; endc = opindex[instr + 1];
for ( currc=opindex[instr] ; currc<endc ; currc++ ) { for (currc = opindex[instr]; currc < endc; currc++)
switch ( ctrunc(*currc)&OPTYPE ) { {
case OPNO : switch ( ctrunc(*currc) & OPTYPE)
return currc ; {
case OPSHORT : case OPNO:
case OPMINI : return currc;
currc++ ; case OPSHORT:
case OPMINI:
currc++;
} }
currc++ ; currc++;
} }
fatal("Cannot find interpreter opcode") ; fatal("Cannot find interpreter opcode");
/* NOTREACHED */ /* NOTREACHED */
return NULL;
} }
int opfit(flag,number,val,i_flag) int opfit(int flag, int number, cons_t val, int i_flag)
int i_flag,flag,number ; cons_t val ; { {
/* Number is invalid if flag does not contain MINI or SHORT */ /* Number is invalid if flag does not contain MINI or SHORT */
switch ( flag&OPRANGE ) { switch (flag & OPRANGE)
case OP_POS : {
if ( val<0 ) return 0 ; case OP_POS:
break ; if (val < 0)
case OP_NEG : return 0;
if ( val>=0 ) return 0 ; break;
break ; case OP_NEG:
if (val >= 0)
return 0;
break;
} }
if ( flag&OPWORD ) { if (flag & OPWORD)
if ( val%wordsize ) return 0 ; {
val /= wordsize ; if (val % wordsize)
return 0;
val /= wordsize;
} }
if ( flag&OPNZ ) { if (flag & OPNZ)
if ( val==0 ) return 0 ; {
val-- ; if (val == 0)
return 0;
val--;
} }
switch ( flag&OPTYPE ) { switch (flag & OPTYPE)
case OPMINI : {
if ( val<0 ) val = -1-val ; case OPMINI:
return val>=0 && val<number ; if (val < 0)
case OPSHORT : val = -1 - val;
if ( val<0 ) val = -1-val ; return val >= 0 && val < number;
return val>=0 && val<number*256 ; case OPSHORT:
if (val < 0)
val = -1 - val;
return val >= 0 && val < number * 256;
case OP16U: case OP16U:
return val>=0 && val<=65535L && return val >= 0 && val <= 65535L && (i_flag != PAR_G || val <= maxadr);
( i_flag!=PAR_G || val<=maxadr ) ; case OP16:
case OP16 : return val >= -32768 && val <= 32767;
return val>= -32768 && val<=32767 ; case OP32:
case OP32 : return TRUE;
return TRUE ; default:
default : fatal("illegal OPTYPE value");
fatal("illegal OPTYPE value") ; return -1;
/* NOTREACHED */ /* NOTREACHED */
} }
} }
int oplength(flag) int flag ; {
int cnt ;
cnt=1 ;
if ( flag&OPESC ) cnt++ ;
switch( flag&OPTYPE ) {
case OPNO :
case OPMINI : break ;
case OP8 :
case OPSHORT : cnt++ ; break ;
case OP16U:
case OP16 : cnt+=2 ; break ;
case OP32 : cnt+=5 ; break ;
case OP64 : cnt+=9 ; break ;
}
return cnt ;
}
/* /*
** return estimation of value of parameter ** return estimation of value of parameter
*/ */
cons_t parval(lnp,defined) cons_t parval(line_t *lnp, char *defined)
line_t *lnp;
char *defined;
{ {
register int type; register int type;
register locl_t *lbp; register locl_t *lbp;
register glob_t *gbp; register glob_t *gbp;
cons_t offs ; cons_t offs;
*defined = TRUE ; *defined = TRUE;
type = lnp->type1; type = lnp->type1;
switch(type) { switch (type)
default: if ( type>=VALLOW && type<=VALHIGH ) {
return VAL1(type) ; default:
error("bad type during parval"); if (type >= VALLOW && type <= VALHIGH)
break; return VAL1(type);
case CONST: error("bad type during parval");
return(lnp->ad.ad_i); break;
case GLOSYM: case CONST:
case GLOOFF: return (lnp->ad.ad_i);
if ( type!=GLOOFF) { case GLOSYM:
gbp = lnp->ad.ad_gp; case GLOOFF:
offs= 0 ; if (type != GLOOFF)
} else { {
gbp =lnp->ad.ad_df.df_gp ; gbp = lnp->ad.ad_gp;
offs=lnp->ad.ad_df.df_i ; offs = 0;
} }
if(gbp->g_status&DEF) else
return(gbp->g_val.g_addr+offs); {
else { gbp = lnp->ad.ad_df.df_gp;
*defined = FALSE ; offs = lnp->ad.ad_df.df_i;
return offs ; }
} if (gbp->g_status & DEF)
case LOCSYM: return (gbp->g_val.g_addr + offs);
lbp = lnp->ad.ad_lp; else
switch(pass) { {
default:error("bad pass in parval"); *defined = FALSE;
case 3: return offs;
*defined = FALSE; }
switch(lbp->l_defined) { case LOCSYM:
default : fatal("Illegal local label") ; lbp = lnp->ad.ad_lp;
case NO : switch (pass)
error("Undefined local label") ; {
lbp->l_defined= NOTPRESENT ; default:
case NOTPRESENT: error("bad pass in parval");
return max_bytes; case 3:
case SEEN : *defined = FALSE;
return max_bytes - lbp->l_min ; switch (lbp->l_defined)
case YES : {
/* l_min contains line_num default:
adjusted for exc's. fatal("Illegal local label");
*/ case NO:
return (lbp->l_min - opt_line -1 ) * maxinsl ; error("Undefined local label");
} lbp->l_defined = NOTPRESENT;
case 4: if(lbp->l_defined == YES) case NOTPRESENT:
return(lbp->l_min-prog_size-maxinsl); return max_bytes;
return max_bytes - lbp->l_max- prog_size; case SEEN:
case 5: if (lbp->l_defined == YES ) return max_bytes - lbp->l_min;
return lbp->l_min ; case YES:
*defined = FALSE ; /* l_min contains line_num
break ; adjusted for exc's.
*/
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; break;
case MISSING: }
*defined = FALSE ; break;
break; case MISSING:
case PROCNAME: *defined = FALSE;
return(lnp->ad.ad_pp->p_num); break;
case PROCNAME:
return (lnp->ad.ad_pp->p_num);
} }
return(0); return (0);
} }
int valid(lnp) register line_t *lnp ; {
cons_t val ;
int type ;
type = lnp->type1 ; static int valid(register line_t *lnp)
if ( type>=VALLOW && type<=VALHIGH ) { {
val= VAL1(type) ; cons_t val;
type= CONST ; int type;
} else if ( type==CONST ) val = lnp->ad.ad_i ;
switch ( em_flag[ctrunc(lnp->instr_num)]&EM_PAR ) { type = lnp->type1;
if (type >= VALLOW && type <= VALHIGH)
{
val = VAL1(type);
type = CONST;
}
else if (type == CONST)
val = lnp->ad.ad_i;
switch (em_flag[ctrunc(lnp->instr_num)] & EM_PAR)
{
case PAR_NO: case PAR_NO:
return type==MISSING ; return type == MISSING;
case PAR_C: case PAR_C:
if ( type!=CONST ) return FALSE; if (type != CONST)
if ( val>maxint && val<=maxunsig ) { return FALSE;
lnp->ad.ad_i = val -maxunsig -1 ; if (val > maxint && val <= maxunsig)
{
lnp->ad.ad_i = val - maxunsig - 1;
} }
return TRUE ; return TRUE;
case PAR_D: case PAR_D:
if ( type!=CONST ) return FALSE; if (type != CONST)
if ( val>maxdint && val<=maxdunsig ) { return FALSE;
lnp->ad.ad_i = val -maxdunsig -1 ; if (val > maxdint && val <= maxdunsig)
{
lnp->ad.ad_i = val - maxdunsig - 1;
} }
return TRUE ; return TRUE;
case PAR_L: case PAR_L:
case PAR_F: case PAR_F:
return type==CONST ; return type == CONST;
case PAR_N: case PAR_N:
return type==CONST && val>=0 ; return type == CONST && val >= 0;
case PAR_G: case PAR_G:
return type==CONST || type==GLOSYM || type==GLOOFF ; return type == CONST || type == GLOSYM || type == GLOOFF;
case PAR_W: case PAR_W:
if ( type==MISSING ) return TRUE ; if (type == MISSING)
return TRUE;
case PAR_S: case PAR_S:
return type==CONST && val>0 && val%wordsize==0 ; return type == CONST && val > 0 && val % wordsize == 0;
case PAR_Z: case PAR_Z:
return type==CONST && val>=0 && val%wordsize==0 ; return type == CONST && val >= 0 && val % wordsize == 0;
case PAR_O: case PAR_O:
return type==CONST && val>=0 && return type == CONST && val >= 0
( val >= wordsize ? val%wordsize : wordsize%val ) == 0 ; && (val >= wordsize ? val % wordsize : wordsize % val) == 0;
case PAR_P: case PAR_P:
return type==PROCNAME ; return type == PROCNAME;
case PAR_B: case PAR_B:
return type==LOCSYM ; return type == LOCSYM;
case PAR_R: case PAR_R:
return type==CONST && val>=0 && val<=3 ; return type == CONST && val >= 0 && val <= 3;
default: default:
fatal("Unknown parameter type") ; fatal("Unknown parameter type");
return -1;
/* NOTREACHED */ /* NOTREACHED */
} }
} }

View file

@ -7,15 +7,13 @@
#include "ass00.h" #include "ass00.h"
#include "assex.h" #include "assex.h"
#ifndef NORCSID
static char rcs_id[] = "$Id$" ;
#endif
/* /*
** Make scans to do final assignment of instruction sizes & formats ** Make scans to do final assignment of instruction sizes & formats
** to those not already done. assign final values to labels ** to those not already done. assign final values to labels
*/ */
pass_4() void pass_4(void)
{ {
register line_t *lnp; register line_t *lnp;
register locl_t *lbp; register locl_t *lbp;

View file

@ -6,19 +6,21 @@
#include "ass00.h" #include "ass00.h"
#include "assex.h" #include "assex.h"
#include "assrl.h"
#include "ip_spec.h" #include "ip_spec.h"
#ifndef NORCSID
static char rcs_id[] = "$Id$" ;
#endif
/* /*
** Pass 5 of EM1 assembler/loader ** Pass 5 of EM1 assembler/loader
** Fix reloc tables ** Fix reloc tables
** Write out code ** Write out code
*/ */
pass_5() { static void patchcase(void);
void pass_5(void)
{
register line_t *lnp; register line_t *lnp;
cons_t off1; cons_t off1;
char defined ; char defined ;
@ -78,14 +80,15 @@ pass_5() {
} /* end pass_5 */ } /* end pass_5 */
genop(startc,value,i_flag) char *startc ; cons_t value ; int i_flag ; {
char *currc ;
register flag ;
char opc ;
/* /**
* Real code generation. * Real code generation.
*/ */
void genop(char *startc,cons_t value,int i_flag)
{
char *currc ;
register int flag ;
char opc ;
currc= startc ; currc= startc ;
flag = ctrunc(*currc++); flag = ctrunc(*currc++);
@ -161,11 +164,12 @@ genop(startc,value,i_flag) char *startc ; cons_t value ; int i_flag ; {
} }
} }
patchcase() { static void patchcase(void)
{
register relc_t *r; register relc_t *r;
register locl_t *k; register locl_t *k;
if ( r= pstate.s_fdata ) { if ( (r= pstate.s_fdata) ) {
r= r->r_next ; r= r->r_next ;
} else { } else {
r= f_data ; r= f_data ;

View file

@ -8,61 +8,73 @@
#include "assex.h" #include "assex.h"
#include "ip_spec.h" #include "ip_spec.h"
#ifndef NORCSID
static char rcs_id[] = "$Id$" ;
#endif
#ifdef DUMP #ifdef DUMP
static char *typestr[] = static char *typestr[] =
{"missing","const","procname","glosym","locsym","glosym+off","pseudo"}; { "missing", "const", "procname", "glosym", "locsym", "glosym+off", "pseudo" };
static char *labstr[] = {"EMPTY","no","yes","seen","notpresent"}; static char *labstr[] =
static char formstr[] = { 'm','s','-','1','2','4','8' }; { "EMPTY", "no", "yes", "seen", "notpresent" };
static char *r_data[] = { "null","glob","head","loc","adr" }; static char formstr[] =
{ 'm', 's', '-', '1', '2', '4', '8' };
static char *r_data[] =
{ "null", "glob", "head", "loc", "adr" };
cons_t nicepr(typ,ap) addr_u *ap; { cons_t nicepr(int typ, addr_u *ap)
{
register proc_t *pl; register proc_t *pl;
switch (typ) { switch (typ)
case CONST: {
return(ap->ad_i); case CONST:
case LOCSYM: return (ap->ad_i);
return(int_cast ap->ad_lp); case LOCSYM:
case GLOOFF: return (int_cast ap->ad_lp);
return(ap->ad_df.df_gp - mglobs); case GLOOFF:
case GLOSYM: return (ap->ad_df.df_gp - mglobs);
return(ap->ad_gp - mglobs); case GLOSYM:
case PROCNAME: return (ap->ad_gp - mglobs);
pl = ap->ad_pp;; case PROCNAME:
if (pl->p_status&EXT) pl = ap->ad_pp;
return((pl-xprocs)+1000); ;
else if (pl->p_status & EXT)
return(pl-mprocs); return ((pl - xprocs) + 1000);
default: else
if ( typ>=VALLOW && typ<=VALHIGH ) return VAL1(typ) ; return (pl - mprocs);
break ; default:
if (typ >= VALLOW && typ <= VALHIGH)
return VAL1(typ);
break;
} }
return(0); return (0);
} }
char *pflags(flg) int flg ; { char *pflags(int flg)
static char res[9] ; {
register char *cp ; static char res[9];
register char *cp;
cp=res ; cp = res;
if ( flg&OPESC ) *cp++ = 'e' ; if (flg & OPESC)
switch ( flg&OPRANGE ) { *cp++ = 'e';
case OP_NEG : *cp++ = 'N' ; break ; switch (flg & OPRANGE)
case OP_POS : *cp++ = 'P' ; break ; {
case OP_NEG:
*cp++ = 'N';
break;
case OP_POS:
*cp++ = 'P';
break;
} }
if ( flg&OPWORD ) *cp++ = 'w' ; if (flg & OPWORD)
if ( flg&OPNZ ) *cp++ = 'o' ; *cp++ = 'w';
*cp++ = formstr[flg&OPTYPE] ; if (flg & OPNZ)
*cp++ = 0 ; *cp++ = 'o';
return res ; *cp++ = formstr[flg & OPTYPE];
*cp++ = 0;
return res;
} }
void dump(int n)
dump(n)
{ {
register glob_t *gb; register glob_t *gb;
register line_t *ln; register line_t *ln;
@ -71,134 +83,152 @@ dump(n)
proc_t *pl; proc_t *pl;
int i; int i;
int insno; int insno;
extern char em_mnem[][4] ; extern char em_mnem[][4];
if (d_flag==0) return; if (d_flag == 0)
if ( (n==0 && d_flag) || (n==4 && d_flag>=2) || (n<100 && d_flag>=3) ) { return;
printf("\nEM1-assembler ***** pass %1d complete:\n",n); if ((n == 0 && d_flag) || (n == 4 && d_flag >= 2)
printf("current size %ld\n",prog_size) ; || (n < 100 && d_flag >= 3))
printf(" %9.9s%9.9s%14.14s%8.8s%8.8s\n", "instr_nr", {
"type1","addr1","length","format"); printf("\nEM1-assembler ***** pass %1d complete:\n", n);
for (ln = pstate.s_fline ; ln ; printf("current size %ld\n", prog_size);
ln = ln->l_next, n>=3 || n==0 ? i++ : i-- ) { printf(" %9.9s%9.9s%14.14s%8.8s%8.8s\n", "instr_nr", "type1", "addr1",
insno = ctrunc(ln->instr_num) ; "length", "format");
if ( insno==sp_fpseu ) { for (ln = pstate.s_fline; ln;
i= ln->ad.ad_ln.ln_first ; ln = ln->l_next, n >= 3 || n == 0 ? i++ : i--)
continue ; {
insno = ctrunc(ln->instr_num);
if (insno == sp_fpseu)
{
i = ln->ad.ad_ln.ln_first;
continue;
}
printf("%4d ", i);
switch (insno)
{
default:
printf(" %3.3s", em_mnem[insno]);
break;
case sp_ilb1:
printf("l ");
break;
case sp_fpseu:
printf("p ");
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)));
printf("\n");
} }
printf("%4d ",i) ; printf("\n %8s%8s%8s%8s%8s\n", "labnum", "labid", "minval", "maxval",
switch(insno) { "defined");
default: for (i = 0, lbhead = *pstate.s_locl; i < LOCLABSIZE; lbhead++, i++)
printf( {
" %3.3s",em_mnem[insno]) ; if (lbhead->l_defined != EMPTY)
break ; printf("%4d\n", i);
case sp_ilb1: for (lbp = lbhead; lbp != lbp_cast 0; lbp = lbp->l_chain)
printf("l "); {
break; if (lbp->l_defined != EMPTY)
case sp_fpseu: printf(" %8d%8d%8d%8d %-s\n",
printf("p "); lbp->l_hinum * LOCLABSIZE + i,
break; int_cast lbp, lbp->l_min, lbp->l_max,
} labstr[(unsigned char)lbp->l_defined]);
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)));
printf("\n");
}
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)
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]);
}
}
}
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\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\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,
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,
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) {
case RELADR:
case RELHEAD:
printf("%10ld\n",rl->r_val.rel_i) ;
break ;
case RELGLO:
printf("%8.8s\n",rl->r_val.rel_gp->g_name) ;
break ;
case RELLOC:
printf("%10d\n",rl->r_val.rel_lp) ;
break ;
case RELNULL:
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") ;
}
} }
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\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\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,
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,
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)
{
case RELADR:
case RELHEAD:
printf("%10ld\n", rl->r_val.rel_i);
break;
case RELGLO:
printf("%8.8s\n", rl->r_val.rel_gp->g_name);
break;
case RELLOC:
printf("%10d\n", rl->r_val.rel_lp);
break;
case RELNULL:
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");
}
}
}
}
} }
#endif #endif

View file

@ -4,12 +4,11 @@
* *
*/ */
#include <string.h>
#include <stddef.h>
#include "ass00.h" #include "ass00.h"
#include "assex.h" #include "assex.h"
#include "asscm.h"
#ifndef NORCSID
static char rcs_id[] = "$Id$" ;
#endif
/* /*
** utilities of EM1-assembler/loader ** utilities of EM1-assembler/loader
@ -17,15 +16,16 @@ static char rcs_id[] = "$Id$" ;
static int globstep; static int globstep;
/* /*
* glohash returns an index in table and leaves a stepsize in globstep * glohash returns an index in table and leaves a stepsize in globstep
* *
*/ */
static int glohash(char *aname ,int size)
static int glohash(aname,size) char *aname; { {
register char *p; register char *p;
register i; register int i;
register sum; register int sum;
/* /*
* Computes a hash-value from a string. * Computes a hash-value from a string.
@ -44,17 +44,19 @@ static int glohash(aname,size) char *aname; {
* return index in labeltable * return index in labeltable
*/ */
glob_t *glo2lookup(name,status) char *name; { glob_t *glo2lookup(char *name ,int status)
{
return(glolookup(name,status,mglobs,oursize->n_mlab)); return(glolookup(name,status,mglobs,oursize->n_mlab));
} }
glob_t *xglolookup(name,status) char *name; { glob_t *xglolookup(char *name,int status)
{
return(glolookup(name,status,xglobs,oursize->n_glab)); return(glolookup(name,status,xglobs,oursize->n_glab));
} }
static void findext(g) glob_t *g ; { static void findext(glob_t *g)
{
glob_t *x; glob_t *x;
x = xglolookup(g->g_name,ENTERING); x = xglolookup(g->g_name,ENTERING);
@ -65,33 +67,30 @@ static void findext(g) glob_t *g ; {
g->g_status |= EXT; g->g_status |= EXT;
} }
glob_t *glolookup(name,status,table,size) /*
char *name; /* name */ * lookup global symbol name in specified table.
int status; /* kind of lookup */ * Various actions are taken depending on status
glob_t *table; /* which table to use */ * parameter.
int size; /* size for hash */ *
* DEFINING:
* Lookup or enter the symbol, check for mult. def.
* OCCURRING:
* Lookup the symbol, export if not known.
* INTERNING:
* Enter symbol local to the module.
* EXTERNING:
* Enter symbol visable from every module.
* SEARCHING:
* Lookup the symbol, return 0 if not found.
* 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 glob_t *g;
register rem,j; register int rem,j;
int new; int new;
/*
* lookup global symbol name in specified table.
* Various actions are taken depending on status.
*
* DEFINING:
* Lookup or enter the symbol, check for mult. def.
* OCCURRING:
* Lookup the symbol, export if not known.
* INTERNING:
* Enter symbol local to the module.
* EXTERNING:
* Enter symbol visable from every module.
* SEARCHING:
* Lookup the symbol, return 0 if not found.
* ENTERING:
* Lookup or enter the symbol, don't check
*/
rem = glohash(name,size); rem = glohash(name,size);
j = 0; new=0; j = 0; new=0;
@ -150,9 +149,18 @@ int size; /* size for hash */
return(g); return(g);
} }
locl_t *loclookup(an,status) { /*
* lookup local label by number and return the
* label definition if found.
*
* DEFINING:
* Lookup or enter the symbol, check for mult. def.
*
*/
locl_t *loclookup(unsigned int an,int status)
{
register locl_t *lbp,*l_lbp; register locl_t *lbp,*l_lbp;
register unsigned num; register unsigned int num;
char hinum; char hinum;
if ( !pstate.s_locl ) fatal("label outside procedure"); if ( !pstate.s_locl ) fatal("label outside procedure");
@ -188,26 +196,27 @@ locl_t *loclookup(an,status) {
return(lbp); return(lbp);
} }
proc_t *prolookup(name,status) char *name; { /*
register proc_t *p; * Look up a procedure name according to status
register pstat; *
* PRO_OCC: Occurrence
* Search both tables, local table first.
* If not found, enter in global table
* PRO_INT: INP
* Enter symbol in local table.
* PRO_DEF: Definition
* Define local procedure.
* PRO_EXT: EXP
* Enter symbol in global table.
*
* 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;
/*
* Look up a procedure name according to status
*
* PRO_OCC: Occurrence
* Search both tables, local table first.
* If not found, enter in global table
* PRO_INT: INP
* Enter symbol in local table.
* PRO_DEF: Definition
* Define local procedure.
* PRO_EXT: EXP
* Enter symbol in global table.
*
* The EXT bit in this table indicates the the name is used
* as external in this module.
*/
switch(status) { switch(status) {
case PRO_OCC: case PRO_OCC:
@ -281,18 +290,15 @@ proc_t *prolookup(name,status) char *name; {
return(enterproc(name,pstat,p)); return(enterproc(name,pstat,p));
} }
proc_t *searchproc(name,table,size) /*
char *name; * return a pointer into table to the place where the procedure
proc_t *table; * name is or should be if in the table.
int size; */
proc_t *searchproc(char *name,proc_t *table,int size)
{ {
register proc_t *p; register proc_t *p;
register rem,j; register int rem,j;
/*
* return a pointer into table to the place where the procedure
* name is or should be if in the table.
*/
rem = glohash(name,size); rem = glohash(name,size);
j = 0; j = 0;
@ -307,25 +313,22 @@ proc_t *searchproc(name,table,size)
return(p); return(p);
} }
proc_t *enterproc(name,status,place) /*
char *name; * Enter the procedure name into the table at place place.
char status; * Place had better be computed by searchproc().
proc_t *place; { *
* NOTE:
* At this point the procedure gets assigned a number.
* This number is used as a parameter of cal and in some
* other ways. There exists a 1-1 correspondence between
* procedures and numbers.
* 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; register proc_t *p;
/*
* Enter the procedure name into the table at place place.
* Place had better be computed by searchproc().
*
* NOTE:
* At this point the procedure gets assigned a number.
* This number is used as a parameter of cal and in some
* other ways. There exists a 1-1 correspondence between
* procedures and numbers.
* Two local procedures with the same name in different
* modules have different numbers.
*/
p=place; p=place;
p->p_name = (char *) getarea((unsigned) (strlen(name) + 1)); p->p_name = (char *) getarea((unsigned) (strlen(name) + 1));
strcpy(p->p_name,name); strcpy(p->p_name,name);

View file

@ -6,28 +6,19 @@
#include "ass00.h" #include "ass00.h"
#include "assex.h" #include "assex.h"
#include <em_path.h> #include "assrl.h"
#include <stddef.h>
#include <stdio.h>
#include <stdarg.h> #include <stdarg.h>
#include "system.h"
#ifndef NORCSID
static char rcs_id[] = "$Id$" ;
#endif
/* /*
* this file contains several library routines. * this file contains several library routines.
*/ */
zero(area,length) char *area; unsigned length ; { static char filename[L_tmpnam];
register char *p;
register n;
/*
* Clear area of length bytes.
*/
if ((n=length)==0)
return;
p = area;
do *p++=0; while (--n);
}
/* VARARGS1 */ /* VARARGS1 */
static void pr_error(const char* string1, va_list ap) { static void pr_error(const char* string1, va_list ap) {
@ -60,7 +51,8 @@ void error(const char* string1, ...)
} }
/* VARARGS1 */ /* VARARGS1 */
void werror(const char* string1, ...) { void werror(const char* string1, ...)
{
va_list ap; va_list ap;
if ( wflag ) return ; if ( wflag ) return ;
@ -69,57 +61,44 @@ void werror(const char* string1, ...) {
va_end(ap); va_end(ap);
} }
fatal(s) char *s; { void fatal(char *s)
{
/* /*
* handle fatal errors * handle fatal errors
*/ */
error("Fatal error: %s",s); error("Fatal error: %s",s);
dump(0); dump(0);
exit(-1); exit(EXIT_FAILURE);
} }
#ifndef CPM
FILE *frewind(f) FILE *f ; {
/* Rewind a file open for writing and open it for reading */
/* Assumption, file descriptor is r/w */
register FILE *tmp ;
tmp=fdopen(dup(fileno(f)),"r");
fclose(f);
rewind(tmp);
return tmp ;
}
#endif
int xgetc(af) register FILE *af; {
int xgetc(register FILE *af)
{
register int nextc; register int nextc;
/*
* read next character; fatal if there isn't one
*/
nextc=fgetc(af) ; nextc=fgetc(af) ;
if ( feof(af) ) if ( feof(af) )
fatal("unexpected end of file"); fatal("unexpected end of file");
return nextc ; return nextc ;
} }
xputc(c,af) register FILE *af; { void xputc(int c,register FILE *af)
/* output one character and scream if it gives an error */ {
fputc(c,af) ; fputc(c,af) ;
if ( ferror(af) ) fatal("write error") ; if ( ferror(af) ) fatal("write error") ;
} }
putblk(stream,from,amount) void putblk(register FILE *stream,register char *from, register int amount)
register FILE *stream; register char *from ; register int amount ; { {
for ( ; amount-- ; from++ ) { for ( ; amount-- ; from++ ) {
fputc(*from,stream) ; fputc(*from,stream) ;
if ( ferror(stream) ) fatal("write error") ; if ( ferror(stream) ) fatal("write error") ;
} }
} }
int getblk(stream,from,amount) int getblk(register FILE *stream, register char *from, register int amount)
register FILE *stream; register char *from ; register int amount ; { {
for ( ; amount-- ; from++ ) { for ( ; amount-- ; from++ ) {
*from = fgetc(stream) ; *from = fgetc(stream) ;
if ( feof(stream) ) return 1 ; if ( feof(stream) ) return 1 ;
@ -127,7 +106,8 @@ int getblk(stream,from,amount)
return 0 ; return 0 ;
} }
xput16(w,f) FILE *f; { void xput16(int w,FILE *f)
{
/* /*
* two times xputc * two times xputc
*/ */
@ -135,19 +115,22 @@ xput16(w,f) FILE *f; {
xputc(w>>8,f); xputc(w>>8,f);
} }
xputarb(l,w,f) int l ; cons_t w ; FILE *f ; { void xputarb(int l,cons_t w, FILE* f)
{
while ( l-- ) { while ( l-- ) {
xputc( int_cast w,f) ; xputc( int_cast w,f) ;
w >>=8 ; w >>=8 ;
} }
} }
put8(n) { void put8(int n)
{
xputc(n,tfile); xputc(n,tfile);
textoff++; textoff++;
} }
put16(n) { void put16(int n)
{
/* /*
* note reversed order of bytes. * note reversed order of bytes.
* this is done for faster interpretation. * this is done for faster interpretation.
@ -157,16 +140,19 @@ put16(n) {
textoff += 2; textoff += 2;
} }
put32(n) cons_t n ; { void put32(cons_t n)
{
put16( int_cast (n>>16)) ; put16( int_cast (n>>16)) ;
put16( int_cast n) ; put16( int_cast n) ;
} }
put64(n) cons_t n ; { void put64(cons_t n)
{
fatal("put64 called") ; fatal("put64 called") ;
} }
int xget8() { int xget8(void)
{
/* /*
* Read one byte from ifile. * Read one byte from ifile.
*/ */
@ -176,7 +162,8 @@ int xget8() {
return fgetc(ifile) ; return fgetc(ifile) ;
} }
unsigned get8() { unsigned int get8(void)
{
register int nextc; register int nextc;
/* /*
* Read one byte from ifile. * Read one byte from ifile.
@ -191,16 +178,17 @@ unsigned get8() {
return nextc ; return nextc ;
} }
cons_t xgetarb(l,f) int l; FILE *f ; { cons_t xgetarb(int l,FILE *f)
{
cons_t val ; cons_t val ;
register int shift ; register int shift ;
int c; int c;
shift=0 ; val=0 ; shift=0 ; val=0 ;
while ( l-- ) { while ( l-- ) {
// val += ((cons_t)(c = ctrunc(xgetc(f))))<<shift ; /* val += ((cons_t)(c = ctrunc(xgetc(f))))<<shift ;
// Bug here: shifts with too large shift counts Bug here: shifts with too large shift counts
// get unspecified results. --Ceriel get unspecified results. --Ceriel */
c = ctrunc(xgetc(f)); c = ctrunc(xgetc(f));
if (shift < 8 * sizeof(cons_t)) { if (shift < 8 * sizeof(cons_t)) {
val += ((cons_t)c)<<shift ; val += ((cons_t)c)<<shift ;
@ -216,7 +204,8 @@ cons_t xgetarb(l,f) int l; FILE *f ; {
return val ; return val ;
} }
ext8(b) { void ext8(int b)
{
/* /*
* Handle one byte of data. * Handle one byte of data.
*/ */
@ -224,55 +213,56 @@ ext8(b) {
xputc(b,dfile); xputc(b,dfile);
} }
extword(w) cons_t w ; { void extword(cons_t w)
{
/* Assemble the word constant w. /* Assemble the word constant w.
* NOTE: The bytes are written low to high. * NOTE: The bytes are written low to high.
*/ */
register i ; register int i ;
for ( i=wordsize ; i-- ; ) { for ( i=wordsize ; i-- ; ) {
ext8( int_cast w) ; ext8( int_cast w) ;
w >>= 8 ; w >>= 8 ;
} }
} }
extarb(size,value) int size ; long value ; { void extarb(int size, long value)
{
/* Assemble the 'size' constant value. /* Assemble the 'size' constant value.
* The bytes are again written low to high. * The bytes are again written low to high.
*/ */
register i ; register int i ;
for ( i=size ; i-- ; ) { for ( i=size ; i-- ; ) {
ext8( int_cast value ) ; ext8( int_cast value ) ;
value >>=8 ; value >>=8 ;
} }
} }
extadr(a) cons_t a ; { void extadr(cons_t a)
/* Assemble the word constant a. {
/* Assemble the pointer constant a.
* NOTE: The bytes are written low to high. * NOTE: The bytes are written low to high.
*/ */
register i ; register int i ;
for ( i=ptrsize ; i-- ; ) { for ( i=ptrsize ; i-- ; ) {
ext8( int_cast a) ; ext8( int_cast a) ;
a >>= 8 ; a >>= 8 ;
} }
} }
xputa(a,f) cons_t a ; FILE *f ; { void xputa(cons_t a,FILE* f)
/* Assemble the pointer constant a. {
* NOTE: The bytes are written low to high.
*/ register int i ;
register i ;
for ( i=ptrsize ; i-- ; ) { for ( i=ptrsize ; i-- ; ) {
xputc( int_cast a,f) ; xputc( int_cast a,f) ;
a >>= 8 ; a >>= 8 ;
} }
} }
cons_t xgeta(f) FILE *f ; { cons_t xgeta(FILE* f)
/* Read the pointer constant a. {
* NOTE: The bytes were written low to high.
*/ register int i, shift ;
register i, shift ;
cons_t val ; cons_t val ;
val = 0 ; shift=0 ; val = 0 ; shift=0 ;
for ( i=ptrsize ; i-- ; ) { for ( i=ptrsize ; i-- ; ) {
@ -282,14 +272,16 @@ cons_t xgeta(f) FILE *f ; {
return val ; return val ;
} }
int icount(size) { int icount(int size)
{
int amount ; int amount ;
amount=(dataoff-lastoff)/size ; amount=(dataoff-lastoff)/size ;
if ( amount>MAXBYTE) fatal("Descriptor overflow"); if ( amount>MAXBYTE) fatal("Descriptor overflow");
return amount ; return amount ;
} }
set_mode(mode) { void set_mode(int mode)
{
if (datamode==mode) { /* in right mode already */ if (datamode==mode) { /* in right mode already */
switch ( datamode ) { switch ( datamode ) {
@ -389,40 +381,12 @@ set_mode(mode) {
} }
} }
#ifndef CPM
int tmpfil() { char* tmpfil(void)
register char *fname, *cpname ; {
static char sfname[] = "tmp.00000"; if (sys_tmpnam(filename)==NULL)
register fildes,pid; {
static char name[80] = TMP_DIR ; fatal("Cannot create temporary filename.");
int count;
/*
* This procedure returns a file-descriptor of a temporary
* file valid for reading and writing.
* After closing the tmpfil-descriptor the file is lost
* Calling this routine frees the program from generating uniqe names.
*/
fname = sfname+4;
count = 10;
pid = getpid();
while (pid!=0) {
*fname++ = (pid&07) + '0';
pid >>= 3;
} }
*fname = 0; return filename;
for ( fname=name ; *fname ; fname++ ) ;
cpname=sfname ;
while ( *fname++ = *cpname++ ) ;
do {
fname = name;
if ((fildes = creat(fname, 0600)) < 0)
if ((fildes = creat(fname=sfname, 0600)) < 0)
return(-1);
if (close(fildes) < 0)
;
} while((fildes = open(fname, 2)) < 0 && count--);
if (unlink(fname) < 0)
;
return(fildes);
} }
#endif

File diff suppressed because it is too large Load diff

20
util/ass/assci.h Normal file
View 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_ */

View file

@ -5,127 +5,143 @@
*/ */
/* Core management for the EM assembler. /* Core management for the EM assembler.
two routines: two routines:
getarea(size) getarea(size)
returns a pointer to a free area of 'size' bytes. returns a pointer to a free area of 'size' bytes.
freearea(ptr,size) freearea(ptr,size)
free's the area of 'size' bytes pointed to by ptr free's the area of 'size' bytes pointed to by ptr
Free blocks are linked together and kept sorted. Free blocks are linked together and kept sorted.
Adjacent free blocks are collapsed. Adjacent free blocks are collapsed.
Free blocks with a size smaller then the administration cannot Free blocks with a size smaller then the administration cannot
exist. exist.
The algorithm is first fit. The algorithm is first fit.
*/ */
#include "ass00.h" #include "ass00.h"
#include "assex.h"
#ifndef NORCSID #include "asscm.h"
static char rcs_id[] = "$Id$" ;
#endif
#ifdef MEMUSE #ifdef MEMUSE
static unsigned m_used = 0 ; static unsigned m_used = 0;
static unsigned m_free = 0 ; static unsigned m_free = 0;
#endif #endif
struct freeblock { struct freeblock
struct freeblock *f_next ; {
unsigned f_size ; struct freeblock *f_next;
} ; unsigned f_size;
};
static struct freeblock freexx[2] = { static struct freeblock freexx[2] =
{ freexx, 0 }, {
{ freexx+1, 0 } { freexx, 0 },
} ; { freexx + 1, 0 } };
#define freehead freexx[1] #define freehead freexx[1]
#define CHUNK 2048 /* Smallest chunk to be gotten from UNIX */ #define CHUNK 2048 /* Smallest chunk to be gotten from UNIX */
area_t getarea(size) unsigned size ; { area_t getarea(unsigned int size)
register struct freeblock *c_ptr,*l_ptr ; {
register char *ptr ; register struct freeblock *c_ptr, *l_ptr;
unsigned rqsize ; register char *ptr;
unsigned rqsize;
size = ((size + (sizeof(int) - 1)) / sizeof(int)) * sizeof(int); size = ((size + (sizeof(int) - 1)) / sizeof(int)) * sizeof(int);
#ifdef MEMUSE #ifdef MEMUSE
m_used += size ; m_used += size;
m_free -= size ; m_free -= size;
#endif #endif
for(;;) { for (;;)
for ( l_ptr= &freehead, c_ptr= freehead.f_next ; {
c_ptr!= &freehead ; c_ptr = c_ptr->f_next ) { for (l_ptr = &freehead, c_ptr= freehead.f_next;
if ( size==c_ptr->f_size ) { c_ptr!= &freehead; c_ptr = c_ptr->f_next )
l_ptr->f_next= c_ptr->f_next ; {
return (area_t) c_ptr ; if ( size==c_ptr->f_size )
{
l_ptr->f_next= c_ptr->f_next;
return (area_t) c_ptr;
} }
if ( size+sizeof freehead <= c_ptr->f_size ) { if ( size+sizeof freehead <= c_ptr->f_size )
c_ptr->f_size -= size ; {
return (area_t) ((char *) c_ptr + c_ptr->f_size) ; c_ptr->f_size -= size;
return (area_t) ((char *) c_ptr + c_ptr->f_size);
} }
l_ptr = c_ptr ; l_ptr = c_ptr;
} }
rqsize = size<CHUNK ? CHUNK : size ; rqsize = size<CHUNK ? CHUNK : size;
for(;;){ for(;;)
ptr = malloc( rqsize ) ; {
if ( ptr ) break ; /* request succesfull */ ptr = malloc( rqsize );
rqsize /= 2 ; if ( ptr ) break; /* request succesfull */
rqsize -= rqsize%sizeof (int) ; rqsize /= 2;
if ( rqsize < sizeof freehead ) { rqsize -= rqsize%sizeof (int);
fatal("Out of memory") ; if ( rqsize < sizeof freehead )
{
fatal("Out of memory");
} }
} }
freearea((area_t)ptr,rqsize) ; freearea((area_t)ptr,rqsize);
#ifdef MEMUSE #ifdef MEMUSE
m_used += rqsize ; m_used += rqsize;
#endif #endif
} }
/* NOTREACHED */ /* NOTREACHED */
} }
freearea(ptr,size) register area_t ptr ; unsigned size ; { void freearea(register area_t ptr, unsigned int size)
register struct freeblock *c_ptr, *l_ptr ; {
register struct freeblock *c_ptr, *l_ptr;
size = ((size + (sizeof(int) - 1)) / sizeof(int)) * sizeof(int); size = ((size + (sizeof(int) - 1)) / sizeof(int)) * sizeof(int);
#ifdef MEMUSE #ifdef MEMUSE
m_free += size ; m_free += size;
m_used -= size ; m_used -= size;
#endif #endif
for ( l_ptr= &freehead, c_ptr=freehead.f_next ; for (l_ptr = &freehead, c_ptr=freehead.f_next;
c_ptr!= &freehead ; c_ptr= c_ptr->f_next ) { c_ptr!= &freehead; c_ptr= c_ptr->f_next )
if ( (area_t)c_ptr>ptr ) break ; {
l_ptr= c_ptr ; if ( (area_t)c_ptr>ptr ) break;
l_ptr= c_ptr;
} }
/* now insert between l_ptr and c_ptr */ /* now insert between l_ptr and c_ptr */
/* Beware they may both point to freehead */ /* Beware they may both point to freehead */
#ifdef MEMUSE #ifdef MEMUSE
if ( ((char *)l_ptr)+l_ptr->f_size> (char *)ptr && (char *)l_ptr<=(char *)ptr ) if (((char *) l_ptr) + l_ptr->f_size > (char *) ptr
fatal("Double freed") ; && (char *) l_ptr <= (char *) ptr)
if ( ((char *)ptr)+size > (char *)c_ptr && (char *)ptr<=(char *)c_ptr ) fatal("Double freed");
fatal("Frreed double") ; if (((char *) ptr) + size > (char *) c_ptr
&& (char *) ptr <= (char *) c_ptr)
fatal("Frreed double");
#endif #endif
/* Is the block before this one adjacent ? */ /* Is the block before this one adjacent ? */
if ( ((char *)l_ptr) + l_ptr->f_size == (char *) ptr ) { if (((char *) l_ptr) + l_ptr->f_size == (char *) ptr)
l_ptr->f_size += size ; /* yes */ {
} else { l_ptr->f_size += size;
/* yes */
}
else
{
/* No, create an entry */ /* No, create an entry */
((struct freeblock *)ptr)->f_next = c_ptr ; ((struct freeblock *) ptr)->f_next = c_ptr;
((struct freeblock *)ptr)->f_size = size ; ((struct freeblock *) ptr)->f_size = size;
l_ptr->f_next = (struct freeblock *)ptr ; l_ptr->f_next = (struct freeblock *) ptr;
l_ptr = (struct freeblock *)ptr ; l_ptr = (struct freeblock *) ptr;
} }
/* Are the two entries adjacent ? */ /* Are the two entries adjacent ? */
if ( (char *)l_ptr + l_ptr->f_size == (char *) c_ptr ) { if ((char *) l_ptr + l_ptr->f_size == (char *) c_ptr)
{
/* the two entries are adjacent */ /* the two entries are adjacent */
l_ptr->f_next = c_ptr->f_next ; l_ptr->f_next = c_ptr->f_next;
l_ptr->f_size += c_ptr->f_size ; l_ptr->f_size += c_ptr->f_size;
} }
} }
#ifdef MEMUSE #ifdef MEMUSE
memuse() { void memuse(void)
printf("Free %7u, Used %7u, Total %7u\n",m_free,m_used,m_free+m_used); {
printf("Free %7u, Used %7u, Total %7u\n", m_free, m_used, m_free + m_used);
} }
#endif #endif

22
util/ass/asscm.h Normal file
View 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_ */

View file

@ -5,11 +5,6 @@
#include "ass00.h" #include "ass00.h"
#include "assex.h" #include "assex.h"
#ifndef NORCSID
static char rcs_id[] = "$Id$" ;
static char rcs_ass[]= RCS_ASS ;
static char rcs_ex[] = RCS_EX ;
#endif
/* /*
* global data * global data

View file

@ -6,7 +6,7 @@
* global data * global data
*/ */
#define RCS_EX "$Id$" #include <stdio.h>
extern int wordsize; extern int wordsize;
extern int ptrsize; extern int ptrsize;
@ -122,31 +122,126 @@ extern char *opindex[] ;
extern char opchoice[] ; extern char opchoice[] ;
extern int maxinsl ; extern int maxinsl ;
/* /* Generate temporary filename. Fatal error in case of error. */
* types of value returning routines extern char *tmpfil(void);
/* Read next byte from "af" file, fatal error if there isn't one. */
extern int xgetc(register FILE *af);
/* Read a value of length "l" bytes from file "f",
* fatal error if cannot be read.
*/ */
#ifndef CPM extern cons_t xgetarb(int l,FILE *f);
extern int tmpfil(); /* Read the pointer constant a from file "f".
extern FILE *frewind(); * NOTE: The bytes were written low to high (little-endian).
#endif */
extern int xgetc(); extern cons_t xgeta(FILE* f);
extern unsigned get8();
extern int get16();
extern cons_t get32();
extern cons_t xgeta(); /* Output one byte into file "af" and fatal error if it gives an error */
extern cons_t parval(); extern void xputc(int c,register FILE *af);
extern cons_t valsize(); /* Output a 16-bit value into file "f" in little-endian, fatal error if it gives an error. */
extern cons_t xgetarb(); extern void xput16(int w,FILE *f);
/* Output a value of "l" bytes into file "f" and fatal error if it gives an error. */
extern void xputarb(int l,cons_t w, FILE* f);
/* Assemble the pointer constant a into file "f".
* NOTE: The bytes are written low to high (little-endian).
*/
extern void xputa(cons_t a,FILE* f);
/* Write a byte value into the code temporary file. */
extern void put8(int n);
/* Write a 16-bit value into the code temporary file. */
extern void put16(int n);
/* Write a 32-bit value into the code temporary file. */
extern void put32(cons_t n);
/* Write a 64-bit value into the code temporary file. */
extern void put64(cons_t n);
/* Read a byte from the input file, return EOF upon error of EOF */
extern int xget8(void);
/* Read a byte from the input file, fatal error upon error or EOF. */
extern unsigned int get8(void);
/* Read a signed 16-bit value from the input file. Raise
* a fatal error upon error or end of stream.
*/
extern int get16(void);
/* Read an unsigned 16-bit value from the input file. Raise
* a fatal error upon error or end of stream.
*/
extern int getu16(void);
/* Read a 32-bit value from the input file. Raise
* a fatal error upon error or end of stream.
*/
extern cons_t get32(void);
/* Write a byte to the data file. */
extern void ext8(int b);
/* Write a 16-bit value to the data file.
* The value is written from low to high (little-endian)
*/
extern void extword(cons_t w);
/* Write "value" of "size" bytes to the data file. The bytes
* are written low to high.
*/
extern void extarb(int size, long value);
/* Write pointer "a". The bytes are
* written from low to high to the data file.
*/
extern void extadr(cons_t a);
/* Returns the opcode length in bytes */
extern int oplength(int);
extern void genop(char *,cons_t,int );
extern void putblk(register FILE *stream,register char *from, register int amount);
extern int getblk(register FILE *stream, register char *from, register int amount);
extern void set_mode(int mode);
/* Dump current information to screen if dump flag is enabled. */
void dump(int n);
/*
extern char *findnop(); extern char *findnop();
extern char *findfit(); extern char *findfit();
extern glob_t *glolookup();
extern glob_t *glo2lookup(); */
extern glob_t *xglolookup(); extern glob_t *glolookup(char *name,int status,glob_t *table, int size);
extern locl_t *loclookup(); extern proc_t *searchproc(char *name,proc_t *table,int size);
extern proc_t *prolookup(); extern glob_t *glo2lookup(char *name ,int status);
extern proc_t *enterproc(); extern glob_t *xglolookup(char *name,int status);
extern proc_t *searchproc(); extern proc_t *prolookup(char *name,int status);
extern relc_t *text_reloc(); extern locl_t *loclookup(unsigned int an,int status);
extern relc_t *data_reloc(); extern proc_t *enterproc(char *name,int status,proc_t *place);
extern area_t getarea(); extern cons_t parval(line_t *lnp,char *defined);
extern void determine_props(line_t *lnp, int *min_len, int *max_len);
extern int opfit(int flag,int number,cons_t val,int i_flag);
extern void initproc(void);
extern void endproc(void);
extern void init_files(void);
extern void init_module(void);
extern void end_module(void);
extern void do_proc(void);
extern void ertrap(void);
extern void init_vars(void);
extern void error(const char* string1, ...);
extern void werror(const char* string1, ...);
extern void fatal(char *s);

View file

@ -4,12 +4,13 @@
* *
*/ */
#include <stdio.h>
#include "ass00.h" #include "ass00.h"
#include "assex.h" #include "assex.h"
#include "asscm.h"
#include "assrl.h"
#ifndef NORCSID
static char rcs_id[] = "$Id$" ;
#endif
#define COPYFINAL 1 #define COPYFINAL 1
#define COPYTEMP 0 #define COPYTEMP 0
@ -18,10 +19,12 @@ static char rcs_id[] = "$Id$" ;
* collection of routines to deal with relocation business * collection of routines to deal with relocation business
*/ */
void dataprocess();
void textprocess(); static void dataprocess(FILE *, FILE *);
relc_t * static void textprocess(FILE *, FILE *);
text_reloc(glosym,off,typ) glob_t *glosym; FOFFSET off ; int typ ; {
relc_t * text_reloc(glob_t *glosym, FOFFSET off, int typ)
{
/* /*
* prepare the relocation that has to be done at text-offset off * prepare the relocation that has to be done at text-offset off
@ -33,48 +36,55 @@ text_reloc(glosym,off,typ) glob_t *glosym; FOFFSET off ; int typ ; {
* into the one in xglobs[] later. * into the one in xglobs[] later.
*/ */
register relc_t *nxtextreloc ; register relc_t *nxtextreloc;
nxtextreloc= rlp_cast getarea(sizeof *nxtextreloc) ; nxtextreloc = rlp_cast getarea(sizeof *nxtextreloc);
if ( !f_text ) { if (!f_text)
f_text= nxtextreloc ; {
} else { f_text = nxtextreloc;
l_text->r_next= nxtextreloc ;
} }
nxtextreloc->r_next= rlp_cast 0 ; else
l_text= nxtextreloc ; {
l_text->r_next = nxtextreloc;
}
nxtextreloc->r_next = rlp_cast 0;
l_text = nxtextreloc;
nxtextreloc->r_off = off; nxtextreloc->r_off = off;
nxtextreloc->r_val.rel_gp = glosym; nxtextreloc->r_val.rel_gp = glosym;
nxtextreloc->r_typ = typ; /* flags of instruction */ nxtextreloc->r_typ = typ; /* flags of instruction */
return(nxtextreloc); return (nxtextreloc);
} }
relc_t * relc_t * data_reloc(char *arg ,FOFFSET off, int typ)
data_reloc(arg,off,typ) char *arg ; FOFFSET off ; int typ ; { {
/* /*
* Same as above. * Same as above.
*/ */
register relc_t *nxdatareloc ; register relc_t *nxdatareloc;
nxdatareloc= rlp_cast getarea(sizeof *nxdatareloc) ; nxdatareloc = rlp_cast getarea(sizeof *nxdatareloc);
if ( !f_data ) { if (!f_data)
f_data= nxdatareloc ; {
} else { f_data = nxdatareloc;
l_data->r_next= nxdatareloc ;
} }
nxdatareloc->r_next= rlp_cast 0 ; else
l_data= nxdatareloc ; {
l_data->r_next = nxdatareloc;
}
nxdatareloc->r_next = rlp_cast 0;
l_data = nxdatareloc;
nxdatareloc->r_off = off; nxdatareloc->r_off = off;
nxdatareloc->r_val.rel_lp = lbp_cast arg; nxdatareloc->r_val.rel_lp = lbp_cast arg;
nxdatareloc->r_typ = typ; nxdatareloc->r_typ = typ;
return(nxdatareloc); return (nxdatareloc);
} }
copyout() { void copyout(void)
register i; {
int remtext ; register int i;
int remtext;
/* /*
* Make the e.out file that looks as follows: * Make the e.out file that looks as follows:
@ -113,145 +123,158 @@ copyout() {
* *
*/ */
remtext = textbytes%wordsize ; remtext = textbytes % wordsize;
if ( remtext != 0 ) remtext = wordsize-remtext ; if (remtext != 0)
remtext = wordsize - remtext;
if ((ifile = fopen(eout,"w")) == 0 ) if ((ifile = fopen(eout, "w")) == 0)
fatal("can't create e.out"); fatal("can't create e.out");
#ifdef CPM
fclose(tfile); tfile=fopen("TFILE.$$$", "r");
fclose(dfile); dfile=fopen("DFILE.$$$", "r");
#else
tfile=frewind(tfile);
dfile=frewind(dfile);
#endif
xput16(as_magic,ifile);
xput16(intflags,ifile);
xput16(unresolved,ifile);
xput16(VERSION,ifile);
xput16(wordsize,ifile);
xput16(ptrsize,ifile);
xput16(0,ifile);
xput16(0,ifile);
xputa(textbytes+remtext ,ifile);
xputa((cons_t)datablocks,ifile);
xputa((cons_t)procnum,ifile);
xputa((cons_t)searchproc(MAIN,xprocs,oursize->n_xproc)->p_num,
ifile);
xputa((cons_t)sourcelines,ifile);
xputa((cons_t)databytes,ifile);
xputa((cons_t)0,ifile);
xputa((cons_t)0,ifile);
textprocess(tfile,ifile); rewind(tfile);
while ( remtext-- ) xputc(0,ifile) ; rewind(dfile);
dataprocess(dfile,ifile); xput16(as_magic, ifile);
for (i=0;i<procnum;i++) { xput16(intflags, ifile);
xputarb(ptrsize,proctab[i].pr_loc,ifile); xput16(unresolved, ifile);
xputarb(ptrsize,proctab[i].pr_off,ifile); xput16(VERSION, ifile);
xput16(wordsize, ifile);
xput16(ptrsize, ifile);
xput16(0, ifile);
xput16(0, ifile);
xputa(textbytes + remtext, ifile);
xputa((cons_t) datablocks, ifile);
xputa((cons_t) procnum, ifile);
xputa((cons_t) searchproc(MAIN, xprocs, oursize->n_xproc)->p_num, ifile);
xputa((cons_t) sourcelines, ifile);
xputa((cons_t) databytes, ifile);
xputa((cons_t) 0, ifile);
xputa((cons_t) 0, ifile);
textprocess(tfile, ifile);
while (remtext--)
xputc(0, ifile);
dataprocess(dfile, ifile);
for (i = 0; i < procnum; i++)
{
xputarb(ptrsize, proctab[i].pr_loc, ifile);
xputarb(ptrsize, proctab[i].pr_off, ifile);
} }
if ( fclose(ifile)==EOF ) ; if (fclose(ifile) == EOF)
;
} }
void dataprocess(f1,f2) FILE *f1,*f2; { static void dataprocess(FILE *f1, FILE *outf)
{
relc_t datareloc; relc_t datareloc;
FOFFSET i; FOFFSET i;
register ieof ; register int ieof;
#ifdef CPM rewind(rdfile);
fclose(rdfile); rdfile=fopen("RDFILE.$$$", "r"); ieof = getblk(rdfile, (char *) (&datareloc.r_off),
#else sizeof datareloc - sizeof datareloc.r_next);
rdfile=frewind(rdfile) ; for (i = 0; i < dataoff && !ieof; i++)
#endif {
ieof=getblk(rdfile,(char *)(&datareloc.r_off), if (i == datareloc.r_off)
sizeof datareloc - sizeof datareloc.r_next) ; {
for (i=0 ; i<dataoff && !ieof ; i++) { switch (datareloc.r_typ)
if (i==datareloc.r_off) { {
switch(datareloc.r_typ) {
case RELADR: case RELADR:
xputa(xgeta(f1)+datareloc.r_val.rel_i,f2) ; xputa(xgeta(f1) + datareloc.r_val.rel_i, outf);
i += ptrsize-1 ; i += ptrsize - 1;
break ; break;
case RELGLO: case RELGLO:
if (datareloc.r_val.rel_gp->g_status&DEF) { if (datareloc.r_val.rel_gp->g_status & DEF)
xputa(xgeta(f1)+ {
datareloc.r_val.rel_gp->g_val.g_addr, xputa(xgeta(f1) + datareloc.r_val.rel_gp->g_val.g_addr, outf);
f2); i += ptrsize - 1;
i+= ptrsize-1 ; break;
break ;
} }
if ( unresolved == 0 ) if (unresolved == 0)
fatal("Definition botch") ; fatal("Definition botch");
case RELHEAD: case RELHEAD:
xputc((int)(xgetc(f1)+datareloc.r_val.rel_i), xputc((int) (xgetc(f1) + datareloc.r_val.rel_i), outf);
f2);
break; break;
default: default:
fatal("Bad r_typ in dataprocess"); fatal("Bad r_typ in dataprocess");
} }
ieof=getblk(rdfile,(char *)(&datareloc.r_off), ieof = getblk(rdfile, (char *) (&datareloc.r_off),
sizeof datareloc - sizeof datareloc.r_next) ; sizeof datareloc - sizeof datareloc.r_next);
} else }
xputc(xgetc(f1),f2); else
xputc(xgetc(f1), outf);
} }
for ( ; i<dataoff ; i++ ) xputc(xgetc(f1),f2) ; for (; i < dataoff; i++)
if ( !ieof && !getblk(rdfile,(char *)&datareloc,1) ) xputc(xgetc(f1), outf);
fatal("data relocation botch") ; if (!ieof && !getblk(rdfile, (char *) &datareloc, 1))
fatal("data relocation botch");
} }
void textprocess(f1,f2) FILE *f1,*f2; { static void textprocess(FILE *f1, FILE *outf)
{
relc_t textreloc; relc_t textreloc;
cons_t n; cons_t n;
FOFFSET i; FOFFSET i;
FILE *otfile ; FILE *otfile;
int insl ; register int ieof ; int insl;
char *op_curr ; register int ieof;
register FOFFSET keep ; char *op_curr;
register FOFFSET keep;
#ifdef CPM rewind(rtfile);
fclose(rtfile); rtfile=fopen("RTFILE.$$$", "r"); keep = textoff;
#else textoff = 0;
rtfile=frewind(rtfile) ; otfile = tfile;
#endif tfile = outf;
keep = textoff ; textoff=0 ; otfile=tfile ; tfile=f2 ;
/* This redirects the output of genop */ /* This redirects the output of genop */
ieof=getblk(rtfile,(char *)(&textreloc.r_off), ieof = getblk(rtfile, (char *) (&textreloc.r_off),
sizeof textreloc - sizeof textreloc.r_next) ; sizeof textreloc - sizeof textreloc.r_next);
for(i=0;i<keep && !ieof ;i++) { for (i = 0; i < keep && !ieof; i++)
if( i == textreloc.r_off ) { {
if (textreloc.r_typ&RELMNS) { if (i == textreloc.r_off)
n=textreloc.r_val.rel_i; {
} else { if (textreloc.r_typ & RELMNS)
if (textreloc.r_val.rel_gp->g_status&DEF) { {
n=textreloc.r_val.rel_gp->g_val.g_addr; n = textreloc.r_val.rel_i;
} else { }
if ( unresolved==0 ) else
fatal("Definition botch") ; {
xputc(xgetc(f1),f2) ; if (textreloc.r_val.rel_gp->g_status & DEF)
ieof=getblk(rtfile,(char *)(&textreloc.r_off), {
sizeof textreloc-sizeof textreloc.r_next); n = textreloc.r_val.rel_gp->g_val.g_addr;
continue ; }
else
{
if (unresolved == 0)
fatal("Definition botch");
xputc(xgetc(f1), outf);
ieof = getblk(rtfile, (char *) (&textreloc.r_off),
sizeof textreloc - sizeof textreloc.r_next);
continue;
} }
} }
op_curr = &opchoice[textreloc.r_typ& ~RELMNS] ; op_curr = &opchoice[textreloc.r_typ & ~RELMNS];
insl = oplength(*op_curr) ; insl = oplength(*op_curr);
genop(op_curr, n+xgetarb(insl,f1), PAR_G); genop(op_curr, n + xgetarb(insl, f1), PAR_G);
i += insl-1 ; i += insl - 1;
ieof=getblk(rtfile,(char *)(&textreloc.r_off), ieof = getblk(rtfile, (char *) (&textreloc.r_off),
sizeof textreloc - sizeof textreloc.r_next) ; sizeof textreloc - sizeof textreloc.r_next);
} else { }
xputc(xgetc(f1),f2) ; else
{
xputc(xgetc(f1), outf);
} }
} }
for ( ; i<keep ; i++ ) xputc(xgetc(f1),f2) ; for (; i < keep; i++)
if ( !ieof && !getblk(rtfile,(char *)&textreloc,1) ) xputc(xgetc(f1), outf);
fatal("text relocation botch") ; if (!ieof && !getblk(rtfile, (char *) &textreloc, 1))
textoff = keep ; fatal("text relocation botch");
tfile = otfile ; textoff = keep;
tfile = otfile;
} }
upd_reloc() { void upd_reloc(void)
{
register relc_t *p; register relc_t *p;
register glob_t *gbp; register glob_t *gbp;
@ -264,28 +287,37 @@ upd_reloc() {
* see also getcore() * see also getcore()
*/ */
while ( p= f_text ) { while ( (p = f_text) != NULL)
gbp= p->r_val.rel_gp ; {
if( gbp->g_status&DEF ) { gbp = p->r_val.rel_gp;
if (gbp->g_status & DEF)
{
p->r_typ |= RELMNS; p->r_typ |= RELMNS;
p->r_val.rel_i = gbp->g_val.g_addr; p->r_val.rel_i = gbp->g_val.g_addr;
} else }
else
p->r_val.rel_gp = gbp->g_val.g_gp; p->r_val.rel_gp = gbp->g_val.g_gp;
putblk(rtfile,(char *)(&(p->r_off)),sizeof *p - sizeof p) ; putblk(rtfile, (char *) (&(p->r_off)), sizeof *p - sizeof p);
f_text= p->r_next ; freearea( (area_t) p , sizeof *p ) ; f_text = p->r_next;
freearea((area_t) p, sizeof *p);
} }
while( p= f_data ) { while ( (p = f_data) != NULL)
if (p->r_typ == RELGLO) { {
gbp= p->r_val.rel_gp ; if (p->r_typ == RELGLO)
if(gbp->g_status&DEF) { {
gbp = p->r_val.rel_gp;
if (gbp->g_status & DEF)
{
p->r_typ = RELADR; p->r_typ = RELADR;
p->r_val.rel_i = gbp->g_val.g_addr; p->r_val.rel_i = gbp->g_val.g_addr;
} else }
else
p->r_val.rel_gp = gbp->g_val.g_gp; p->r_val.rel_gp = gbp->g_val.g_gp;
} }
putblk(rdfile,(char *)(&(p->r_off)),sizeof *p - sizeof p) ; putblk(rdfile, (char *) (&(p->r_off)), sizeof *p - sizeof p);
f_data= p->r_next ; freearea( (area_t) p , sizeof *p ) ; f_data = p->r_next;
freearea((area_t) p, sizeof *p);
} }
l_data= rlp_cast 0 ; l_data = rlp_cast 0;
} }

21
util/ass/assrl.h Normal file
View 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_ */

View file

@ -36,7 +36,7 @@ cprogram {
"modules/src/em_data+lib", "modules/src/em_data+lib",
--"modules/src/data+lib", --"modules/src/data+lib",
--"modules/src/object+lib", --"modules/src/object+lib",
--"modules/src/system+lib", "modules/src/system+lib",
"./ass*.h", "./ass*.h",
} }
} }

View file

@ -64,7 +64,7 @@ produced code the only messages to expect are "Out of memory"
or of the or of the
form: Overflow in XXXX. The latter can usually be cured by giving form: Overflow in XXXX. The latter can usually be cured by giving
a -sx flag, a -sx flag,
the former means the program is too big, dimishing the former means the program is too big, diminishing
the size of very large procedures can sometimes help. the size of very large procedures can sometimes help.
The most likely errors, however, are unresolved references, The most likely errors, however, are unresolved references,
probably caused by the omission of a library argument. probably caused by the omission of a library argument.

View file

@ -6,471 +6,646 @@
#include "ip_spec.h" #include "ip_spec.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <em_spec.h> #include <em_spec.h>
#include <em_flag.h> #include <em_flag.h>
#ifndef NORCSID
static char rcs_id[] = "$Id$" ;
#endif
/* This program reads the human readable interpreter specification /* This program reads the human readable interpreter specification
and produces a efficient machine representation that can be and produces a efficient machine representation that can be
translated by a C-compiler. translated by a C-compiler.
*/ */
#define NOTAB 600 /* The max no of interpreter specs */ #define NOTAB 600 /* The max no of interpreter specs */
#define ESCAP 256 #define ESCAP 256
struct opform intable[NOTAB] ; struct opform intable[NOTAB];
struct opform *lastform = intable-1 ; struct opform *lastform = intable - 1;
int nerror = 0 ; int nerror = 0;
int atend = 0 ; int atend = 0;
int line = 1 ; int line = 1;
int maxinsl= 0 ; int maxinsl = 0;
extern char em_mnem[][4] ; extern char em_mnem[][4];
char esca[] = "escape" ; char esca[] = "escape";
#define ename(no) ((no)==ESCAP?esca:em_mnem[(no)]) #define ename(no) ((no)==ESCAP?esca:em_mnem[(no)])
extern char em_flag[] ; extern char em_flag[];
main(argc,argv) char **argv ; {
if ( argc>1 ) { /* Forward declarations */
if ( freopen(argv[1],"r",stdin)==NULL) { static int readchar(void);
fatal("Cannot open %s",argv[1]) ; static void pushback(int);
static void readin(void);
static char *ident(void);
static int getmnem(char *);
static void writeout(void);
static void checkall(void);
static void chkc(int, int, int);
static void ckop(int, int, int, int);
static int oplength(struct opform *);
static void check(int);
static int decflag(char *);
int compare(const void *, const void *);
static void error(char *format, ...);
static void mess(char *format, ...);
static void fatal(char *format, ...);
int main(int argc, char **argv)
{
if (argc > 1)
{
if (freopen(argv[1], "r", stdin) == NULL)
{
fatal("Cannot open %s", argv[1]);
} }
} }
if ( argc>2 ) { if (argc > 2)
if ( freopen(argv[2],"w",stdout)==NULL) { {
fatal("Cannot create %s",argv[2]) ; if (freopen(argv[2], "w", stdout) == NULL)
{
fatal("Cannot create %s", argv[2]);
} }
} }
if ( argc>3 ) { if (argc > 3)
fatal("%s [ file [ file ] ]",argv[0]) ; {
fatal("%s [ file [ file ] ]", argv[0]);
} }
atend=0 ; atend = 0;
readin(); readin();
atend=1 ; atend = 1;
checkall(); checkall();
if ( nerror==0 ) { if (nerror == 0)
{
writeout(); writeout();
} }
exit(nerror); exit(nerror);
} }
readin() { static void readin(void)
register struct opform *nextform ; {
char *ident(); register struct opform *nextform;
char *firstid ; char *firstid;
register maxl ; register int maxl;
maxl = 0 ; maxl = 0;
for ( nextform=intable ; for (nextform = intable; !feof(stdin) && nextform < &intable[NOTAB];)
!feof(stdin) && nextform<&intable[NOTAB] ; ) { {
firstid=ident() ; firstid = ident();
if ( *firstid=='\n' || feof(stdin) ) continue ; if (*firstid == '\n' || feof(stdin))
lastform=nextform ; continue;
nextform->i_opcode = getmnem(firstid) ; lastform = nextform;
nextform->i_flag = decflag(ident()) ; nextform->i_opcode = getmnem(firstid);
switch ( nextform->i_flag&OPTYPE ) { nextform->i_flag = decflag(ident());
switch (nextform->i_flag & OPTYPE)
{
case OPMINI: case OPMINI:
case OPSHORT: case OPSHORT:
nextform->i_num = atoi(ident()) ; nextform->i_num = atoi(ident());
break ; break;
} }
nextform->i_low = atoi(ident()) ; nextform->i_low = atoi(ident());
if ( *ident()!='\n' ) { if (*ident() != '\n')
int c ; {
int c;
error("End of line expected"); error("End of line expected");
while ( (c=readchar())!='\n' && c!=EOF ) ; while ((c = readchar()) != '\n' && c != EOF)
;
} }
if ( oplength(nextform)>maxl ) maxl=oplength(nextform) ; if (oplength(nextform) > maxl)
nextform++ ; maxl = oplength(nextform);
nextform++;
} }
if ( !feof(stdin) ) fatal("Internal table too small") ; if (!feof(stdin))
maxinsl = maxl ; fatal("Internal table too small");
maxinsl = maxl;
} }
char *ident() { static char *ident(void)
{
/* skip spaces and tabs, anything up to space,tab or eof is /* skip spaces and tabs, anything up to space,tab or eof is
a identifier. a identifier.
Anything from # to end-of-line is an end-of-line. Anything from # to end-of-line is an end-of-line.
End-of-line is an identifier all by itself. End-of-line is an identifier all by itself.
*/ */
static char array[200] ; static char array[200];
register int c ; register int c;
register char *cc ; register char *cc;
do { do
c=readchar() ; {
} while ( c==' ' || c=='\t' ) ; c = readchar();
for ( cc=array ; cc<&array[(sizeof array) - 1] ; cc++ ) { } while (c == ' ' || c == '\t');
if ( c=='#' ) { for (cc = array; cc < &array[(sizeof array) - 1]; cc++)
do { {
c=readchar(); if (c == '#')
} while ( c!='\n' && c!=EOF ) ; {
do
{
c = readchar();
} while (c != '\n' && c != EOF);
} }
*cc = c ; *cc = c;
if ( c=='\n' && cc==array ) break ; if (c == '\n' && cc == array)
c=readchar() ; break;
if ( c=='\n' ) { c = readchar();
pushback(c) ; if (c == '\n')
break ; {
pushback(c);
break;
} }
if ( c==' ' || c=='\t' || c==EOF ) break ; if (c == ' ' || c == '\t' || c == EOF)
break;
} }
*++cc=0 ; *++cc = 0;
return array ; return array;
} }
int getmnem(str) char *str ; { static int getmnem(char *str)
char (*ptr)[4] ; {
char (*ptr)[4];
for ( ptr = em_mnem ; *ptr<= &em_mnem[sp_lmnem-sp_fmnem][0] ; ptr++ ) { for (ptr = em_mnem; *ptr <= &em_mnem[sp_lmnem - sp_fmnem][0]; ptr++)
if ( strcmp(*ptr,str)==0 ) return (ptr-em_mnem) ; {
if (strcmp(*ptr, str) == 0)
return (ptr - em_mnem);
} }
error("Illegal mnemonic") ; error("Illegal mnemonic");
return 0 ; return 0;
} }
error(str,a1,a2,a3,a4,a5,a6) /* VARARGS1 */ char *str ; { /* VARARGS1 */
if ( !atend ) fprintf(stderr,"line %d: ",line) ; static void error(char *format, ...)
fprintf(stderr,str,a1,a2,a3,a4,a5,a6) ; {
fprintf(stderr,"\n"); va_list argptr;
nerror++ ; if (!atend)
fprintf(stderr, "line %d: ", line);
va_start(argptr, format);
vfprintf(stderr, format, argptr);
va_end(argptr);
fprintf(stderr, "\n");
nerror++;
} }
mess(str,a1,a2,a3,a4,a5,a6) /* VARARGS1 */ char *str ; { /* VARARGS1 */
if ( !atend ) fprintf(stderr,"line %d: ",line) ; static void mess(char *format, ...)
fprintf(stderr,str,a1,a2,a3,a4,a5,a6) ; {
fprintf(stderr,"\n"); va_list argptr;
if (!atend)
fprintf(stderr, "line %d: ", line);
va_start(argptr, format);
vfprintf(stderr, format, argptr);
va_end(argptr);
fprintf(stderr, "\n");
} }
fatal(str,a1,a2,a3,a4,a5,a6) /* VARARGS1 */ char *str ; { /* VARARGS1 */
error(str,a1,a2,a3,a4,a5,a6) ; static void fatal(char *format, ...)
exit(1) ; {
va_list argptr;
if (!atend)
fprintf(stderr, "line %d: ", line);
va_start(argptr, format);
vfprintf(stderr, format, argptr);
va_end(argptr);
fprintf(stderr, "\n");
exit(EXIT_FAILURE);
} }
#define ILLGL -1 #define ILLGL -1
check(val) int val ; { static void check(int val)
if ( val!=ILLGL ) error("Illegal flag combination") ; {
if (val != ILLGL)
error("Illegal flag combination");
} }
int decflag(str) char *str ; { static int decflag(char *str)
int type ; {
int escape ; int type;
int range ; int escape;
int wordm ; int range;
int notzero ; int wordm;
int notzero;
type=escape=range=wordm=notzero= ILLGL ; type = escape = range = wordm = notzero = ILLGL;
while ( *str ) switch ( *str++ ) { while (*str)
case 'm' : switch (*str++)
check(type) ; type=OPMINI ; break ; {
case 's' : case 'm':
check(type) ; type=OPSHORT ; break ; check(type);
case '-' : type = OPMINI;
check(type) ; type=OPNO ; break ; break;
case '1' : case 's':
check(type) ; type=OP8 ; break ; check(type);
case '2' : type = OPSHORT;
check(type) ; type=OP16 ; break ; break;
case '4' : case '-':
check(type) ; type=OP32 ; break ; check(type);
case '8' : type = OPNO;
check(type) ; type=OP64 ; break ; break;
case 'u': case '1':
check(type) ; type=OP16U ; break ; check(type);
case 'e' : type = OP8;
check(escape) ; escape=0 ; break ; break;
case 'N' : case '2':
check(range) ; range= 2 ; break ; check(type);
case 'P' : type = OP16;
check(range) ; range= 1 ; break ; break;
case 'w' : case '4':
check(wordm) ; wordm=0 ; break ; check(type);
case 'o' : type = OP32;
check(notzero) ; notzero=0 ; break ; break;
default : case '8':
error("Unknown flag") ; check(type);
} type = OP64;
if ( type==ILLGL ) error("Type must be specified") ; break;
switch ( type ) { case 'u':
case OP64 : check(type);
case OP32 : type = OP16U;
if ( escape!=ILLGL ) error("Conflicting escapes") ; break;
escape=ILLGL ; case 'e':
case OP16 : check(escape);
case OP16U : escape = 0;
case OP8 : break;
case OPSHORT : case 'N':
case OPNO : check(range);
if ( notzero!=ILLGL ) mess("Improbable OPNZ") ; range = 2;
if ( type==OPNO && range!=ILLGL ) { break;
mess("No operand in range") ; 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 ( escape!=ILLGL ) type|=OPESC ; if (escape != ILLGL)
if ( wordm!=ILLGL ) type|=OPWORD ; type |= OPESC;
switch ( range) { if (wordm != ILLGL)
case ILLGL : type|=OP_BOTH ; type |= OPWORD;
if ( type==OPMINI || type==OPSHORT ) switch (range)
error("Minies and shorties must have P or N") ; {
break ; case ILLGL:
case 1 : type|=OP_POS ; break ; type |= OP_BOTH;
case 2 : type|=OP_NEG ; break ; if (type == OPMINI || type == OPSHORT)
error("Minies and shorties must have P or N");
break;
case 1:
type |= OP_POS;
break;
case 2:
type |= OP_NEG;
break;
} }
if ( notzero!=ILLGL ) type|=OPNZ ; if (notzero != ILLGL)
return type ; type |= OPNZ;
return type;
} }
writeout() { static void writeout(void)
register struct opform *next ; {
int elem[sp_lmnem-sp_fmnem+1+1] ; register struct opform *next;
/* for each op points to first of descr. */ int elem[sp_lmnem - sp_fmnem + 1 + 1];
register int i,currop ; /* for each op points to first of descr. */
int nch ; register int i, currop;
int compare() ; 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) ; printf("int\tmaxinsl\t= %d ;\n", maxinsl);
currop= -1 ; nch=0 ; currop = -1;
printf("char opchoice[] = {\n") ; nch = 0;
for (next=intable ; next<=lastform ; next++ ) { printf("char opchoice[] = {\n");
if ( (next->i_opcode&0377)!=currop ) { for (next = intable; next <= lastform; next++)
for ( currop++ ; {
currop<(next->i_opcode&0377) ; currop++ ) { if ((next->i_opcode & 0377) != currop)
elem[currop]= nch ; {
error("Missing opcode %s",em_mnem[currop]) ; for (currop++; currop < (next->i_opcode & 0377); currop++)
{
elem[currop] = nch;
error("Missing opcode %s", em_mnem[currop]);
} }
elem[currop]= nch ; elem[currop] = nch;
} }
printf("%d, %d,",next->i_flag&0377,next->i_low&0377) ; printf("%d, %d,", next->i_flag & 0377, next->i_low & 0377);
nch+=2 ; nch += 2;
switch ( next->i_flag&OPTYPE ) { switch (next->i_flag & OPTYPE)
case OPMINI : {
case OPSHORT : case OPMINI:
printf("%d,",next->i_num&0377) ; nch++ ; case OPSHORT:
printf("%d,", next->i_num & 0377);
nch++;
} }
printf("\n") ; printf("\n");
} }
for ( currop++ ; currop<=sp_lmnem-sp_fmnem ; currop++ ) { for (currop++; currop <= sp_lmnem - sp_fmnem; currop++)
elem[currop]= nch ; {
error("Missing opcode %s",em_mnem[currop]) ; elem[currop] = nch;
error("Missing opcode %s", em_mnem[currop]);
} }
elem[sp_lmnem-sp_fmnem+1]=nch ; elem[sp_lmnem - sp_fmnem + 1] = nch;
printf("0 } ;\n\nchar *opindex[] = {\n"); printf("0 } ;\n\nchar *opindex[] = {\n");
for ( i=0 ; i<=sp_lmnem-sp_fmnem+1 ; i++ ) { for (i = 0; i <= sp_lmnem - sp_fmnem + 1; i++)
printf(" &opchoice[%d], /* %d = %s */\n",elem[i], i, em_mnem[i]) ; {
printf(" &opchoice[%d], /* %d = %s */\n", elem[i], i, em_mnem[i]);
} }
printf("} ;\n") ; printf("} ;\n");
} }
int compare(a,b) struct opform *a,*b ; { int compare(const void *a1, const void *b1)
if ( a->i_opcode!=b->i_opcode ) { {
return (a->i_opcode&0377)-(b->i_opcode&0377) ; struct opform *a = (struct opform *)(a1);
struct opform *b = (struct opform *)(b1);
if (a->i_opcode != b->i_opcode)
{
return (a->i_opcode & 0377) - (b->i_opcode & 0377);
} }
return oplength(a)-oplength(b) ; return oplength(a) - oplength(b);
} }
int oplength(a) struct opform *a ; { static int oplength(struct opform *a)
int cnt ; {
int cnt;
cnt=1 ; cnt = 1;
if ( a->i_flag&OPESC ) cnt++ ; if (a->i_flag & OPESC)
switch( a->i_flag&OPTYPE ) { cnt++;
case OPNO : switch (a->i_flag & OPTYPE)
case OPMINI : break ; {
case OP8 : case OPNO:
case OPSHORT : cnt++ ; break ; case OPMINI:
case OP16U : break;
case OP16 : cnt+=2 ; break ; case OP8:
case OP32 : cnt+=5 ; break ; case OPSHORT:
case OP64 : cnt+=9 ; break ; cnt++;
break;
case OP16U:
case OP16:
cnt += 2;
break;
case OP32:
cnt += 5;
break;
case OP64:
cnt += 9;
break;
} }
return cnt ; return cnt;
} }
/* ----------- checking --------------*/ /* ----------- checking --------------*/
int ecodes[256],codes[256],lcodes[256] ; int ecodes[256], codes[256], lcodes[256];
#define NMNEM (sp_lmnem-sp_fmnem+1) #define NMNEM (sp_lmnem-sp_fmnem+1)
#define MUST 1 #define MUST 1
#define MAY 2 #define MAY 2
#define FORB 3 #define FORB 3
char negc[NMNEM], zc[NMNEM], posc[NMNEM] ; char negc[NMNEM], zc[NMNEM], posc[NMNEM];
checkall() { static void checkall(void)
register i,flag ; {
register struct opform *next ; register int i, flag;
int opc,low ; register struct opform *next;
int opc, low;
for ( i=0 ; i<NMNEM ; i++ ) negc[i]=zc[i]=posc[i]=0 ; for (i = 0; i < NMNEM; i++)
for ( i=0 ; i<256 ; i++ ) lcodes[i]= codes[i]= ecodes[i]= -1 ; negc[i] = zc[i] = posc[i] = 0;
codes[254]=codes[255]=ESCAP; for (i = 0; i < 256; i++)
lcodes[i] = codes[i] = ecodes[i] = -1;
codes[254] = codes[255] = ESCAP;
atend=0 ; line=0 ; atend = 0;
for ( next=intable ; next<=lastform ; next++ ) { line = 0;
line++ ; for (next = intable; next <= lastform; next++)
flag = next->i_flag&0377 ; {
opc = next->i_opcode&0377 ; line++;
low = next->i_low&0377 ; flag = next->i_flag & 0377;
chkc(flag,low,opc) ; opc = next->i_opcode & 0377;
switch(flag&OPTYPE) { low = next->i_low & 0377;
case OPNO : zc[opc]++ ; break ; chkc(flag, low, opc);
case OPMINI : switch (flag & OPTYPE)
case OPSHORT : {
for ( i=1 ; i<((next->i_num)&0377) ; i++ ) { case OPNO:
chkc(flag,low+i,opc) ; zc[opc]++;
break;
case OPMINI:
case OPSHORT:
for (i = 1; i < ((next->i_num) & 0377); i++)
{
chkc(flag, low + i, opc);
} }
if ( !(em_flag[opc]&PAR_G) && if (!(em_flag[opc] & PAR_G) && (flag & OPRANGE) == OP_BOTH)
(flag&OPRANGE)==OP_BOTH) { {
mess("Mini's and shorties should have P or N"); mess("Mini's and shorties should have P or N");
} }
break ; break;
case OP8 : case OP8:
error("OP8 is removed") ; error("OP8 is removed");
break ; break;
case OP16 : case OP16:
if ( flag&OP_NEG ) if (flag & OP_NEG)
negc[opc]++ ; negc[opc]++;
else if ( flag&OP_POS ) else if (flag & OP_POS)
posc[opc]++ ; posc[opc]++;
break ; break;
case OP16U : case OP16U:
case OP32 : case OP32:
case OP64 : case OP64:
break ; break;
default : default:
error("Illegal type") ; error("Illegal type");
break ; break;
} }
} }
atend=1 ; atend = 1;
for ( i=0 ; i<256 ; i++ ) if ( codes[i]== -1 ) { for (i = 0; i < 256; i++)
mess("interpreter opcode %d not used",i) ; if (codes[i] == -1)
} {
for ( opc=0 ; opc<NMNEM ; opc++ ) { mess("interpreter opcode %d not used", i);
switch(em_flag[opc]&EM_PAR) { }
case PAR_NO : for (opc = 0; opc < NMNEM; opc++)
ckop(opc,MUST,FORB,FORB) ; {
break ; switch (em_flag[opc] & EM_PAR)
{
case PAR_NO:
ckop(opc, MUST, FORB, FORB);
break;
case PAR_C: case PAR_C:
case PAR_D: case PAR_D:
case PAR_F: case PAR_F:
case PAR_B: case PAR_B:
ckop(opc,FORB,MAY,MAY) ; ckop(opc, FORB, MAY, MAY);
break ; break;
case PAR_N: case PAR_N:
case PAR_G: case PAR_G:
case PAR_S: case PAR_S:
case PAR_Z: case PAR_Z:
case PAR_O: case PAR_O:
case PAR_P: case PAR_P:
ckop(opc,FORB,MAY,FORB) ; ckop(opc, FORB, MAY, FORB);
break ; break;
case PAR_R: case PAR_R:
ckop(opc,FORB,MAY,FORB) ; ckop(opc, FORB, MAY, FORB);
break ; break;
case PAR_L: case PAR_L:
ckop(opc,FORB,MUST,MUST) ; ckop(opc, FORB, MUST, MUST);
break ; break;
case PAR_W: case PAR_W:
ckop(opc,MUST,MAY,FORB) ; ckop(opc, MUST, MAY, FORB);
break ; break;
default : default:
error("Unknown instruction type of %s",ename(opc)) ; error("Unknown instruction type of %s", ename(opc));
break ; break;
} }
} }
} }
chkc(flag,icode,emc) { static void chkc(int flag, int icode, int emc)
if ( flag&OPESC ) { {
if ( ecodes[icode]!=-1 ) { if (flag & OPESC)
mess("Escaped opcode %d used by %s and %s", {
icode,ename(emc),ename(ecodes[icode])) ; if (ecodes[icode] != -1)
{
mess("Escaped opcode %d used by %s and %s", icode, ename(emc),
ename(ecodes[icode]));
} }
ecodes[icode]=emc; ecodes[icode] = emc;
} else switch ( flag&OPTYPE ) {
default:
if ( codes[icode]!=-1 ) {
mess("Opcode %d used by %s and %s",
icode,ename(emc),ename(codes[icode])) ;
}
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])) ;
}
lcodes[icode]=emc;
break ;
} }
else
switch (flag & OPTYPE)
{
default:
if (codes[icode] != -1)
{
mess("Opcode %d used by %s and %s", icode, ename(emc),
ename(codes[icode]));
}
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]));
}
lcodes[icode] = emc;
break;
}
} }
ckop(emc,zf,pf,nf) { static void ckop(int emc, int zf, int pf, int nf)
if ( zc[emc]>1 ) mess("More then one OPNO for %s",ename(emc)) ; {
if ( posc[emc]>1 ) mess("More then one OP16(pos) for %s",ename(emc)) ; if (zc[emc] > 1)
if ( negc[emc]>1 ) mess("More then one OP16(neg) for %s",ename(emc)) ; mess("More then one OPNO for %s", ename(emc));
switch(zf) { if (posc[emc] > 1)
mess("More then one OP16(pos) for %s", ename(emc));
if (negc[emc] > 1)
mess("More then one OP16(neg) for %s", ename(emc));
switch (zf)
{
case MUST: case MUST:
if ( zc[emc]==0 ) mess("No OPNO for %s",ename(emc)) ; if (zc[emc] == 0)
break ; mess("No OPNO for %s", ename(emc));
break;
case FORB: case FORB:
if ( zc[emc]==1 ) mess("Forbidden OPNO for %s",ename(emc)) ; if (zc[emc] == 1)
break ; mess("Forbidden OPNO for %s", ename(emc));
break;
} }
switch(pf) { switch (pf)
{
case MUST: case MUST:
if ( posc[emc]==0 ) mess("No OP16(pos) for %s",ename(emc)) ; if (posc[emc] == 0)
break ; mess("No OP16(pos) for %s", ename(emc));
break;
case FORB: case FORB:
if ( posc[emc]==1 ) if (posc[emc] == 1)
mess("Forbidden OP16(pos) for %s",ename(emc)) ; mess("Forbidden OP16(pos) for %s", ename(emc));
break ; break;
} }
switch(nf) { switch (nf)
{
case MUST: case MUST:
if ( negc[emc]==0 ) mess("No OP16(neg) for %s",ename(emc)) ; if (negc[emc] == 0)
break ; mess("No OP16(neg) for %s", ename(emc));
break;
case FORB: case FORB:
if ( negc[emc]==1 ) if (negc[emc] == 1)
mess("Forbidden OP16(neg) for %s",ename(emc)) ; mess("Forbidden OP16(neg) for %s", ename(emc));
break ; break;
} }
} }
static int pushchar ; static int pushchar;
static int pushf ; static int pushf;
int readchar() { static int readchar(void)
int c ; {
int c;
if ( pushf ) { if (pushf)
pushf=0 ; {
c = pushchar ; pushf = 0;
} else { c = pushchar;
if ( feof(stdin) ) return EOF ;
c=getc(stdin) ;
} }
if ( c=='\n' ) line++ ; else
return c ; {
if (feof(stdin))
return EOF;
c = getc(stdin);
}
if (c == '\n')
line++;
return c;
} }
pushback(c) { static void pushback(int c)
if ( pushf ) { {
fatal("Double pushback") ; if (pushf)
{
fatal("Double pushback");
} }
pushf++ ; pushf++;
pushchar=c ; pushchar = c;
if ( c=='\n' ) line-- ; if (c == '\n')
line--;
} }