/* Copyright (c) 1979 Regents of the University of California */
#define readonly
#define	NINST	300
#define	NSYM	4000
#define	NHASH	(NSYM+1)
#define	NLOC	4		/* number of location ctrs */
#define	NCPS	8		/* number of characters per symbol, fixed */

/*
 * Symbol types
 */
#define	XUNDEF	0x0
#define	XABS	0x2
#define	XTEXT	0x4
#define	XDATA	0x6
#define	XBSS	0x8
#define	XDATAO	0xA
#define	XBSSO	0xC
#define	XTEXTO	0xE
#define	XABSO	0x10
#define	XUNDEFO	0x12

#define	XTXRN	0xA	/* external symbol */
#define	XXTRN	0x1
#define	XTYPE	0x1E

#define	XFORW	0x20	/* Was forward-referenced when undefined */

#define	ERR	(-1)
#define	NBPW	32	/* Bits per word */

#define	AMASK	017

/*
 * Actual argument syntax types
 */
#define AREG	1	/* %r */
#define ABASE	2	/* (%r) */
#define ADECR	3	/* -(%r) */
#define AINCR	4	/* (%r)+ */
#define ADISP	5	/* expr(%r) */
#define AEXP	6	/* expr */
#define AIMM	7	/* $ expr */
#define ASTAR	8	/* * */
#define AINDX	16	/* [%r] */

/*
 * Argument access types used to test validity of operands to operators
 */
#define ACCA	(8<<3)	/* address only */
#define ACCR	(1<<3)	/* read */
#define ACCW	(2<<3)	/* write */
#define ACCM	(3<<3)	/* modify */
#define ACCB	(4<<3)	/* branch displacement */
#define ACCI	(5<<3)	/* XFC code */

/*
 * Argument data types
 */
#define TYPB	0	/* byte */
#define TYPW	1	/* word */
#define TYPL	2	/* long */
#define TYPQ	3	/* quad */
#define TYPF	4	/* floating */
#define TYPD	5	/* double floating */

#define TYPMASK 7

/* reference types for loader */
#define PCREL 1
#define LEN1 2
#define LEN2 4
#define LEN4 6
#define LEN8 8

#define	TMPC	7	/* offset into the string /tmp/aaaXXX for creating tmp file names*/
#define	HW	01
#define	FW	03
#define	DW	07

#include <pagsiz.h>

#define	round(x,y)	(((x)+(y)) & ~(y))

#define	STABTYPS	0340
#define STABFLAG	0200

/*
 *	Follows are the definitions for the symbol table tags, which are
 *	all unsigned characters..
 *	High value tags are generated by the asembler for internal
 *	use.
 *	Low valued tags are the parser coded tokens the scanner returns.
 *	There are several pertinant bounds in this ordering:
 *		a)	Symbols greater than JXQUESTIONABLE
 *			are used by the jxxx bumper, indicating that
 *			the symbol table entry is a jxxx entry
 *			that has yet to be bumped.
 *		b)	Symbols greater than IGNOREBOUND are not
 *			bequeathed to the loader; they are truly
 *			for assembler internal use only.
 *		c)	Symbols greater than OKTOBUMP represent
 *			indices into the program text that should
 *			be changed in preceeding jumps or aligns
 *			must get turned into their long form.
 */

#define TAGMASK		0xFF

#	define	JXACTIVE	0xFF	/*jxxx instruction size unknown*/
#	define	JXNOTYET	0xFE	/*jxxx instruction size known, but not yet expanded*/
#	define	JXALIGN		0xFD	/*align jxxx entry*/
#	define	JXINACTIVE	0xFC	/*jxxx instruction size known and expanded*/

#define JXQUESTIONABLE		0xFB

#	define	JXTUNNEL	0xFA	/*jxxx instruction that jumps to another*/
#	define	OBSOLETE	0xF9	/*erroneously entered symbol*/

#define	IGNOREBOUND	0xF8	/*symbols greater than this are ignored*/
#	define	STABFLOATING	0xF7
#	define	LABELID		0xF6

#define	OKTOBUMP	0xF5
#	define	STABFIXED	0xF4

/*
 *	astoks.h contains reserved word codings the parser should
 *	know about
 */
#include "astoks.h"

/*
 *	The structure for one symbol table entry.
 *	Symbol table entries are used for both user defined symbols,
 *	and symbol slots generated to create the jxxx jump from
 *	slots.
 */

#define symfirstfields	char	*name;	unsigned char tag, type

struct symtab{
		symfirstfields;
#ifdef vax
		short	___hole;
#endif
      /*save*/	char	ptype;		/*tag == NAME*/

#define		jxbump	ptype		/*tag == JX..., how far to expand*/

     /*save*/	char	other;		/*for stab info*/

     /*save*/	short	desc;		/*tag == NAME*/

#define		jxfear	desc		/*how far needs to be bumped*/

     /*save*/	long	value;		/*address in the segment*/
		char	jxoveralign;	/*if a JXXX, jumped over an align*/
		short	index;		/*which segment*/
		struct	symtab *dest;	/*if JXXX, where going to*/
#ifdef DJXXX
		short	jxline;		/*source line of the jump from*/
#endif
};

struct instab{
	symfirstfields;

#define		opcode type		/*use the same field as symtab.type*/

	char	nargs;			/*how many arguments*/
	char	argtype[6];		/*argument type info*/
};

struct	arg {				/*one argument to an instruction*/
	char	atype;
	char	areg1;
	char	areg2;
	char	dispsize;		/*usually d124, unless have B^, etc*/
	struct	exp *xp;
};

struct	exp {
	char	xtype;
	char	xloc;
	long	xvalue;
	struct	symtab *xname;
	union{
		double	dvalue;	
		struct {
			unsigned int doub_MSW, doub_LSW;
		} dis_dvalue;
	} doubval;
};

/*
 *	Magic layout macros
 */
#define 	MINBYTE	-128
#define		MAXBYTE	127
#define		MINWORD	-32768
#define		MAXWORD	32767

#define		LITFLTMASK 0x000043F0	/*really magic*/
/*
 *		Is the floating point double word in xp a
 *		short literal floating point number?
 */
#define		slitflt(xp) \
			(    (xp->doubval.dis_dvalue.doub_LSW == 0) \
			 && ((xp->doubval.dis_dvalue.doub_MSW & LITFLTMASK) \
			   == xp->doubval.dis_dvalue.doub_MSW) )

#define		extlitflt(xp) \
			xp->doubval.dis_dvalue.doub_MSW >> 4

/*
 *	Structure that appears at the head of a.out
 */
struct	hdr {
	long	magic;
	long	tsize;
	long	dsize;
	long	bsize;
	long	ssize;
	long	entry;
	long	trsize;
	long	drsize;
};

	struct	arg	arglist[6];	/*building operands in instructions*/
	struct	exp	explist[20];	/*building up a list of expressions*/

	/*
	 *	Communication between the scanner and the jxxx handlers.
	 *	lastnam:	the last name seen on the input
	 *	lastjxxx:	pointer to the last symbol table entry for
	 *			a jump from
	 */
	extern	struct	symtab	*lastnam;
	extern	struct	symtab	*lastjxxx;	
	/*
	 *	For each of the named .text .data segments
	 *	(introduced by .text <expr>), we maintain
	 *	the current value of the dot, and the Files where
	 *	the information for each of the segments is salted
	 *	away.
	 *
	 *	Use of rulesfile and usefile is unclear
	 */
	extern	struct	exp	usedot[NLOC+NLOC];
	extern		FILE	*usefile[NLOC+NLOC];
	extern		FILE	*rusefile[NLOC+NLOC];
	/*
	 *	Strings used to construct the temporary files
	 *	for each of the named segments in pass 2.
	 */
	extern	char	*tmpn2;			/* /tmp/aaaXXXX */
	extern	char	*tmpn3;			/* /tmp/aabXXX */

	extern	struct	exp	*dotp;		/*the current dot location*/
	extern	int	loctr;
	extern	long	tsize;			/* total text size */
	extern	long	dsize;			/* total data size */
	extern	long	datbase;		/* base of the data segment */
	/*
	 *	Bitoff and bitfield keep track of the packing into 
	 *	bytes mandated by the expression syntax <expr> ':' <expr>
	 */
	extern	int	bitoff;	
	extern	long	bitfield;
	
	/*
	 *	The lexical analyzer builds up symbols in yytext.  Lookup
	 *	expects its argument in this buffer
	 */
	extern	char	yytext[NCPS+2];		/* text buffer for lexical */
	/*
	 *	Variables to manage the input assembler source file
	 */
	extern	int	lineno;			/*the line number*/
	extern	char	*dotsname;		/*the name of the as source*/
	/*extern FILE	stdin*;*/		/*the as source input*/

	extern	FILE	*txtfil;		/* file for text*/
	extern	FILE	*tmpfil;		/* interpass communication*/
	extern	FILE	*relfil;		/* holds relocation informtion*/

	extern	int	passno;			/* 1 or 2 */

	extern	int	anyerrs;		/*errors assembling arguments*/
	extern	int	silent;			/*don't mention the errors*/
	extern	int	savelabels;		/*save labels in a.out*/
		int	orgwarn;		/* questionable origin ? */
		int	useVM;			/*use virtual memory temp file*/
#ifdef DEBUG
	extern	int	debug;
	extern	int	toktrace;
#endif
	/*
	 *	Information about the instructions
	 */
	struct	instab	*itab[NINST];		/*maps opcodes to instructions*/
	extern  readonly struct instab instab[];

	int	curlen;				/*current storage size*/
	
	struct	symtab	**lookup();		/*argument in yytext*/
	struct 	symtab	*symalloc();

#ifdef METRIC
	int	outcounters;			/*should we print them?*/
	int	nhcollision;
	int	nhashed;
	int	nentered;
	int	lgtmpfile;
	int	jxxxiterate;
	int	jxxxtunnel;			/*how many tunnel jumps done*/
	int	jxdeadlock;
	int	nbadjxsegs;
#endif


#define outb(val) {dotp->xvalue++; if (passno==2) putc((val), txtfil);}

#define outs(cp, lg) dotp->xvalue += (lg); if (passno == 2) fwrite((cp), 1, (lg), txtfil)

/*
 *	Most of the time, the argument to flushfield is a power of two constant,
 *	the calculations involving it can be optimized to shifts.
 */
#define flushfield(n) if (bitoff != 0)  Flushfield( ( (bitoff+n-1) /n ) * n)
