/* Copyright (c) 1980 Regents of the University of California */ /* "@(#)as.h 4.1 08/13/80" */ #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 #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 ':' */ 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 ), 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;