Merge pull request #181 from ccodere/carl-ansi-part1

More ANSI C conversion
This commit is contained in:
David Given 2019-03-20 15:53:22 +01:00 committed by GitHub
commit 3f61c0d507
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
84 changed files with 5377 additions and 4236 deletions

View file

@ -1,4 +1,3 @@
.\" $Id$
.RP
.ND Nov 1984
.TL

File diff suppressed because it is too large Load diff

View file

@ -14,14 +14,16 @@
#include "arith.h"
#include "stack.h"
#include "def.h"
#include "idf.h"
#include "type.h"
#include "proto.h"
#include "struct.h"
#include "field.h"
#include "print.h"
#include "Lpars.h"
#include "label.h"
#include "expr.h"
#include "static.h"
/*#include "static.h"*/
#include "declar.h"
/* Some routines (symbol2str, type2str, qual2str) which should have
@ -36,16 +38,29 @@
extern char options[];
extern char *sprint();
extern struct idf *idf_hashtable[];
extern char *symbol2str(), *type2str(), *qual2str(), *next_transient();
extern char *symbol2str();
enum sdef_kind {selector, field}; /* parameter for dumpsdefs */
static int dumplevel;
newline() {
/* Forward declarations */
static void dumpstack(void);
static char *next_transient(void);
static char *qual2str(int);
static char *type2str(register struct type *);
static void p1_indent(register int);
static void dumpdefs(register struct def *, int);
void dumpidf(register struct idf *, int);
void dumptags(register struct tag *);
void dumptype(register struct type *);
void dumpsdefs(register struct sdef *, enum sdef_kind);
static void p1_expr(int, register struct expr *);
void newline(void)
{
register int dl = dumplevel;
print("\n");
@ -57,10 +72,9 @@ newline() {
print(" ");
}
int dumpidf();
dumpidftab(msg, opt)
char msg[];
void dumpidftab(char msg[], int opt)
{
/* Dumps the identifier table in readable form (but in
arbitrary order).
@ -76,7 +90,7 @@ dumpidftab(msg, opt)
print(">>> DUMPIDF, %s (end)\n", msg);
}
dumpstack()
static void dumpstack(void)
{
/* Dumps the identifier stack, starting at the top.
*/
@ -96,8 +110,7 @@ dumpstack()
print("\n");
}
dumpidf(idf, opt)
register struct idf *idf;
void dumpidf(register struct idf *idf, int opt)
{
/* All information about the identifier idf is divulged in a
hopefully readable format.
@ -136,8 +149,7 @@ dumpidf(idf, opt)
}
}
dumpdefs(def, opt)
register struct def *def;
void dumpdefs(register struct def *def, int opt)
{
dumplevel++;
while (def && ((opt&4) || def->df_level)) {
@ -158,8 +170,7 @@ dumpdefs(def, opt)
dumplevel--;
}
dumptags(tag)
register struct tag *tag;
void dumptags(register struct tag *tag)
{
dumplevel++;
while (tag) {
@ -186,9 +197,7 @@ dumptags(tag)
dumplevel--;
}
dumpsdefs(sdef, sdk)
register struct sdef *sdef;
enum sdef_kind sdk;
void dumpsdefs(register struct sdef *sdef, enum sdef_kind sdk)
{
/* Since sdef's are members of two chains, there are actually
two dumpsdefs's, one following the chain of all selectors
@ -218,8 +227,7 @@ dumpsdefs(sdef, sdk)
dumplevel--;
}
dumpproto(pl)
register struct proto *pl;
void dumpproto(register struct proto *pl)
{
register struct type *type;
register int argcnt = 0;
@ -234,7 +242,7 @@ dumpproto(pl)
: (pl->pl_flag & PL_ELLIPSIS
? "ellipsis" : "unknown" ));
newline();
if (type = pl->pl_type){
if ( (type = pl->pl_type) ){
dumptype(type);
newline();
}
@ -250,8 +258,7 @@ dumpproto(pl)
print("dump proto type list (end)\n");
}
dumptype(tp)
register struct type *tp;
void dumptype(register struct type *tp)
{
int ops = 1;
@ -308,9 +315,7 @@ dumptype(tp)
dumplevel--;
}
char *
type2str(tp)
register struct type *tp;
static char *type2str(register struct type *tp)
{
/* Yields a pointer to a one-line description of the type tp.
*/
@ -362,9 +367,7 @@ type2str(tp)
return buf;
}
char *
qual2str(qual)
int qual;
static char *qual2str(int qual)
{
char *buf = next_transient();
@ -381,8 +384,8 @@ qual2str(qual)
GSTATIC char trans_buf[MAXTRANS][300];
char * /* the ultimate transient buffer supplier */
next_transient()
static char * /* the ultimate transient buffer supplier */
next_transient(void)
{
static int bnum;
@ -391,9 +394,7 @@ next_transient()
return trans_buf[bnum];
}
print_expr(msg, expr)
char msg[];
struct expr *expr;
void print_expr(char msg[], struct expr *expr)
{
/* Provisional routine to print an expression preceded by a
message msg.
@ -405,8 +406,7 @@ print_expr(msg, expr)
}
}
p1_expr(lvl, expr)
register struct expr *expr;
static void p1_expr(int lvl, register struct expr *expr)
{
p1_indent(lvl);
if (!expr) {
@ -481,8 +481,7 @@ p1_expr(lvl, expr)
}
}
p1_indent(lvl)
register int lvl;
static void p1_indent(register int lvl)
{
while (lvl--)
print(" ");

View file

@ -284,8 +284,8 @@ void Info(void)
{
extern int cnt_string_cst, cnt_formal,
cnt_decl_unary, cnt_def, cnt_expr, cnt_field,
cnt_e_stack, cnt_localvar, cnt_proto, cnt_repl,
cnt_args, cnt_macro, cnt_stack_level,
cnt_e_stack, cnt_localvar, cnt_proto,
cnt_stack_level,
cnt_stack_entry, cnt_stmt_block, cnt_sdef, cnt_tag,
cnt_switch_hdr, cnt_case_entry, cnt_type, cnt_brace,
cnt_lint_stack_entry, cnt_state, cnt_auto_def,
@ -293,16 +293,16 @@ void Info(void)
print("\
%6d string_cst\n%6d formal\n\
%6d decl_unary\n%6d def\n%6d expr\n%6d field\n\
%6d e_stack\n%6d localvar\n%6d proto\n%6d repl\n\
%6d args\n%6d macro\n%6d stack_level\n\
%6d e_stack\n%6d localvar\n%6d proto\n\
%6d stack_level\n\
%6d stack_entry\n%6d stmt_block\n%6d sdef\n%6d tag\n\
%6d switch_hdr\n%6d case_entry\n%6d type\n%6d brace\n\
%6d lint_stack_entry\n%6d state\n%6d auto_def\n\
%6d expr_state\n%6d argument\n",
cnt_string_cst, cnt_formal,
cnt_decl_unary, cnt_def, cnt_expr, cnt_field,
cnt_e_stack, cnt_localvar, cnt_proto, cnt_repl,
cnt_args, cnt_macro, cnt_stack_level,
cnt_e_stack, cnt_localvar, cnt_proto,
cnt_stack_level,
cnt_stack_entry, cnt_stmt_block, cnt_sdef, cnt_tag,
cnt_switch_hdr, cnt_case_entry, cnt_type, cnt_brace,
cnt_lint_stack_entry, cnt_state, cnt_auto_def,

View file

@ -73,9 +73,6 @@ void add_sel( /* this is horrible */
given in sdefpp; the hook itself must still be empty.
*/
arith offset;
#ifndef NOBITFIELD
extern arith add_field();
#endif /* NOBITFIELD */
struct tag *tg = stp->tp_idf->id_tag; /* or union */
struct sdef *sdef = idf->id_sdef;

View file

@ -93,7 +93,7 @@ void hash_stat(void)
print("End hash table tally\n");
}
void idfappfun(int (*fun)(), int opt)
void idfappfun(int (*fun)(struct idf *, int), int opt)
{
register int i;

View file

@ -43,3 +43,7 @@ extern void init_idf(void);
struct idf *str2idf(char* tg, int cp);
#define findidf(tg) str2idf(tg, -1)
#ifdef IDF_DEBUG
void idfappfun(int (*fun)(struct idf *, int), int opt);
#endif

View file

@ -0,0 +1,57 @@
/* Copyright (c) 2019. See the file License in
* the root directory for more information.
*
* Contains path related utilities.
*/
#include <string.h>
void sys_basename(char *str, register char *dst)
{
register char *p1 = str;
register char *p2 = p1;
register char *end;
register char *start;
int len = strlen(str);
/* Point to the end of the string. */
p1 = p1 + len - 1;
end = p1;
while ((*p1 == '/') || (*p1 == '\\'))
{
if (p1 == str)
{
dst[0] = *p1;
dst[1] = '\0';
return;
}
p1--;
}
/* Only a volume specification */
if (*p1 == ':')
{
strcpy(dst,str);
return;
}
/* Do a reverse search. */
p2 = p1;
len = 0;
while (p2 != str)
{
if ((*p1 == '/') || (*p1 == '\\') || (*p1 == ':'))
{
strncpy(dst,p2,len);
dst[len] = '\0';
return;
}
p2 = p1;
len++;
p1--;
}
/* Only a pathname */
strcpy(dst,str);
}

View file

@ -2,7 +2,7 @@ clibrary {
name = "lib",
srcs = {
"./access.c", "./break.c", "./chmode.c", "./close.c",
"./create.c", "./filesize.c",
"./create.c", "./filesize.c","./basename.c","./tmpnam.c",
--"./lock.c",
"./modtime.c", "./open.c", "./read.c", "./remove.c",
"./rename.c", "./seek.c", "./stop.c", "./system.c",

View file

@ -67,4 +67,19 @@ time_t sys_modtime(char *);
/* return value for sys_break */
#define ILL_BREAK ((char *)0)
/* Extract the base name from a full path specification
* in "str" and returns it in "dst".
*
* "dst" should be large enough to receive the copied
* data.
*
* Supports both DOS and UNIX style paths.
* */
void sys_basename(const char *str, register char *dst);
/* Creates a temporary filename. This has
* the same semantics as ISO C90 tmpnam() */
char* sys_tmpnam(char *buffer);
#endif /* __SYSTEM_INCLUDED__ */

View file

@ -0,0 +1,16 @@
/* Copyright (c) 2019. See the file License in
* the root directory for more information.
*
* Created on: 2019-03-13
*
*/
#include <stdio.h>
/* This has been placed here, because on some famous platforms, this
* call is completely broken (e.g Windows up to recent versions of CRT)
*/
char* sys_tmpnam(char *buffer)
{
return tmpnam(buffer);
}

View file

@ -43,17 +43,7 @@ void UNLINK(string x)
#endif
}
void RENAME(string x,string y)
{
/* Must move the file "x" to the file "y" */
#ifdef USE_SYS
if(!sys_rename(x,y)) fatal(1,"Cannot rename to %s",y);
#else
if (rename(x, y) == -1)
fatal(1, "Cannot rename to %s", y);
#endif
}
string libpath(string s)
{

View file

@ -353,6 +353,28 @@ void copyfile(string file)
fclose(f);
}
void copyto(string target, string source)
{
FILE *fsource;
FILE *ftarget;
int c;
ftarget = fopen(target,"wb+");
if (ftarget == NULL)
{
fatal(0, "Cannot open file %s, call an expert", target);
}
fsource = fopen(source,"rb");
if (fsource == NULL)
{
fatal(0, "Cannot open file %s, call an expert", source);
}
while ((c = getc(fsource)) != EOF)
putc(c, ftarget);
fclose(fsource);
fclose(ftarget);
}
void install(string target, string source)
{
/*
@ -377,7 +399,7 @@ void install(string target, string source)
if ((f2 = fopen(target, "r")) == NULL)
{
fclose(f1);
RENAME(f_pars, target);
copyto(target, f_pars);
return;
}
/*
@ -406,6 +428,6 @@ void install(string target, string source)
{
fatal(0, "%s : not a file generated by LLgen", target);
}
RENAME(f_pars, target);
copyto(target, f_pars);
}
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -4,12 +4,11 @@
*
*/
#include <string.h>
#include <stddef.h>
#include "ass00.h"
#include "assex.h"
#ifndef NORCSID
static char rcs_id[] = "$Id$" ;
#endif
#include "asscm.h"
/*
** utilities of EM1-assembler/loader
@ -17,15 +16,16 @@ static char rcs_id[] = "$Id$" ;
static int globstep;
/*
* glohash returns an index in table and leaves a stepsize in globstep
*
*/
static int glohash(aname,size) char *aname; {
static int glohash(char *aname ,int size)
{
register char *p;
register i;
register sum;
register int i;
register int sum;
/*
* Computes a hash-value from a string.
@ -44,17 +44,19 @@ static int glohash(aname,size) char *aname; {
* return index in labeltable
*/
glob_t *glo2lookup(name,status) char *name; {
glob_t *glo2lookup(char *name ,int status)
{
return(glolookup(name,status,mglobs,oursize->n_mlab));
}
glob_t *xglolookup(name,status) char *name; {
glob_t *xglolookup(char *name,int status)
{
return(glolookup(name,status,xglobs,oursize->n_glab));
}
static void findext(g) glob_t *g ; {
static void findext(glob_t *g)
{
glob_t *x;
x = xglolookup(g->g_name,ENTERING);
@ -65,33 +67,30 @@ static void findext(g) glob_t *g ; {
g->g_status |= EXT;
}
glob_t *glolookup(name,status,table,size)
char *name; /* name */
int status; /* kind of lookup */
glob_t *table; /* which table to use */
int size; /* size for hash */
/*
* lookup global symbol name in specified table.
* Various actions are taken depending on status
* parameter.
*
* 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 rem,j;
register int rem,j;
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);
j = 0; new=0;
@ -150,9 +149,18 @@ int size; /* size for hash */
return(g);
}
locl_t *loclookup(an,status) {
/*
* lookup local label by number and return the
* label definition if found.
*
* DEFINING:
* Lookup or enter the symbol, check for mult. def.
*
*/
locl_t *loclookup(unsigned int an,int status)
{
register locl_t *lbp,*l_lbp;
register unsigned num;
register unsigned int num;
char hinum;
if ( !pstate.s_locl ) fatal("label outside procedure");
@ -188,26 +196,27 @@ locl_t *loclookup(an,status) {
return(lbp);
}
proc_t *prolookup(name,status) char *name; {
register proc_t *p;
register pstat;
/*
* Look up a procedure name according to status
*
* PRO_OCC: Occurrence
* 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) {
case PRO_OCC:
@ -281,18 +290,15 @@ proc_t *prolookup(name,status) char *name; {
return(enterproc(name,pstat,p));
}
proc_t *searchproc(name,table,size)
char *name;
proc_t *table;
int size;
/*
* return a pointer into table to the place where the procedure
* name is or should be if in the table.
*/
proc_t *searchproc(char *name,proc_t *table,int size)
{
register proc_t *p;
register 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);
j = 0;
@ -307,25 +313,22 @@ proc_t *searchproc(name,table,size)
return(p);
}
proc_t *enterproc(name,status,place)
char *name;
char status;
proc_t *place; {
/*
* 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.
*/
proc_t *enterproc(char *name,int status,proc_t *place)
{
register proc_t *p;
/*
* Enter the procedure name into the table at place place.
* Place had better be computed by searchproc().
*
* 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->p_name = (char *) getarea((unsigned) (strlen(name) + 1));
strcpy(p->p_name,name);

View file

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

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

22
util/ass/asscm.h Normal file
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 "assex.h"
#ifndef NORCSID
static char rcs_id[] = "$Id$" ;
static char rcs_ass[]= RCS_ASS ;
static char rcs_ex[] = RCS_EX ;
#endif
/*
* global data

View file

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

View file

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

21
util/ass/assrl.h Normal file
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/data+lib",
--"modules/src/object+lib",
--"modules/src/system+lib",
"modules/src/system+lib",
"./ass*.h",
}
}

View file

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

View file

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

View file

@ -1,12 +1,19 @@
/* $Id$ */
/** @file
* Memory allocation routines that will cause
* fatal error if allocation fails.
*/
#include <stdlib.h>
#include "debug.h"
#include "global.h"
#include "alloc.h"
#include "io.h"
char *Malloc(sz, descr)
size sz;
char *descr;
/** Allocate "sz" bytes on the heap with description
* "descr", raise a fatal error if it cannot be
* allocated. Returns a pointer to the newly allocated
* block.
*/
char *Malloc(size sz, char *descr)
{
register char *new = malloc((unsigned int) (sz));
@ -31,10 +38,12 @@ char *Malloc(sz, descr)
return new;
}
char *Realloc(old, sz, descr)
char *old;
size sz;
char *descr;
/** Reallocates an "old" memory block with new size
* "sz" in bytes. Raise a fatal error if the block
* cannot be reallocated.
*
*/
char *Realloc(char *old, size sz, char *descr)
{
register char *new = realloc(old, (unsigned int) (sz));

View file

@ -3,12 +3,17 @@
afterwards, we use a version that will either succeed or call
fatal().
*/
#ifndef ALLOC_H_
#define ALLOC_H_
/* $Id$ */
#include "global.h"
char *Malloc(size sz, char *descr);
char *Realloc(char *old, size sz, char *descr);
extern char *Realloc(), *Malloc();
/* reallocation factor */
#define allocfrac(s) ((s) * 3 / 2)
#endif /* ALLOC_H_ */

View file

@ -1,17 +1,16 @@
/*
/** @file
Core dumping routines
*/
/* $Id$ */
#include "logging.h"
#include "global.h"
#include "warn.h"
#include "shadow.h"
#include "fra.h"
#include <stdio.h>
core_dump()
void core_dump(void)
{
FILE *core_file;

View file

@ -1,10 +1,10 @@
/*
Data access
/** @file
Data access routines
*/
/* $Id$ */
#include <em_abs.h>
#include "em_abs.h"
#include "logging.h"
#include "nofloat.h"
#include "global.h"
@ -16,18 +16,20 @@
#include "mem.h"
#include "shadow.h"
#define HEAPSIZE 1000L /* initial heap size */
/** Initial heap size in bytes. */
#define HEAPSIZE 1000L
extern size maxheap; /* from main.c */
#ifdef LOGGING
char *data_sh; /* shadowbytes */
PRIVATE void warn_dtbits(ptr, size);
PRIVATE void dt_clear_area(ptr, ptr );
#endif /* LOGGING */
PRIVATE warn_dtbits();
init_data(hb)
ptr hb;
/** Initialize the heap with "hb" address. */
void init_data(ptr hb)
{
HB = hb; /* set Heap Base */
HP = HB; /* initialize Heap Pointer */
@ -49,8 +51,8 @@ init_data(hb)
* *
********************************************************/
newHP(ap)
ptr ap;
/** Grows the heap space with the new heap pointer. */
void newHP(ptr ap)
{
register ptr p = ap;
@ -99,9 +101,8 @@ newHP(ap)
* *
************************************************************************/
dt_stdp(addr, ap)
register ptr addr;
ptr ap;
/** Store data pointer "ap" at address "addr". */
void dt_stdp(register ptr addr, ptr ap)
{
register int i;
register long p = (long) ap;
@ -117,9 +118,7 @@ dt_stdp(addr, ap)
}
}
dt_stip(addr, ap)
register ptr addr;
ptr ap;
void dt_stip(register ptr addr, ptr ap)
{
register int i;
register long p = (long) ap;
@ -135,10 +134,8 @@ dt_stip(addr, ap)
}
}
dt_stn(addr, al, n)
register ptr addr;
long al;
size n;
/** Store "n" byte integer "al" at address "addr". */
void dt_stn(register ptr addr, long al, size n)
{
register int i;
register long l = al;
@ -160,9 +157,8 @@ dt_stn(addr, al, n)
}
}
dt_stw(addr, al)
register ptr addr;
long al;
/** Store word sized integer "al" at address. */
void dt_stw(register ptr addr, long al)
{
register int i;
register long l = al;
@ -185,10 +181,8 @@ dt_stw(addr, al)
}
#ifndef NOFLOAT
dt_stf(addr, f, n)
register ptr addr;
double f;
register size n;
/** Store a real value "f" or size "n" bytes at address "addr". */
void dt_stf(register ptr addr, double f, register size n)
{
register char *cp = (char *) &f;
register int i;
@ -222,8 +216,8 @@ dt_stf(addr, f, n)
* *
************************************************************************/
ptr dt_lddp(addr)
register ptr addr;
/** Load a data segment pointer located at address "addr". */
ptr dt_lddp(register ptr addr)
{
register ptr p;
@ -243,8 +237,7 @@ ptr dt_lddp(addr)
return (p);
}
ptr dt_ldip(addr)
register ptr addr;
ptr dt_ldip(register ptr addr)
{
register ptr p;
@ -264,9 +257,8 @@ ptr dt_ldip(addr)
return (p);
}
unsigned long dt_ldu(addr, n)
register ptr addr;
size n;
/** Load an unsigned integer of "n" bytes from address "addr". */
unsigned long dt_ldu(register ptr addr, size n)
{
register int i;
register unsigned long u = 0;
@ -290,8 +282,8 @@ unsigned long dt_ldu(addr, n)
return (u);
}
unsigned long dt_lduw(addr)
register ptr addr;
/** Load an unsigned integer of word size from address "addr". */
unsigned long dt_lduw(register ptr addr)
{
register int i;
register unsigned long u = 0;
@ -315,9 +307,8 @@ unsigned long dt_lduw(addr)
return (u);
}
long dt_lds(addr, n)
register ptr addr;
size n;
/** Load an integer of size "n" bytes from address "addr". */
long dt_lds(register ptr addr, size n)
{
register int i;
register long l;
@ -342,8 +333,8 @@ long dt_lds(addr, n)
return (l);
}
long dt_ldsw(addr)
register ptr addr;
/** Load a word size integer from address "addr". */
long dt_ldsw(register ptr addr)
{
register int i;
register long l;
@ -379,9 +370,8 @@ long dt_ldsw(addr)
* *
************************************************************************/
dt_mvd(d2, d1, n) /* d1 -> d2 */
register ptr d2, d1;
size n;
/** Move "n" bytes from "d1" to "d2". */
void dt_mvd(ptr d2, ptr d1, size n)
{
register int i;
@ -399,9 +389,8 @@ dt_mvd(d2, d1, n) /* d1 -> d2 */
}
}
dt_mvs(d, s, n) /* s -> d */
register ptr d, s;
size n;
/** Move "n" bytes from stack address "s" to data address "d". */
void dt_mvs(ptr d, ptr s, size n) /* s -> d */
{
register int i;
@ -422,9 +411,7 @@ dt_mvs(d, s, n) /* s -> d */
#ifdef LOGGING
PRIVATE warn_dtbits(addr, n)
register ptr addr;
register size n;
PRIVATE void warn_dtbits(ptr addr, size n)
{
register int or_bits = 0;
register int and_bits = 0xff;
@ -452,5 +439,15 @@ PRIVATE warn_dtbits(addr, n)
warningcont(WWASINSP);
}
void dt_clear_area(ptr from, ptr to)
{
/* includes *from but excludes *to */
register ptr a;
for (a = from; a < to; a++) {
dt_undef(a);
}
}
#endif /* LOGGING */

30
util/int/data.h Normal file
View file

@ -0,0 +1,30 @@
/* Copyright (c) 2019 ACK Project.
* See the copyright notice in the ACK home directory,
* in the file "Copyright".
*
*/
#ifndef DATA_H_
#define DATA_H_
#include "global.h"
void init_data(ptr hb);
void newHP(ptr ap);
void dt_stdp(register ptr addr, ptr ap);
void dt_stn(register ptr addr, long al, size n);
void dt_stw(register ptr addr, long al);
void dt_stip(register ptr addr, ptr ap);
#ifndef NOFLOAT
void dt_stf(register ptr addr, double f, register size n);
#endif
ptr dt_lddp(register ptr addr);
unsigned long dt_ldu(register ptr addr, size n);
unsigned long dt_lduw(register ptr addr);
long dt_lds(register ptr addr, size n);
long dt_ldsw(register ptr addr);
void dt_mvd(ptr d2, ptr d1, size n);
void dt_mvs(ptr d, ptr s, size n);
#endif /* DATA_H_ */

File diff suppressed because it is too large Load diff

View file

@ -1,10 +1,10 @@
/*
* Sources of the "ARRAY" group instructions
/** @file
* Sources of the "ARRAY" group instructions
*/
/* $Id$ */
#include <em_abs.h>
#include "em_abs.h"
#include "global.h"
#include "log.h"
#include "trap.h"
@ -16,26 +16,24 @@
#define SAR 2
#define AAR 3
PRIVATE arr();
PRIVATE void arr(int, size);
DoLAR(arg)
size arg;
void DoLAR(size arg)
{
/* LAR w: Load array element, descriptor contains integers of size w */
LOG(("@A6 DoLAR(%ld)", arg));
arr(LAR, arg_wi(arg));
}
DoSAR(arg)
size arg;
void DoSAR(size arg)
{
/* SAR w: Store array element */
LOG(("@A6 DoSAR(%ld)", arg));
arr(SAR, arg_wi(arg));
}
DoAAR(arg)
size arg;
void DoAAR(size arg)
{
/* AAR w: Load address of array element */
LOG(("@A6 DoAAR(%ld)", arg));
@ -54,9 +52,9 @@ DoAAR(arg)
* 6. Perform the correct function. *
*********************************************************/
PRIVATE arr(type, elm_size)
int type; /* operation TYPE */
size elm_size; /* ELeMent SIZE */
PRIVATE void arr(int type, /* operation TYPE */
size elm_size /* ELeMent SIZE */
)
{
register ptr desc = dppop(); /* array DESCriptor */
register size obj_size; /* OBJect SIZE */

View file

@ -1,10 +1,10 @@
/*
/** @file
* Sources of the "BRANCH" group instructions
*/
/* $Id$ */
#include <em_abs.h>
#include "em_abs.h"
#include "global.h"
#include "log.h"
#include "mem.h"
@ -21,8 +21,7 @@
#define do_jump(j) { newPC(PC + (j)); }
DoBRA(jump)
register long jump;
void DoBRA(register long jump)
{
/* BRA b: Branch unconditionally to label b */
@ -30,8 +29,7 @@ DoBRA(jump)
do_jump(arg_c(jump));
}
DoBLT(jump)
register long jump;
void DoBLT(register long jump)
{
/* BLT b: Branch less (pop 2 words, branch if top > second) */
register long t = wpop();
@ -42,8 +40,7 @@ DoBLT(jump)
do_jump(arg_c(jump));
}
DoBLE(jump)
register long jump;
void DoBLE(register long jump)
{
/* BLE b: Branch less or equal */
register long t = wpop();
@ -54,8 +51,7 @@ DoBLE(jump)
do_jump(arg_c(jump));
}
DoBEQ(jump)
register long jump;
void DoBEQ(register long jump)
{
/* BEQ b: Branch equal */
register long t = wpop();
@ -66,8 +62,7 @@ DoBEQ(jump)
do_jump(arg_c(jump));
}
DoBNE(jump)
register long jump;
void DoBNE(register long jump)
{
/* BNE b: Branch not equal */
register long t = wpop();
@ -78,8 +73,7 @@ DoBNE(jump)
do_jump(arg_c(jump));
}
DoBGE(jump)
register long jump;
void DoBGE(register long jump)
{
/* BGE b: Branch greater or equal */
register long t = wpop();
@ -90,8 +84,7 @@ DoBGE(jump)
do_jump(arg_c(jump));
}
DoBGT(jump)
register long jump;
void DoBGT(register long jump)
{
/* BGT b: Branch greater */
register long t = wpop();
@ -102,8 +95,7 @@ DoBGT(jump)
do_jump(arg_c(jump));
}
DoZLT(jump)
register long jump;
void DoZLT(register long jump)
{
/* ZLT b: Branch less than zero (pop 1 word, branch negative) */
@ -113,8 +105,7 @@ DoZLT(jump)
do_jump(arg_c(jump));
}
DoZLE(jump)
register long jump;
void DoZLE(register long jump)
{
/* ZLE b: Branch less or equal to zero */
@ -124,8 +115,7 @@ DoZLE(jump)
do_jump(arg_c(jump));
}
DoZEQ(jump)
register long jump;
void DoZEQ(register long jump)
{
/* ZEQ b: Branch equal zero */
@ -135,8 +125,7 @@ DoZEQ(jump)
do_jump(arg_c(jump));
}
DoZNE(jump)
register long jump;
void DoZNE(register long jump)
{
/* ZNE b: Branch not zero */
@ -146,8 +135,7 @@ DoZNE(jump)
do_jump(arg_c(jump));
}
DoZGE(jump)
register long jump;
void DoZGE(register long jump)
{
/* ZGE b: Branch greater or equal zero */
@ -157,8 +145,7 @@ DoZGE(jump)
do_jump(arg_c(jump));
}
DoZGT(jump)
register long jump;
void DoZGT(register long jump)
{
/* ZGT b: Branch greater than zero */

View file

@ -1,10 +1,10 @@
/*
* Sources of the "COMPARE" group instructions
/** @file
* Sources of the "COMPARE" group instructions
*/
/* $Id$ */
#include <em_abs.h>
#include "em_abs.h"
#include "logging.h"
#include "nofloat.h"
#include "global.h"
@ -15,15 +15,12 @@
#include "trap.h"
#include "text.h"
#include "fra.h"
#include "stack.h"
#ifndef NOFLOAT
extern double fpop();
#endif /* NOFLOAT */
PRIVATE compare_obj();
PRIVATE void compare_obj(size);
DoCMI(l)
register size l;
void DoCMI(register size l)
{
/* CMI w: Compare w byte integers, Push negative, zero, positive for <, = or > */
register long t = spop(arg_wi(l));
@ -34,8 +31,7 @@ DoCMI(l)
wpush((long)(t < s ? 1 : t > s ? -1 : 0));
}
DoCMF(l)
register size l;
void DoCMF(register size l)
{
/* CMF w: Compare w byte reals */
#ifndef NOFLOAT
@ -50,8 +46,7 @@ DoCMF(l)
#endif /* NOFLOAT */
}
DoCMU(l)
register size l;
void DoCMU(register size l)
{
/* CMU w: Compare w byte unsigneds */
register unsigned long t = upop(arg_wi(l));
@ -62,8 +57,7 @@ DoCMU(l)
wpush((long)(t < s ? 1 : t > s ? -1 : 0));
}
DoCMS(l)
register size l;
void DoCMS(register size l)
{
/* CMS w: Compare w byte values, can only be used for bit for bit equality test */
@ -72,7 +66,7 @@ DoCMS(l)
compare_obj(arg_w(l));
}
DoCMP()
void DoCMP(void)
{
/* CMP -: Compare pointers */
register ptr t, s;
@ -84,7 +78,7 @@ DoCMP()
wpush((long)(t < s ? 1 : t > s ? -1 : 0));
}
DoTLT()
void DoTLT(void)
{
/* TLT -: True if less, i.e. iff top of stack < 0 */
LOG(("@T6 DoTLT()"));
@ -92,7 +86,7 @@ DoTLT()
wpush((long)(wpop() < 0 ? 1 : 0));
}
DoTLE()
void DoTLE(void)
{
/* TLE -: True if less or equal, i.e. iff top of stack <= 0 */
LOG(("@T6 DoTLE()"));
@ -100,7 +94,7 @@ DoTLE()
wpush((long)(wpop() <= 0 ? 1 : 0));
}
DoTEQ()
void DoTEQ(void)
{
/* TEQ -: True if equal, i.e. iff top of stack = 0 */
LOG(("@T6 DoTEQ()"));
@ -108,7 +102,7 @@ DoTEQ()
wpush((long)(wpop() == 0 ? 1 : 0));
}
DoTNE()
void DoTNE(void)
{
/* TNE -: True if not equal, i.e. iff top of stack non zero */
LOG(("@T6 DoTNE()"));
@ -116,7 +110,7 @@ DoTNE()
wpush((long)(wpop() != 0 ? 1 : 0));
}
DoTGE()
void DoTGE(void)
{
/* TGE -: True if greater or equal, i.e. iff top of stack >= 0 */
LOG(("@T6 DoTGE()"));
@ -124,7 +118,7 @@ DoTGE()
wpush((long)(wpop() >= 0 ? 1 : 0));
}
DoTGT()
void DoTGT(void)
{
/* TGT -: True if greater, i.e. iff top of stack > 0 */
LOG(("@T6 DoTGT()"));
@ -133,17 +127,15 @@ DoTGT()
}
/********************************************************
* Compare objects *
* *
* Two 'obj_size' sized objects are bytewise *
* compared; as soon as one byte is different *
* 1 is returned, otherwise 0. No type checking *
* is performed. Checking for undefined bytes *
* is done when LOGGING is defined. *
* Compare objects.
*
* Two 'obj_size' sized objects are bytewise
* compared; as soon as one byte is different
* 1 is returned, otherwise 0. No type checking
* is performed. Checking for undefined bytes
* is done when LOGGING is defined.
********************************************************/
PRIVATE compare_obj(obj_size)
size obj_size;
PRIVATE void compare_obj(size obj_size)
{
register ptr addr1; /* ADDRess in object highest on st. */
register ptr addr2; /* ADDRess in object deeper in st. */

View file

@ -1,10 +1,10 @@
/*
/** @file
* Sources of the "CONVERT" group instructions
*/
/* $Id$ */
#include <em_abs.h>
#include "em_abs.h"
#include "nofloat.h"
#include "global.h"
#include "log.h"
@ -13,12 +13,9 @@
#include "text.h"
#include "fra.h"
#include "warn.h"
#include "stack.h"
#ifndef NOFLOAT
extern double fpop();
#endif /* NOFLOAT */
DoCII()
void DoCII(void)
{
/* CII -: Convert integer to integer (*) */
register int newsize = swpop();
@ -62,7 +59,7 @@ DoCII()
}
}
DoCUI()
void DoCUI(void)
{
/* CUI -: Convert unsigned to integer (*) */
register int newsize = swpop();
@ -112,7 +109,7 @@ DoCUI()
}
}
DoCFI()
void DoCFI(void)
{
/* CFI -: Convert floating to integer (*) */
#ifndef NOFLOAT
@ -168,7 +165,7 @@ DoCFI()
#endif /* NOFLOAT */
}
DoCIF()
void DoCIF(void)
{
/* CIF -: Convert integer to floating (*) */
#ifndef NOFLOAT
@ -203,7 +200,7 @@ DoCIF()
#endif /* NOFLOAT */
}
DoCUF()
void DoCUF(void)
{
/* CUF -: Convert unsigned to floating (*) */
#ifndef NOFLOAT
@ -249,7 +246,7 @@ DoCUF()
#endif /* NOFLOAT */
}
DoCFF()
void DoCFF(void)
{
/* CFF -: Convert floating to floating (*) */
#ifndef NOFLOAT
@ -276,7 +273,7 @@ DoCFF()
#endif /* NOFLOAT */
}
DoCIU()
void DoCIU(void)
{
/* CIU -: Convert integer to unsigned */
register int newsize = swpop();
@ -310,7 +307,7 @@ DoCIU()
}
}
DoCUU()
void DoCUU(void)
{
/* CUU -: Convert unsigned to unsigned */
register int newsize = swpop();
@ -342,7 +339,7 @@ DoCUU()
}
}
DoCFU()
void DoCFU(void)
{
/* CFU -: Convert floating to unsigned */
#ifndef NOFLOAT

View file

@ -1,10 +1,10 @@
/*
* Sources of the "FLOATING POINT ARITHMETIC" group instructions
/** @file
* Sources of the "FLOATING POINT ARITHMETIC" group instructions
*/
/* $Id$ */
#include <em_abs.h>
#include "em_abs.h"
#include "nofloat.h"
#include "global.h"
#include "log.h"
@ -12,6 +12,7 @@
#include "trap.h"
#include "text.h"
#include "fra.h"
#include "io.h"
#include "warn.h"
#ifndef NOFLOAT
@ -30,15 +31,14 @@ extern double fpop();
#endif /* not __STDC__ */
#define SMALL (1.0/MAXDOUBLE)
PRIVATE double adf(), sbf(), mlf(), dvf();
PRIVATE double ttttp();
PRIVATE double floor(), fabs();
PRIVATE fef(), fif();
PRIVATE double adf(double, double), sbf(double, double), mlf(double, double), dvf(double, double);
PRIVATE double ttttp(double, int);
PRIVATE double floor(double), fabs(double);
PRIVATE void fef(double, size), fif(double, double, size);
#endif /* NOFLOAT */
DoADF(l)
register size l;
void DoADF(register size l)
{
/* ADF w: Floating add (*) */
#ifndef NOFLOAT
@ -52,8 +52,7 @@ DoADF(l)
#endif /* NOFLOAT */
}
DoSBF(l)
register size l;
void DoSBF(register size l)
{
/* SBF w: Floating subtract (*) */
#ifndef NOFLOAT
@ -67,8 +66,7 @@ DoSBF(l)
#endif /* NOFLOAT */
}
DoMLF(l)
register size l;
void DoMLF(register size l)
{
/* MLF w: Floating multiply (*) */
#ifndef NOFLOAT
@ -82,8 +80,7 @@ DoMLF(l)
#endif /* NOFLOAT */
}
DoDVF(l)
register size l;
void DoDVF(register size l)
{
/* DVF w: Floating divide (*) */
#ifndef NOFLOAT
@ -97,10 +94,9 @@ DoDVF(l)
#endif /* NOFLOAT */
}
DoNGF(l)
register size l;
void DoNGF(register size l)
{
/* NGF w: Floating negate (*) */
/** NGF w: Floating negate (*) */
#ifndef NOFLOAT
double t = fpop(arg_wf(l));
@ -112,8 +108,7 @@ DoNGF(l)
#endif /* NOFLOAT */
}
DoFIF(l)
register size l;
void DoFIF(register size l)
{
/* FIF w: Floating multiply and split integer and fraction part (*) */
#ifndef NOFLOAT
@ -127,8 +122,7 @@ DoFIF(l)
#endif /* NOFLOAT */
}
DoFEF(l)
register size l;
void DoFEF(register size l)
{
/* FEF w: Split floating number in exponent and fraction part (*) */
#ifndef NOFLOAT
@ -144,8 +138,8 @@ DoFEF(l)
/* Service routines */
PRIVATE double adf(f1, f2) /* returns f1 + f2 */
double f1, f2;
/** Returns "f1" + "f2" */
PRIVATE double adf(double f1, double f2)
{
if (must_test && !(IgnMask&BIT(EFOVFL))) {
if (f1 > 0.0 && f2 > 0.0) {
@ -164,8 +158,8 @@ PRIVATE double adf(f1, f2) /* returns f1 + f2 */
return (f1 + f2);
}
PRIVATE double sbf(f1, f2) /* returns f1 - f2 */
double f1, f2;
/** Returns "f1" - "f2" */
PRIVATE double sbf(double f1, double f2)
{
if (must_test && !(IgnMask&BIT(EFOVFL))) {
if (f2 < 0.0 && f1 > 0.0) {
@ -184,8 +178,8 @@ PRIVATE double sbf(f1, f2) /* returns f1 - f2 */
return (f1 - f2);
}
PRIVATE double mlf(f1, f2) /* returns f1 * f2 */
double f1, f2;
/** Returns "f1" * "f2" */
PRIVATE double mlf(double f1, double f2)
{
double ff1 = fabs(f1), ff2 = fabs(f2);
@ -214,8 +208,8 @@ PRIVATE double mlf(f1, f2) /* returns f1 * f2 */
return (f1 * f2);
}
PRIVATE double dvf(f1, f2) /* returns f1 / f2 */
double f1, f2;
/** Returns "f1" / "f2" */
PRIVATE double dvf(double f1, double f2)
{
double ff1 = fabs(f1), ff2 = fabs(f2);
@ -251,9 +245,7 @@ PRIVATE double dvf(f1, f2) /* returns f1 / f2 */
return (f1 / f2);
}
PRIVATE fif(f1, f2, n)
double f1, f2;
size n;
PRIVATE void fif(double f1, double f2, size n)
{
double f = mlf(f1, f2);
double fl = floor(fabs(f));
@ -262,9 +254,7 @@ PRIVATE fif(f1, f2, n)
fpush((f < 0.0) ? -fl : fl, n); /* push integer-part */
}
PRIVATE fef(f, n)
double f;
size n;
PRIVATE void fef(double f, size n)
{
register long exponent, sign = (long) (f < 0.0);
@ -286,14 +276,12 @@ PRIVATE fef(f, n)
/* floating point service routines, to avoid having to use -lm */
PRIVATE double fabs(f)
double f;
PRIVATE double fabs(double f)
{
return (f < 0.0 ? -f : f);
}
PRIVATE double floor(f)
double f;
PRIVATE double floor(double f)
{
double res, d;
register int sign = 1;
@ -327,8 +315,8 @@ PRIVATE double floor(f)
return res;
}
PRIVATE double ttttp(f, n) /* times ten to the power */
double f;
/** Times ten to the power. */
PRIVATE double ttttp(double f, int n)
{
while (n > 0) {
f = mlf(f, 10.0);
@ -341,13 +329,11 @@ PRIVATE double ttttp(f, n) /* times ten to the power */
return f;
}
/* Str2double is used to initialize the global data area with floats;
/** Str2double is used to initialize the global data area with floats;
we do not use, e.g., sscanf(), to be able to check the grammar of
the string and to give warnings.
*/
double str2double(str)
char *str;
double str2double(char *str)
{
register char b;
register int sign = 1; /* either +1 or -1 */
@ -451,7 +437,8 @@ BadFloat:
#else /* NOFLOAT */
nofloat() {
void nofloat(void)
{
fatal("attempt to execute a floating point instruction on an EM machine without FP");
}

View file

@ -1,33 +1,34 @@
/*
* Sources of the "INCREMENT/DECREMENT/ZERO" group instructions
/** @file
* Sources of the "INCREMENT/DECREMENT/ZERO" group instructions
*/
/* $Id$ */
#include <em_abs.h>
#include "em_abs.h"
#include "global.h"
#include "log.h"
#include "nofloat.h"
#include "trap.h"
#include "mem.h"
#include "data.h"
#include "text.h"
#include "stack.h"
#include "fra.h"
#include "warn.h"
PRIVATE long inc(), dec();
PRIVATE long inc(long), dec(long);
DoINC()
/** INC -: Increment word on top of stack by 1 (*) */
void DoINC(void)
{
/* INC -: Increment word on top of stack by 1 (*) */
LOG(("@Z6 DoINC()"));
spoilFRA();
wpush(inc(swpop()));
}
DoINL(l)
register long l;
/** INL l: Increment local or parameter (*) */
void DoINL(register long l)
{
/* INL l: Increment local or parameter (*) */
register ptr p;
LOG(("@Z6 DoINL(%ld)", l));
@ -36,10 +37,10 @@ DoINL(l)
st_stw(p, inc(st_ldsw(p)));
}
DoINE(arg)
register long arg;
/** INE g: Increment external (*) */
void DoINE(register long arg)
{
/* INE g: Increment external (*) */
register ptr p = i2p(arg);
LOG(("@Z6 DoINE(%lu)", p));
@ -48,18 +49,19 @@ DoINE(arg)
dt_stw(p, inc(dt_ldsw(p)));
}
DoDEC()
/** DEC -: Decrement word on top of stack by 1 (*) */
void DoDEC(void)
{
/* DEC -: Decrement word on top of stack by 1 (*) */
LOG(("@Z6 DoDEC()"));
spoilFRA();
wpush(dec(swpop()));
}
DoDEL(l)
register long l;
/** DEL l: Decrement local or parameter (*) */
void DoDEL(register long l)
{
/* DEL l: Decrement local or parameter (*) */
register ptr p;
LOG(("@Z6 DoDEL(%ld)", l));
@ -69,10 +71,10 @@ DoDEL(l)
st_stw(p, dec(st_ldsw(p)));
}
DoDEE(arg)
register long arg;
/** DEE g: Decrement external (*) */
void DoDEE(register long arg)
{
/* DEE g: Decrement external (*) */
register ptr p = i2p(arg);
LOG(("@Z6 DoDEE(%lu)", p));
@ -81,10 +83,10 @@ DoDEE(arg)
dt_stw(p, dec(dt_ldsw(p)));
}
DoZRL(l)
register long l;
/** ZRL l: Zero local or parameter */
void DoZRL(register long l)
{
/* ZRL l: Zero local or parameter */
LOG(("@Z6 DoZRL(%ld)", l));
spoilFRA();
@ -92,10 +94,10 @@ DoZRL(l)
st_stw(loc_addr(l), 0L);
}
DoZRE(arg)
register long arg;
/** ZRE g: Zero external */
void DoZRE(register long arg)
{
/* ZRE g: Zero external */
register ptr p = i2p(arg);
LOG(("@Z6 DoZRE(%lu)", p));
@ -103,10 +105,10 @@ DoZRE(arg)
dt_stw(arg_g(p), 0L);
}
DoZRF(l)
register size l;
/** ZRF w: Load a floating zero of size w */
void DoZRF(register size l)
{
/* ZRF w: Load a floating zero of size w */
#ifndef NOFLOAT
LOG(("@Z6 DoZRF(%ld)", l));
spoilFRA();
@ -116,13 +118,9 @@ DoZRF(l)
nofloat();
#endif /* NOFLOAT */
}
DoZER(l)
register size l;
/** ZER w: Load w zero bytes */
void DoZER(register size l)
{
/* ZER w: Load w zero bytes */
register size i;
LOG(("@Z6 DoZER(%ld)", l));
spoilFRA();
npush(0L, arg_w(l));
@ -133,8 +131,7 @@ DoZER(l)
*/
}
PRIVATE long inc(l)
long l;
PRIVATE long inc(long l)
{
if (must_test && !(IgnMask&BIT(EIOVFL))) {
if (l == i_maxsw)
@ -143,8 +140,7 @@ PRIVATE long inc(l)
return (l + 1);
}
PRIVATE long dec(l)
long l;
PRIVATE long dec(long l)
{
if (must_test && !(IgnMask&BIT(EIOVFL))) {
if (l == i_minsw)

View file

@ -1,10 +1,10 @@
/*
* Sources of the "INTEGER ARITHMETIC" group instructions
/** @file
* Sources of the "INTEGER ARITHMETIC" group instructions
*/
/* $Id$ */
#include <em_abs.h>
#include "em_abs.h"
#include "logging.h"
#include "global.h"
#include "log.h"
@ -14,12 +14,13 @@
#include "text.h"
#include "fra.h"
PRIVATE long adi(), sbi(), dvi(), mli(), rmi(), ngi(), sli(), sri();
PRIVATE long adi(long, long, size), sbi(long, long, size), dvi(long, long);
PRIVATE long mli(long, long, size), rmi(long, long), ngi(long, size);
PRIVATE long sli(long, long, size), sri(long, long, size);
DoADI(l)
register size l;
/** ADI w: Addition (*) */
void DoADI(register size l)
{
/* ADI w: Addition (*) */
register long t = spop(arg_wi(l));
LOG(("@I6 DoADI(%ld)", l));
@ -27,10 +28,9 @@ DoADI(l)
npush(adi(spop(l), t, l), l);
}
DoSBI(l)
register size l;
/** SBI w: Subtraction (*) */
void DoSBI(register size l)
{
/* SBI w: Subtraction (*) */
register long t = spop(arg_wi(l));
LOG(("@I6 DoSBI(%ld)", l));
@ -38,10 +38,9 @@ DoSBI(l)
npush(sbi(spop(l), t, l), l);
}
DoMLI(l)
register size l;
/** MLI w: Multiplication (*) */
void DoMLI(register size l)
{
/* MLI w: Multiplication (*) */
register long t = spop(arg_wi(l));
LOG(("@I6 DoMLI(%ld)", l));
@ -49,10 +48,9 @@ DoMLI(l)
npush(mli(spop(l), t, l), l);
}
DoDVI(l)
register size l;
/** DVI w: Division (*) */
void DoDVI(register size l)
{
/* DVI w: Division (*) */
register long t = spop(arg_wi(l));
LOG(("@I6 DoDVI(%ld)", l));
@ -60,10 +58,9 @@ DoDVI(l)
npush(dvi(spop(l), t), l);
}
DoRMI(l)
register size l;
/** RMI w: Remainder (*) */
void DoRMI(register size l)
{
/* RMI w: Remainder (*) */
register long t = spop(arg_wi(l));
LOG(("@I6 DoRMI(%ld)", l));
@ -71,21 +68,18 @@ DoRMI(l)
npush(rmi(spop(l), t), l);
}
DoNGI(l)
register size l;
/** NGI w: Negate (two's complement) (*) */
void DoNGI(register size l)
{
/* NGI w: Negate (two's complement) (*) */
LOG(("@I6 DoNGI(%ld)", l));
spoilFRA();
l = arg_wi(l);
npush(ngi(spop(l), l), l);
}
DoSLI(l)
register size l;
/** SLI w: Shift left (*) */
void DoSLI(register size l)
{
/* SLI w: Shift left (*) */
register long t = swpop();
LOG(("@I6 DoSLI(%ld)", l));
@ -94,10 +88,9 @@ DoSLI(l)
npush(sli(spop(l), t, l), l);
}
DoSRI(l)
register size l;
/** SRI w: Shift right (*) */
void DoSRI(register size l)
{
/* SRI w: Shift right (*) */
register long t = swpop();
LOG(("@I6 DoSRI(%ld)", l));
@ -109,9 +102,8 @@ DoSRI(l)
#define i_maxs(n) ((n == 2) ? I_MAXS2 : I_MAXS4)
#define i_mins(n) ((n == 2) ? I_MINS2 : I_MINS4)
PRIVATE long adi(w1, w2, nbytes) /* returns w1 + w2 */
long w1, w2;
size nbytes;
/** Returns "w1" + "w2". */
PRIVATE long adi(long w1, long w2, size nbytes)
{
if (must_test && !(IgnMask&BIT(EIOVFL))) {
if (w1 > 0 && w2 > 0) {
@ -126,9 +118,8 @@ PRIVATE long adi(w1, w2, nbytes) /* returns w1 + w2 */
return (w1 + w2);
}
PRIVATE long sbi(w1, w2, nbytes) /* returns w1 - w2 */
long w1, w2;
size nbytes;
/** Returns "w1" - "w2" */
PRIVATE long sbi(long w1, long w2, size nbytes)
{
if (must_test && !(IgnMask&BIT(EIOVFL))) {
if (w2 < 0 && w1 > 0) {
@ -146,9 +137,8 @@ PRIVATE long sbi(w1, w2, nbytes) /* returns w1 - w2 */
#define labs(w) ((w < 0) ? (-w) : w)
PRIVATE long mli(w1, w2, nbytes) /* returns w1 * w2 */
long w1, w2;
size nbytes;
/** Returns "w1" * "w2" */
PRIVATE long mli(long w1, long w2, size nbytes)
{
if (w1 == 0 || w2 == 0)
return (0L);
@ -172,8 +162,7 @@ PRIVATE long mli(w1, w2, nbytes) /* returns w1 * w2 */
return (w1 * w2);
}
PRIVATE long dvi(w1, w2)
long w1, w2;
PRIVATE long dvi(long w1, long w2)
{
if (w2 == 0) {
if (!(IgnMask&BIT(EIDIVZ))) {
@ -184,8 +173,7 @@ PRIVATE long dvi(w1, w2)
return (w1 / w2);
}
PRIVATE long rmi(w1, w2)
long w1, w2;
PRIVATE long rmi(long w1, long w2)
{
if (w2 == 0) {
if (!(IgnMask&BIT(EIDIVZ))) {
@ -196,9 +184,7 @@ PRIVATE long rmi(w1, w2)
return (w1 % w2);
}
PRIVATE long ngi(w1, nbytes)
long w1;
size nbytes;
PRIVATE long ngi(long w1, size nbytes)
{
if (must_test && !(IgnMask&BIT(EIOVFL))) {
if (w1 == i_mins(nbytes)) {
@ -208,9 +194,8 @@ PRIVATE long ngi(w1, nbytes)
return (-w1);
}
PRIVATE long sli(w1, w2, nbytes) /* w1 << w2 */
long w1, w2;
size nbytes;
/** "w1" << "w2" */
PRIVATE long sli(long w1, long w2, size nbytes)
{
if (must_test) {
#ifdef LOGGING
@ -240,9 +225,7 @@ PRIVATE long sli(w1, w2, nbytes) /* w1 << w2 */
}
/*ARGSUSED*/
PRIVATE long sri(w1, w2, nbytes) /* w1 >> w2 */
long w1, w2;
size nbytes;
PRIVATE long sri(long w1, long w2, size nbytes) /* w1 >> w2 */
{
#ifdef LOGGING
if (must_test) {

View file

@ -1,10 +1,10 @@
/*
* Sources of the "LOAD" group instructions
/** @file
* Sources of the "LOAD" group instructions
*/
/* $Id$ */
#include <em_abs.h>
#include "em_abs.h"
#include "global.h"
#include "log.h"
#include "mem.h"
@ -14,44 +14,37 @@
#include "rsb.h"
#include "warn.h"
PRIVATE ptr lexback_LB();
PRIVATE ptr lexback_LB(unsigned long);
DoLOC(l)
register long l;
/** LOC c: Load constant (i.e. push one word onto the stack) */
void DoLOC(register long l)
{
/* LOC c: Load constant (i.e. push one word onto the stack) */
LOG(("@L6 DoLOC(%ld)", l));
spoilFRA();
wpush(arg_c(l));
}
DoLDC(l)
register long l;
/** LDC d: Load double constant ( push two words ) */
void DoLDC(register long l)
{
/* LDC d: Load double constant ( push two words ) */
LOG(("@L6 DoLDC(%ld)", l));
spoilFRA();
l = arg_d(l);
npush(l, dwsize);
}
DoLOL(l)
register long l;
/** LOL l: Load word at l-th local (l<0) or parameter (l>=0) */
void DoLOL(register long l)
{
/* LOL l: Load word at l-th local (l<0) or parameter (l>=0) */
LOG(("@L6 DoLOL(%ld)", l));
spoilFRA();
l = arg_l(l);
pushw_st(loc_addr(l));
}
DoLOE(arg)
register long arg;
/** LOE g: Load external word g */
void DoLOE(register long arg)
{
/* LOE g: Load external word g */
register ptr p = i2p(arg);
LOG(("@L6 DoLOE(%lu)", p));
@ -59,21 +52,18 @@ DoLOE(arg)
pushw_m(arg_g(p));
}
DoLIL(l)
register long l;
/** LIL l: Load word pointed to by l-th local or parameter */
void DoLIL(register long l)
{
/* LIL l: Load word pointed to by l-th local or parameter */
LOG(("@L6 DoLIL(%ld)", l));
spoilFRA();
l = arg_l(l);
pushw_m(st_lddp(loc_addr(l)));
}
DoLOF(l)
register long l;
/** LOF f: Load offsetted (top of stack + f yield address) */
void DoLOF(register long l)
{
/* LOF f: Load offsetted (top of stack + f yield address) */
register ptr p = dppop();
LOG(("@L6 DoLOF(%ld)", l));
@ -81,10 +71,10 @@ DoLOF(l)
pushw_m(p + arg_f(l));
}
DoLAL(l)
register long l;
/** LAL l: Load address of local or parameter */
void DoLAL(register long l)
{
/* LAL l: Load address of local or parameter */
LOG(("@L6 DoLAL(%ld)", l));
spoilFRA();
@ -92,10 +82,10 @@ DoLAL(l)
dppush(loc_addr(l));
}
DoLAE(arg)
register unsigned long arg;
/** LAE g: Load address of external */
void DoLAE(register unsigned long arg)
{
/* LAE g: Load address of external */
register ptr p = i2p(arg);
LOG(("@L6 DoLAE(%lu)", p));
@ -103,10 +93,9 @@ DoLAE(arg)
dppush(arg_lae(p));
}
DoLXL(l)
register unsigned long l;
/** LXL n: Load lexical (address of LB n static levels back) */
void DoLXL(register unsigned long l)
{
/* LXL n: Load lexical (address of LB n static levels back) */
register ptr p;
LOG(("@L6 DoLXL(%lu)", l));
@ -116,10 +105,9 @@ DoLXL(l)
dppush(p);
}
DoLXA(l)
register unsigned long l;
/** LXA n: Load lexical (address of AB n static levels back) */
void DoLXA(register unsigned long l)
{
/* LXA n: Load lexical (address of AB n static levels back) */
register ptr p;
LOG(("@L6 DoLXA(%lu)", l));
@ -129,10 +117,9 @@ DoLXA(l)
dppush(p + rsbsize);
}
DoLOI(l)
register size l;
/** LOI o: Load indirect o bytes (address is popped from the stack) */
void DoLOI(register size l)
{
/* LOI o: Load indirect o bytes (address is popped from the stack) */
register ptr p = dppop();
LOG(("@L6 DoLOI(%ld)", l));
@ -141,10 +128,10 @@ DoLOI(l)
push_m(p, l);
}
DoLOS(l)
register size l;
/** LOS w: Load indirect, w-byte integer on top of stack gives
* object size */
void DoLOS(register size l)
{
/* LOS w: Load indirect, w-byte integer on top of stack gives object size */
register ptr p;
LOG(("@L6 DoLOS(%ld)", l));
@ -155,21 +142,18 @@ DoLOS(l)
push_m(p, arg_o(l));
}
DoLDL(l)
register long l;
/** LDL l: Load double local or parameter (two consecutive words are stacked) */
void DoLDL(register long l)
{
/* LDL l: Load double local or parameter (two consecutive words are stacked) */
LOG(("@L6 DoLDL(%ld)", l));
spoilFRA();
l = arg_l(l);
push_st(loc_addr(l), dwsize);
}
DoLDE(arg)
register long arg;
/** LDE g: Load double external (two consecutive externals are stacked) */
void DoLDE(register long arg)
{
/* LDE g: Load double external (two consecutive externals are stacked) */
register ptr p = i2p(arg);
LOG(("@L6 DoLDE(%lu)", p));
@ -177,10 +161,9 @@ DoLDE(arg)
push_m(arg_g(p), dwsize);
}
DoLDF(l)
register long l;
/** LDF f: Load double offsetted (top of stack + f yield address) */
void DoLDF(register long l)
{
/* LDF f: Load double offsetted (top of stack + f yield address) */
register ptr p = dppop();
LOG(("@L6 DoLDF(%ld)", l));
@ -188,18 +171,15 @@ DoLDF(l)
push_m(p + arg_f(l), dwsize);
}
DoLPI(pi)
register long pi;
/** LPI p: Load procedure identifier */
void DoLPI(register long pi)
{
/* LPI p: Load procedure identifier */
LOG(("@L6 DoLPI(%ld)", pi));
spoilFRA();
npush(arg_p(pi), psize);
}
PRIVATE ptr lexback_LB(n)
unsigned long n;
PRIVATE ptr lexback_LB(unsigned long n)
{
/* LB n static levels back */
register ptr lb = LB;

View file

@ -1,10 +1,10 @@
/*
* Sources of the "LOGICAL" group instructions
/** @file
* Sources of the "LOGICAL" group instructions
*/
/* $Id$ */
#include <em_abs.h>
#include "em_abs.h"
#include "logging.h"
#include "global.h"
#include "log.h"
@ -25,11 +25,11 @@ extern int must_test;
#define check_def(p,l)
#endif /* LOGGING */
DoAND(l)
register size l;
/** AND w: Boolean and on two groups of w bytes. Size of objects to be compared
* (in bytes) on top of stack
*/
void DoAND(register size l)
{
/* AND w: Boolean and on two groups of w bytes */
/* size of objects to be compared (in bytes) on top of stack */
register ptr p;
LOG(("@X6 DoAND(%ld)", l));
@ -42,10 +42,9 @@ DoAND(l)
st_dec(l);
}
DoIOR(l)
register size l;
/** IOR w: Boolean inclusive or on two groups of w bytes */
void DoIOR(register size l)
{
/* IOR w: Boolean inclusive or on two groups of w bytes */
register ptr p;
LOG(("@X6 DoIOR(%ld)", l));
@ -58,10 +57,9 @@ DoIOR(l)
st_dec(l);
}
DoXOR(l)
register size l;
/** XOR w: Boolean exclusive or on two groups of w bytes */
void DoXOR(register size l)
{
/* XOR w: Boolean exclusive or on two groups of w bytes */
register ptr p;
LOG(("@X6 DoXOR(%ld)", l));
@ -74,10 +72,9 @@ DoXOR(l)
st_dec(l);
}
DoCOM(l)
register size l;
/** COM w: Complement (one's complement of top w bytes) */
void DoCOM(register size l)
{
/* COM w: Complement (one's complement of top w bytes) */
register ptr p;
LOG(("@X6 DoCOM(%ld)", l));
@ -89,10 +86,9 @@ DoCOM(l)
}
}
DoROL(l)
register size l;
/** ROL w: Rotate left a group of w bytes */
void DoROL(register size l)
{
/* ROL w: Rotate left a group of w bytes */
register long s, t = uwpop();
register long signbit;
@ -122,10 +118,9 @@ DoROL(l)
npush(s, l);
}
DoROR(l)
register size l;
/** ROR w: Rotate right a group of w bytes */
void DoROR(register size l)
{
/* ROR w: Rotate right a group of w bytes */
register long s, t = uwpop();
register long signbit;

View file

@ -1,5 +1,5 @@
/*
* Sources of the "MISCELLANEOUS" group instructions
/** @file
* Sources of the "MISCELLANEOUS" group instructions
*/
/* $Id$ */
@ -12,38 +12,43 @@
#include "warn.h"
#include "mem.h"
#include "memdirect.h"
#include "segment.h"
#include "shadow.h"
#include "data.h"
#include "text.h"
#include "stack.h"
#include "read.h"
#include "fra.h"
#include "rsb.h"
#include "io.h"
#include "linfil.h"
extern int running; /* from main.c */
/* Two useful but unofficial registers */
/** Current line number */
long LIN;
/** Pointer to the filename. */
ptr FIL;
PRIVATE index_jump(), range_check(), search_jump();
PRIVATE gto();
PRIVATE void index_jump(size), range_check(size), search_jump(size);
PRIVATE void gto(ptr);
void putLIN(long);
void putFIL(ptr);
#define asp(l) newSP(SP + arg_f(l))
DoASP(l)
register long l;
{
/* ASP f: Adjust the stack pointer by f */
extern void moncall(void);
/** ASP f: Adjust the stack pointer by f */
void DoASP(register long l)
{
LOG(("@M6 DoASP(%ld)", l));
asp(l);
}
DoASS(l)
register size l;
/** ASS w: Adjust the stack pointer by w-byte integer */
void DoASS(register size l)
{
/* ASS w: Adjust the stack pointer by w-byte integer */
LOG(("@M6 DoASS(%ld)", l));
spoilFRA();
l = spop(arg_wi(l));
@ -57,10 +62,9 @@ DoASS(l)
else { if (in_stack(a2)) dt_mvs(a1, a2, n); \
else dt_mvd(a1, a2, n); }
DoBLM(l)
register size l;
/** BLM z: Block move z bytes; first pop destination addr, then source addr */
void DoBLM(register size l)
{
/* BLM z: Block move z bytes; first pop destination addr, then source addr */
register ptr dp1, dp2; /* Destination Pointers */
LOG(("@M6 DoBLM(%ld)", l));
@ -70,10 +74,9 @@ DoBLM(l)
block_move(dp1, dp2, arg_z(l));
}
DoBLS(l)
register size l;
/** BLS w: Block move, size is in w-byte integer on top of stack */
void DoBLS(register size l)
{
/* BLS w: Block move, size is in w-byte integer on top of stack */
register ptr dp1, dp2;
LOG(("@M6 DoBLS(%ld)", l));
@ -84,29 +87,25 @@ DoBLS(l)
block_move(dp1, dp2, arg_z(l));
}
DoCSA(l)
register size l;
/** CSA w: Case jump; address of jump table at top of stack */
void DoCSA(register size l)
{
/* CSA w: Case jump; address of jump table at top of stack */
LOG(("@M6 DoCSA(%ld)", l));
spoilFRA();
index_jump(arg_wi(l));
}
DoCSB(l)
register size l;
/** CSB w: Table lookup jump; address of jump table at top of stack */
void DoCSB(register size l)
{
/* CSB w: Table lookup jump; address of jump table at top of stack */
LOG(("@M6 DoCSB(%ld)", l));
spoilFRA();
search_jump(arg_wi(l));
}
DoDCH()
/** DCH -: Follow dynamic chain, convert LB to LB of caller */
void DoDCH(void)
{
/* DCH -: Follow dynamic chain, convert LB to LB of caller */
register ptr lb;
LOG(("@M6 DoDCH()"));
@ -118,10 +117,9 @@ DoDCH()
dppush(st_lddp(lb + rsb_LB));
}
DoDUP(arg)
size arg;
/** DUP s: Duplicate top s bytes */
void DoDUP(size arg)
{
/* DUP s: Duplicate top s bytes */
register ptr oldSP = SP;
LOG(("@M6 DoDUP(%ld)", arg));
@ -130,10 +128,9 @@ DoDUP(arg)
st_mvs(SP, oldSP, arg);
}
DoDUS(l)
register size l;
/** DUS w: Duplicate top w bytes */
void DoDUS(register size l)
{
/* DUS w: Duplicate top w bytes */
register ptr oldSP;
LOG(("@M6 DoDUS(%ld)", l));
@ -144,10 +141,9 @@ DoDUS(l)
st_mvs(SP, oldSP, l);
}
DoEXG(l)
register size l;
/** EXG w: Exchange top w bytes */
void DoEXG(register size l)
{
/* EXG w: Exchange top w bytes */
register ptr oldSP = SP;
LOG(("@M6 DoEXG(%ld)", l));
@ -159,10 +155,9 @@ DoEXG(l)
st_dec(l);
}
DoFIL(arg)
register unsigned long arg;
/** FIL g: File name (external 4 := g) */
void DoFIL(register unsigned long arg)
{
/* FIL g: File name (external 4 := g) */
register ptr p = i2p(arg);
LOG(("@M6 DoFIL(%lu)", p));
@ -173,47 +168,42 @@ DoFIL(arg)
putFIL(arg_g(p));
}
DoGTO(arg)
register unsigned long arg;
/** GTO g: Non-local goto, descriptor at g */
void DoGTO(register unsigned long arg)
{
/* GTO g: Non-local goto, descriptor at g */
register ptr p = i2p(arg);
LOG(("@M6 DoGTO(%lu)", p));
gto(arg_gto(p));
}
DoLIM()
/** LIM -: Load 16 bit ignore mask */
void DoLIM(void)
{
/* LIM -: Load 16 bit ignore mask */
LOG(("@M6 DoLIM()"));
spoilFRA();
wpush(IgnMask);
}
DoLIN(l)
register unsigned long l;
/** LIN n: Line number (external 0 := n) */
void DoLIN(register unsigned long l)
{
/* LIN n: Line number (external 0 := n) */
LOG(("@M6 DoLIN(%lu)", l));
spoilFRA();
putLIN((long) arg_lin(l));
}
DoLNI()
/** LNI -: Line number increment */
void DoLNI(void)
{
/* LNI -: Line number increment */
LOG(("@M6 DoLNI()"));
spoilFRA();
putLIN((long)getLIN() + 1);
}
DoLOR(l)
register long l;
/** LOR r: Load register (0=LB, 1=SP, 2=HP) */
void DoLOR(register long l)
{
/* LOR r: Load register (0=LB, 1=SP, 2=HP) */
LOG(("@M6 DoLOR(%ld)", l));
spoilFRA();
switch ((int) arg_r(l)) {
@ -229,9 +219,9 @@ DoLOR(l)
}
}
DoLPB()
/** LPB -: Convert local base to argument base */
void DoLPB(void)
{
/* LPB -: Convert local base to argument base */
register ptr lb;
LOG(("@M6 DoLPB()"));
@ -243,35 +233,33 @@ DoLPB()
dppush(lb + rsbsize);
}
DoMON()
/** MON -: Monitor call */
void DoMON(void)
{
/* MON -: Monitor call */
LOG(("@M6 DoMON()"));
spoilFRA();
moncall();
}
DoNOP()
/** NOP -: No operation */
void DoNOP(void)
{
/* NOP -: No operation */
LOG(("@M6 DoNOP()"));
spoilFRA();
message("NOP instruction");
}
DoRCK(l)
register size l;
/** RCK w: Range check; trap on error */
void DoRCK(register size l)
{
/* RCK w: Range check; trap on error */
LOG(("@M6 DoRCK(%ld)", l));
spoilFRA();
range_check(arg_wi(l));
}
DoRTT()
/** RTT -: Return from trap */
void DoRTT(void)
{
/* RTT -: Return from trap */
LOG(("@M6 DoRTT()"));
switch (poprsb(1)) {
@ -303,9 +291,9 @@ DoRTT()
popFRA(FRASize);
}
DoSIG()
/** SIG -: Trap errors to proc identifier on top of stack, \-2 resets default */
void DoSIG(void)
{
/* SIG -: Trap errors to proc identifier on top of stack, \-2 resets default */
register long tpi = spop(psize);
LOG(("@M6 DoSIG()"));
@ -325,19 +313,17 @@ DoSIG()
}
}
DoSIM()
/** SIM -: Store 16 bit ignore mask */
void DoSIM(void)
{
/* SIM -: Store 16 bit ignore mask */
LOG(("@M6 DoSIM()"));
spoilFRA();
IgnMask = (uwpop() | PreIgnMask) & MASK2;
}
DoSTR(l)
register long l;
/** STR r: Store register (0=LB, 1=SP, 2=HP) */
void DoSTR(register long l)
{
/* STR r: Store register (0=LB, 1=SP, 2=HP) */
LOG(("@M6 DoSTR(%ld)", l));
spoilFRA();
switch ((int) arg_r(l)) {
@ -354,9 +340,9 @@ DoSTR(l)
}
}
DoTRP()
/** TRP -: Cause trap to occur (Error number on stack) */
void DoTRP(void)
{
/* TRP -: Cause trap to occur (Error number on stack) */
register unsigned int tr = (unsigned int)uwpop();
LOG(("@M6 DoTRP()"));
@ -369,8 +355,7 @@ DoTRP()
/* Service routines */
PRIVATE gto(p)
ptr p;
PRIVATE void gto(ptr p)
{
register ptr old_LB = LB;
register ptr new_PC = dt_ldip(p);
@ -397,8 +382,7 @@ PRIVATE gto(p)
(variables LIN and FIL) and in the data space.
*/
putLIN(lin)
long lin;
void putLIN(long lin)
{
dt_unprot(i2p(LINO_AD), (long)LINSIZE);
dt_stn(i2p(LINO_AD), lin, (long)LINSIZE);
@ -406,8 +390,7 @@ putLIN(lin)
dt_prot(i2p(LINO_AD), (long)LINSIZE);
}
putFIL(fil)
ptr fil;
void putFIL(ptr fil)
{
dt_unprot(i2p(FILN_AD), psize);
dt_stdp(i2p(FILN_AD), fil);
@ -426,8 +409,7 @@ putFIL(fil)
* 6. Else: load default value. *
********************************************************/
PRIVATE index_jump(nbytes)
size nbytes;
PRIVATE void index_jump(size nbytes)
{
register ptr cdp = dppop(); /* Case Descriptor Pointer */
register long t_index = /* Table INDEX */
@ -454,8 +436,7 @@ PRIVATE index_jump(nbytes)
* 6. Else: load default value. *
********************************************************/
PRIVATE search_jump(nbytes)
size nbytes;
PRIVATE void search_jump(size nbytes)
{
register ptr cdp = dppop(); /* Case Descriptor Pointer */
register long sv = spop(nbytes);/* Search Value */
@ -486,9 +467,7 @@ PRIVATE search_jump(nbytes)
* 3. Generate trap if necessary. *
* 4. DON'T remove integer. *
********************************************************/
PRIVATE range_check(nbytes)
size nbytes;
PRIVATE void range_check(size nbytes)
{
register ptr rdp = dppop(); /* Range check Descriptor Pointer */
register long cv = /* Check Value */

View file

@ -1,16 +1,17 @@
/*
* Sources of the "PROCEDURE CALL" group instructions
/** @file
* Sources of the "PROCEDURE CALL" group instructions
*/
/* $Id$ */
#include <em_abs.h>
#include "em_abs.h"
#include "logging.h"
#include "global.h"
#include "log.h"
#include "mem.h"
#include "shadow.h"
#include "memdirect.h"
#include "segment.h"
#include "trap.h"
#include "warn.h"
#include "text.h"
@ -21,51 +22,45 @@
extern int running; /* from main.c */
PRIVATE lfr(), ret();
/* Forward declarations */
PRIVATE void lfr(size), ret(size);
void call(long, int);
DoCAI() /* proc identifier on top of stack */
/** CAI -: Call procedure (procedure identifier on stack) */
void DoCAI(void) /* proc identifier on top of stack */
{
/* CAI -: Call procedure (procedure identifier on stack) */
register long pi = spop(psize);
LOG(("@P6 DoCAI(%lu)", pi));
call(arg_p(pi), RSB_CAL);
}
DoCAL(pi)
register long pi;
/** CAL p: Call procedure (with identifier p) */
void DoCAL(register long pi)
{
/* CAL p: Call procedure (with identifier p) */
LOG(("@P6 DoCAL(%lu)", pi));
call(arg_p(pi), RSB_CAL);
}
DoLFR(l)
register size l;
/** LFR s: Load function result */
void DoLFR(register size l)
{
/* LFR s: Load function result */
LOG(("@P6 DoLFR(%ld)", l));
lfr(arg_s(l));
}
DoRET(l)
register size l;
/** RET z: Return (function result consists of top z bytes) */
void DoRET(register size l)
{
/* RET z: Return (function result consists of top z bytes) */
LOG(("@P6 DoRET(%ld)", l));
ret(arg_z(l));
}
/************************************************************************
* Calling a new procedure. *
* Calling a new procedure. *
************************************************************************/
call(new_PI, rsbcode)
long new_PI;
int rsbcode;
void call(long new_PI, int rsbcode)
{
/* legality of new_PI has already been checked */
register size nloc = proctab[new_PI].pr_nloc;
@ -84,11 +79,10 @@ call(new_PI, rsbcode)
}
/************************************************************************
* Loading a function result. *
* Loading a function result. *
************************************************************************/
PRIVATE lfr(sz)
size sz;
PRIVATE void lfr(size sz)
{
if (sz > FRALimit) {
wtrap(WILLLFR, EILLINS);
@ -113,8 +107,7 @@ PRIVATE lfr(sz)
* Returning from a procedure. *
************************************************************************/
PRIVATE ret(sz)
size sz;
PRIVATE void ret(size sz)
{
if (sz > FRALimit) {
wtrap(WILLRET, EILLINS);

View file

@ -1,12 +1,13 @@
/*
* Sources of the "POINTER ARITHMETIC" group instructions
/** @file
* Sources of the "POINTER ARITHMETIC" group instructions
*/
/* $Id$ */
#include <em_abs.h>
#include "em_abs.h"
#include "segcheck.h"
#include "global.h"
#include "segment.h"
#include "log.h"
#include "mem.h"
#include "trap.h"
@ -27,10 +28,10 @@
#endif /* SEGCHECK */
DoADP(l)
register long l;
/** ADP f: Add f to pointer on top of stack */
void DoADP(register long l)
{
/* ADP f: Add f to pointer on top of stack */
register ptr p, t = st_lddp(SP);
LOG(("@R6 DoADP(%ld)", l));
@ -44,10 +45,9 @@ DoADP(l)
st_stdp(SP, p);
}
DoADS(l)
register size l;
/** ADS w: Add w-byte value and pointer */
void DoADS(register size l)
{
/* ADS w: Add w-byte value and pointer */
register long t = spop(arg_wi(l));
register ptr p, s = st_lddp(SP);
@ -62,10 +62,9 @@ DoADS(l)
st_stdp(SP, p);
}
DoSBS(l)
register size l;
/** SBS w: Subtract pointers in same fragment and push diff as size w integer */
void DoSBS(register size l)
{
/* SBS w: Subtract pointers in same fragment and push diff as size w integer */
register ptr t = st_lddp(SP);
register ptr s = st_lddp(SP + psize);
register long w;

View file

@ -1,10 +1,10 @@
/*
* Sources of the "SETS" group instructions
/** @file
* Sources of the "SETS" group instructions
*/
/* $Id$ */
#include <em_abs.h>
#include "em_abs.h"
#include "global.h"
#include "log.h"
#include "trap.h"
@ -12,39 +12,30 @@
#include "text.h"
#include "fra.h"
PRIVATE bit_test(), create_set();
PRIVATE void bit_test(size), create_set(size);
DoINN(l)
register size l;
/** INN w: Bit test on w byte set (bit number on top of stack) */
void DoINN(register size l)
{
/* INN w: Bit test on w byte set (bit number on top of stack) */
LOG(("@Y6 DoINN(%ld)", l));
spoilFRA();
bit_test(arg_w(l));
}
DoSET(l)
register size l;
/** SET w: Create singleton w byte set with bit n on (n is top of stack) */
void DoSET(register size l)
{
/* SET w: Create singleton w byte set with bit n on (n is top of stack) */
LOG(("@Y6 DoSET(%ld)", l));
spoilFRA();
create_set(arg_w(l));
}
/********************************************************
* bit testing *
* *
* Tests whether the bit with number to be found *
* on TOS is on in 'w'-byte set. *
* ON --> push 1 on stack. *
* OFF -> push 0 on stack. *
********************************************************/
PRIVATE bit_test(w)
size w;
/** Bit testing. Tests whether the bit with number to be found
* on TOS is on in 'w'-byte set.
* ON --> push 1 on stack.
* OFF -> push 0 on stack.
**/
PRIVATE void bit_test(size w)
{
register int bitno =
(int) swpop(); /* bitno on TOS */
@ -65,17 +56,12 @@ PRIVATE bit_test(w)
wpush((long)((test_byte & BIT(bitoff)) ? 1 : 0));
}
/********************************************************
* set creation *
* *
* Creates a singleton 'w'-byte set with as *
* singleton member, the bit with number on *
* TOS. The w bytes constituting the set are *
* pushed on the stack. *
********************************************************/
PRIVATE create_set(w)
size w;
/** Set creation. Creates a singleton 'w'-byte set with as
* singleton member, the bit with number on TOS.
* The w bytes constituting the set are
* pushed on the stack.
**/
PRIVATE void create_set(size w)
{
register int bitno = (int) swpop();
register size nbytes = w;

View file

@ -1,10 +1,10 @@
/*
* Sources of the "STORE" group instructions
/** @file
* Sources of the "STORE" group instructions
*/
/* $Id$ */
#include <em_abs.h>
#include "em_abs.h"
#include "global.h"
#include "log.h"
#include "mem.h"
@ -13,21 +13,18 @@
#include "fra.h"
#include "warn.h"
DoSTL(l)
register long l;
/** STL l: Store local or parameter */
void DoSTL(register long l)
{
/* STL l: Store local or parameter */
LOG(("@S6 DoSTL(%ld)", l));
spoilFRA();
l = arg_l(l);
popw_st(loc_addr(l));
}
DoSTE(arg)
register unsigned long arg;
/** STE g: Store external */
void DoSTE(register unsigned long arg)
{
/* STE g: Store external */
register ptr p = i2p(arg);
LOG(("@S6 DoSTE(%lu)", p));
@ -35,21 +32,18 @@ DoSTE(arg)
popw_m(arg_g(p));
}
DoSIL(l)
register long l;
/** SIL l: Store into word pointed to by l-th local or parameter */
void DoSIL(register long l)
{
/* SIL l: Store into word pointed to by l-th local or parameter */
LOG(("@S6 DoSIL(%ld)", l));
spoilFRA();
l = arg_l(l);
popw_m(st_lddp(loc_addr(l)));
}
DoSTF(l)
register long l;
/** STF f: Store offsetted */
void DoSTF(register long l)
{
/* STF f: Store offsetted */
register ptr p = dppop();
LOG(("@S6 DoSTF(%ld)", l));
@ -57,10 +51,9 @@ DoSTF(l)
popw_m(p + arg_f(l));
}
DoSTI(l)
register size l;
/** STI o: Store indirect o bytes (pop address, then data) */
void DoSTI(register size l)
{
/* STI o: Store indirect o bytes (pop address, then data) */
register ptr p = dppop();
LOG(("@S6 DoSTI(%ld)", l));
@ -68,10 +61,9 @@ DoSTI(l)
pop_m(p, arg_o(l));
}
DoSTS(l)
register size l;
/** STS w: Store indirect, w-byte integer on top of stack gives object size */
void DoSTS(register size l)
{
/* STS w: Store indirect, w-byte integer on top of stack gives object size */
register ptr p;
LOG(("@S6 DoSTS(%ld)", l));
@ -81,10 +73,9 @@ DoSTS(l)
pop_m(p, arg_o(l));
}
DoSDL(l)
register long l;
/** SDL l: Store double local or parameter */
void DoSDL(register long l)
{
/* SDL l: Store double local or parameter */
LOG(("@S6 DoSDL(%ld)", l));
spoilFRA();
@ -92,10 +83,9 @@ DoSDL(l)
pop_st(loc_addr(l), dwsize);
}
DoSDE(arg)
register unsigned long arg;
/** SDE g: Store double external */
void DoSDE(register unsigned long arg)
{
/* SDE g: Store double external */
register ptr p = i2p(arg);
LOG(("@S6 DoSDE(%lu)", p));
@ -103,10 +93,9 @@ DoSDE(arg)
pop_m(arg_g(p), dwsize);
}
DoSDF(l)
register long l;
/** SDF f: Store double offsetted */
void DoSDF(register long l)
{
/* SDF f: Store double offsetted */
register ptr p = dppop();
LOG(("@S6 DoSDF(%ld)", l));

View file

@ -1,10 +1,10 @@
/*
/** @file
* Sources of the "UNSIGNED ARITHMETIC" group instructions
*/
/* $Id$ */
#include <em_abs.h>
#include "em_abs.h"
#include "logging.h"
#include "global.h"
#include "log.h"
@ -33,10 +33,9 @@ extern int must_test;
PRIVATE unsigned long dvu(), rmu(), slu(), sru();
DoADU(l)
register size l;
/** ADU w: Addition */
void DoADU(register size l)
{
/* ADU w: Addition */
register unsigned long t = upop(arg_wi(l));
LOG(("@U6 DoADU(%ld)", l));
@ -44,10 +43,9 @@ DoADU(l)
npush((long) adu(upop(l), t), l);
}
DoSBU(l)
register size l;
/** SBU w: Subtraction */
void DoSBU(register size l)
{
/* SBU w: Subtraction */
register unsigned long t = upop(arg_wi(l));
LOG(("@U6 DoSBU(%ld)", l));
@ -55,10 +53,9 @@ DoSBU(l)
npush((long) sbu(upop(l), t), l);
}
DoMLU(l)
register size l;
/** MLU w: Multiplication */
void DoMLU(register size l)
{
/* MLU w: Multiplication */
register unsigned long t = upop(arg_wi(l));
LOG(("@U6 DoMLU(%ld)", l));
@ -66,10 +63,9 @@ DoMLU(l)
npush((long) mlu(upop(l), t), l);
}
DoDVU(l)
register size l;
/** DVU w: Division */
void DoDVU(register size l)
{
/* DVU w: Division */
register unsigned long t = upop(arg_wi(l));
LOG(("@U6 DoDVU(%ld)", l));
@ -77,10 +73,9 @@ DoDVU(l)
npush((long) dvu(upop(l), t), l);
}
DoRMU(l)
register size l;
/** RMU w: Remainder */
void DoRMU(register size l)
{
/* RMU w: Remainder */
register unsigned long t = upop(arg_wi(l));
LOG(("@U6 DoRMU(%ld)", l));
@ -88,10 +83,9 @@ DoRMU(l)
npush((long) rmu(upop(l), t), l);
}
DoSLU(l)
register size l;
/** SLU w: Shift left */
void DoSLU(register size l)
{
/* SLU w: Shift left */
register unsigned long t = uwpop();
LOG(("@U6 DoSLU(%ld)", l));
@ -100,10 +94,9 @@ DoSLU(l)
npush((long) slu(upop(l), t, l), l);
}
DoSRU(l)
register size l;
/** SRU w: Shift right */
void DoSRU(register size l)
{
/* SRU w: Shift right */
register unsigned long t = uwpop();
LOG(("@U6 DoSRU(%ld)", l));
@ -112,8 +105,9 @@ DoSRU(l)
npush((long) sru(upop(l), t, l), l);
}
PRIVATE unsigned long dvu(w1, w2)
unsigned long w1, w2;
PRIVATE unsigned long dvu(
unsigned long w1,
unsigned long w2)
{
if (w2 == 0) {
if (!(IgnMask&BIT(EIDIVZ))) {
@ -124,8 +118,9 @@ PRIVATE unsigned long dvu(w1, w2)
return (w1 / w2);
}
PRIVATE unsigned long rmu(w1, w2)
unsigned long w1, w2;
PRIVATE unsigned long rmu(
unsigned long w1,
unsigned long w2)
{
if (w2 == 0) {
if (!(IgnMask&BIT(EIDIVZ))) {
@ -137,10 +132,12 @@ PRIVATE unsigned long rmu(w1, w2)
}
/*ARGSUSED*/
PRIVATE unsigned long slu(w1, w2, nbytes) /* w1 << w2 */
unsigned long w1, w2;
size nbytes;
PRIVATE unsigned long slu(
unsigned long w1,
unsigned long w2,
size nbytes)
{
/* w1 << w2 */
#ifdef LOGGING
if (must_test) {
/* check shift distance */
@ -156,10 +153,12 @@ PRIVATE unsigned long slu(w1, w2, nbytes) /* w1 << w2 */
}
/*ARGSUSED*/
PRIVATE unsigned long sru(w1, w2, nbytes) /* w1 >> w2 */
unsigned long w1, w2;
size nbytes;
PRIVATE unsigned long sru(
unsigned long w1,
unsigned long w2,
size nbytes)
{
/* w1 >> w2 */
#ifdef LOGGING
if (must_test) {
/* check shift distance */

View file

@ -1,4 +1,4 @@
/*
/** @file
For dumping the stack, GDA, heap and text segment.
*/
@ -6,7 +6,8 @@
#include <ctype.h>
#include <em_abs.h>
#include "em_abs.h"
#include "dump.h"
#include "logging.h"
#include "global.h"
#include "log.h"
@ -31,19 +32,18 @@ extern long inr; /* from log.c */
although it is not directly evident how.
*/
PRIVATE char *displ_undefs(), *displ_fil(), *displ_sh(), *displ_code();
PRIVATE ptr std_raw(), std_rsb();
PRIVATE int std_bytes(), dtd_bytes(), FRAd_bytes();
PRIVATE std_item(), std_left_undefs();
PRIVATE gdad_item(), gdad_left_undefs();
PRIVATE hpd_item(), hpd_left_undefs();
PRIVATE FRA_dump(), FRA_item();
/* Forward declarations */
PRIVATE char *displ_undefs(int, ptr), *displ_fil(ptr), *displ_sh(char, int), *displ_code(int);
PRIVATE ptr std_raw(ptr, int), std_rsb(ptr);
PRIVATE int std_bytes(ptr, ptr, int), dtd_bytes(ptr, ptr, int), FRAd_bytes(int, int, int);
PRIVATE void std_item(ptr), std_left_undefs(int, ptr);
PRIVATE void gdad_item(ptr), gdad_left_undefs(int, ptr);
PRIVATE void hpd_item(ptr), hpd_left_undefs(int, ptr);
PRIVATE void FRA_dump(void), FRA_item(int);
/******** Stack Dump ********/
std_all(sz, rawfl)
long sz;
int rawfl;
void std_all(long sz, int rawfl)
{
register ptr addr;
@ -79,11 +79,9 @@ std_all(sz, rawfl)
LOG((" d2 "));
}
PRIVATE ptr
std_raw(addr, rawfl)
ptr addr;
int rawfl;
{ /* Produces a formatted dump of the stack segment starting
PRIVATE ptr std_raw(ptr addr, int rawfl)
{
/* Produces a formatted dump of the stack segment starting
at addr, up to the Return Status Block (identified
by protection bits)
*/
@ -112,8 +110,7 @@ std_raw(addr, rawfl)
return addr;
}
PRIVATE std_item(addr)
ptr addr;
PRIVATE void std_item(ptr addr)
{
if ( is_wordaligned(addr)
&& is_in_stack(addr, psize)
@ -147,10 +144,9 @@ PRIVATE std_item(addr)
}
}
PRIVATE ptr
std_rsb(addr)
ptr addr;
{ /* Dumps the Return Status Block */
/** Dumps the Return Status Block. */
PRIVATE ptr std_rsb(ptr addr)
{
ptr dmp_lb;
int code;
long pi;
@ -194,8 +190,7 @@ std_rsb(addr)
return addr - rsbsize;
}
PRIVATE char *displ_code(rsbcode)
int rsbcode;
PRIVATE char *displ_code(int rsbcode)
{
switch (rsbcode) {
case RSB_STP: return "STP";
@ -207,9 +202,7 @@ PRIVATE char *displ_code(rsbcode)
/*NOTREACHED*/
}
PRIVATE std_left_undefs(nundef, addr)
int nundef;
ptr addr;
PRIVATE void std_left_undefs(int nundef, ptr addr)
{
/* handle pending undefineds */
switch (nundef) {
@ -226,7 +219,7 @@ PRIVATE std_left_undefs(nundef, addr)
}
}
PRIVATE FRA_dump()
PRIVATE void FRA_dump(void)
{
register int addr;
@ -238,8 +231,7 @@ PRIVATE FRA_dump()
}
}
PRIVATE FRA_item(addr)
int addr;
PRIVATE void FRA_item(int addr)
{
if ( is_wordaligned(addr)
&& is_in_FRA(addr, psize)
@ -276,8 +268,7 @@ PRIVATE FRA_item(addr)
/******** Global Data Area Dump ********/
gdad_all(low, high)
ptr low, high;
void gdad_all(ptr low, ptr high)
{
register ptr addr;
register int nundef = 0;
@ -316,8 +307,7 @@ gdad_all(low, high)
LOG((" +1 "));
}
PRIVATE gdad_item(addr)
ptr addr;
PRIVATE void gdad_item(ptr addr)
{
if ( is_wordaligned(addr)
&& is_in_data(addr, psize)
@ -351,9 +341,7 @@ PRIVATE gdad_item(addr)
}
}
PRIVATE gdad_left_undefs(nundef, addr)
int nundef;
ptr addr;
PRIVATE void gdad_left_undefs(int nundef, ptr addr)
{
/* handle pending undefineds */
switch (nundef) {
@ -372,7 +360,7 @@ PRIVATE gdad_left_undefs(nundef, addr)
/******** Heap Area Dump ********/
hpd_all()
void hpd_all(void)
{
register ptr addr;
register int nundef = 0;
@ -406,8 +394,7 @@ hpd_all()
LOG((" *1 "));
}
PRIVATE hpd_item(addr)
ptr addr;
PRIVATE void hpd_item(ptr addr)
{
if ( is_wordaligned(addr)
&& is_in_data(addr, psize)
@ -441,9 +428,7 @@ PRIVATE hpd_item(addr)
}
}
PRIVATE hpd_left_undefs(nundef, addr)
int nundef;
ptr addr;
PRIVATE void hpd_left_undefs(int nundef, ptr addr)
{
/* handle pending undefineds */
switch (nundef) {
@ -463,9 +448,7 @@ PRIVATE hpd_left_undefs(nundef, addr)
/* Service routines */
PRIVATE int std_bytes(low, high, bits)
ptr low, high;
int bits;
PRIVATE int std_bytes(ptr low, ptr high, int bits)
{
/* True if all stack bytes from low to high-1 have one of the
bits in bits on.
@ -480,9 +463,7 @@ PRIVATE int std_bytes(low, high, bits)
return byte & bits;
}
PRIVATE int dtd_bytes(low, high, bits)
ptr low, high;
int bits;
PRIVATE int dtd_bytes(ptr low, ptr high, int bits)
{
/* True if all data bytes from low to high-1 have one of the
bits in bits on.
@ -497,9 +478,7 @@ PRIVATE int dtd_bytes(low, high, bits)
return byte & bits;
}
PRIVATE int FRAd_bytes(low, high, bits)
int low, high;
int bits;
PRIVATE int FRAd_bytes(int low, int high, int bits)
{
/* True if all data bytes from low to high-1 have one of the
bits in bits on.
@ -514,10 +493,7 @@ PRIVATE int FRAd_bytes(low, high, bits)
return byte & bits;
}
PRIVATE char * /* transient */
displ_undefs(nundef, addr)
int nundef;
ptr addr;
PRIVATE char *displ_undefs(int nundef, ptr addr)
{
/* Given the number of undefineds, we want to report the number
of words with the left-over numbers of bytes on both sides:
@ -562,9 +538,7 @@ displ_undefs(nundef, addr)
return buf;
}
PRIVATE char *
displ_fil(fil) /* transient */
ptr fil;
PRIVATE char *displ_fil(ptr fil)
{ /* Returns a buffer containing a representation of the
filename derived from FIL-value fil.
*/
@ -590,10 +564,7 @@ displ_fil(fil) /* transient */
return &buf[0];
}
PRIVATE char *
displ_sh(shadow, byte) /* transient */
char shadow;
int byte;
PRIVATE char *displ_sh(char shadow, int byte)
{ /* Returns a buffer containing a description of the
shadow byte.
*/

17
util/int/dump.h Normal file
View file

@ -0,0 +1,17 @@
/* Copyright (c) 2019 ACK Project.
* See the copyright notice in the ACK home directory,
* in the file "Copyright".
*
* Created on: 2019-03-16
*
*/
#ifndef DUMP_H_
#define DUMP_H_
#ifdef LOGGING
void std_all(long, int);
void gdad_all(ptr, ptr);
void hpd_all(void);
#endif
#endif /* DUMP_H_ */

View file

@ -8,19 +8,19 @@
#include "alloc.h"
#ifdef LOGGING
char *FRA_sh; /* shadowbytes */
char *FRA_sh; /* shadowbytes */
#endif /* LOGGING */
init_FRA() {
void init_FRA(void)
{
FRA = Malloc(FRALimit, "Function Return Area");
#ifdef LOGGING
FRA_sh = Malloc(FRALimit, "shadowspace for Function Return Area");
#endif /* LOGGING */
FRA_def = UNDEFINED; /* set FRA illegal */
FRA_def = UNDEFINED; /* set FRA illegal */
}
pushFRA(sz)
size sz;
void pushFRA(size sz)
{
register int i;
@ -28,7 +28,8 @@ pushFRA(sz)
return;
st_inc(max(sz, wsize));
for (i = 0; i < sz; i++) {
for (i = 0; i < sz; i++)
{
stack_loc(SP + i) = FRA[i];
#ifdef LOGGING
st_sh(SP + i) = (i < FRASize ? FRA_sh[i] : UNDEFINED);
@ -36,15 +37,15 @@ pushFRA(sz)
}
}
popFRA(sz)
size sz;
void popFRA(size sz)
{
register int i;
if (sz == 0)
return;
for (i = 0; i < sz; i++) {
for (i = 0; i < sz; i++)
{
FRA[i] = stack_loc(SP + i);
#ifdef LOGGING
FRA_sh[i] = st_sh(SP + i);

View file

@ -6,6 +6,11 @@
#include "logging.h"
void init_FRA(void);
void pushFRA(size);
void popFRA(size);
#ifdef LOGGING
extern char *FRA_sh; /* shadowbytes of Function Return Area */

View file

@ -1,37 +1,46 @@
/*
Startup routines
/** @file
Startup routines.
*/
/* $Id$ */
#include <stdio.h>
#include <string.h>
#include <em_abs.h>
#include "em_abs.h"
#include "logging.h"
#include "global.h"
#include "segment.h"
#include "log.h"
#include "rsb.h"
#include "fra.h"
#include "read.h"
#include "stack.h"
#include "text.h"
#include "data.h"
#include "alloc.h"
#include "warn.h"
#include "mem.h"
#include "io.h"
#include "shadow.h"
#include "trap.h"
#include "read.h"
/****************************************************************
* The EM-machine is not implemented as a contiguous *
* piece of memory. Instead there are a number of *
* "floating" pieces of memory, each representing a *
* specific part of the machine. There are separate *
* allocations for: *
* - stack and local area (stack), *
* - heap area & global data area (data), *
* - program text & procedure descriptors (text). *
* The names in parenthesis are the names of the global *
* variables used within our program, pointing to *
* the beginning of such an area. The sizes of the global *
* data area and the program text can be determined *
* once and for all in the "rd_header" routine. *
* The EM-machine is not implemented as a contiguous *
* piece of memory. Instead there are a number of *
* "floating" pieces of memory, each representing a *
* specific part of the machine. There are separate *
* allocations for: *
* - stack and local area (stack), *
* - heap area & global data area (data), *
* - program text & procedure descriptors (text). *
* The names in parenthesis are the names of the global *
* variables used within our program, pointing to *
* the beginning of such an area. The sizes of the global *
* data area and the program text can be determined *
* once and for all in the "rd_header" routine. *
****************************************************************/
extern char **environ;
@ -41,9 +50,7 @@ PRIVATE size alignedstrlen();
char *load_name;
init(ac, av)
int ac;
char **av;
void init(int ac, char **av)
{
register char **p;
register size env_vec_size; /* size of environ vector */
@ -137,17 +144,14 @@ init(ac, av)
wpush((long) ac); /* push argc */
}
PRIVATE size alignedstrlen(s)
char *s;
PRIVATE size alignedstrlen(char *s)
{
register size len = strlen(s) + 1;
return (len + wsize - 1) / wsize * wsize;
}
PRIVATE ptr storestring(addr, s)
ptr addr;
char *s;
PRIVATE ptr storestring(ptr addr, char *s)
{
/* Store string, aligned to a fit multiple of wsize bytes.
Return first address on a wordsize boundary after string.
@ -174,29 +178,7 @@ PRIVATE ptr storestring(addr, s)
return (addr + i);
}
#ifdef LOGGING
dt_clear_area(from, to)
ptr from;
register ptr to;
{
/* includes *from but excludes *to */
register ptr a;
for (a = from; a < to; a++) {
dt_undef(a);
}
}
st_clear_area(from, to)
ptr from;
register ptr to;
{
/* includes both *from and *to (since ML+1 is unexpressible) */
register ptr a;
for (a = from; a >= to; a--) {
st_undef(a);
}
}
#endif /* LOGGING */

View file

@ -1,35 +1,35 @@
/*
/** @file
In and output, error messages, etc.
*/
/* $Id$ */
#include <stdio.h>
#if __STDC__
#include <stdarg.h>
extern fatal(char *, ...);
#else
#include <varargs.h>
#endif
#include "logging.h"
#include "global.h"
#include "mem.h"
#include "io.h"
#include "warn.h"
#include "log.h"
#include "linfil.h"
extern int running; /* from main.c */
extern char *prog_name; /* from main.c */
extern char *load_name; /* from init.c */
extern void core_dump(void);
/******** The message file ********/
extern char mess_file[64]; /* from main.c */
long mess_id; /* Id, to determine unique mess file */
FILE *mess_fp; /* Filepointer of message file */
PRIVATE do_fatal();
PRIVATE void do_fatal(FILE *, char *, va_list);
incr_mess_id()
void incr_mess_id(void)
{ /* for a new child */
mess_id++;
}
@ -44,12 +44,11 @@ PRIVATE int highestfd();
int fd_limit = 100; /* first non-available file descriptor */
FILE *fcreat_high(fn)
char *fn;
/** Creates an unbuffered FILE with name "fn" on the highest
* possible file descriptor.
*/
FILE *fcreat_high(char *fn)
{
/* Creates an unbuffered FILE with name fn on the highest
possible file descriptor.
*/
register int fd;
register FILE *fp;
@ -63,13 +62,13 @@ FILE *fcreat_high(fn)
return fp;
}
PRIVATE int highestfd(fd)
int fd;
/** Moves the (open) file descriptor "fd" to the highest available
* position and returns the new "fd". Does this without knowing
* how many fd-s are available.
*/
PRIVATE int highestfd(int fd)
{
/* Moves the (open) file descriptor fd to the highest available
position and returns the new fd. Does this without knowing
how many fd-s are available.
*/
register int newfd, higherfd;
/* try to get a better fd */
@ -89,8 +88,7 @@ PRIVATE int highestfd(fd)
return higherfd; /* this is a deep one */
}
init_ofiles(firsttime)
int firsttime;
void init_ofiles(int firsttime)
{
if (!firsttime) {
fclose(mess_fp); /* old message file */
@ -110,9 +108,8 @@ init_ofiles(firsttime)
#endif /* LOGGING */
}
#if __STDC__
/*VARARGS0*/
fatal(char *fmt, ...)
void fatal(char *fmt, ...)
{
va_list ap;
@ -137,40 +134,8 @@ fatal(char *fmt, ...)
close_down(1);
}
#else
/*VARARGS0*/
fatal(va_alist)
va_dcl
{
va_list ap;
fprintf(stderr, "%s: ", prog_name);
va_start(ap);
{
register char *fmt = va_arg(ap, char *);
do_fatal(stderr, fmt, ap);
}
va_end(ap);
if (mess_fp) {
va_start(ap);
{
register char *fmt = va_arg(ap, char *);
do_fatal(mess_fp, fmt, ap);
}
va_end(ap);
}
if (running)
core_dump();
close_down(1);
}
#endif
close_down(rc)
int rc;
void close_down(int rc)
{
/* all exits should go through here */
if (mess_fp) {
@ -185,10 +150,7 @@ close_down(rc)
exit(rc);
}
PRIVATE do_fatal(fp, fmt, ap)
FILE *fp;
char *fmt;
va_list ap;
PRIVATE void do_fatal(FILE *fp, char *fmt, va_list ap)
{
fprintf(fp, "(Fatal error) ");
if (load_name)
@ -197,9 +159,8 @@ PRIVATE do_fatal(fp, fmt, ap)
fputc('\n', fp);
}
#if __STDC__
/*VARARGS0*/
message(char *fmt, ...)
void message(char *fmt, ...)
{
va_list ap;
@ -213,27 +174,8 @@ message(char *fmt, ...)
fprintf(mess_fp, " at %s\n", position());
}
#else
/*VARARGS0*/
message(va_alist)
va_dcl
{
va_list ap;
fprintf(mess_fp, "(Message): ");
va_start(ap);
{
register char *fmt = va_arg(ap, char *);
vfprintf(mess_fp, fmt, ap);
}
va_end(ap);
fprintf(mess_fp, " at %s\n", position());
}
#endif
char *position() /* transient */
char *position(void) /* transient */
{
static char buff[300];
register char *fn = dt_fname(getFIL());

16
util/int/io.h Normal file
View file

@ -0,0 +1,16 @@
/* Copyright (c) 2019 ACK Project.
* See the copyright notice in the ACK home directory,
* in the file "Copyright".
*
* Created on: 2019-03-16
*
*/
#ifndef IO_H_
#define IO_H_
void fatal(char *fmt, ...);
void message(char *fmt, ...);
void init_ofiles(int firsttime);
void close_down(int rc);
#endif /* IO_H_ */

View file

@ -1,6 +1,6 @@
/*
The logging machine
*/
The logging machine
*/
/* $Id$ */
@ -14,62 +14,65 @@
#include "logging.h"
#include "global.h"
#include "dump.h"
#include "linfil.h"
#include "io.h"
#ifdef LOGGING
extern long mess_id; /* from io.c */
extern FILE *fcreat_high(); /* from io.c */
extern long mess_id; /* from io.c */
extern FILE *fcreat_high(); /* from io.c */
/******** The Logging Machine Variables ********/
extern long atol();
long inr; /* current instruction number */
long inr; /* current instruction number */
int must_log; /* set if logging may be required */
long log_start; /* first instruction to be logged */
int logging; /* set as soon as logging starts */
int must_log; /* set if logging may be required */
long log_start; /* first instruction to be logged */
int logging; /* set as soon as logging starts */
PRIVATE long stop; /* inr after which to stop */
PRIVATE long gdump; /* inr at which to dump GDA */
PRIVATE ptr gmin, gmax; /* GDA dump limits */
PRIVATE long hdump; /* inr at which to dump the heap */
PRIVATE long stdsize; /* optional size of stack dump */
PRIVATE int stdrawflag; /* set if unformatted stack dump */
PRIVATE long stop; /* inr after which to stop */
PRIVATE long gdump; /* inr at which to dump GDA */
PRIVATE ptr gmin, gmax; /* GDA dump limits */
PRIVATE long hdump; /* inr at which to dump the heap */
PRIVATE long stdsize; /* optional size of stack dump */
PRIVATE int stdrawflag; /* set if unformatted stack dump */
PRIVATE char log_file[64] = "int.log"; /* Name of log file */
PRIVATE long at; /* patch to set log_start */
PRIVATE char *lmask; /* patch to set logmask */
PRIVATE char *logvar; /* Name of LOG variable */
PRIVATE int log_level[128]; /* Holds the log levels */
PRIVATE FILE *log_fp; /* Filepointer of log file */
PRIVATE char log_file[64] = "int.log"; /* Name of log file */
PRIVATE long at; /* patch to set log_start */
PRIVATE char *lmask; /* patch to set logmask */
PRIVATE char *logvar; /* Name of LOG variable */
PRIVATE int log_level[128]; /* Holds the log levels */
PRIVATE FILE *log_fp; /* Filepointer of log file */
/* arguments for the logging machine */
PRIVATE int argcount;
PRIVATE char *arglist[20]; /* arbitrary size */
PRIVATE char *arglist[20]; /* arbitrary size */
PRIVATE char *getpar();
PRIVATE long longpar();
PRIVATE set_lmask();
PRIVATE void set_lmask(char *mask);
PRIVATE char *getpar(char *);
PRIVATE long longpar(char *, long);
int logarg(str)
char *str;
int logarg(char *str)
{
/* If the string might be an interesting argument for the
logging machine, it is stored in the arglist, and logarg
succeeds. Otherwise it fails.
logging machine, it is stored in the arglist, and logarg
succeeds. Otherwise it fails.
The string is interesting if it contains a '='.
*/
The string is interesting if it contains a '='.
*/
register char *arg = str;
register char ch;
while ((ch = *arg) && (ch != '=')) {
while ((ch = *arg) && (ch != '='))
{
arg++;
}
if (ch == '=') {
if (argcount == (sizeof arglist /sizeof arglist[0]))
if (ch == '=')
{
if (argcount == (sizeof arglist / sizeof arglist[0]))
fatal("too many logging arguments on command line");
arglist[argcount++] = str;
return 1;
@ -77,39 +80,44 @@ int logarg(str)
return 0;
}
init_log()
void init_log(void)
{
/* setting the logging machine */
stop = longpar("STOP", 0L);
gdump = longpar("GDA", 0L);
if (gdump) {
if (gdump)
{
gmin = i2p(longpar("GMIN", 0L));
gmax = i2p(longpar("GMAX", 0L));
set_lmask("+1");
}
hdump = longpar("HEAP", 0L);
if (hdump) {
if (hdump)
{
set_lmask("*1");
}
stdsize = longpar("STDSIZE", 0L);
stdrawflag = longpar("RAWSTACK", 0L);
if (getpar("LOGFILE")) {
if (getpar("LOGFILE"))
{
strcpy(log_file, getpar("LOGFILE"));
}
if ((at = longpar("AT", 0L))) {
if ((at = longpar("AT", 0L)))
{
/* abbreviation for: */
stop = at + 1; /* stop AFTER at + 1 */
stop = at + 1; /* stop AFTER at + 1 */
/* Note: the setting of log_start is deferred to
init_ofiles(1), for implementation reasons. The
AT-variable presently only works for the top
level.
*/
init_ofiles(1), for implementation reasons. The
AT-variable presently only works for the top
level.
*/
}
if ((lmask = getpar("L"))) {
if ((lmask = getpar("L")))
{
/* abbreviation for: */
log_start = 0;
must_log = 1;
@ -118,132 +126,141 @@ init_log()
inr = 0;
}
/******** The log file ********/
open_log(firsttime)
int firsttime;
void open_log(int firsttime)
{
if (!firsttime) {
if (!firsttime)
{
sprintf(logvar, "%s%ld", logvar, mess_id);
if (log_fp) {
if (log_fp)
{
fclose(log_fp);
log_fp = 0;
}
logging = 0;
if ((must_log = getpar(logvar) != 0)) {
if ((must_log = getpar(logvar) != 0))
{
sprintf(log_file, "%s%ld", log_file, mess_id);
log_start = atol(getpar(logvar));
}
}
else {
else
{
/* first time, top level */
logvar = "LOG\0 ";
if (at) { /* patch */
if (at)
{ /* patch */
must_log = 1;
log_start = at - 1;
}
else
if (!must_log && (must_log = getpar(logvar) != 0)) {
else if (!must_log && (must_log = getpar(logvar) != 0))
{
log_start = atoi(getpar(logvar));
}
set_lmask(lmask ? lmask :
getpar("LOGMASK") ? getpar("LOGMASK") :
"A-Z9d2twx9");
set_lmask(
lmask ? lmask :
getpar("LOGMASK") ? getpar("LOGMASK") : "A-Z9d2twx9");
}
/* Create logfile if needed */
if (must_log) {
if (must_log)
{
if ((log_fp = fcreat_high(log_file)) == NULL)
fatal("Cannot create logfile '%s'", log_file);
}
if (must_log && inr >= log_start) {
if (must_log && inr >= log_start)
{
logging = 1;
}
}
close_log() {
if (log_fp) {
void close_log(void)
{
if (log_fp)
{
fclose(log_fp);
log_fp = 0;
}
}
/******** The logmask ********/
#define inrange(c,l,h) (l <= c && c <= h)
#define layout(c) (c == ' ' || c == '\t' || c == ',')
PRIVATE set_lmask(mask)
char *mask;
PRIVATE void set_lmask(char *mask)
{
register char *mp = mask;
while (*mp != 0) {
while (*mp != 0)
{
register char *lvp;
register int lev;
while (layout(*mp)) {
while (layout(*mp))
{
mp++;
}
/* find level */
lvp = mp;
while (*lvp != 0 && !inrange(*lvp, '0', '9')) {
while (*lvp != 0 && !inrange(*lvp, '0', '9'))
{
lvp++;
}
lev = *lvp - '0';
/* find classes */
while (mp != lvp) {
register mc = *mp;
while (mp != lvp)
{
register int mc = *mp;
if ( inrange(mc, 'a', 'z')
|| inrange(mc, 'A', 'Z')
|| mc == '+'
|| mc == '*'
) {
if ( inrange(mc, 'a', 'z') || inrange(mc, 'A', 'Z') || mc == '+'
|| mc == '*')
{
log_level[mc] = lev;
mp++;
}
else if (mc == '-') {
else if (mc == '-')
{
register char c;
for (c = *(mp-1) + 1; c <= *(mp + 1); c++) {
log_level[c] = lev;
for (c = *(mp - 1) + 1; c <= *(mp + 1); c++)
{
log_level[(unsigned char)c] = lev;
}
mp += 2;
}
else if (layout(mc)) {
else if (layout(mc))
{
mp++;
}
else fatal("Bad logmask initialization string");
else
fatal("Bad logmask initialization string");
}
mp = lvp + 1;
}
}
/******** The logging ********/
int check_log(mark)
char mark[];
int check_log(char mark[])
{
/* mark must be of the form ".CL...", C is class letter,
L is level digit.
*/
L is level digit.
*/
if (!logging)
return 0;
return ((mark[2] - '0') <= log_level[mark[1]]);
return ((mark[2] - '0') <= log_level[(unsigned char)mark[1]]);
}
#if __STDC__
/*VARARGS*/
do_log(char *fmt, ...)
void do_log(char *fmt, ...)
{
va_list ap;
@ -251,26 +268,28 @@ do_log(char *fmt, ...)
{
#else
/*VARARGS*/
do_log(va_alist)
va_dcl
{
va_list ap;
/*VARARGS*/
do_log(va_alist)
va_dcl
{
va_list ap;
va_start(ap);
{
char *fmt = va_arg(ap, char *);
va_start(ap);
{
char *fmt = va_arg(ap, char *);
#endif
if (!check_log(fmt))
return;
if (fmt[0] == '@') {
if (fmt[0] == '@')
{
/* include position */
fprintf(log_fp, "%.4s%s, ", fmt, position());
vfprintf(log_fp, &fmt[4], ap);
}
else {
else
{
vfprintf(log_fp, &fmt[0], ap);
}
}
@ -279,10 +298,11 @@ do_log(va_alist)
putc('\n', log_fp);
}
log_eoi()
void log_eoi(void)
{
/* Logging to be done at end of instruction */
if (logging) {
if (logging)
{
if (inr == gdump)
gdad_all(gmin, gmax);
if (inr == hdump)
@ -290,40 +310,42 @@ log_eoi()
std_all(stdsize, stdrawflag);
}
if (inr == stop) {
if (inr == stop)
{
message("program stopped on request");
close_down(0);
}
}
/******** Service routines ********/
PRIVATE char *getpar(var)
char *var;
PRIVATE char *getpar(char *var)
{
/* Looks up the name in the argument list.
*/
*/
register int count;
register int ln = strlen(var);
for (count = 0; count < argcount; count++) {
for (count = 0; count < argcount; count++)
{
register char *arg = arglist[count];
if (strncmp(var, arg, ln) == 0 && arg[ln] == '=') {
return &arg[ln+1];
if (strncmp(var, arg, ln) == 0 && arg[ln] == '=')
{
return &arg[ln + 1];
}
}
return 0;
}
PRIVATE long longpar(var, def)
char *var; /* name of the variable */
long def; /* default value */
PRIVATE long longpar(
char *var, /* name of the variable */
long def /* default value */
)
{
register char *res = getpar(var);
return (res ? atol(res) : def);
}

View file

@ -16,6 +16,19 @@ extern int logging; /* set if logging in progress */
#define LOG(a) { if (logging) do_log a; }
/* Initalize logging system. */
void init_log(void);
int logarg(char *str);
/* Open the log file. */
void open_log(int firsttime);
/* Close the log file. */
void close_log(void);
int check_log(char mark[]);
/* Log an entry into the logfile. */
void do_log(char *fmt, ...);
void log_eoi(void);
#else
#define LOG(a)

View file

@ -1,6 +1,6 @@
/*
Dedicated treatment of the sigtrp system call, MON 48.
*/
/** @file
* Dedicated treatment of the sigtrp system call, MON 48.
*/
/* $Id$ */
@ -10,6 +10,8 @@
#include "log.h"
#include "warn.h"
#include "trap.h"
#include "m_sigtrp.h"
#include "io.h"
/*************************** SIGTRP *************************************
* The monitor call "sigtrp()" is handled by "do_sigtrp()". The first *
@ -26,31 +28,39 @@
#ifndef NSIG
#define NSIG _NSIG
#endif
PRIVATE int sig_map[NSIG+1]; /* maps signals onto trap numbers */
PRIVATE int sig_map[NSIG + 1]; /* maps signals onto trap numbers */
PRIVATE void HndlIntSig(); /* handle signal to interpreter */
PRIVATE void HndlEmSig(); /* handle signal to user program */
PRIVATE void HndlIntSig(int); /* handle signal to interpreter */
PRIVATE void HndlEmSig(int); /* handle signal to user program */
init_signals() {
void init_signals(void)
{
int sn;
for (sn = 0; sn < NSIG+1; sn++) {
sig_map[sn] = -2; /* Default EM trap number */
for (sn = 0; sn < NSIG + 1; sn++)
{
sig_map[sn] = -2; /* Default EM trap number */
}
for (sn = 0; sn < NSIG+1; sn++) {
for (sn = 0; sn < NSIG + 1; sn++)
{
/* for all signals that would cause termination */
if (!UNIX_trap(sn)) {
if (!UNIX_trap(sn))
{
#ifdef SIGCHLD
if (sn == SIGCHLD) continue;
if (sn == SIGCHLD)
continue;
#endif
#ifdef SIGIO
if (sn == SIGIO) continue;
if (sn == SIGIO)
continue;
#endif
#ifdef SIGWINCH
if (sn == SIGWINCH) continue;
if (sn == SIGWINCH)
continue;
#endif
if (signal(sn, SIG_IGN) != SIG_IGN) {
if (signal(sn, SIG_IGN) != SIG_IGN)
{
/* we take our fate in our own hand */
signal(sn, HndlIntSig);
}
@ -58,74 +68,79 @@ init_signals() {
}
}
int do_sigtrp(tn, sn)
int tn; /* EM trap number */
int sn; /* UNIX signal number */
int do_sigtrp(
int tn, /* EM trap number */
int sn /* UNIX signal number */
)
{
register int old_tn;
if (sn <= 0 || sn > NSIG) {
if (sn <= 0 || sn > NSIG)
{
einval(WILLSN);
return (-1);
}
if (UNIX_trap(sn)) {
if (UNIX_trap(sn))
{
einval(WUNIXTR);
return (-1);
}
old_tn = sig_map[sn];
sig_map[sn] = tn;
if (tn == -2) { /* reset default for signal sn */
if (tn == -2)
{ /* reset default for signal sn */
signal(sn, SIG_DFL);
}
else if (tn == -3) { /* ignore signal sn */
else if (tn == -3)
{ /* ignore signal sn */
signal(sn, SIG_IGN);
}
else if (tn >= 0 && tn <= 252) {/* legal tn */
if ((int)signal(sn, HndlEmSig) == -1) {
else if (tn >= 0 && tn <= 252)
{/* legal tn */
if ((int) signal(sn, HndlEmSig) == -1)
{
sig_map[sn] = old_tn;
return (-1);
}
}
else {
else
{
/* illegal trap number */
einval(WILLTN);
sig_map[sn] = old_tn; /* restore sig_map */
sig_map[sn] = old_tn; /* restore sig_map */
return (-1);
}
return (old_tn);
}
trap_signal()
/** Execute the trap belonging to the signal that came in during
* the last instruction
*/
void trap_signal(void)
{
/* execute the trap belonging to the signal that came in during
the last instruction
*/
register int old_sig = signalled;
signalled = 0;
trap(sig_map[old_sig]);
}
/* The handling functions for the UNIX signals */
PRIVATE void HndlIntSig(sn)
int sn;
PRIVATE void HndlIntSig(int sn)
{
/* The interpreter got the signal */
signal(sn, SIG_IGN); /* peace and quiet for close_down() */
signal(sn, SIG_IGN); /* peace and quiet for close_down() */
LOG(("@t1 signal %d caught by interpreter", sn));
message("interpreter received signal %d, which was not caught by the interpreted program",
sn);
message(
"interpreter received signal %d, which was not caught by the interpreted program",
sn);
close_down(1);
}
PRIVATE void HndlEmSig(sn)
int sn;
PRIVATE void HndlEmSig(int sn)
{
/* The EM machine got the signal */
signal(sn, HndlIntSig); /* Revert to old situation */
signal(sn, HndlIntSig); /* Revert to old situation */
signalled = sn;
}

15
util/int/m_sigtrp.h Normal file
View file

@ -0,0 +1,15 @@
/* Copyright (c) 2019 ACK Project.
* See the copyright notice in the ACK home directory,
* in the file "Copyright".
*
* Created on: 2019-03-17
*
*/
#ifndef M_SIGTRP_H_
#define M_SIGTRP_H_
void init_signals(void);
int do_sigtrp(int tn, int sn);
void trap_signal(void);
#endif /* M_SIGTRP_H_ */

View file

@ -15,11 +15,13 @@
#include "nofloat.h"
#include "global.h"
#include "log.h"
#include "io.h"
#include "trap.h"
#include "warn.h"
#include "text.h"
#include "read.h"
#include "opcode.h"
#include "m_sigtrp.h"
#include "rsb.h"
char mess_file[64] = "int.mess"; /* name of message file */
@ -37,9 +39,13 @@ extern long inr; /* from log.c */
PRIVATE char *dflt_av[] = {"e.out", 0}; /* default arguments */
main(argc, argv)
int argc;
char *argv[];
/* External definitions - too lazy to create a header file for each. */
extern void init(int , char **);
extern void disassemble(void);
extern void tally(void);
extern void out_tally(void);
int main(int argc, char *argv[])
{
register int i;
register int nosetjmp = 1;

View file

@ -4,6 +4,7 @@
/* $Id$ */
#include "stack.h"
/******** Memory address & location defines ********/

View file

@ -123,13 +123,13 @@ PRIVATE check_buf();
PRIVATE int savestr();
PRIVATE int vec();
moncall()
void moncall(void)
{
int n; /* number actually read/written */
int status; /* status for wait-call */
int flag; /* various flag parameters */
int mode; /* various mode parameters */
int oldmask; /* for umask call */
mode_t oldmask; /* for umask call */
int whence; /* parameter for lseek */
int address; /* address parameter typed int2 */
int owner; /* owner parameter typed int2 */
@ -987,7 +987,7 @@ moncall()
case 60: /* Umask */
mode = pop_int2();
oldmask = umask(mode);
oldmask = umask((mode_t)mode);
push_int(oldmask);
LOG(("@m9 Umask: succeeded, mode = %d, oldmask = %d",
mode, oldmask));

View file

@ -1,5 +1,5 @@
/*
Handling the proctable
/** @file
proctable management routines.
*/
/* $Id$ */
@ -7,22 +7,27 @@
#include "logging.h"
#include "global.h"
#include "log.h"
#include "io.h"
#include "alloc.h"
#include "proctab.h"
/** Procedure table */
struct proc *proctab;
PRIVATE long pr_cnt;
init_proctab()
/** Allocates and initializes the procedure table. */
void init_proctab(void)
{
proctab = (struct proc *)
Malloc(NProc * sizeof (struct proc), "proctable");
pr_cnt = 0;
}
add_proc(nloc, ep)
size nloc;
ptr ep;
/** Add a procedure to the procedure entry table.
* "ep" is the pointer to the entry point of the
* procedure to add.
*/
void add_proc(size nloc, ptr ep)
{
register struct proc *pr = &proctab[pr_cnt++];
register struct proc *p;
@ -55,7 +60,7 @@ add_proc(nloc, ep)
pr->pr_ff = ff;
}
end_init_proctab()
void end_init_proctab(void)
{
#ifdef LOGGING
register long p;

View file

@ -1,9 +1,13 @@
/*
Handling the proctable
*/
#ifndef PROCTAB_H_
#define PROCTAB_H_
/* $Id$ */
#include "global.h"
struct proc {
size pr_nloc;
ptr pr_ep;
@ -11,3 +15,9 @@ struct proc {
};
extern struct proc *proctab;
void init_proctab(void);
void add_proc(size, ptr);
void end_init_proctab(void);
#endif /* PROCTAB_H_ */

View file

@ -1,18 +1,21 @@
/*
Reading the EM object file
*/
/** @file
* Reading the EM object file
*/
/* $Id$ */
#include <stdio.h>
#include <local.h> /* for VERSION */
#include <em_spec.h>
#include <as_spec.h> /* for as_magic */
#include "local.h" /* for VERSION */
#include "em_spec.h"
#include "as_spec.h" /* for as_magic */
#include "logging.h"
#include "nofloat.h"
#include "global.h"
#include "log.h"
#include "io.h"
#include "data.h"
#include "proctab.h"
#include "warn.h"
#include "mem.h"
#include "shadow.h"
@ -49,22 +52,22 @@ long ENTRY;
long NLINE;
size SZDATA;
PRIVATE FILE *load_fp; /* Filepointer of load file */
PRIVATE FILE *load_fp; /* Filepointer of load file */
PRIVATE ptr rd_repeat();
PRIVATE ptr rd_descr();
PRIVATE int rd_byte();
PRIVATE long rd_int();
PRIVATE ptr rd_repeat(ptr, size, ptr);
PRIVATE ptr rd_descr(int, size, ptr);
PRIVATE int rd_byte(void);
PRIVATE long rd_int(size);
rd_open(fname)
char *fname;
{ /* Open loadfile */
if ((load_fp = fopen(fname, "r")) == NULL) {
void rd_open(char *fname)
{ /* Open loadfile */
if ((load_fp = fopen(fname, "r")) == NULL)
{
fatal("Cannot open loadfile '%s'", fname);
}
}
rd_header()
void rd_header(void)
{
/* Part 1 */
if (rd_int(2L) != as_magic)
@ -81,22 +84,22 @@ rd_header()
/* We only allow the following wordsize/pointersize combinations: */
/* 2/2, 2/4, 4/4 */
/* A fatal error will be generated if other combinations occur. */
wsize = rd_int(2L);
if (!(wsize == 2 || wsize == 4))
fatal("Bad wordsize in loadfile");
dwsize = 2 * wsize; /* set double wordsize */
wsizem1 = wsize - 1; /* wordsize - 1 used often */
dwsize = 2 * wsize; /* set double wordsize */
wsizem1 = wsize - 1; /* wordsize - 1 used often */
psize = rd_int(2L);
if (!(psize == 2 || psize == 4) || psize < wsize)
fatal("Bad pointersize in loadfile");
if (2 * psize > FRALimit)
fatal("FRA maximum size too small");
rd_int(2L); /* Entry 7 is unused */
rd_int(2L); /* Entry 8 is unused */
rd_int(2L); /* Entry 7 is unused */
rd_int(2L); /* Entry 8 is unused */
/* Part 2 */
NTEXT = rd_int(psize);
@ -106,49 +109,53 @@ rd_header()
if (ENTRY < 0 || ENTRY >= NPROC)
fatal("Bad entry point");
NLINE = rd_int(psize);
if (NLINE == 0) {
if (NLINE == 0)
{
warning(WNLINEZR);
NLINE = I_MAXS4;
}
SZDATA = rd_int(psize);
rd_int(psize); /* entry 7 is unused */
rd_int(psize); /* entry 8 is unused */
rd_int(psize); /* entry 7 is unused */
rd_int(psize); /* entry 8 is unused */
}
rd_text()
void rd_text(void)
{
fread(text, 1, (int) DB, load_fp);
}
rd_gda()
void rd_gda(void)
{
register int type, prev_type;
register ptr pos, prev_pos; /* prev_pos invalid if prev_type==0 */
register ptr pos, prev_pos; /* prev_pos invalid if prev_type==0 */
register long i;
type = prev_type = 0;
pos = prev_pos = i2p(0);
for (i = 1; i <= NDATA; i++) {
for (i = 1; i <= NDATA; i++)
{
type = btol(rd_byte());
LOG((" r6 rd_gda(), i = %ld, pos = %u", i, pos));
if (type == 0) {
if (type == 0)
{
/* repetition descriptor */
register size count = rd_int(psize);
LOG((" r6 rd_gda(), case 0: count = %lu", count));
if (prev_type == 0) {
if (prev_type == 0)
{
fatal("Type 0 initialisation on type 0");
}
pos = rd_repeat(pos, count, prev_pos);
prev_type = 0;
}
else {
else
{
/* filling descriptor */
register size count = btol(rd_byte());
LOG((" r6 rd_gda(), case %d: count = %lu",
type, count));
LOG((" r6 rd_gda(), case %d: count = %lu", type, count));
prev_pos = pos;
pos = rd_descr(type, count, prev_pos);
prev_type = type;
@ -160,12 +167,13 @@ rd_gda()
dt_prot(i2p(4), psize);
}
rd_proctab()
void rd_proctab(void)
{
register long p;
init_proctab();
for (p = 0; p < NPROC; p++) {
for (p = 0; p < NPROC; p++)
{
register long nloc = rd_int(psize);
register ptr ep = i2p(rd_int(psize));
@ -174,7 +182,7 @@ rd_proctab()
end_init_proctab();
}
rd_close()
void rd_close(void)
{
fclose(load_fp);
load_fp = 0;
@ -199,17 +207,17 @@ rd_close()
* number is also stored in a double. *
************************************************************************/
PRIVATE ptr rd_repeat(pos, count, prev_pos)
ptr pos, prev_pos;
size count;
PRIVATE ptr rd_repeat(ptr pos, size count, ptr prev_pos)
{
register size diff = pos - prev_pos;
register size j;
for (j = 0; j < count; j++) {
for (j = 0; j < count; j++)
{
register long i;
for (i = 0; i < diff; i++) {
for (i = 0; i < diff; i++)
{
data_loc(pos) = data_loc(pos - diff);
#ifdef LOGGING
/* copy shadow byte, including protection bit */
@ -221,64 +229,68 @@ PRIVATE ptr rd_repeat(pos, count, prev_pos)
return pos;
}
PRIVATE ptr rd_descr(type, count, pos)
int type;
size count;
ptr pos;
PRIVATE ptr rd_descr(int type, size count, ptr pos)
{
register size j;
char fl_rep[128]; /* fp number representation */
char fl_rep[128]; /* fp number representation */
register int fl_cnt;
switch (type) {
case 1: /* m uninitialized words */
switch (type)
{
case 1: /* m uninitialized words */
j = count;
while (j--) {
while (j--)
{
dt_stw(pos, 0L);
pos += wsize;
}
break;
case 2: /* m initialized bytes */
case 2: /* m initialized bytes */
j = count;
while (j--) {
while (j--)
{
dt_stn(pos++, btol(rd_byte()), 1L);
}
break;
case 3: /* m initialized wordsize integers */
for (j = 0; j < count; j++) {
case 3: /* m initialized wordsize integers */
for (j = 0; j < count; j++)
{
dt_stw(pos, rd_int(wsize));
pos += wsize;
}
break;
case 4: /* m initialized data pointers */
for (j = 0; j < count; j++) {
case 4: /* m initialized data pointers */
for (j = 0; j < count; j++)
{
dt_stdp(pos, i2p(rd_int(psize)));
pos += psize;
}
break;
case 5: /* m initialized instruction pointers */
for (j = 0; j < count; j++) {
case 5: /* m initialized instruction pointers */
for (j = 0; j < count; j++)
{
dt_stip(pos, i2p(rd_int(psize)));
pos += psize;
}
break;
case 6: /* initialized integer of size m */
case 7: /* initialized unsigned int of size m */
case 6: /* initialized integer of size m */
case 7: /* initialized unsigned int of size m */
if ((j = count) != 1 && j != 2 && j != 4)
fatal("Bad integersize during initialisation");
dt_stn(pos, rd_int(j), j);
pos += j;
break;
case 8: /* initialized float of size m */
case 8: /* initialized float of size m */
if ((j = count) != 4 && j != 8)
fatal("Bad floatsize during initialisation");
/* get fp representation */
fl_cnt = 0;
while (fl_rep[fl_cnt] = rd_byte()) {
while ( (fl_rep[fl_cnt] = rd_byte()) )
{
fl_cnt++;
if (fl_cnt >= sizeof (fl_rep)) {
fatal("Initialized float longer than %d chars",
sizeof (fl_rep));
if (fl_cnt >= sizeof(fl_rep))
{
fatal("Initialized float longer than %d chars", sizeof(fl_rep));
}
}
#ifndef NOFLOAT
@ -297,24 +309,24 @@ PRIVATE ptr rd_descr(type, count, pos)
return pos;
}
PRIVATE int rd_byte()
PRIVATE int rd_byte(void)
{
register int i;
if ((i = getc(load_fp)) == EOF)
fatal("EOF reached during initialization");
return (i);
}
PRIVATE long rd_int(n)
size n;
PRIVATE long rd_int(size n)
{
register long l;
register int i;
l = btol(rd_byte());
for (i = 1; i < n; i++) {
l |= (btol(rd_byte()) << (i*8));
for (i = 1; i < n; i++)
{
l |= (btol(rd_byte()) << (i * 8));
}
return (l);
}

View file

@ -16,3 +16,30 @@ extern long NPROC; /* number of procedure descriptors */
extern long ENTRY; /* procedure identifier of start procedure */
extern long NLINE; /* the maximum source line number */
extern size SZDATA; /* number of gda bytes after initialization */
/* Open e.out file with "fname". Raise a fatal error if
it cannot be opened. */
void rd_open(char *fname);
/* Read the header of the load file and populates
* the "FLAGS", "NTEXT", "NDATA", "NPROC", "ENTRY", "NLINE"
* and "SZDATA" variables. A fatail error is raised
* if there is an error reading the load file.
*/
void rd_header(void);
/* Read the text segment from the load file into the
* the address pointed to by the "text" variable.
*/
void rd_text(void);
/* Read and populate the data segment from the load file
* into the address pointed to by the "data" variable.
*/
void rd_gda(void);
/* Read the procedure table from the load file. */
void rd_proctab(void);
/* Close the load file. */
void rd_close(void);

View file

@ -11,6 +11,8 @@
#include "proctab.h"
#include "linfil.h"
#include "shadow.h"
#include "segment.h"
#include "text.h"
#include "warn.h"
/* offsets to be added to a local base */
@ -22,7 +24,7 @@ int rsb_LIN;
int rsb_FIL;
int rsbsize;
init_rsb()
void init_rsb(void)
{
rsb_rsbcode = 0;
rsb_PI = wsize;
@ -33,8 +35,7 @@ init_rsb()
rsbsize = rsb_FIL + psize;
}
pushrsb(rsbcode)
int rsbcode;
void pushrsb(int rsbcode)
{
/* fill Return Status Block */
incSP((size)rsbsize);
@ -61,8 +62,7 @@ pushrsb(rsbcode)
}
/*ARGSUSED*/
int poprsb(rtt)
int rtt; /* set to 1 if working for RTT */
int poprsb(int rtt) /* set to 1 if working for RTT */
{
/* pops the RSB and returns the rsbcode, for further testing */
register int rsbcode;

View file

@ -29,3 +29,6 @@ extern int rsbsize;
#define is_LB(p) ((st_lds(p+rsb_rsbcode, wsize) & RSBMASK) == RSBCODE)
void init_rsb(void);
void pushrsb(int rsbcode);
int poprsb(int rtt);

View file

@ -11,6 +11,7 @@
/* $Id$ */
#include "segcheck.h"
#include "segment.h"
#include "global.h"
#include "mem.h"
#include "alloc.h"
@ -26,17 +27,16 @@ PRIVATE ptr *AB_list;
PRIVATE size frame_limit;
PRIVATE size curr_frame;
init_AB_list() {
/* Allocate space for AB_list & initialize frame variables */
/** Allocate space for AB_list & initialize frame variables */
void init_AB_list(void)
{
frame_limit = ABLISTSIZE;
curr_frame = 0L;
AB_list = (ptr *) Malloc(frame_limit * sizeof (ptr), "AB_list");
AB_list[curr_frame] = AB;
}
push_frame(p)
ptr p;
void push_frame(ptr p)
{
if (++curr_frame == frame_limit) {
frame_limit = allocfrac(frame_limit);
@ -46,14 +46,14 @@ push_frame(p)
AB_list[curr_frame] = p;
}
pop_frames() {
void pop_frames(void)
{
while (AB_list[curr_frame] < AB) {
curr_frame--;
}
}
int ptr2seg(p)
ptr p;
int ptr2seg(ptr p)
{
register int s;
@ -74,11 +74,11 @@ int ptr2seg(p)
#else /* SEGCHECK */
init_AB_list() {}
void init_AB_list(void) {}
push_frame() {}
void push_frame(ptr) {}
pop_frames() {}
void pop_frames(void) {}
#endif /* SEGCHECK */

18
util/int/segment.h Normal file
View file

@ -0,0 +1,18 @@
/* Copyright (c) 2019 ACK Project.
* See the copyright notice in the ACK home directory,
* in the file "Copyright".
*
* Created on: 2019-03-16
*
*/
#ifndef SEGMENT_H_
#define SEGMENT_H_
#include "global.h"
void init_AB_list(void);
void push_frame(ptr);
void pop_frames(void);
int ptr2seg(ptr);
#endif /* SEGMENT_H_ */

View file

@ -1,12 +1,12 @@
/*
Stack manipulation
/** \file
Stack manipulation routines.
*/
/* $Id$ */
#include <stdio.h>
#include <em_abs.h>
#include "em_abs.h"
#include "logging.h"
#include "nofloat.h"
#include "global.h"
@ -17,27 +17,33 @@
#include "memdirect.h"
#include "mem.h"
#include "shadow.h"
#include "stack.h"
#include "data.h"
#include "rsb.h"
#define STACKSIZE 1000L /* initial stack size */
/** initial stack size in bytes */
#define STACKSIZE 1000L
extern size maxstack; /* from main.c */
extern size maxstack; /* from main.c */
#ifdef LOGGING
char *stack_sh; /* stadowbytes */
char *stackML_sh; /* speed up access of stadowbytes */
char *stack_sh; /* stadowbytes */
char *stackML_sh; /* speed up access of stadowbytes */
PRIVATE void st_clear_area(ptr, ptr);
#endif /* LOGGING */
PRIVATE warn_stbits();
PRIVATE void warn_stbits(ptr, size);
init_stack() {
ML = max_addr; /* set Memory Limit */
SP = ML + 1; /* initialize Stack Pointer */
SL = ML + 1; /* initialize Stack Limit */
LB = ML + 1; /* initialize Local Base */
AB = ML + 1; /* initialize Actual Base */
/** Initialize and allocate the operand stack space "stack". */
void init_stack(void)
{
ML = max_addr; /* set Memory Limit */
SP = ML + 1; /* initialize Stack Pointer */
SL = ML + 1; /* initialize Stack Limit */
LB = ML + 1; /* initialize Local Base */
AB = ML + 1; /* initialize Actual Base */
SL = ML + 1 - STACKSIZE; /* initialize Stack Limit */
SL = ML + 1 - STACKSIZE; /* initialize Stack Limit */
stack = Malloc(STACKSIZE, "stack space");
stackML = stack + ML;
#ifdef LOGGING
@ -47,7 +53,6 @@ init_stack() {
#endif /* LOGGING */
}
/************************************************************************
* EM-register division. *
************************************************************************
@ -59,40 +64,49 @@ init_stack() {
* *
************************************************************************/
newSP(ap)
ptr ap;
/** Set the value of the stack pointer "SP" to the value "ap".
* Full validation of the new value is done beforehand.
*/
void newSP(ptr ap)
{
register ptr p = ap;
LOG(("@s6 newSP(%lu), ML = %lu, SP = %lu", p, ML, SP));
if (LB < p) {
if (LB < p)
{
wtrap(WSPGTLB, ESTACK);
}
if (!is_wordaligned(p)) {
if (!is_wordaligned(p))
{
wtrap(WSPODD, ESTACK);
}
if (p < SP) {
if (p < HP) {
if (p < SP)
{
if (p < HP)
{
wtrap(WSPINHEAP, ESTACK);
}
if (maxstack) {
if (maxstack)
{
/* more than allowed on command line */
if (ML - p > maxstack) {
if (ML - p > maxstack)
{
warning(WESTACK);
trap(ESTACK);
}
}
if (p < SL) {
if (p < SL)
{
/* extend stack space */
register size stacksize = ML + 1 - p;
stacksize = allocfrac(stacksize);
SL = ML + 1 - stacksize;
stack = Realloc(stack, (size)(stacksize), "stack space");
stack = Realloc(stack, (size) (stacksize), "stack space");
stackML = stack + ML;
#ifdef LOGGING
stack_sh = Realloc(stack_sh, (size)(stacksize),
"shadowspace for stack");
stack_sh = Realloc(stack_sh, (size) (stacksize),
"shadowspace for stack");
stackML_sh = stack_sh + ML;
#endif /* LOGGING */
}
@ -104,23 +118,25 @@ newSP(ap)
SP = p;
}
incSP(n)
#ifdef LOGGING
register
#endif
size n;
/** Increment stack pointer "SP" by "n" bytes.
* Full validation on stack alignment and address is done.
*/
void incSP(size n)
{
register ptr p = SP - n;
if (p < HP || maxstack || p < SL) newSP(p);
else {
if (p < HP || maxstack || p < SL)
newSP(p);
else
{
LOG(("@s6 newSP(%lu), ML = %lu, SP = %lu", p, ML, SP));
#ifdef LOGGING
/* inline version of st_clear_area.
*/
*/
SP = p;
{
while (n--) {
while (n--)
{
st_undef(p);
p++;
}
@ -129,35 +145,40 @@ incSP(n)
}
}
decSP(n)
size n;
/** Decrement stack pointer "SP" by "n" bytes.
* Full validation on stack alignment and address is done.
*/
void decSP(size n)
{
register ptr p = SP + n;
if (LB < p) newSP(p);
else {
if (LB < p)
newSP(p);
else
{
LOG(("@s6 newSP(%lu), ML = %lu, SP = %lu", p, ML, SP));
SP = p;
}
}
newLB(p)
ptr p;
void newLB(ptr p)
{
if (!in_stack(p)) {
if (!in_stack(p))
{
wtrap(WLBOUT, ESTACK);
}
if (!is_wordaligned(p)) {
if (!is_wordaligned(p))
{
wtrap(WLBODD, ESTACK);
}
if (!is_LB(p)) {
if (!is_LB(p))
{
wtrap(WLBRSB, ESTACK);
}
LB = p;
AB = LB + rsbsize;
}
/************************************************************************
* Stack store division. *
************************************************************************
@ -170,9 +191,10 @@ newLB(p)
* *
************************************************************************/
st_stdp(addr, ap)
register ptr addr;
ptr ap;
/** Store data pointer "ap" in stack at address "addr".
* Full validation is done on "addr" before storing into it.
*/
void st_stdp(register ptr addr, ptr ap)
{
register int i;
register long p = (long) ap;
@ -180,18 +202,20 @@ st_stdp(addr, ap)
LOG(("@s6 st_stdp(%lu, %lu)", addr, p));
ch_in_stack(addr, psize);
ch_wordaligned(addr);
for (i = (int) psize; i > 0; i--, addr++) {
for (i = (int) psize; i > 0; i--, addr++)
{
ch_st_prot(addr);
stack_loc(addr) = (char) (p);
st_dp(addr);
p = p>>8;
p = p >> 8;
}
}
st_stip(addr, ap)
register ptr addr;
ptr ap;
/** Store code pointer "ap" in stack address "addr".
* Full validation is done on "addr" before storing into it.
*/
void st_stip(register ptr addr, ptr ap)
{
register int i;
register long p = (long) ap;
@ -199,24 +223,25 @@ st_stip(addr, ap)
LOG(("@s6 st_stip(%lu, %lu)", addr, p));
ch_in_stack(addr, psize);
ch_wordaligned(addr);
for (i = (int) psize; i > 0; i--, addr++) {
for (i = (int) psize; i > 0; i--, addr++)
{
ch_st_prot(addr);
stack_loc(addr) = (char) (p);
st_ip(addr);
p = p>>8;
p = p >> 8;
}
}
st_stn(addr, al, n)
register ptr addr;
long al;
size n;
/** Store an integer value "al" of "n" bytes in size in stack at address "addr".
* Full validation is done on "addr" before storing into it.
*/
void st_stn(register ptr addr, long al, size n)
{
register int i;
register long l = al;
#ifdef LOGGING
/* a psize zero is ambiguous */
int sh_flags = (l == 0 && n == psize) ? (SH_INT|SH_DATAP) : SH_INT;
int sh_flags = (l == 0 && n == psize) ? (SH_INT | SH_DATAP) : SH_INT;
#endif
LOG(("@s6 st_stn(%lu, %ld, %lu)", addr, l, n));
@ -224,25 +249,27 @@ st_stn(addr, al, n)
ch_aligned(addr, n);
/* store the bytes */
for (i = (int) n; i > 0; i--, addr++) {
for (i = (int) n; i > 0; i--, addr++)
{
ch_st_prot(addr);
stack_loc(addr) = (char) l;
#ifdef LOGGING
st_sh(addr) = sh_flags;
#endif /* LOGGING */
l = l>>8;
l = l >> 8;
}
}
st_stw(addr, al)
register ptr addr;
long al;
/** Store an integer value "al" of word size bytes in stack at address "addr".
* Full validation is done on "addr" before storing into it.
*/
void st_stw(register ptr addr, long al)
{
register int i;
register long l = al;
#ifdef LOGGING
/* a psize zero is ambiguous */
int sh_flags = (l == 0 && wsize == psize) ? (SH_INT|SH_DATAP) : SH_INT;
int sh_flags = (l == 0 && wsize == psize) ? (SH_INT | SH_DATAP) : SH_INT;
#endif
LOG(("@s6 st_stw(%lu, %ld)", addr, l));
@ -250,21 +277,22 @@ st_stw(addr, al)
ch_wordaligned(addr);
/* store the bytes */
for (i = (int) wsize; i > 0; i--, addr++) {
for (i = (int) wsize; i > 0; i--, addr++)
{
ch_st_prot(addr);
stack_loc(addr) = (char) l;
#ifdef LOGGING
st_sh(addr) = sh_flags;
#endif /* LOGGING */
l = l>>8;
l = l >> 8;
}
}
#ifndef NOFLOAT
st_stf(addr, f, n)
register ptr addr;
double f;
size n;
/** Store a real value "f" of "n" bytes in size in stack at address "addr".
* Full validation is done on "addr" before storing into it.
*/
void st_stf(register ptr addr, double f, size n)
{
register char *cp = (char *) &f;
float fl;
@ -273,11 +301,13 @@ st_stf(addr, f, n)
LOG(("@s6 st_stf(%lu, %g, %lu)", addr, f, n));
ch_in_stack(addr, n);
ch_wordaligned(addr);
if ((int) n == 4) {
if ((int) n == 4)
{
fl = f;
cp = (char *) &fl;
}
for (i = (int) n; i > 0; i--, addr++) {
for (i = (int) n; i > 0; i--, addr++)
{
ch_st_prot(addr);
stack_loc(addr) = *(cp++);
st_fl(addr);
@ -299,8 +329,10 @@ st_stf(addr, f, n)
* *
************************************************************************/
ptr st_lddp(addr)
register ptr addr;
/** Loads and returns a data pointer stored on the stack
* at address "addr".
*/
ptr st_lddp(register ptr addr)
{
register ptr p;
@ -309,7 +341,8 @@ ptr st_lddp(addr)
ch_in_stack(addr, psize);
ch_wordaligned(addr);
#ifdef LOGGING
if (!is_st_set(addr, psize, SH_DATAP)) {
if (!is_st_set(addr, psize, SH_DATAP))
{
warning(WLDPEXP);
warn_stbits(addr, psize);
}
@ -320,8 +353,10 @@ ptr st_lddp(addr)
return (p);
}
ptr st_ldip(addr)
register ptr addr;
/** Loads and returns a core pointer stored on the stack
* at address "addr".
*/
ptr st_ldip(register ptr addr)
{
register ptr p;
@ -330,7 +365,8 @@ ptr st_ldip(addr)
ch_in_stack(addr, psize);
ch_wordaligned(addr);
#ifdef LOGGING
if (!is_st_set(addr, psize, SH_INSP)) {
if (!is_st_set(addr, psize, SH_INSP))
{
warning(WLIPEXP);
warn_stbits(addr, psize);
}
@ -341,9 +377,11 @@ ptr st_ldip(addr)
return (p);
}
unsigned long st_ldu(addr, n)
register ptr addr;
size n;
/** Loads and returns an unsigned integer value of
* "n" bytes in size stored in the stack at address
* "addr".
*/
unsigned long st_ldu(register ptr addr, size n)
{
register int i;
register unsigned long u = 0;
@ -353,22 +391,27 @@ unsigned long st_ldu(addr, n)
ch_in_stack(addr, n);
ch_aligned(addr, n);
#ifdef LOGGING
if (!is_st_set(addr, n, SH_INT)) {
if (!is_st_set(addr, n, SH_INT))
{
warning(n == 1 ? WLCEXP : WLIEXP);
warn_stbits(addr, n);
}
#endif /* LOGGING */
addr += n-1;
for (i = (int) n-1; i >= 0; i--, addr--) {
u = (u<<8) | (btou(stack_loc(addr)));
addr += n - 1;
for (i = (int) n - 1; i >= 0; i--, addr--)
{
u = (u << 8) | (btou(stack_loc(addr)));
}
LOG(("@s6 st_ldu() returns %ld", u));
return (u);
}
unsigned long st_lduw(addr)
register ptr addr;
/** Loads and returns an unsigned integer value of
* word size bytes stored in the stack at address
* "addr".
*/
unsigned long st_lduw(register ptr addr)
{
register int i;
register unsigned long u = 0;
@ -378,23 +421,27 @@ unsigned long st_lduw(addr)
ch_w_in_stack(addr);
ch_wordaligned(addr);
#ifdef LOGGING
if (!is_st_set(addr, wsize, SH_INT)) {
if (!is_st_set(addr, wsize, SH_INT))
{
warning(WLIEXP);
warn_stbits(addr, wsize);
}
#endif /* LOGGING */
addr += wsize - 1;
for (i = (int) wsize-1; i >= 0; i--, addr--) {
u = (u<<8) | (btou(stack_loc(addr)));
for (i = (int) wsize - 1; i >= 0; i--, addr--)
{
u = (u << 8) | (btou(stack_loc(addr)));
}
LOG(("@s6 st_lduw() returns %ld", u));
return (u);
}
long st_lds(addr, n)
register ptr addr;
size n;
/** Loads and returns a signed integer value of
* "n" bytes in size stored in the stack at address
* "addr".
*/
long st_lds(register ptr addr, size n)
{
register int i;
register long l;
@ -404,7 +451,8 @@ long st_lds(addr, n)
ch_in_stack(addr, n);
ch_aligned(addr, n);
#ifdef LOGGING
if (!is_st_set(addr, n, SH_INT)) {
if (!is_st_set(addr, n, SH_INT))
{
warning(n == 1 ? WLCEXP : WLIEXP);
warn_stbits(addr, n);
}
@ -412,15 +460,19 @@ long st_lds(addr, n)
addr += n - 2;
l = btos(stack_loc(addr + 1));
for (i = n - 2; i >= 0; i--, addr--) {
l = (l<<8) | btol(stack_loc(addr));
for (i = n - 2; i >= 0; i--, addr--)
{
l = (l << 8) | btol(stack_loc(addr));
}
LOG(("@s6 st_lds() returns %ld", l));
return (l);
}
long st_ldsw(addr)
register ptr addr;
/** Loads and returns a signed integer value of
* word size bytes stored in the stack at address
* "addr".
*/
long st_ldsw(register ptr addr)
{
register int i;
register long l;
@ -430,7 +482,8 @@ long st_ldsw(addr)
ch_w_in_stack(addr);
ch_wordaligned(addr);
#ifdef LOGGING
if (!is_st_set(addr, wsize, SH_INT)) {
if (!is_st_set(addr, wsize, SH_INT))
{
warning(WLIEXP);
warn_stbits(addr, wsize);
}
@ -438,17 +491,19 @@ long st_ldsw(addr)
addr += wsize - 2;
l = btos(stack_loc(addr+1));
for (i = wsize - 2; i >= 0; i--, addr--) {
l = (l<<8) | btol(stack_loc(addr));
for (i = wsize - 2; i >= 0; i--, addr--)
{
l = (l << 8) | btol(stack_loc(addr));
}
LOG(("@s6 st_ldsw() returns %ld", l));
return (l);
}
#ifndef NOFLOAT
double st_ldf(addr, n)
register ptr addr;
size n;
/** Loads and returns a real value of "n" bytes
* stored in the stack at address "addr".
*/
double st_ldf(register ptr addr, size n)
{
double f;
float fl;
@ -457,25 +512,30 @@ double st_ldf(addr, n)
LOG(("@s6 st_ldf(%lu, %lu)", addr, n));
if ((int)n == 4) {
if ((int) n == 4)
{
cp = (char *) &fl;
}
else {
else
{
cp = (char *) &f;
}
ch_in_stack(addr, n);
ch_wordaligned(addr);
#ifdef LOGGING
if (!is_st_set(addr, n, SH_FLOAT)) {
if (!is_st_set(addr, n, SH_FLOAT))
{
warning(WLFEXP);
warn_stbits(addr, n);
}
#endif /* LOGGING */
for (i = (int) n; i > 0; i--, addr++) {
for (i = (int) n; i > 0; i--, addr++)
{
*(cp++) = stack_loc(addr);
}
if ((int)n == 4) {
if ((int) n == 4)
{
f = fl;
}
return (f);
@ -499,9 +559,11 @@ double st_ldf(addr, n)
* *
************************************************************************/
st_mvs(s2, s1, n) /* s1 -> s2 */
register ptr s2, s1;
size n;
/** Moves "n" bytes from stack address "s1" to
* stack address "s2".
*/
void st_mvs(register ptr s2, register ptr s1, size n)
/* s1 -> s2 */
{
register int i;
@ -510,7 +572,8 @@ st_mvs(s2, s1, n) /* s1 -> s2 */
ch_in_stack(s2, n);
ch_wordaligned(s2);
for (i = (int) n; i > 0; i--, s1++, s2++) {
for (i = (int) n; i > 0; i--, s1++, s2++)
{
ch_st_prot(s2);
ch_st_prot(s1);
stack_loc(s2) = stack_loc(s1);
@ -520,9 +583,11 @@ st_mvs(s2, s1, n) /* s1 -> s2 */
}
}
st_mvd(s, d, n) /* d -> s */
register ptr s, d;
size n;
/** Move "n" bytes from data pointer "d" to
* stack address "s".
*/
void st_mvd(ptr s, ptr d, size n)
/* d -> s */
{
register int i;
@ -531,7 +596,8 @@ st_mvd(s, d, n) /* d -> s */
ch_in_stack(s, n);
ch_wordaligned(s);
for (i = (int) n; i > 0; i--, s++, d++) {
for (i = (int) n; i > 0; i--, s++, d++)
{
ch_st_prot(s);
stack_loc(s) = data_loc(d);
#ifdef LOGGING
@ -558,7 +624,8 @@ st_mvd(s, d, n) /* d -> s */
* *
************************************************************************/
ptr dppop()
/** Pop and return as a data pointer from the stack. */
ptr dppop(void)
{
register ptr p;
@ -568,8 +635,8 @@ ptr dppop()
return (p);
}
unsigned long upop(n)
size n;
/** Pop and return as an unsigned integer "n" bytes from the stack. */
unsigned long upop(size n)
{
register unsigned long l;
@ -579,7 +646,8 @@ unsigned long upop(n)
return (l);
}
unsigned long uwpop()
/** Pop and return a word size unsigned integer from the stack. */
unsigned long uwpop(void)
{
register unsigned long l;
@ -589,8 +657,8 @@ unsigned long uwpop()
return (l);
}
long spop(n)
size n;
/** Pop and return as an integer "n" bytes from the stack. */
long spop(size n)
{
register long l;
@ -600,7 +668,8 @@ long spop(n)
return (l);
}
long swpop()
/** Pop and return a word size signed integer from the stack. */
long swpop(void)
{
register long l;
@ -610,47 +679,53 @@ long swpop()
return (l);
}
pop_dt(d, n)
ptr d;
size n;
/** Pop "n" bytes from the stack and store them at data pointer
* address "d".
*/
void pop_dt(ptr d, size n)
{
if (n < wsize)
dt_stn(d, (long) upop(n), n);
else {
else
{
dt_mvs(d, SP, n);
decSP(n);
}
}
popw_dt(d)
ptr d;
/** Pop word size bytes from the stack and store them at data pointer
* address "d".
*/
void popw_dt(ptr d)
{
dt_mvs(d, SP, wsize);
decSP(wsize);
}
pop_st(s, n)
ptr s;
size n;
/** Pop "n" bytes from the stack and store them at stack address "s". */
void pop_st(ptr s, size n)
{
if (n < wsize)
st_stn(s, (long) upop(n), n);
else {
else
{
st_mvs(s, SP, n);
decSP(n);
}
}
popw_st(s)
ptr s;
/** Pop word size bytes from the stack and store them at stack
* address "s".
*/
void popw_st(ptr s)
{
st_mvs(s, SP, wsize);
decSP(wsize);
}
#ifndef NOFLOAT
double fpop(n)
size n;
/** Pop a real value of "n" bytes from the stack. */
double fpop(size n)
{
double d;
@ -660,10 +735,11 @@ double fpop(n)
}
#endif /* NOFLOAT */
long wpop()
/** Pop a word size value, independently of its type. */
long wpop(void)
{
register long l;
l = w_in_stack(SP);
decSP(wsize);
return (l);
@ -684,80 +760,92 @@ long wpop()
* *
************************************************************************/
dppush(p)
ptr p;
/** Push a data pointer "p" unto the stack. */
void dppush(ptr p)
{
incSP(psize);
st_stdp(SP, p);
}
wpush(l)
long l;
/** Push a word size integer "l" unto the stack. */
void wpush(long l)
{
incSP(wsize);
st_stw(SP, l);
}
npush(l, n)
register long l;
register size n;
/** Push "n" bytes from value "l" unto the stack. */
void npush(register long l, register size n)
{
if (n <= wsize) {
if (n <= wsize)
{
incSP(wsize);
if (n == 1) l &= MASK1;
else if (n == 2) l &= MASK2;
if (n == 1)
l &= MASK1;
else if (n == 2)
l &= MASK2;
st_stw(SP, l);
}
else {
else
{
incSP(n);
st_stn(SP, l, n);
}
}
push_dt(d, n)
ptr d;
size n;
/** Push "n" bytes of data pointed to by the
* data pointer "d" unto the stack.
*/
void push_dt(ptr d, size n)
{
if (n < wsize) {
if (n < wsize)
{
npush((long) dt_ldu(d, n), n);
}
else {
else
{
incSP(n);
st_mvd(SP, d, n);
}
}
pushw_dt(d)
ptr d;
/** Push word size bytes of data pointed to by
* the data pointer "d" unto the stack.
*/
void pushw_dt(ptr d)
{
incSP(wsize);
st_mvd(SP, d, wsize);
}
push_st(s, n)
ptr s;
size n;
/** Push "n" bytes of data pointed to by the
* stack pointer "s" unto the stack.
*/
void push_st(ptr s, size n)
{
if (n < wsize) {
if (n < wsize)
{
npush((long) st_ldu(s, n), n);
}
else {
else
{
incSP(n);
st_mvs(SP, s, n);
}
}
pushw_st(s)
ptr s;
/** Push word size bytes of data pointed to by
* the stack pointer "s" unto the stack.
*/
void pushw_st(ptr s)
{
incSP(wsize);
st_mvs(SP, s, wsize);
}
#ifndef NOFLOAT
fpush(f, n)
double f;
size n;
/** Push a real value of "n" bytes unto the stack. */
void fpush(double f, size n)
{
incSP(n);
st_stf(SP, f, n);
@ -766,20 +854,20 @@ fpush(f, n)
#ifdef LOGGING
PRIVATE warn_stbits(addr, n)
register ptr addr;
register size n;
PRIVATE void warn_stbits(ptr addr, size n)
{
register int or_bits = 0;
register int and_bits = 0xff;
while (n--) {
while (n--)
{
or_bits |= st_sh(addr);
and_bits &= st_sh(addr);
addr++;
}
if (or_bits != and_bits) {
if (or_bits != and_bits)
{
/* no use trying to diagnose */
warningcont(WWASMISC);
return;
@ -796,5 +884,16 @@ PRIVATE warn_stbits(addr, n)
warningcont(WWASINSP);
}
PRIVATE void st_clear_area(ptr from, ptr to)
{
/* includes both *from and *to (since ML+1 is unexpressible) */
register ptr a;
for (a = from; a >= to; a--) {
st_undef(a);
}
}
#endif /* LOGGING */

53
util/int/stack.h Normal file
View file

@ -0,0 +1,53 @@
/* Copyright (c) 2019 ACK Project.
* See the copyright notice in the ACK home directory,
* in the file "Copyright".
*
* Created on: 2019-03-15
*
*/
#ifndef STACK_H_
#define STACK_H_
#include "global.h"
void init_stack(void);
void newSP(ptr ap);
void incSP(size n);
void decSP(size n);
void newLB(ptr p);
void st_stdp(register ptr addr, ptr ap);
void st_stip(register ptr addr, ptr ap);
void st_stn(register ptr addr, long al, size n);
void st_stw(register ptr addr, long al);
void st_stf(register ptr addr, double f, size n);
ptr st_lddp(register ptr addr);
ptr st_ldip(register ptr addr);
unsigned long st_ldu(register ptr addr, size n);
unsigned long st_lduw(register ptr addr);
long st_lds(register ptr addr, size n);
long st_ldsw(register ptr addr);
double st_ldf(register ptr addr, size n);
void st_mvs(register ptr s2, register ptr s1, size n);
void st_mvd(ptr s, ptr d, size n);
ptr dppop(void);
unsigned long upop(size n);
unsigned long uwpop(void);
long spop(size n);
long swpop(void);
void pop_dt(ptr d, size n);
void popw_dt(ptr d);
void pop_st(ptr s, size n);
void popw_st(ptr s);
double fpop(size n);
long wpop(void);
void dppush(ptr p);
void wpush(long l);
void npush(register long l, register size n);
void push_dt(ptr d, size n);
void pushw_dt(ptr d);
void push_st(ptr s, size n);
void pushw_st(ptr s);
void fpush(double f, size n);
#endif /* STACK_H_ */

View file

@ -11,8 +11,7 @@
#include "trap.h"
#include "warn.h"
do_instr(opcode)
unsigned int opcode;
void do_instr(unsigned int opcode)
{
switch (opcode) {
#include "DoCases" /* for the muscle */

View file

@ -1,6 +1,6 @@
/*
Gathering run-time statistics
*/
Gathering run-time statistics
*/
/* $Id$ */
@ -10,38 +10,46 @@
#include "linfil.h"
#include "alloc.h"
struct line_tally { /* one for each line */
long lt_cnt; /* counts entrances */
long lt_instr; /* counts instructions */
struct line_tally
{ /* one for each line */
long lt_cnt; /* counts entrances */
long lt_instr; /* counts instructions */
};
struct file_tally { /* one for each file */
struct file_tally
{ /* one for each file */
struct file_tally *next;
ptr ft_fil; /* file name */
long ft_limit; /* size of line array */
struct line_tally *ft_line; /* pointer to line array */
ptr ft_fil; /* file name */
long ft_limit; /* size of line array */
struct line_tally *ft_line; /* pointer to line array */
};
PRIVATE struct file_tally *first_tally; /* start of chain */
PRIVATE struct file_tally *file; /* present file */
PRIVATE struct file_tally *first_tally; /* start of chain */
PRIVATE struct file_tally *file; /* present file */
PRIVATE long lastLIN;
PRIVATE tally_newFIL();
PRIVATE enlarge();
PRIVATE FILE *tally_fp;
tally()
/* Forward declarations. */
PRIVATE void tally_newFIL(ptr);
PRIVATE void enlarge(struct file_tally *, long);
void tally(void)
{
if (!FIL)
return;
if (!file || FIL != file->ft_fil) {
if (!file || FIL != file->ft_fil)
{
tally_newFIL(FIL);
file->ft_fil = FIL;
lastLIN = -1;
}
if (LIN != lastLIN) {
if (LIN >= file->ft_limit) {
if (LIN != lastLIN)
{
if (LIN >= file->ft_limit)
{
enlarge(file, LIN);
}
file->ft_line[LIN].lt_cnt++;
@ -50,62 +58,59 @@ tally()
file->ft_line[LIN].lt_instr++;
}
PRIVATE tally_newFIL(f)
ptr f;
PRIVATE void tally_newFIL(ptr f)
{
struct file_tally **hook = &first_tally;
while (*hook) {
while (*hook)
{
if ((*hook)->ft_fil == f)
break;
hook = &(*hook)->next;
}
if (!*hook) {
if (!*hook)
{
/* first time we see this file */
/* construct a new entry */
struct file_tally *nt = (struct file_tally *)
Malloc((size) sizeof (struct file_tally), "file_tally");
nt->next = (struct file_tally *)0;
struct file_tally *nt = (struct file_tally *) Malloc(
(size) sizeof(struct file_tally), "file_tally");
nt->next = (struct file_tally *) 0;
nt->ft_fil = f;
nt->ft_limit = 1; /* provisional length */
nt->ft_line = (struct line_tally *)
Malloc((size) sizeof (struct line_tally),
"struct line_tally");
nt->ft_limit = 1; /* provisional length */
nt->ft_line = (struct line_tally *) Malloc(
(size) sizeof(struct line_tally), "struct line_tally");
nt->ft_line[0].lt_cnt = 0;
nt->ft_line[0].lt_instr = 0;
/* and hook it in */
*hook = nt;
}
file = *hook;
}
PRIVATE enlarge(ft, l)
struct file_tally *ft;
long l;
PRIVATE void enlarge(struct file_tally *ft, long l)
{
long limit = allocfrac(l < 100 ? 100 : l);
if (limit <= ft->ft_limit)
return;
ft->ft_line = (struct line_tally *)
Realloc((char *)ft->ft_line,
(size)(limit*sizeof (struct line_tally)),
"array line_tally");
while (ft->ft_limit < limit) {
ft->ft_line = (struct line_tally *) Realloc((char *) ft->ft_line,
(size) (limit * sizeof(struct line_tally)), "array line_tally");
while (ft->ft_limit < limit)
{
ft->ft_line[ft->ft_limit].lt_cnt = 0;
ft->ft_line[ft->ft_limit].lt_instr = 0;
ft->ft_limit++;
}
}
PRIVATE FILE *tally_fp;
out_tally()
void out_tally(void)
{
struct file_tally **hook = &first_tally;
if (!*hook)
return;
@ -113,18 +118,21 @@ out_tally()
if (!tally_fp)
return;
while (*hook) {
while (*hook)
{
struct file_tally *ft = *hook;
register long i;
fprintf(tally_fp, "%s:\n", dt_fname(ft->ft_fil));
for (i = 0; i < ft->ft_limit; i++) {
for (i = 0; i < ft->ft_limit; i++)
{
struct line_tally *lt = &ft->ft_line[i];
if (lt->lt_cnt) {
if (lt->lt_cnt)
{
/* we visited this line */
fprintf(tally_fp, "\t%ld\t%ld\t%ld\n",
i, lt->lt_cnt, lt->lt_instr);
fprintf(tally_fp, "\t%ld\t%ld\t%ld\n", i, lt->lt_cnt,
lt->lt_instr);
}
}
fprintf(tally_fp, "\n");

View file

@ -1,10 +1,9 @@
/*
Manipulating the Program Counter
*/
/** @file
* Program counter manipulation routines */
/* $Id$ */
#include <em_abs.h>
#include "em_abs.h"
#include "global.h"
#include "alloc.h"
#include "trap.h"
@ -13,9 +12,10 @@
#include "proctab.h"
#include "warn.h"
init_text() {
DB = i2p(NTEXT); /* set Descriptor Base */
NProc = NPROC; /* set Number of Proc. Descriptors */
void init_text(void)
{
DB = i2p(NTEXT); /* set Descriptor Base */
NProc = NPROC; /* set Number of Proc. Descriptors */
PI = -1; /* initialize Procedure Identifier */
PC = 0; /* initialize Program Counter */
@ -31,8 +31,7 @@ init_text() {
* *
************************************************************************/
newPC(p)
register ptr p;
void newPC(register ptr p)
{
register struct proc *pr = &proctab[PI];

View file

@ -112,3 +112,11 @@
#define arg_lin(u) ((u > NLINE) ? (trap(EBADLIN), u) : u)
/* Allocates the "text" variable that will hold the text
* segment.
*/
void init_text(void);
/* Sets the new value of the PC register to the specified
* value "p".
*/
void newPC(register ptr p);

View file

@ -1,6 +1,6 @@
/*
Trap handling
*/
/** @file
* Trap handling and management routines.
*/
/* $Id$ */
@ -11,6 +11,7 @@
#include "global.h"
#include "log.h"
#include "trap.h"
#include "io.h"
#include "warn.h"
#include "mem.h"
#include "shadow.h"
@ -18,29 +19,28 @@
#include "rsb.h"
#include "fra.h"
extern jmp_buf trapbuf; /* from main.c */
extern jmp_buf trapbuf; /* from main.c */
int must_test; /* TEST-bit on in EM header word 2 */
int must_test; /* TEST-bit on in EM header word 2 */
int signalled;
PRIVATE int nonreturnable();
PRIVATE char *trap_msg[] = {
#include "trap_msg" /* generated from $(EM)/etc/traps */
""
};
char *trap2text(nr) /* transient */
int nr;
PRIVATE char *trap_msg[] =
{
if ( /* trap number in predefined range */
nr < sizeof (trap_msg) / sizeof (trap_msg[0])
&& /* trap message not the empty string */
trap_msg[nr][0]
) {
#include "trap_msg" /* generated from $(EM)/etc/traps */
"" };
char *trap2text(int nr)
{
if ( /* trap number in predefined range */
nr < sizeof(trap_msg) / sizeof(trap_msg[0]) && /* trap message not the empty string */
trap_msg[nr][0])
{
return trap_msg[nr];
}
else {
else
{
static char buf[50];
sprintf(buf, "TRAP %d", nr);
@ -49,37 +49,35 @@ char *trap2text(nr) /* transient */
}
/*ARGSUSED*/
do_trap(nr, L, F)
int nr;
int L;
char *F;
void do_trap(int nr, int L, char *F)
{
/*
1. The trap has not been masked.
2. This routine does not return; it either ends in a call of
fatal() or in a longjmp().
*/
static int rec_nr; /* Recursive trap number */
static int rec_trap = 0; /* To detect traps inside do_trap() */
register long tpi; /* Trap Procedure Identifier */
1. The trap has not been masked.
2. This routine does not return; it either ends in a call of
fatal() or in a longjmp().
*/
static int rec_nr; /* Recursive trap number */
static int rec_trap = 0; /* To detect traps inside do_trap() */
register long tpi; /* Trap Procedure Identifier */
LOG(("@t1 trap(%d) [%s: %d]", nr, F, L));
warning(WMSG + nr);
switch (OnTrap) {
switch (OnTrap)
{
case TR_ABORT:
fatal("trap \"%s\" before program started", trap2text(nr));
/*NOTREACHED*/
case TR_HALT:
fatal("trap \"%s\" not caught at %s",
trap2text(nr), position());
fatal("trap \"%s\" not caught at %s", trap2text(nr), position());
/*NOTREACHED*/
case TR_TRAP:
/* execute the trap */
if (rec_trap) {
if (rec_trap)
{
fatal("recursive trap; first trap number was \"%s\"",
trap2text(rec_nr));
}
@ -88,13 +86,13 @@ do_trap(nr, L, F)
/* save the Function Return Area */
pushFRA(FRASize);
wpush((long)FRASize);
wpush((long)FRA_def);
wpush((long) FRASize);
wpush((long) FRA_def);
/* set up the trap number as the only parameter */
wpush((long) nr);
tpi = TrapPI; /* allowed since OnTrap == TR_TRAP */
tpi = TrapPI; /* allowed since OnTrap == TR_TRAP */
TrapPI = 0;
OnTrap = TR_HALT;
call(tpi, (nonreturnable(nr) ? RSB_NRT : RSB_RTT));
@ -104,10 +102,10 @@ do_trap(nr, L, F)
}
}
PRIVATE int nonreturnable(nr)
int nr;
PRIVATE int nonreturnable(int nr)
{
switch (nr) {
switch (nr)
{
case ESTACK:
case EILLINS:
case EODDZ:

View file

@ -1,6 +1,10 @@
/*
Trap handling
*/
#ifndef TRAP_H_
#define TRAP_H_
#include "warn.h"
/* $Id$ */
@ -12,3 +16,12 @@ extern int signalled; /* signal nr if trap was due to sig */
extern int must_test; /* must trap on overfl./out of range*/
/* TEST-bit on in EM header word 2 */
/* Execute the specified trap. "nr" represents the signal
* number, "L" is the line number and "F" is the filename
* where the trap occurred.
*/
void do_trap(int nr, int L, char *F);
#endif /* TRAP_H_ */

View file

@ -1,5 +1,5 @@
/*
Warnings.
/** @file
* Warning management.
*/
/* $Id$ */
@ -32,7 +32,7 @@ PRIVATE struct warn_msg warn_msg[] = {
PRIVATE char *warn_text[WMSG+1];
init_wmsg()
void init_wmsg(void)
{
register int i;
register struct warn_msg *wmsg;
@ -58,8 +58,7 @@ struct warn_cnt {
PRIVATE struct warn_cnt *warn_cnt[WMSG];
PRIVATE char warnmask[WMSG];
PRIVATE long count_wrn(nr)
int nr;
PRIVATE long count_wrn(int nr)
{ /* returns the occurrence counter for the warning with number
nr; keeps track of the warnings, sorted by warning number,
file name and line number.
@ -67,7 +66,7 @@ PRIVATE long count_wrn(nr)
register struct warn_cnt **warn_hook = &warn_cnt[nr];
register struct warn_cnt *wrn;
while (wrn = *warn_hook) {
while ( (wrn = *warn_hook) ) {
if (wrn->wc_fil == FIL && wrn->wc_lin == LIN) {
return ++wrn->wc_cnt;
}
@ -95,10 +94,7 @@ PRIVATE long count_wrn(nr)
PRIVATE int latest_warning_printed; /* set if ... */
/*ARGSUSED*/
do_warn(nr, L, F)
int nr;
int L;
char *F;
void do_warn(int nr, int L, char *F)
{
latest_warning_printed = 0;
if (nr < WMSG) {
@ -130,8 +126,7 @@ do_warn(nr, L, F)
#ifdef LOGGING
warningcont(nr)
int nr;
void warningcont(int nr)
{
/* continued warning */
if (latest_warning_printed) {
@ -148,8 +143,7 @@ warningcont(nr)
#endif /* LOGGING */
set_wmask(i)
int i;
void set_wmask(int i)
{
if (i < WMSG) {
warnmask[i] = 1;