Merge pull request #181 from ccodere/carl-ansi-part1
More ANSI C conversion
This commit is contained in:
		
						commit
						3f61c0d507
					
				
					 84 changed files with 5377 additions and 4236 deletions
				
			
		|  | @ -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…
	
	Add table
		
		Reference in a new issue