1601Sbill /* Copyright (c) 1980 Regents of the University of California */ 2*635Shenry /* "@(#)as.h 4.3 08/15/80" */ 3601Sbill #ifdef VMS 4601Sbill # define vax 1 5601Sbill # define VAX 1 6601Sbill #endif VMS 7601Sbill 8*635Shenry #include <sys/types.h> 9*635Shenry #ifdef UNIX 10*635Shenry 11*635Shenry #ifdef FLEXNAMES 12*635Shenry # include <a.out.h> 13*635Shenry # include <stab.h> 14*635Shenry #else not FLEXNAMES 15*635Shenry # include <olda.out.h> 16*635Shenry # include <stab.h> 17*635Shenry #endif FLEXNAMES 18*635Shenry 19*635Shenry #endif UNIX 20*635Shenry #ifdef VMS 21*635Shenry 22*635Shenry #ifdef UNIXDEVEL 23*635Shenry # include <a.out.h> 24*635Shenry #else not UNIXDEVEL 25*635Shenry # include <aout.h> 26*635Shenry #endif not UNIXDEVEL 27*635Shenry 28*635Shenry #endif VMS 29*635Shenry 30601Sbill #define readonly 31601Sbill #define NINST 300 32601Sbill 33601Sbill #define NEXP 20 /* max number of expr. terms per instruction */ 34601Sbill #define NARG 6 /* max number of args per instruction */ 35601Sbill #define NHASH 1103 /* hash table is dynamically extended */ 36626Shenry #define TNAMESIZE 32 /* maximum length of temporary file names */ 37601Sbill #define NLOC 4 /* number of location ctrs */ 38601Sbill 39601Sbill #ifdef UNIX 40601Sbill # ifndef FLEXNAMES 41601Sbill # ifndef NCPS 42601Sbill # define NCPS 8 /* number of characters per symbol*/ 43601Sbill # endif 44601Sbill # else 45601Sbill # ifdef NCPS 46601Sbill # undef NCPS 47601Sbill # endif 48601Sbill # define NCPS BUFSIZ /* needed to allocate yytext */ 49601Sbill # endif 50601Sbill # endif UNIX 51601Sbill 52601Sbill # ifdef VMS 53601Sbill # ifdef NCPS 54601Sbill # undef NCPS 55601Sbill # endif NCPS 56601Sbill # define NCPS 15 57601Sbill # endif VMS 58601Sbill 59601Sbill /* 60601Sbill * Symbol types 61601Sbill */ 62601Sbill #define XUNDEF 0x0 63601Sbill #define XABS 0x2 64601Sbill #define XTEXT 0x4 65601Sbill #define XDATA 0x6 66601Sbill #define XBSS 0x8 67601Sbill 68601Sbill #define XXTRN 0x1 69601Sbill #define XTYPE 0x1E 70601Sbill 71601Sbill #define XFORW 0x20 /* Was forward-referenced when undefined */ 72601Sbill 73601Sbill #define ERR (-1) 74601Sbill #define NBPW 32 /* Bits per word */ 75601Sbill 76601Sbill #define AMASK 017 77601Sbill 78601Sbill /* 79601Sbill * Actual argument syntax types 80601Sbill */ 81626Shenry #define AREG 1 /* %r */ 82626Shenry #define ABASE 2 /* (%r) */ 83626Shenry #define ADECR 3 /* -(%r) */ 84626Shenry #define AINCR 4 /* (%r)+ */ 85626Shenry #define ADISP 5 /* expr(%r) */ 86626Shenry #define AEXP 6 /* expr */ 87626Shenry #define AIMM 7 /* $ expr */ 88626Shenry #define ASTAR 8 /* * */ 89626Shenry #define AINDX 16 /* [%r] */ 90601Sbill 91601Sbill /* 92601Sbill * Argument access types used to test validity of operands to operators 93601Sbill */ 94626Shenry #define ACCA (8<<3) /* address only */ 95626Shenry #define ACCR (1<<3) /* read */ 96626Shenry #define ACCW (2<<3) /* write */ 97626Shenry #define ACCM (3<<3) /* modify */ 98626Shenry #define ACCB (4<<3) /* branch displacement */ 99626Shenry #define ACCI (5<<3) /* XFC code */ 100601Sbill 101601Sbill /* 102601Sbill * Argument data types 103601Sbill */ 104626Shenry #define TYPB 0 /* byte */ 105626Shenry #define TYPW 1 /* word */ 106626Shenry #define TYPL 2 /* long */ 107626Shenry #define TYPQ 3 /* quad */ 108626Shenry #define TYPF 4 /* floating */ 109626Shenry #define TYPD 5 /* double floating */ 110601Sbill 111626Shenry #define TYPMASK 7 112601Sbill 113601Sbill /* reference types for loader */ 114626Shenry #define PCREL 1 115626Shenry #define LEN1 2 116626Shenry #define LEN2 4 117626Shenry #define LEN4 6 118626Shenry #define LEN8 8 119601Sbill /* 120601Sbill * reflen table converts between LEN* and PCREL to numbers 121601Sbill * of bytes. 122601Sbill * lgreflen table is the lg base 2 of the values in reflen. 123601Sbill */ 124601Sbill extern int reflen[]; /* reference lengths */ 125626Shenry extern int lgreflen[]; /* lg reference lengths */ 126601Sbill 127601Sbill #define TMPC 7 128601Sbill #define HW 01 129601Sbill #define FW 03 130601Sbill #define DW 07 131601Sbill 132601Sbill #ifdef UNIX 133601Sbill # include <pagsiz.h> 134601Sbill #endif UNIX 135601Sbill 136601Sbill #ifdef VMS 137601Sbill # define PAGRND 0x1FFL 138601Sbill #endif VMS 139601Sbill 140601Sbill #define round(x,y) (((x)+(y)) & ~(y)) 141601Sbill 142601Sbill #define STABTYPS 0340 143626Shenry #define STABFLAG 0200 144601Sbill 145601Sbill /* 146601Sbill * Follows are the definitions for the symbol table tags, which are 147601Sbill * all unsigned characters.. 148601Sbill * High value tags are generated by the asembler for internal 149601Sbill * use. 150601Sbill * Low valued tags are the parser coded tokens the scanner returns. 151601Sbill * There are several pertinant bounds in this ordering: 152601Sbill * a) Symbols greater than JXQUESTIONABLE 153601Sbill * are used by the jxxx bumper, indicating that 154601Sbill * the symbol table entry is a jxxx entry 155601Sbill * that has yet to be bumped. 156601Sbill * b) Symbols greater than IGNOREBOUND are not 157601Sbill * bequeathed to the loader; they are truly 158601Sbill * for assembler internal use only. 159601Sbill * c) Symbols greater than OKTOBUMP represent 160601Sbill * indices into the program text that should 161601Sbill * be changed in preceeding jumps or aligns 162601Sbill * must get turned into their long form. 163601Sbill */ 164601Sbill 165626Shenry #define TAGMASK 0xFF 166601Sbill 167601Sbill # define JXACTIVE 0xFF /*jxxx size unknown*/ 168601Sbill # define JXNOTYET 0xFE /*jxxx size known, but not yet expanded*/ 169601Sbill # define JXALIGN 0xFD /*align jxxx entry*/ 170601Sbill # define JXINACTIVE 0xFC /*jxxx size known and expanded*/ 171601Sbill 172626Shenry #define JXQUESTIONABLE 0xFB 173601Sbill 174601Sbill # define JXTUNNEL 0xFA /*jxxx that jumps to another*/ 175601Sbill # define OBSOLETE 0xF9 /*erroneously entered symbol*/ 176601Sbill 177601Sbill #define IGNOREBOUND 0xF8 /*symbols greater than this are ignored*/ 178601Sbill # define STABFLOATING 0xF7 179601Sbill # define LABELID 0xF6 180601Sbill 181601Sbill #define OKTOBUMP 0xF5 182601Sbill # define STABFIXED 0xF4 183601Sbill 184601Sbill /* 185601Sbill * astoks.h contains reserved word codings the parser should 186601Sbill * know about 187601Sbill */ 188601Sbill #include "astoks.h" 189601Sbill 190601Sbill /* 191601Sbill * The structure for one symbol table entry. 192601Sbill * Symbol table entries are used for both user defined symbols, 193601Sbill * and symbol slots generated to create the jxxx jump from 194601Sbill * slots. 195*635Shenry * Caution: the instructions are stored in a shorter version 196*635Shenry * of the struct symtab, using all fields in sym_nm and 197*635Shenry * tag. The fields used in sym_nm are carefully redeclared 198*635Shenry * in struct Instab and struct instab (see below). 199*635Shenry * If struct nlist gets changed, then Instab and instab may 200*635Shenry * have to be changed. 201601Sbill */ 202601Sbill 203601Sbill struct symtab{ 204*635Shenry struct nlist s_nm; 205*635Shenry u_char s_tag; /* assembler tag */ 206*635Shenry u_char s_ptype; /* if tag == NAME */ 207*635Shenry u_char s_jxoveralign; /* if a JXXX, jumped over align */ 208*635Shenry short s_index; /* which segment */ 209*635Shenry struct symtab *s_dest; /* if JXXX, where going to */ 210601Sbill #ifdef DJXXX 211*635Shenry short s_jxline; /* source line of the jump from */ 212601Sbill #endif 213601Sbill }; 214*635Shenry /* 215*635Shenry * Redefinitions of the fields in symtab for 216*635Shenry * use when the symbol table entry marks a jxxx instruction. 217*635Shenry */ 218*635Shenry #define s_jxbump s_ptype /* tag == JX..., how far to expand */ 219*635Shenry #define s_jxfear s_desc /* how far needs to be bumped */ 220*635Shenry /* 221*635Shenry * Redefinitions of fields in the struct nlist for symbols so that 222*635Shenry * one saves typing, and so that they conform 223*635Shenry * with the old naming conventions. 224*635Shenry */ 225*635Shenry #ifdef FLEXNAMES 226*635Shenry #define s_name s_nm.n_un.n_name /* name pointer */ 227*635Shenry #define s_nmx s_nm.n_un.n_strx /* string table index */ 228*635Shenry #else not FLEXNAMES 229*635Shenry #define s_name s_nm.n_name 230*635Shenry #endif 231*635Shenry #define s_type s_nm.n_type /* type of the symbol */ 232*635Shenry #define s_other s_nm.n_other /* other information for sdb */ 233*635Shenry #define s_desc s_nm.n_desc /* type descriptor */ 234*635Shenry #define s_value s_nm.n_value /* value of the symbol, or sdb delta */ 235601Sbill 236*635Shenry struct instab{ 237*635Shenry struct nlist s_nm; /* instruction name, type (opcode) */ 238*635Shenry u_char s_tag; 239601Sbill }; 240*635Shenry /* 241*635Shenry * The fields nm.n_desc and nm.n_value total 6 bytes; this is 242*635Shenry * just enough for the 6 bytes describing the argument types. 243*635Shenry * We use a macro to define access to these 6 bytes, assuming that 244*635Shenry * they are allocated adjacently. 245*635Shenry * IF THE FORMAT OF STRUCT nlist CHANGES, THESE MAY HAVE TO BE CHANGED. 246*635Shenry * 247*635Shenry * Instab is cleverly declared to look very much the combination of 248*635Shenry * a struct symtab and a struct nlist. 249*635Shenry */ 250*635Shenry struct Instab{ 251*635Shenry #ifdef FLEXNAMES 252*635Shenry char *I_name; 253*635Shenry #else not FLEXNAMES 254*635Shenry char I_name[NCPS]; 255*635Shenry #endif 256*635Shenry u_char I_opcode; 257*635Shenry char I_nargs; 258*635Shenry char I_args[6]; 259*635Shenry u_char I_s_tag; 260*635Shenry }; 261*635Shenry /* 262*635Shenry * Redefinitions of fields in the struct nlist for instructions so that 263*635Shenry * one saves typing, and conforms to the old naming conventions 264*635Shenry */ 265*635Shenry #define i_opcode s_nm.n_type /* use the same field as symtab.type */ 266*635Shenry #define i_nargs s_nm.n_other /* number of arguments */ 267*635Shenry #define fetcharg(ptr, n) ((struct Instab *)ptr)->I_args[n] 268601Sbill 269601Sbill struct arg { /*one argument to an instruction*/ 270*635Shenry char a_atype; 271*635Shenry char a_areg1; 272*635Shenry char a_areg2; 273*635Shenry char a_dispsize; /*usually d124, unless have B^, etc*/ 274*635Shenry struct exp *a_xp; 275601Sbill }; 276601Sbill 277601Sbill struct exp { 278*635Shenry long e_xvalue; /* MUST be the first field (look at union Double) */ 279*635Shenry long e_yvalue; /* MUST be second field; least sig word of a double */ 280*635Shenry char e_xtype; 281*635Shenry char e_xloc; 282*635Shenry struct symtab *e_xname; 283601Sbill }; 284601Sbill 285*635Shenry #define doub_MSW e_xvalue 286*635Shenry #define doub_LSW e_yvalue 287601Sbill 288*635Shenry union Double { 289601Sbill struct{ 290601Sbill long doub_MSW; 291601Sbill long doub_LSW; 292601Sbill } dis_dvalue; 293601Sbill double dvalue; 294601Sbill }; 295601Sbill 296*635Shenry struct Quad { 297601Sbill long quad_low_long; 298601Sbill long quad_high_long; 299601Sbill }; 300601Sbill 301601Sbill /* 302601Sbill * Magic layout macros 303601Sbill */ 304601Sbill #define MINBYTE -128 305601Sbill #define MAXBYTE 127 306601Sbill #define MINWORD -32768 307601Sbill #define MAXWORD 32767 308601Sbill 309601Sbill #define LITFLTMASK 0x000043F0 /*really magic*/ 310601Sbill /* 311601Sbill * Is the floating point double word in xp a 312601Sbill * short literal floating point number? 313601Sbill */ 314601Sbill #define slitflt(xp) \ 315601Sbill ( (xp->doub_LSW == 0) \ 316601Sbill && ( (xp->doub_MSW & LITFLTMASK) \ 317601Sbill == xp->doub_MSW) ) 318601Sbill /* 319601Sbill * If it is a slitflt, then extract the 6 interesting bits 320601Sbill */ 321601Sbill #define extlitflt(xp) \ 322601Sbill xp->doub_MSW >> 4 323601Sbill 324601Sbill extern struct arg arglist[NARG]; /*building operands in instructions*/ 325601Sbill extern struct exp explist[NEXP]; /*building up a list of expressions*/ 326601Sbill extern struct exp *xp; /*current free expression*/ 327601Sbill /* 328601Sbill * Communication between the scanner and the jxxx handlers. 329601Sbill * lastnam: the last name seen on the input 330601Sbill * lastjxxx: pointer to the last symbol table entry for 331601Sbill * a jump from 332601Sbill */ 333601Sbill extern struct symtab *lastnam; 334601Sbill extern struct symtab *lastjxxx; 335601Sbill 336601Sbill #ifdef VMS 337*635Shenry extern char *vms_obj_ptr; /* object buffer pointer */ 338*635Shenry extern char sobuf[]; /* object buffer */ 339601Sbill extern int objfil; /* VMS object file descriptor */ 340601Sbill #endif VMS 341601Sbill 342601Sbill /* 343601Sbill * Lgensym is used to make up funny names for local labels. 344601Sbill * lgensym[i] is the current funny number to put after 345601Sbill * references to if, lgensym[i]-1 is for ib. 346601Sbill * genref[i] is set when the label is referenced before 347601Sbill * it is defined (i.e. 2f) so that we can be sure these 348601Sbill * labels are always defined to avoid weird diagnostics 349601Sbill * from the loader later. 350601Sbill */ 351601Sbill extern int lgensym[10]; 352601Sbill extern char genref[10]; 353601Sbill 354601Sbill extern char tmpn1[TNAMESIZE]; /* Interpass temporary */ 355601Sbill extern struct exp *dotp; /* the current dot location */ 356601Sbill extern int loctr; 357601Sbill 358601Sbill extern struct exec hdr; /* a.out header */ 359601Sbill extern u_long tsize; /* total text size */ 360601Sbill extern u_long dsize; /* total data size */ 361601Sbill extern u_long trsize; /* total text relocation size */ 362601Sbill extern u_long drsize; /* total data relocation size */ 363601Sbill extern u_long datbase; /* base of the data segment */ 364601Sbill /* 365601Sbill * Bitoff and bitfield keep track of the packing into 366601Sbill * bytes mandated by the expression syntax <expr> ':' <expr> 367601Sbill */ 368601Sbill extern int bitoff; 369601Sbill extern long bitfield; 370601Sbill 371601Sbill /* 372601Sbill * The lexical analyzer builds up symbols in yytext. Lookup 373601Sbill * expects its argument in this buffer 374601Sbill */ 375601Sbill extern char yytext[NCPS+2]; /* text buffer for lexical */ 376601Sbill /* 377601Sbill * Variables to manage the input assembler source file 378601Sbill */ 379601Sbill extern int lineno; /*the line number*/ 380601Sbill extern char *dotsname; /*the name of the as source*/ 381601Sbill 382601Sbill extern FILE *tmpfil; /* interpass communication*/ 383601Sbill 384601Sbill extern int passno; /* 1 or 2 */ 385601Sbill 386601Sbill extern int anyerrs; /*errors assembling arguments*/ 387601Sbill extern int silent; /*don't mention the errors*/ 388601Sbill extern int savelabels; /*save labels in a.out*/ 389601Sbill extern int orgwarn; /* questionable origin ? */ 390601Sbill extern int useVM; /*use virtual memory temp file*/ 391601Sbill #ifdef DEBUG 392601Sbill extern int debug; 393601Sbill extern int toktrace; 394601Sbill #endif 395601Sbill /* 396601Sbill * Information about the instructions 397601Sbill */ 398601Sbill extern struct instab *itab[NINST]; /*maps opcodes to instructions*/ 399*635Shenry extern readonly struct Instab instab[]; 400601Sbill 401601Sbill extern int curlen; /*current literal storage size*/ 402601Sbill extern int d124; /*current pointer storage size*/ 403601Sbill 404601Sbill struct symtab **lookup(); /*argument in yytext*/ 405601Sbill struct symtab *symalloc(); 406601Sbill 407*635Shenry #define outb(val) {dotp->e_xvalue++; if (passno==2) bputc((val), (txtfil));} 408601Sbill 409*635Shenry #define outs(cp, lg) dotp->e_xvalue += (lg); if (passno == 2) bwrite((cp), (lg), (txtfil)) 410601Sbill 411601Sbill /* 412601Sbill * Most of the time, the argument to flushfield is a power of two constant, 413601Sbill * the calculations involving it can be optimized to shifts. 414601Sbill */ 415601Sbill #define flushfield(n) if (bitoff != 0) Flushfield( ( (bitoff+n-1) /n ) * n) 416601Sbill 417601Sbill /* 418601Sbill * The biobuf structure and associated routines are used to write 419601Sbill * into one file at several places concurrently. Calling bopen 420601Sbill * with a biobuf structure sets it up to write ``biofd'' starting 421601Sbill * at the specified offset. You can then use ``bwrite'' and/or ``bputc'' 422601Sbill * to stuff characters in the stream, much like ``fwrite'' and ``fputc''. 423601Sbill * Calling bflush drains all the buffers and MUST be done before exit. 424601Sbill */ 425601Sbill struct biobuf { 426601Sbill short b_nleft; /* Number free spaces left in b_buf */ 427601Sbill /* Initialize to be less than BUFSIZ initially, to boundary align in file */ 428601Sbill char *b_ptr; /* Next place to stuff characters */ 429601Sbill char b_buf[BUFSIZ]; /* The buffer itself */ 430601Sbill off_t b_off; /* Current file offset */ 431601Sbill struct biobuf *b_link; /* Link in chain for bflush() */ 432601Sbill }; 433601Sbill #define bputc(c,b) ((b)->b_nleft ? (--(b)->b_nleft, *(b)->b_ptr++ = (c)) \ 434601Sbill : bflushc(b, c)) 435601Sbill #define BFILE struct biobuf 436601Sbill 437601Sbill extern BFILE *biobufs; /* head of the block I/O buffer chain */ 438601Sbill extern int biofd; /* file descriptor for block I/O file */ 439601Sbill extern off_t boffset; /* physical position in logical file */ 440601Sbill 441601Sbill /* 442601Sbill * For each of the named .text .data segments 443601Sbill * (introduced by .text <expr>), we maintain 444601Sbill * the current value of the dot, and the BFILE where 445601Sbill * the information for each of the segments is placed 446601Sbill * during the second pass. 447601Sbill */ 448601Sbill extern struct exp usedot[NLOC + NLOC]; 449601Sbill extern BFILE *usefile[NLOC + NLOC]; 450601Sbill extern BFILE *txtfil;/* file for text and data: into usefile */ 451601Sbill /* 452601Sbill * Relocation information for each segment is accumulated 453601Sbill * seperately from the others. Writing the relocation 454601Sbill * information is logically viewed as writing to one 455601Sbill * relocation saving file for each segment; physically 456601Sbill * we have a bunch of buffers allocated internally that 457601Sbill * contain the relocation information. 458601Sbill */ 459601Sbill struct relbufdesc *rusefile[NLOC + NLOC]; 460601Sbill struct relbufdesc *relfil; 461