Merge pull request #181 from ccodere/carl-ansi-part1
More ANSI C conversion
This commit is contained in:
commit
3f61c0d507
|
@ -1,4 +1,3 @@
|
|||
.\" $Id$
|
||||
.RP
|
||||
.ND Nov 1984
|
||||
.TL
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -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(" ");
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
57
modules/src/system/basename.c
Normal file
57
modules/src/system/basename.c
Normal 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);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -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",
|
||||
|
|
|
@ -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__ */
|
||||
|
|
16
modules/src/system/tmpnam.c
Normal file
16
modules/src/system/tmpnam.c
Normal 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);
|
||||
}
|
||||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
627
util/ass/ass00.c
627
util/ass/ass00.c
|
@ -1,5 +1,10 @@
|
|||
#include <string.h>
|
||||
#include <stddef.h>
|
||||
#include "ass00.h"
|
||||
#include "assex.h"
|
||||
#include "assci.h"
|
||||
#include "asscm.h"
|
||||
#include "assrl.h"
|
||||
|
||||
/*
|
||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
|
@ -7,205 +12,289 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#ifndef NORCSID
|
||||
static char rcs_id[] = "$Id$" ;
|
||||
#endif
|
||||
char oflag;
|
||||
static int memflg;
|
||||
|
||||
/* Forward declarations. */
|
||||
static siz_t* getsizes(char *);
|
||||
static void getcore(void);
|
||||
static void argument(char *);
|
||||
static void flags(char *);
|
||||
static void skipentry(void);
|
||||
static void enmd_pro(void);
|
||||
static void enmd_glo(void);
|
||||
static void archive(void);
|
||||
static void finish_up(void);
|
||||
static void check_def(void);
|
||||
|
||||
static void c_print(void);
|
||||
static void c_dprint(char *, char*);
|
||||
|
||||
/* External definitions */
|
||||
void pass_3(void);
|
||||
void pass_4(void);
|
||||
void pass_5(void);
|
||||
|
||||
/*
|
||||
** Main routine of EM1-assembler/loader
|
||||
*/
|
||||
** Main routine of EM1-assembler/loader
|
||||
*/
|
||||
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
/*
|
||||
* Usage: ass [-[d][p][m][u][U]] [-s(s/m/l/x)] [ [file] [flag] ] ...
|
||||
* The d flag can be repeated several times, resulting in more
|
||||
* debugging information.
|
||||
*/
|
||||
char workspace[6000] ;
|
||||
register char *cp ;
|
||||
register int argno ;
|
||||
char workspace[6000];
|
||||
register char *cp;
|
||||
register int argno;
|
||||
|
||||
progname = argv[0];
|
||||
for ( cp=argv[0] ; *cp ; ) if ( *cp++ == '/' ) progname= cp;
|
||||
for ( argno=1 ; argno<argc ; argno++ ) {
|
||||
if ( argv[argno][0] == '-' && LC(argv[argno][1]) == 's') {
|
||||
getsizes(&argv[argno][2]);
|
||||
break ;
|
||||
for (cp = argv[0]; *cp;)
|
||||
if (*cp++ == '/')
|
||||
progname = cp;
|
||||
for (argno = 1; argno < argc; argno++)
|
||||
{
|
||||
if (argv[argno][0] == '-' && LC(argv[argno][1]) == 's')
|
||||
{
|
||||
oursize = getsizes(&argv[argno][2]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* A piece of the interpreter's stack frame is used as
|
||||
free area initially */
|
||||
freearea( (area_t) workspace, (unsigned) sizeof workspace ) ;
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -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$"
|
||||
|
||||
|
|
614
util/ass/ass30.c
614
util/ass/ass30.c
|
@ -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 */
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,15 +7,13 @@
|
|||
#include "ass00.h"
|
||||
#include "assex.h"
|
||||
|
||||
#ifndef NORCSID
|
||||
static char rcs_id[] = "$Id$" ;
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
** Make scans to do final assignment of instruction sizes & formats
|
||||
** to those not already done. assign final values to labels
|
||||
*/
|
||||
pass_4()
|
||||
void pass_4(void)
|
||||
{
|
||||
register line_t *lnp;
|
||||
register locl_t *lbp;
|
||||
|
|
|
@ -6,19 +6,21 @@
|
|||
|
||||
#include "ass00.h"
|
||||
#include "assex.h"
|
||||
#include "assrl.h"
|
||||
#include "ip_spec.h"
|
||||
|
||||
#ifndef NORCSID
|
||||
static char rcs_id[] = "$Id$" ;
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Pass 5 of EM1 assembler/loader
|
||||
** Fix reloc tables
|
||||
** Write out code
|
||||
*/
|
||||
|
||||
pass_5() {
|
||||
static void patchcase(void);
|
||||
|
||||
|
||||
|
||||
void pass_5(void)
|
||||
{
|
||||
register line_t *lnp;
|
||||
cons_t off1;
|
||||
char defined ;
|
||||
|
@ -78,14 +80,15 @@ pass_5() {
|
|||
|
||||
} /* end pass_5 */
|
||||
|
||||
genop(startc,value,i_flag) char *startc ; cons_t value ; int i_flag ; {
|
||||
char *currc ;
|
||||
register flag ;
|
||||
char opc ;
|
||||
|
||||
/*
|
||||
* Real code generation.
|
||||
*/
|
||||
/**
|
||||
* 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 ;
|
||||
|
|
362
util/ass/ass60.c
362
util/ass/ass60.c
|
@ -8,61 +8,73 @@
|
|||
#include "assex.h"
|
||||
#include "ip_spec.h"
|
||||
|
||||
#ifndef NORCSID
|
||||
static char rcs_id[] = "$Id$" ;
|
||||
#endif
|
||||
|
||||
#ifdef DUMP
|
||||
static char *typestr[] =
|
||||
{"missing","const","procname","glosym","locsym","glosym+off","pseudo"};
|
||||
static char *labstr[] = {"EMPTY","no","yes","seen","notpresent"};
|
||||
static char formstr[] = { 'm','s','-','1','2','4','8' };
|
||||
static char *r_data[] = { "null","glob","head","loc","adr" };
|
||||
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
|
||||
|
|
167
util/ass/ass70.c
167
util/ass/ass70.c
|
@ -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);
|
||||
|
|
180
util/ass/ass80.c
180
util/ass/ass80.c
|
@ -6,28 +6,19 @@
|
|||
|
||||
#include "ass00.h"
|
||||
#include "assex.h"
|
||||
#include <em_path.h>
|
||||
#include "assrl.h"
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include "system.h"
|
||||
|
||||
#ifndef NORCSID
|
||||
static char rcs_id[] = "$Id$" ;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* this file contains several library routines.
|
||||
*/
|
||||
|
||||
zero(area,length) char *area; unsigned length ; {
|
||||
register char *p;
|
||||
register n;
|
||||
/*
|
||||
* Clear area of length bytes.
|
||||
*/
|
||||
if ((n=length)==0)
|
||||
return;
|
||||
p = area;
|
||||
do *p++=0; while (--n);
|
||||
}
|
||||
static char filename[L_tmpnam];
|
||||
|
||||
|
||||
/* VARARGS1 */
|
||||
static void pr_error(const char* string1, va_list ap) {
|
||||
|
@ -60,7 +51,8 @@ void error(const char* string1, ...)
|
|||
}
|
||||
|
||||
/* VARARGS1 */
|
||||
void werror(const char* string1, ...) {
|
||||
void werror(const char* string1, ...)
|
||||
{
|
||||
va_list ap;
|
||||
if ( wflag ) return ;
|
||||
|
||||
|
@ -69,57 +61,44 @@ void werror(const char* string1, ...) {
|
|||
va_end(ap);
|
||||
}
|
||||
|
||||
fatal(s) char *s; {
|
||||
void fatal(char *s)
|
||||
{
|
||||
/*
|
||||
* handle fatal errors
|
||||
*/
|
||||
error("Fatal error: %s",s);
|
||||
dump(0);
|
||||
exit(-1);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
#ifndef CPM
|
||||
FILE *frewind(f) FILE *f ; {
|
||||
/* Rewind a file open for writing and open it for reading */
|
||||
/* Assumption, file descriptor is r/w */
|
||||
register FILE *tmp ;
|
||||
tmp=fdopen(dup(fileno(f)),"r");
|
||||
fclose(f);
|
||||
rewind(tmp);
|
||||
return tmp ;
|
||||
}
|
||||
#endif
|
||||
|
||||
int xgetc(af) register FILE *af; {
|
||||
|
||||
int xgetc(register FILE *af)
|
||||
{
|
||||
register int nextc;
|
||||
/*
|
||||
* read next character; fatal if there isn't one
|
||||
*/
|
||||
nextc=fgetc(af) ;
|
||||
if ( feof(af) )
|
||||
fatal("unexpected end of file");
|
||||
return nextc ;
|
||||
}
|
||||
|
||||
xputc(c,af) register FILE *af; {
|
||||
/* output one character and scream if it gives an error */
|
||||
void xputc(int c,register FILE *af)
|
||||
{
|
||||
fputc(c,af) ;
|
||||
if ( ferror(af) ) fatal("write error") ;
|
||||
}
|
||||
|
||||
|
||||
putblk(stream,from,amount)
|
||||
register FILE *stream; register char *from ; register int amount ; {
|
||||
|
||||
void putblk(register FILE *stream,register char *from, register int amount)
|
||||
{
|
||||
for ( ; amount-- ; from++ ) {
|
||||
fputc(*from,stream) ;
|
||||
if ( ferror(stream) ) fatal("write error") ;
|
||||
}
|
||||
}
|
||||
|
||||
int getblk(stream,from,amount)
|
||||
register FILE *stream; register char *from ; register int amount ; {
|
||||
|
||||
int getblk(register FILE *stream, register char *from, register int amount)
|
||||
{
|
||||
for ( ; amount-- ; from++ ) {
|
||||
*from = fgetc(stream) ;
|
||||
if ( feof(stream) ) return 1 ;
|
||||
|
@ -127,7 +106,8 @@ int getblk(stream,from,amount)
|
|||
return 0 ;
|
||||
}
|
||||
|
||||
xput16(w,f) FILE *f; {
|
||||
void xput16(int w,FILE *f)
|
||||
{
|
||||
/*
|
||||
* two times xputc
|
||||
*/
|
||||
|
@ -135,19 +115,22 @@ xput16(w,f) FILE *f; {
|
|||
xputc(w>>8,f);
|
||||
}
|
||||
|
||||
xputarb(l,w,f) int l ; cons_t w ; FILE *f ; {
|
||||
void xputarb(int l,cons_t w, FILE* f)
|
||||
{
|
||||
while ( l-- ) {
|
||||
xputc( int_cast w,f) ;
|
||||
w >>=8 ;
|
||||
}
|
||||
}
|
||||
|
||||
put8(n) {
|
||||
void put8(int n)
|
||||
{
|
||||
xputc(n,tfile);
|
||||
textoff++;
|
||||
}
|
||||
|
||||
put16(n) {
|
||||
void put16(int n)
|
||||
{
|
||||
/*
|
||||
* note reversed order of bytes.
|
||||
* this is done for faster interpretation.
|
||||
|
@ -157,16 +140,19 @@ put16(n) {
|
|||
textoff += 2;
|
||||
}
|
||||
|
||||
put32(n) cons_t n ; {
|
||||
void put32(cons_t n)
|
||||
{
|
||||
put16( int_cast (n>>16)) ;
|
||||
put16( int_cast n) ;
|
||||
}
|
||||
|
||||
put64(n) cons_t n ; {
|
||||
void put64(cons_t n)
|
||||
{
|
||||
fatal("put64 called") ;
|
||||
}
|
||||
|
||||
int xget8() {
|
||||
int xget8(void)
|
||||
{
|
||||
/*
|
||||
* Read one byte from ifile.
|
||||
*/
|
||||
|
@ -176,7 +162,8 @@ int xget8() {
|
|||
return fgetc(ifile) ;
|
||||
}
|
||||
|
||||
unsigned get8() {
|
||||
unsigned int get8(void)
|
||||
{
|
||||
register int nextc;
|
||||
/*
|
||||
* Read one byte from ifile.
|
||||
|
@ -191,16 +178,17 @@ unsigned get8() {
|
|||
return nextc ;
|
||||
}
|
||||
|
||||
cons_t xgetarb(l,f) int l; FILE *f ; {
|
||||
cons_t xgetarb(int l,FILE *f)
|
||||
{
|
||||
cons_t val ;
|
||||
register int shift ;
|
||||
int c;
|
||||
|
||||
shift=0 ; val=0 ;
|
||||
while ( l-- ) {
|
||||
// val += ((cons_t)(c = ctrunc(xgetc(f))))<<shift ;
|
||||
// Bug here: shifts with too large shift counts
|
||||
// get unspecified results. --Ceriel
|
||||
/* val += ((cons_t)(c = ctrunc(xgetc(f))))<<shift ;
|
||||
Bug here: shifts with too large shift counts
|
||||
get unspecified results. --Ceriel */
|
||||
c = ctrunc(xgetc(f));
|
||||
if (shift < 8 * sizeof(cons_t)) {
|
||||
val += ((cons_t)c)<<shift ;
|
||||
|
@ -216,7 +204,8 @@ cons_t xgetarb(l,f) int l; FILE *f ; {
|
|||
return val ;
|
||||
}
|
||||
|
||||
ext8(b) {
|
||||
void ext8(int b)
|
||||
{
|
||||
/*
|
||||
* Handle one byte of data.
|
||||
*/
|
||||
|
@ -224,55 +213,56 @@ ext8(b) {
|
|||
xputc(b,dfile);
|
||||
}
|
||||
|
||||
extword(w) cons_t w ; {
|
||||
void extword(cons_t w)
|
||||
{
|
||||
/* Assemble the word constant w.
|
||||
* NOTE: The bytes are written low to high.
|
||||
*/
|
||||
register i ;
|
||||
register int i ;
|
||||
for ( i=wordsize ; i-- ; ) {
|
||||
ext8( int_cast w) ;
|
||||
w >>= 8 ;
|
||||
}
|
||||
}
|
||||
|
||||
extarb(size,value) int size ; long value ; {
|
||||
void extarb(int size, long value)
|
||||
{
|
||||
/* Assemble the 'size' constant value.
|
||||
* The bytes are again written low to high.
|
||||
*/
|
||||
register i ;
|
||||
register int i ;
|
||||
for ( i=size ; i-- ; ) {
|
||||
ext8( int_cast value ) ;
|
||||
value >>=8 ;
|
||||
}
|
||||
}
|
||||
|
||||
extadr(a) cons_t a ; {
|
||||
/* Assemble the word constant a.
|
||||
void extadr(cons_t a)
|
||||
{
|
||||
/* Assemble the pointer constant a.
|
||||
* NOTE: The bytes are written low to high.
|
||||
*/
|
||||
register i ;
|
||||
register int i ;
|
||||
for ( i=ptrsize ; i-- ; ) {
|
||||
ext8( int_cast a) ;
|
||||
a >>= 8 ;
|
||||
}
|
||||
}
|
||||
|
||||
xputa(a,f) cons_t a ; FILE *f ; {
|
||||
/* Assemble the pointer constant a.
|
||||
* NOTE: The bytes are written low to high.
|
||||
*/
|
||||
register i ;
|
||||
void xputa(cons_t a,FILE* f)
|
||||
{
|
||||
|
||||
register int i ;
|
||||
for ( i=ptrsize ; i-- ; ) {
|
||||
xputc( int_cast a,f) ;
|
||||
a >>= 8 ;
|
||||
}
|
||||
}
|
||||
|
||||
cons_t xgeta(f) FILE *f ; {
|
||||
/* Read the pointer constant a.
|
||||
* NOTE: The bytes were written low to high.
|
||||
*/
|
||||
register i, shift ;
|
||||
cons_t xgeta(FILE* f)
|
||||
{
|
||||
|
||||
register int i, shift ;
|
||||
cons_t val ;
|
||||
val = 0 ; shift=0 ;
|
||||
for ( i=ptrsize ; i-- ; ) {
|
||||
|
@ -282,14 +272,16 @@ cons_t xgeta(f) FILE *f ; {
|
|||
return val ;
|
||||
}
|
||||
|
||||
int icount(size) {
|
||||
int icount(int size)
|
||||
{
|
||||
int amount ;
|
||||
amount=(dataoff-lastoff)/size ;
|
||||
if ( amount>MAXBYTE) fatal("Descriptor overflow");
|
||||
return amount ;
|
||||
}
|
||||
|
||||
set_mode(mode) {
|
||||
void set_mode(int mode)
|
||||
{
|
||||
|
||||
if (datamode==mode) { /* in right mode already */
|
||||
switch ( datamode ) {
|
||||
|
@ -389,40 +381,12 @@ set_mode(mode) {
|
|||
}
|
||||
}
|
||||
|
||||
#ifndef CPM
|
||||
int tmpfil() {
|
||||
register char *fname, *cpname ;
|
||||
static char sfname[] = "tmp.00000";
|
||||
register fildes,pid;
|
||||
static char name[80] = TMP_DIR ;
|
||||
int count;
|
||||
/*
|
||||
* This procedure returns a file-descriptor of a temporary
|
||||
* file valid for reading and writing.
|
||||
* After closing the tmpfil-descriptor the file is lost
|
||||
* Calling this routine frees the program from generating uniqe names.
|
||||
*/
|
||||
fname = sfname+4;
|
||||
count = 10;
|
||||
pid = getpid();
|
||||
while (pid!=0) {
|
||||
*fname++ = (pid&07) + '0';
|
||||
pid >>= 3;
|
||||
|
||||
char* tmpfil(void)
|
||||
{
|
||||
if (sys_tmpnam(filename)==NULL)
|
||||
{
|
||||
fatal("Cannot create temporary filename.");
|
||||
}
|
||||
*fname = 0;
|
||||
for ( fname=name ; *fname ; fname++ ) ;
|
||||
cpname=sfname ;
|
||||
while ( *fname++ = *cpname++ ) ;
|
||||
do {
|
||||
fname = name;
|
||||
if ((fildes = creat(fname, 0600)) < 0)
|
||||
if ((fildes = creat(fname=sfname, 0600)) < 0)
|
||||
return(-1);
|
||||
if (close(fildes) < 0)
|
||||
;
|
||||
} while((fildes = open(fname, 2)) < 0 && count--);
|
||||
if (unlink(fname) < 0)
|
||||
;
|
||||
return(fildes);
|
||||
return filename;
|
||||
}
|
||||
#endif
|
||||
|
|
1169
util/ass/assci.c
1169
util/ass/assci.c
File diff suppressed because it is too large
Load diff
20
util/ass/assci.h
Normal file
20
util/ass/assci.h
Normal file
|
@ -0,0 +1,20 @@
|
|||
/* Copyright (c) 2019 ACK Project.
|
||||
* See the copyright notice in the ACK home directory,
|
||||
* in the file "Copyright".
|
||||
*
|
||||
* Created on: 2019-03-12
|
||||
*
|
||||
*/
|
||||
#ifndef ASSCI_H_
|
||||
#define ASSCI_H_
|
||||
|
||||
|
||||
/*
|
||||
* read module in compact EM1 code and fill in the table in memory
|
||||
* with all the specified data as a linked list.
|
||||
*/
|
||||
void read_compact(void);
|
||||
void newline(int type);
|
||||
void align(int size);
|
||||
|
||||
#endif /* ASSCI_H_ */
|
166
util/ass/asscm.c
166
util/ass/asscm.c
|
@ -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
22
util/ass/asscm.h
Normal file
|
@ -0,0 +1,22 @@
|
|||
/* Copyright (c) 2019 ACK Project.
|
||||
* See the copyright notice in the ACK home directory,
|
||||
* in the file "Copyright".
|
||||
*
|
||||
* Created on: 2019-03-12
|
||||
*
|
||||
*/
|
||||
#ifndef ASSCM_H_
|
||||
#define ASSCM_H_
|
||||
|
||||
/* Allocates an area of "size" bytes in memory
|
||||
* and returns a pointer to this area.
|
||||
*/
|
||||
area_t getarea(unsigned int size);
|
||||
/* Frees an area of memory of "size" bytes. */
|
||||
void freearea(register area_t ptr, unsigned int size);
|
||||
|
||||
#ifdef MEMUSE
|
||||
void memuse(void);
|
||||
#endif
|
||||
|
||||
#endif /* ASSCM_H_ */
|
|
@ -5,11 +5,6 @@
|
|||
#include "ass00.h"
|
||||
#include "assex.h"
|
||||
|
||||
#ifndef NORCSID
|
||||
static char rcs_id[] = "$Id$" ;
|
||||
static char rcs_ass[]= RCS_ASS ;
|
||||
static char rcs_ex[] = RCS_EX ;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* global data
|
||||
|
|
145
util/ass/assex.h
145
util/ass/assex.h
|
@ -6,7 +6,7 @@
|
|||
* global data
|
||||
*/
|
||||
|
||||
#define RCS_EX "$Id$"
|
||||
#include <stdio.h>
|
||||
|
||||
extern int wordsize;
|
||||
extern int ptrsize;
|
||||
|
@ -122,31 +122,126 @@ extern char *opindex[] ;
|
|||
extern char opchoice[] ;
|
||||
extern int maxinsl ;
|
||||
|
||||
/*
|
||||
* types of value returning routines
|
||||
/* Generate temporary filename. Fatal error in case of error. */
|
||||
extern char *tmpfil(void);
|
||||
|
||||
|
||||
/* Read next byte from "af" file, fatal error if there isn't one. */
|
||||
extern int xgetc(register FILE *af);
|
||||
/* Read a value of length "l" bytes from file "f",
|
||||
* fatal error if cannot be read.
|
||||
*/
|
||||
#ifndef CPM
|
||||
extern int tmpfil();
|
||||
extern FILE *frewind();
|
||||
#endif
|
||||
extern int xgetc();
|
||||
extern unsigned get8();
|
||||
extern int get16();
|
||||
extern cons_t get32();
|
||||
extern cons_t xgeta();
|
||||
extern cons_t parval();
|
||||
extern cons_t valsize();
|
||||
extern cons_t xgetarb();
|
||||
extern cons_t xgetarb(int l,FILE *f);
|
||||
/* Read the pointer constant a from file "f".
|
||||
* NOTE: The bytes were written low to high (little-endian).
|
||||
*/
|
||||
extern cons_t xgeta(FILE* f);
|
||||
|
||||
|
||||
|
||||
/* Output one byte into file "af" and fatal error if it gives an error */
|
||||
extern void xputc(int c,register FILE *af);
|
||||
/* Output a 16-bit value into file "f" in little-endian, fatal error if it gives an error. */
|
||||
extern void xput16(int w,FILE *f);
|
||||
/* Output a value of "l" bytes into file "f" and fatal error if it gives an error. */
|
||||
extern void xputarb(int l,cons_t w, FILE* f);
|
||||
/* Assemble the pointer constant a into file "f".
|
||||
* NOTE: The bytes are written low to high (little-endian).
|
||||
*/
|
||||
extern void xputa(cons_t a,FILE* f);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* Write a byte value into the code temporary file. */
|
||||
extern void put8(int n);
|
||||
/* Write a 16-bit value into the code temporary file. */
|
||||
extern void put16(int n);
|
||||
/* Write a 32-bit value into the code temporary file. */
|
||||
extern void put32(cons_t n);
|
||||
/* Write a 64-bit value into the code temporary file. */
|
||||
extern void put64(cons_t n);
|
||||
|
||||
|
||||
/* Read a byte from the input file, return EOF upon error of EOF */
|
||||
extern int xget8(void);
|
||||
/* Read a byte from the input file, fatal error upon error or EOF. */
|
||||
extern unsigned int get8(void);
|
||||
/* Read a signed 16-bit value from the input file. Raise
|
||||
* a fatal error upon error or end of stream.
|
||||
*/
|
||||
extern int get16(void);
|
||||
/* Read an unsigned 16-bit value from the input file. Raise
|
||||
* a fatal error upon error or end of stream.
|
||||
*/
|
||||
extern int getu16(void);
|
||||
/* Read a 32-bit value from the input file. Raise
|
||||
* a fatal error upon error or end of stream.
|
||||
*/
|
||||
extern cons_t get32(void);
|
||||
|
||||
|
||||
|
||||
/* Write a byte to the data file. */
|
||||
extern void ext8(int b);
|
||||
/* Write a 16-bit value to the data file.
|
||||
* The value is written from low to high (little-endian)
|
||||
*/
|
||||
extern void extword(cons_t w);
|
||||
/* Write "value" of "size" bytes to the data file. The bytes
|
||||
* are written low to high.
|
||||
*/
|
||||
extern void extarb(int size, long value);
|
||||
/* Write pointer "a". The bytes are
|
||||
* written from low to high to the data file.
|
||||
*/
|
||||
extern void extadr(cons_t a);
|
||||
|
||||
|
||||
|
||||
/* Returns the opcode length in bytes */
|
||||
extern int oplength(int);
|
||||
extern void genop(char *,cons_t,int );
|
||||
|
||||
extern void putblk(register FILE *stream,register char *from, register int amount);
|
||||
extern int getblk(register FILE *stream, register char *from, register int amount);
|
||||
|
||||
|
||||
extern void set_mode(int mode);
|
||||
|
||||
/* Dump current information to screen if dump flag is enabled. */
|
||||
void dump(int n);
|
||||
|
||||
/*
|
||||
extern char *findnop();
|
||||
extern char *findfit();
|
||||
extern glob_t *glolookup();
|
||||
extern glob_t *glo2lookup();
|
||||
extern glob_t *xglolookup();
|
||||
extern locl_t *loclookup();
|
||||
extern proc_t *prolookup();
|
||||
extern proc_t *enterproc();
|
||||
extern proc_t *searchproc();
|
||||
extern relc_t *text_reloc();
|
||||
extern relc_t *data_reloc();
|
||||
extern area_t getarea();
|
||||
|
||||
*/
|
||||
extern glob_t *glolookup(char *name,int status,glob_t *table, int size);
|
||||
extern proc_t *searchproc(char *name,proc_t *table,int size);
|
||||
extern glob_t *glo2lookup(char *name ,int status);
|
||||
extern glob_t *xglolookup(char *name,int status);
|
||||
extern proc_t *prolookup(char *name,int status);
|
||||
extern locl_t *loclookup(unsigned int an,int status);
|
||||
extern proc_t *enterproc(char *name,int status,proc_t *place);
|
||||
extern cons_t parval(line_t *lnp,char *defined);
|
||||
|
||||
|
||||
extern void determine_props(line_t *lnp, int *min_len, int *max_len);
|
||||
extern int opfit(int flag,int number,cons_t val,int i_flag);
|
||||
|
||||
extern void initproc(void);
|
||||
extern void endproc(void);
|
||||
extern void init_files(void);
|
||||
extern void init_module(void);
|
||||
extern void end_module(void);
|
||||
extern void do_proc(void);
|
||||
extern void ertrap(void);
|
||||
extern void init_vars(void);
|
||||
|
||||
extern void error(const char* string1, ...);
|
||||
extern void werror(const char* string1, ...);
|
||||
extern void fatal(char *s);
|
||||
|
||||
|
||||
|
|
336
util/ass/assrl.c
336
util/ass/assrl.c
|
@ -4,12 +4,13 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "ass00.h"
|
||||
#include "assex.h"
|
||||
#include "asscm.h"
|
||||
#include "assrl.h"
|
||||
|
||||
|
||||
#ifndef NORCSID
|
||||
static char rcs_id[] = "$Id$" ;
|
||||
#endif
|
||||
|
||||
#define COPYFINAL 1
|
||||
#define COPYTEMP 0
|
||||
|
@ -18,10 +19,12 @@ static char rcs_id[] = "$Id$" ;
|
|||
* collection of routines to deal with relocation business
|
||||
*/
|
||||
|
||||
void dataprocess();
|
||||
void textprocess();
|
||||
relc_t *
|
||||
text_reloc(glosym,off,typ) glob_t *glosym; FOFFSET off ; int typ ; {
|
||||
|
||||
static void dataprocess(FILE *, FILE *);
|
||||
static void textprocess(FILE *, FILE *);
|
||||
|
||||
relc_t * text_reloc(glob_t *glosym, FOFFSET off, int typ)
|
||||
{
|
||||
|
||||
/*
|
||||
* prepare the relocation that has to be done at text-offset off
|
||||
|
@ -33,48 +36,55 @@ text_reloc(glosym,off,typ) glob_t *glosym; FOFFSET off ; int typ ; {
|
|||
* into the one in xglobs[] later.
|
||||
*/
|
||||
|
||||
register relc_t *nxtextreloc ;
|
||||
register relc_t *nxtextreloc;
|
||||
|
||||
nxtextreloc= rlp_cast getarea(sizeof *nxtextreloc) ;
|
||||
if ( !f_text ) {
|
||||
f_text= nxtextreloc ;
|
||||
} else {
|
||||
l_text->r_next= nxtextreloc ;
|
||||
nxtextreloc = rlp_cast getarea(sizeof *nxtextreloc);
|
||||
if (!f_text)
|
||||
{
|
||||
f_text = nxtextreloc;
|
||||
}
|
||||
nxtextreloc->r_next= rlp_cast 0 ;
|
||||
l_text= nxtextreloc ;
|
||||
else
|
||||
{
|
||||
l_text->r_next = nxtextreloc;
|
||||
}
|
||||
nxtextreloc->r_next = rlp_cast 0;
|
||||
l_text = nxtextreloc;
|
||||
nxtextreloc->r_off = off;
|
||||
nxtextreloc->r_val.rel_gp = glosym;
|
||||
nxtextreloc->r_typ = typ; /* flags of instruction */
|
||||
return(nxtextreloc);
|
||||
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
21
util/ass/assrl.h
Normal file
|
@ -0,0 +1,21 @@
|
|||
/* Copyright (c) 2019 ACK Project.
|
||||
* See the copyright notice in the ACK home directory,
|
||||
* in the file "Copyright".
|
||||
*
|
||||
* Created on: 2019-03-13
|
||||
*
|
||||
*/
|
||||
#ifndef ASSRL_H_
|
||||
#define ASSRL_H_
|
||||
|
||||
/* Generates an e.out file from the the temporary code file "tfile" and
|
||||
* data temporary "dfile" file. Output the data to "ifile".
|
||||
*/
|
||||
void copyout(void);
|
||||
/* Update the relocation entries and place them into "rtfile" and "rdfile". */
|
||||
void upd_reloc(void);
|
||||
|
||||
relc_t * data_reloc(char *arg ,FOFFSET off, int typ);
|
||||
relc_t * text_reloc(glob_t *glosym, FOFFSET off, int typ);
|
||||
|
||||
#endif /* ASSRL_H_ */
|
|
@ -36,7 +36,7 @@ cprogram {
|
|||
"modules/src/em_data+lib",
|
||||
--"modules/src/data+lib",
|
||||
--"modules/src/object+lib",
|
||||
--"modules/src/system+lib",
|
||||
"modules/src/system+lib",
|
||||
"./ass*.h",
|
||||
}
|
||||
}
|
||||
|
|
|
@ -64,7 +64,7 @@ produced code the only messages to expect are "Out of memory"
|
|||
or of the
|
||||
form: Overflow in XXXX. The latter can usually be cured by giving
|
||||
a -sx flag,
|
||||
the former means the program is too big, dimishing
|
||||
the former means the program is too big, diminishing
|
||||
the size of very large procedures can sometimes help.
|
||||
The most likely errors, however, are unresolved references,
|
||||
probably caused by the omission of a library argument.
|
||||
|
|
|
@ -6,471 +6,646 @@
|
|||
|
||||
#include "ip_spec.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <em_spec.h>
|
||||
#include <em_flag.h>
|
||||
|
||||
#ifndef NORCSID
|
||||
static char rcs_id[] = "$Id$" ;
|
||||
#endif
|
||||
|
||||
/* This program reads the human readable interpreter specification
|
||||
and produces a efficient machine representation that can be
|
||||
translated by a C-compiler.
|
||||
*/
|
||||
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--;
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
30
util/int/data.h
Normal 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
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
17
util/int/dump.h
Normal 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_ */
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
106
util/int/io.c
106
util/int/io.c
|
@ -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
16
util/int/io.h
Normal 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_ */
|
246
util/int/log.c
246
util/int/log.c
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
15
util/int/m_sigtrp.h
Normal 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_ */
|
|
@ -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;
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
/* $Id$ */
|
||||
|
||||
#include "stack.h"
|
||||
|
||||
/******** Memory address & location defines ********/
|
||||
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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_ */
|
||||
|
|
168
util/int/read.c
168
util/int/read.c
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
18
util/int/segment.h
Normal 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_ */
|
459
util/int/stack.c
459
util/int/stack.c
|
@ -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
53
util/int/stack.h
Normal 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_ */
|
|
@ -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 */
|
||||
|
|
110
util/int/tally.c
110
util/int/tally.c
|
@ -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");
|
||||
|
|
|
@ -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];
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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_ */
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue