+/* Copyright (c) 1980 Regents of the University of California */
+/* "@(#)as.h 4.1 %G%" */
+#ifdef VMS
+# define vax 1
+# define VAX 1
+#endif VMS
+
+#define readonly
+
+#define NINST 300
+
+#define NEXP 20 /* max number of expr. terms per instruction */
+#define NARG 6 /* max number of args per instruction */
+#define NHASH 1103 /* hash table is dynamically extended */
+#define TNAMESIZE 32 /* maximum length of temporary file names */
+#define NLOC 4 /* number of location ctrs */
+
+#ifdef UNIX
+# ifndef FLEXNAMES
+# ifndef NCPS
+# define NCPS 8 /* number of characters per symbol*/
+# endif
+# else
+# ifdef NCPS
+# undef NCPS
+# endif
+# define NCPS BUFSIZ /* needed to allocate yytext */
+# endif
+# endif UNIX
+
+# ifdef VMS
+# ifdef NCPS
+# undef NCPS
+# endif NCPS
+# define NCPS 15
+# endif VMS
+
+/*
+ * Symbol types
+ */
+#define XUNDEF 0x0
+#define XABS 0x2
+#define XTEXT 0x4
+#define XDATA 0x6
+#define XBSS 0x8
+
+#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
+ /*
+ * reflen table converts between LEN* and PCREL to numbers
+ * of bytes.
+ * lgreflen table is the lg base 2 of the values in reflen.
+ */
+ extern int reflen[]; /* reference lengths */
+ extern int lgrefltn[]; /* lg reference lengths */
+
+#define TMPC 7
+#define HW 01
+#define FW 03
+#define DW 07
+
+#ifdef UNIX
+# include <pagsiz.h>
+#endif UNIX
+
+#ifdef VMS
+# define PAGRND 0x1FFL
+#endif VMS
+
+#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 size unknown*/
+# define JXNOTYET 0xFE /*jxxx size known, but not yet expanded*/
+# define JXALIGN 0xFD /*align jxxx entry*/
+# define JXINACTIVE 0xFC /*jxxx size known and expanded*/
+
+#define JXQUESTIONABLE 0xFB
+
+# define JXTUNNEL 0xFA /*jxxx 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;
+ short ___hole;
+ char ptype; /*tag == NAME*/
+
+#define jxbump ptype /*tag == JX..., how far to expand*/
+
+ char other; /*for stab info*/
+
+ short desc; /*tag == NAME*/
+
+#define jxfear desc /*how far needs to be bumped*/
+
+ 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 {
+ long xvalue; /* MUST be the first field (look at union Double) */
+ long yvalue; /* MUST be second field; least sig word of a double */
+ char xtype;
+ char xloc;
+ struct symtab *xname;
+};
+
+#define doub_MSW xvalue
+#define doub_LSW yvalue
+
+union Double {
+ struct{
+ long doub_MSW;
+ long doub_LSW;
+ } dis_dvalue;
+ double dvalue;
+};
+
+struct Quad {
+ long quad_low_long;
+ long quad_high_long;
+};
+
+/*
+ * 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->doub_LSW == 0) \
+ && ( (xp->doub_MSW & LITFLTMASK) \
+ == xp->doub_MSW) )
+/*
+ * If it is a slitflt, then extract the 6 interesting bits
+ */
+#define extlitflt(xp) \
+ xp->doub_MSW >> 4
+
+ extern struct arg arglist[NARG]; /*building operands in instructions*/
+ extern struct exp explist[NEXP]; /*building up a list of expressions*/
+ extern struct exp *xp; /*current free expression*/
+ /*
+ * 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;
+
+#ifdef VMS
+ extern char *vms_obj_ptr; /* object buffer pointer */
+ extern char sobuf[]; /* object buffer */
+ extern int objfil; /* VMS object file descriptor */
+#endif VMS
+
+ /*
+ * Lgensym is used to make up funny names for local labels.
+ * lgensym[i] is the current funny number to put after
+ * references to if, lgensym[i]-1 is for ib.
+ * genref[i] is set when the label is referenced before
+ * it is defined (i.e. 2f) so that we can be sure these
+ * labels are always defined to avoid weird diagnostics
+ * from the loader later.
+ */
+ extern int lgensym[10];
+ extern char genref[10];
+
+ extern char tmpn1[TNAMESIZE]; /* Interpass temporary */
+ extern struct exp *dotp; /* the current dot location */
+ extern int loctr;
+
+ extern struct exec hdr; /* a.out header */
+ extern u_long tsize; /* total text size */
+ extern u_long dsize; /* total data size */
+ extern u_long trsize; /* total text relocation size */
+ extern u_long drsize; /* total data relocation size */
+ extern u_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 *tmpfil; /* interpass communication*/
+
+ 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*/
+ extern int orgwarn; /* questionable origin ? */
+ extern int useVM; /*use virtual memory temp file*/
+#ifdef DEBUG
+ extern int debug;
+ extern int toktrace;
+#endif
+ /*
+ * Information about the instructions
+ */
+ extern struct instab *itab[NINST]; /*maps opcodes to instructions*/
+ extern readonly struct instab instab[];
+
+ extern int curlen; /*current literal storage size*/
+ extern int d124; /*current pointer storage size*/
+
+ struct symtab **lookup(); /*argument in yytext*/
+ struct symtab *symalloc();
+
+#define outb(val) {dotp->xvalue++; if (passno==2) bputc((val), (txtfil));}
+
+#define outs(cp, lg) dotp->xvalue += (lg); if (passno == 2) bwrite((cp), (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)
+
+/*
+ * The biobuf structure and associated routines are used to write
+ * into one file at several places concurrently. Calling bopen
+ * with a biobuf structure sets it up to write ``biofd'' starting
+ * at the specified offset. You can then use ``bwrite'' and/or ``bputc''
+ * to stuff characters in the stream, much like ``fwrite'' and ``fputc''.
+ * Calling bflush drains all the buffers and MUST be done before exit.
+ */
+struct biobuf {
+ short b_nleft; /* Number free spaces left in b_buf */
+/* Initialize to be less than BUFSIZ initially, to boundary align in file */
+ char *b_ptr; /* Next place to stuff characters */
+ char b_buf[BUFSIZ]; /* The buffer itself */
+ off_t b_off; /* Current file offset */
+ struct biobuf *b_link; /* Link in chain for bflush() */
+};
+#define bputc(c,b) ((b)->b_nleft ? (--(b)->b_nleft, *(b)->b_ptr++ = (c)) \
+ : bflushc(b, c))
+#define BFILE struct biobuf
+
+ extern BFILE *biobufs; /* head of the block I/O buffer chain */
+ extern int biofd; /* file descriptor for block I/O file */
+ extern off_t boffset; /* physical position in logical file */
+
+ /*
+ * For each of the named .text .data segments
+ * (introduced by .text <expr>), we maintain
+ * the current value of the dot, and the BFILE where
+ * the information for each of the segments is placed
+ * during the second pass.
+ */
+ extern struct exp usedot[NLOC + NLOC];
+ extern BFILE *usefile[NLOC + NLOC];
+ extern BFILE *txtfil;/* file for text and data: into usefile */
+ /*
+ * Relocation information for each segment is accumulated
+ * seperately from the others. Writing the relocation
+ * information is logically viewed as writing to one
+ * relocation saving file for each segment; physically
+ * we have a bunch of buffers allocated internally that
+ * contain the relocation information.
+ */
+ struct relbufdesc *rusefile[NLOC + NLOC];
+ struct relbufdesc *relfil;