X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/4d0e73ae0ab53e54ac17bb6bd084240eade1a275..31cef89cb428866f787983e68246030321893df4:/usr/src/cmd/as/as.h diff --git a/usr/src/cmd/as/as.h b/usr/src/cmd/as/as.h index 58d35b977c..ca6cfbc439 100644 --- a/usr/src/cmd/as/as.h +++ b/usr/src/cmd/as/as.h @@ -1,10 +1,61 @@ -/* Copyright (c) 1979 Regents of the University of California */ +/* Copyright (c) 1980 Regents of the University of California */ +/* "@(#)as.h 4.8 11/5/80" */ +#ifdef VMS +# define vax 1 +# define VAX 1 +#endif VMS + +#include +#ifdef UNIX + +#ifdef FLEXNAMES +# include +# include +#else not FLEXNAMES +# define ONLIST +# include "a.out.h" +# include +#endif FLEXNAMES + +#endif UNIX +#ifdef VMS + +#ifdef UNIXDEVEL +# include +#else not UNIXDEVEL +# include +#endif not UNIXDEVEL + +#endif VMS + #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 */ +#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 @@ -14,13 +65,7 @@ #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 @@ -34,56 +79,80 @@ /* * 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] */ +#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 */ +#define ACCR (1<<3) /* read */ +#define ACCW (2<<3) /* write */ +#define ACCB (4<<3) /* branch displacement */ +#define ACCA (8<<3) /* address only */ +#define ACCM (ACCR | ACCW) /* modify */ +#define ACCI (ACCB | ACCR) /* XFC code */ + +#define ACCESSMASK (ACCA | ACCR | ACCW | ACCB) /* the mask */ + +/* + * Argument data types + * Also used to tell outrel what it is relocating + * (possibly in combination with RELOC_PCREL and TYPNONE) + */ +#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 TYPNONE 6 /* when nothing */ +#define RELOC_PCREL 8 /* implicit argument to outrel; ==> PCREL */ + +#define TYPMASK 7 /* - * Argument data types + * reference types for loader */ -#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 PCREL 1 +#define LEN1 2 +#define LEN2 4 +#define LEN4 6 +#define LEN8 8 + +extern int reflen[]; /* {LEN*+PCREL} ==> number of bytes */ +extern int lgreflen[]; /* {LEN*+PCREL} ==> lg number of bytes */ +extern int len124[]; /* {1,2,4,8} ==> {LEN1, LEN2, LEN4, LEN8} */ +extern char mod124[]; /* {1,2,4,8} ==> {bits to construct operands */ +extern int type_124[]; /* {1,2,4,8} ==> {TYPB, TYPW, TYPL, TYPQ} */ +extern int ty_NORELOC[]; /* {TYPB..TYPD} ==> {1 if relocation not OK */ +extern int ty_LEN[]; /* {TYPB..TYPD} ==> {LEN1..LEN8} */ +extern int ty_nbyte[]; /* {TYPB..TYPD} ==> {1,2,4,8} */ +extern int ty_nlg[]; /* {TYPB..TYPD} ==> lg{1,2,4,8} */ + +#define TMPC 7 #define HW 01 #define FW 03 #define DW 07 -#include +#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 +#define STABFLAG 0200 /* * Follows are the definitions for the symbol table tags, which are @@ -105,19 +174,19 @@ * must get turned into their long form. */ -#define TAGMASK 0xFF +#define TAGMASK 0xFF -# define JXACTIVE 0xFF /*jxxx instruction size unknown*/ -# define JXNOTYET 0xFE /*jxxx instruction size known, but not yet expanded*/ +# 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 instruction size known and expanded*/ +# define JXINACTIVE 0xFC /*jxxx size known and expanded*/ -#define JXQUESTIONABLE 0xFB +#define JXQUESTIONABLE 0xFB -# define JXTUNNEL 0xFA /*jxxx instruction that jumps to another*/ +# define JXTUNNEL 0xFA /*jxxx that jumps to another*/ # define OBSOLETE 0xF9 /*erroneously entered symbol*/ -#define IGNOREBOUND 0xF8 /*symbols greater than this are ignored*/ +#define IGNOREBOUND 0xF8 /*symbols greater than this are ignored*/ # define STABFLOATING 0xF7 # define LABELID 0xF6 @@ -135,62 +204,112 @@ * Symbol table entries are used for both user defined symbols, * and symbol slots generated to create the jxxx jump from * slots. + * Caution: the instructions are stored in a shorter version + * of the struct symtab, using all fields in sym_nm and + * tag. The fields used in sym_nm are carefully redeclared + * in struct Instab and struct instab (see below). + * If struct nlist gets changed, then Instab and instab may + * have to be changed. */ -#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*/ + struct nlist s_nm; + u_char s_tag; /* assembler tag */ + u_char s_ptype; /* if tag == NAME */ + u_char s_jxoveralign; /* if a JXXX, jumped over align */ + short s_index; /* which segment */ + struct symtab *s_dest; /* if JXXX, where going to */ #ifdef DJXXX - short jxline; /*source line of the jump from*/ + short s_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*/ +/* + * Redefinitions of the fields in symtab for + * use when the symbol table entry marks a jxxx instruction. + */ +#define s_jxbump s_ptype /* tag == JX..., how far to expand */ +#define s_jxfear s_desc /* how far needs to be bumped */ +/* + * Redefinitions of fields in the struct nlist for symbols so that + * one saves typing, and so that they conform + * with the old naming conventions. + */ +#ifdef FLEXNAMES +#define s_name s_nm.n_un.n_name /* name pointer */ +#define s_nmx s_nm.n_un.n_strx /* string table index */ +#else not FLEXNAMES +#define s_name s_nm.n_name +#endif +#define s_type s_nm.n_type /* type of the symbol */ +#define s_other s_nm.n_other /* other information for sdb */ +#define s_desc s_nm.n_desc /* type descriptor */ +#define s_value s_nm.n_value /* value of the symbol, or sdb delta */ + +struct instab{ + struct nlist s_nm; /* instruction name, type (opcode) */ + u_char s_tag; + char s_pad[3]; /* round to 20 bytes */ }; +/* + * The fields nm.n_desc and nm.n_value total 6 bytes; this is + * just enough for the 6 bytes describing the argument types. + * We use a macro to define access to these 6 bytes, assuming that + * they are allocated adjacently. + * IF THE FORMAT OF STRUCT nlist CHANGES, THESE MAY HAVE TO BE CHANGED. + * + * Instab is cleverly declared to look very much like the combination of + * a struct symtab and a struct nlist. + */ +struct Instab{ +#ifdef FLEXNAMES + char *I_name; +#else not FLEXNAMES + char I_name[NCPS]; +#endif + u_char I_opcode; + char I_nargs; + char I_args[6]; + u_char I_s_tag; + char I_pad[3]; /* round to 20 bytes */ +}; +/* + * Redefinitions of fields in the struct nlist for instructions so that + * one saves typing, and conforms to the old naming conventions + */ +#define i_opcode s_nm.n_type /* use the same field as symtab.type */ +#define i_nargs s_nm.n_other /* number of arguments */ +#define fetcharg(ptr, n) ((struct Instab *)ptr)->I_args[n] struct arg { /*one argument to an instruction*/ - char atype; - char areg1; - char areg2; - char dispsize; /*usually d124, unless have B^, etc*/ - struct exp *xp; + char a_atype; + char a_areg1; + char a_areg2; + char a_dispsize; /*usually d124, unless have B^, etc*/ + struct exp *a_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; + long e_xvalue; /* MUST be the first field (look at union Double) */ + long e_yvalue; /* MUST be second field; least sig word of a double */ + char e_xtype; + char e_xloc; + struct symtab *e_xname; +}; + +#define doub_MSW e_xvalue +#define doub_LSW e_yvalue + +union Double { + struct{ + long doub_MSW; + long doub_LSW; + } dis_dvalue; + double dvalue; +}; + +struct Quad { + long quad_low_long; + long quad_high_long; }; /* @@ -206,31 +325,19 @@ struct exp { * 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 - +#define slitflt(xp) \ + ( (xp->doub_LSW == 0) \ + && ( (xp->doub_MSW & LITFLTMASK) \ + == xp->doub_MSW) ) /* - * Structure that appears at the head of a.out + * If it is a slitflt, then extract the 6 interesting bits */ -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*/ +#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 @@ -239,30 +346,35 @@ struct hdr { */ 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 + /* - * For each of the named .text .data segments - * (introduced by .text ), 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. + * 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 char *tmpn2; /* /tmp/aaaXXXX */ - extern char *tmpn3; /* /tmp/aabXXX */ + extern int lgensym[10]; + extern char genref[10]; - extern struct exp *dotp; /*the current dot location*/ + extern char tmpn1[TNAMESIZE]; /* Interpass temporary */ + 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 */ + + 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 ':' @@ -280,19 +392,18 @@ struct hdr { */ 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*/ + extern int orgwarn; /* questionable origin ? */ + extern int useVM; /*use virtual memory temp file*/ + extern int jxxxJUMP; /*use jmp instead of brw for jxxx */ + extern int readonlydata; /*initialized data into text space*/ #ifdef DEBUG extern int debug; extern int toktrace; @@ -300,33 +411,66 @@ struct hdr { /* * Information about the instructions */ - struct instab *itab[NINST]; /*maps opcodes to instructions*/ - extern readonly struct instab instab[]; + extern struct instab *itab[NINST]; /*maps opcodes to instructions*/ + extern readonly struct Instab instab[]; - int curlen; /*current storage size*/ + extern int curlen; /*current literal storage size*/ + extern int d124; /*current pointer 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->e_xvalue++; if (passno==2) bputc((val), (txtfil));} -#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) +#define outs(cp, lg) dotp->e_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;