1601Sbill /* Copyright (c) 1980 Regents of the University of California */ 2*626Shenry /* "@(#)as.h 4.2 08/15/80" */ 3601Sbill #ifdef VMS 4601Sbill # define vax 1 5601Sbill # define VAX 1 6601Sbill #endif VMS 7601Sbill 8601Sbill #define readonly 9601Sbill 10601Sbill #define NINST 300 11601Sbill 12601Sbill #define NEXP 20 /* max number of expr. terms per instruction */ 13601Sbill #define NARG 6 /* max number of args per instruction */ 14601Sbill #define NHASH 1103 /* hash table is dynamically extended */ 15*626Shenry #define TNAMESIZE 32 /* maximum length of temporary file names */ 16601Sbill #define NLOC 4 /* number of location ctrs */ 17601Sbill 18601Sbill #ifdef UNIX 19601Sbill # ifndef FLEXNAMES 20601Sbill # ifndef NCPS 21601Sbill # define NCPS 8 /* number of characters per symbol*/ 22601Sbill # endif 23601Sbill # else 24601Sbill # ifdef NCPS 25601Sbill # undef NCPS 26601Sbill # endif 27601Sbill # define NCPS BUFSIZ /* needed to allocate yytext */ 28601Sbill # endif 29601Sbill # endif UNIX 30601Sbill 31601Sbill # ifdef VMS 32601Sbill # ifdef NCPS 33601Sbill # undef NCPS 34601Sbill # endif NCPS 35601Sbill # define NCPS 15 36601Sbill # endif VMS 37601Sbill 38601Sbill /* 39601Sbill * Symbol types 40601Sbill */ 41601Sbill #define XUNDEF 0x0 42601Sbill #define XABS 0x2 43601Sbill #define XTEXT 0x4 44601Sbill #define XDATA 0x6 45601Sbill #define XBSS 0x8 46601Sbill 47601Sbill #define XXTRN 0x1 48601Sbill #define XTYPE 0x1E 49601Sbill 50601Sbill #define XFORW 0x20 /* Was forward-referenced when undefined */ 51601Sbill 52601Sbill #define ERR (-1) 53601Sbill #define NBPW 32 /* Bits per word */ 54601Sbill 55601Sbill #define AMASK 017 56601Sbill 57601Sbill /* 58601Sbill * Actual argument syntax types 59601Sbill */ 60*626Shenry #define AREG 1 /* %r */ 61*626Shenry #define ABASE 2 /* (%r) */ 62*626Shenry #define ADECR 3 /* -(%r) */ 63*626Shenry #define AINCR 4 /* (%r)+ */ 64*626Shenry #define ADISP 5 /* expr(%r) */ 65*626Shenry #define AEXP 6 /* expr */ 66*626Shenry #define AIMM 7 /* $ expr */ 67*626Shenry #define ASTAR 8 /* * */ 68*626Shenry #define AINDX 16 /* [%r] */ 69601Sbill 70601Sbill /* 71601Sbill * Argument access types used to test validity of operands to operators 72601Sbill */ 73*626Shenry #define ACCA (8<<3) /* address only */ 74*626Shenry #define ACCR (1<<3) /* read */ 75*626Shenry #define ACCW (2<<3) /* write */ 76*626Shenry #define ACCM (3<<3) /* modify */ 77*626Shenry #define ACCB (4<<3) /* branch displacement */ 78*626Shenry #define ACCI (5<<3) /* XFC code */ 79601Sbill 80601Sbill /* 81601Sbill * Argument data types 82601Sbill */ 83*626Shenry #define TYPB 0 /* byte */ 84*626Shenry #define TYPW 1 /* word */ 85*626Shenry #define TYPL 2 /* long */ 86*626Shenry #define TYPQ 3 /* quad */ 87*626Shenry #define TYPF 4 /* floating */ 88*626Shenry #define TYPD 5 /* double floating */ 89601Sbill 90*626Shenry #define TYPMASK 7 91601Sbill 92601Sbill /* reference types for loader */ 93*626Shenry #define PCREL 1 94*626Shenry #define LEN1 2 95*626Shenry #define LEN2 4 96*626Shenry #define LEN4 6 97*626Shenry #define LEN8 8 98601Sbill /* 99601Sbill * reflen table converts between LEN* and PCREL to numbers 100601Sbill * of bytes. 101601Sbill * lgreflen table is the lg base 2 of the values in reflen. 102601Sbill */ 103601Sbill extern int reflen[]; /* reference lengths */ 104*626Shenry extern int lgreflen[]; /* lg reference lengths */ 105601Sbill 106601Sbill #define TMPC 7 107601Sbill #define HW 01 108601Sbill #define FW 03 109601Sbill #define DW 07 110601Sbill 111601Sbill #ifdef UNIX 112601Sbill # include <pagsiz.h> 113601Sbill #endif UNIX 114601Sbill 115601Sbill #ifdef VMS 116601Sbill # define PAGRND 0x1FFL 117601Sbill #endif VMS 118601Sbill 119601Sbill #define round(x,y) (((x)+(y)) & ~(y)) 120601Sbill 121601Sbill #define STABTYPS 0340 122*626Shenry #define STABFLAG 0200 123601Sbill 124601Sbill /* 125601Sbill * Follows are the definitions for the symbol table tags, which are 126601Sbill * all unsigned characters.. 127601Sbill * High value tags are generated by the asembler for internal 128601Sbill * use. 129601Sbill * Low valued tags are the parser coded tokens the scanner returns. 130601Sbill * There are several pertinant bounds in this ordering: 131601Sbill * a) Symbols greater than JXQUESTIONABLE 132601Sbill * are used by the jxxx bumper, indicating that 133601Sbill * the symbol table entry is a jxxx entry 134601Sbill * that has yet to be bumped. 135601Sbill * b) Symbols greater than IGNOREBOUND are not 136601Sbill * bequeathed to the loader; they are truly 137601Sbill * for assembler internal use only. 138601Sbill * c) Symbols greater than OKTOBUMP represent 139601Sbill * indices into the program text that should 140601Sbill * be changed in preceeding jumps or aligns 141601Sbill * must get turned into their long form. 142601Sbill */ 143601Sbill 144*626Shenry #define TAGMASK 0xFF 145601Sbill 146601Sbill # define JXACTIVE 0xFF /*jxxx size unknown*/ 147601Sbill # define JXNOTYET 0xFE /*jxxx size known, but not yet expanded*/ 148601Sbill # define JXALIGN 0xFD /*align jxxx entry*/ 149601Sbill # define JXINACTIVE 0xFC /*jxxx size known and expanded*/ 150601Sbill 151*626Shenry #define JXQUESTIONABLE 0xFB 152601Sbill 153601Sbill # define JXTUNNEL 0xFA /*jxxx that jumps to another*/ 154601Sbill # define OBSOLETE 0xF9 /*erroneously entered symbol*/ 155601Sbill 156601Sbill #define IGNOREBOUND 0xF8 /*symbols greater than this are ignored*/ 157601Sbill # define STABFLOATING 0xF7 158601Sbill # define LABELID 0xF6 159601Sbill 160601Sbill #define OKTOBUMP 0xF5 161601Sbill # define STABFIXED 0xF4 162601Sbill 163601Sbill /* 164601Sbill * astoks.h contains reserved word codings the parser should 165601Sbill * know about 166601Sbill */ 167601Sbill #include "astoks.h" 168601Sbill 169601Sbill /* 170601Sbill * The structure for one symbol table entry. 171601Sbill * Symbol table entries are used for both user defined symbols, 172601Sbill * and symbol slots generated to create the jxxx jump from 173601Sbill * slots. 174601Sbill */ 175601Sbill 176601Sbill #define symfirstfields char *name; unsigned char tag, type 177601Sbill 178601Sbill struct symtab{ 179601Sbill symfirstfields; 180601Sbill short ___hole; 181601Sbill char ptype; /*tag == NAME*/ 182601Sbill 183601Sbill #define jxbump ptype /*tag == JX..., how far to expand*/ 184601Sbill 185601Sbill char other; /*for stab info*/ 186601Sbill 187601Sbill short desc; /*tag == NAME*/ 188601Sbill 189601Sbill #define jxfear desc /*how far needs to be bumped*/ 190601Sbill 191601Sbill long value; /*address in the segment*/ 192601Sbill char jxoveralign; /*if a JXXX, jumped over an align*/ 193601Sbill short index; /*which segment*/ 194601Sbill struct symtab *dest; /*if JXXX, where going to*/ 195601Sbill #ifdef DJXXX 196601Sbill short jxline; /*source line of the jump from*/ 197601Sbill #endif 198601Sbill }; 199601Sbill 200601Sbill struct instab{ 201601Sbill symfirstfields; 202601Sbill 203601Sbill #define opcode type /*use the same field as symtab.type*/ 204601Sbill 205601Sbill char nargs; /*how many arguments*/ 206601Sbill char argtype[6]; /*argument type info*/ 207601Sbill }; 208601Sbill 209601Sbill struct arg { /*one argument to an instruction*/ 210601Sbill char atype; 211601Sbill char areg1; 212601Sbill char areg2; 213601Sbill char dispsize; /*usually d124, unless have B^, etc*/ 214601Sbill struct exp *xp; 215601Sbill }; 216601Sbill 217601Sbill struct exp { 218601Sbill long xvalue; /* MUST be the first field (look at union Double) */ 219601Sbill long yvalue; /* MUST be second field; least sig word of a double */ 220601Sbill char xtype; 221601Sbill char xloc; 222601Sbill struct symtab *xname; 223601Sbill }; 224601Sbill 225601Sbill #define doub_MSW xvalue 226601Sbill #define doub_LSW yvalue 227601Sbill 228601Sbill union Double { 229601Sbill struct{ 230601Sbill long doub_MSW; 231601Sbill long doub_LSW; 232601Sbill } dis_dvalue; 233601Sbill double dvalue; 234601Sbill }; 235601Sbill 236601Sbill struct Quad { 237601Sbill long quad_low_long; 238601Sbill long quad_high_long; 239601Sbill }; 240601Sbill 241601Sbill /* 242601Sbill * Magic layout macros 243601Sbill */ 244601Sbill #define MINBYTE -128 245601Sbill #define MAXBYTE 127 246601Sbill #define MINWORD -32768 247601Sbill #define MAXWORD 32767 248601Sbill 249601Sbill #define LITFLTMASK 0x000043F0 /*really magic*/ 250601Sbill /* 251601Sbill * Is the floating point double word in xp a 252601Sbill * short literal floating point number? 253601Sbill */ 254601Sbill #define slitflt(xp) \ 255601Sbill ( (xp->doub_LSW == 0) \ 256601Sbill && ( (xp->doub_MSW & LITFLTMASK) \ 257601Sbill == xp->doub_MSW) ) 258601Sbill /* 259601Sbill * If it is a slitflt, then extract the 6 interesting bits 260601Sbill */ 261601Sbill #define extlitflt(xp) \ 262601Sbill xp->doub_MSW >> 4 263601Sbill 264601Sbill extern struct arg arglist[NARG]; /*building operands in instructions*/ 265601Sbill extern struct exp explist[NEXP]; /*building up a list of expressions*/ 266601Sbill extern struct exp *xp; /*current free expression*/ 267601Sbill /* 268601Sbill * Communication between the scanner and the jxxx handlers. 269601Sbill * lastnam: the last name seen on the input 270601Sbill * lastjxxx: pointer to the last symbol table entry for 271601Sbill * a jump from 272601Sbill */ 273601Sbill extern struct symtab *lastnam; 274601Sbill extern struct symtab *lastjxxx; 275601Sbill 276601Sbill #ifdef VMS 277601Sbill extern char *vms_obj_ptr; /* object buffer pointer */ 278601Sbill extern char sobuf[]; /* object buffer */ 279601Sbill extern int objfil; /* VMS object file descriptor */ 280601Sbill #endif VMS 281601Sbill 282601Sbill /* 283601Sbill * Lgensym is used to make up funny names for local labels. 284601Sbill * lgensym[i] is the current funny number to put after 285601Sbill * references to if, lgensym[i]-1 is for ib. 286601Sbill * genref[i] is set when the label is referenced before 287601Sbill * it is defined (i.e. 2f) so that we can be sure these 288601Sbill * labels are always defined to avoid weird diagnostics 289601Sbill * from the loader later. 290601Sbill */ 291601Sbill extern int lgensym[10]; 292601Sbill extern char genref[10]; 293601Sbill 294601Sbill extern char tmpn1[TNAMESIZE]; /* Interpass temporary */ 295601Sbill extern struct exp *dotp; /* the current dot location */ 296601Sbill extern int loctr; 297601Sbill 298601Sbill extern struct exec hdr; /* a.out header */ 299601Sbill extern u_long tsize; /* total text size */ 300601Sbill extern u_long dsize; /* total data size */ 301601Sbill extern u_long trsize; /* total text relocation size */ 302601Sbill extern u_long drsize; /* total data relocation size */ 303601Sbill extern u_long datbase; /* base of the data segment */ 304601Sbill /* 305601Sbill * Bitoff and bitfield keep track of the packing into 306601Sbill * bytes mandated by the expression syntax <expr> ':' <expr> 307601Sbill */ 308601Sbill extern int bitoff; 309601Sbill extern long bitfield; 310601Sbill 311601Sbill /* 312601Sbill * The lexical analyzer builds up symbols in yytext. Lookup 313601Sbill * expects its argument in this buffer 314601Sbill */ 315601Sbill extern char yytext[NCPS+2]; /* text buffer for lexical */ 316601Sbill /* 317601Sbill * Variables to manage the input assembler source file 318601Sbill */ 319601Sbill extern int lineno; /*the line number*/ 320601Sbill extern char *dotsname; /*the name of the as source*/ 321601Sbill 322601Sbill extern FILE *tmpfil; /* interpass communication*/ 323601Sbill 324601Sbill extern int passno; /* 1 or 2 */ 325601Sbill 326601Sbill extern int anyerrs; /*errors assembling arguments*/ 327601Sbill extern int silent; /*don't mention the errors*/ 328601Sbill extern int savelabels; /*save labels in a.out*/ 329601Sbill extern int orgwarn; /* questionable origin ? */ 330601Sbill extern int useVM; /*use virtual memory temp file*/ 331601Sbill #ifdef DEBUG 332601Sbill extern int debug; 333601Sbill extern int toktrace; 334601Sbill #endif 335601Sbill /* 336601Sbill * Information about the instructions 337601Sbill */ 338601Sbill extern struct instab *itab[NINST]; /*maps opcodes to instructions*/ 339601Sbill extern readonly struct instab instab[]; 340601Sbill 341601Sbill extern int curlen; /*current literal storage size*/ 342601Sbill extern int d124; /*current pointer storage size*/ 343601Sbill 344601Sbill struct symtab **lookup(); /*argument in yytext*/ 345601Sbill struct symtab *symalloc(); 346601Sbill 347601Sbill #define outb(val) {dotp->xvalue++; if (passno==2) bputc((val), (txtfil));} 348601Sbill 349601Sbill #define outs(cp, lg) dotp->xvalue += (lg); if (passno == 2) bwrite((cp), (lg), (txtfil)) 350601Sbill 351601Sbill /* 352601Sbill * Most of the time, the argument to flushfield is a power of two constant, 353601Sbill * the calculations involving it can be optimized to shifts. 354601Sbill */ 355601Sbill #define flushfield(n) if (bitoff != 0) Flushfield( ( (bitoff+n-1) /n ) * n) 356601Sbill 357601Sbill /* 358601Sbill * The biobuf structure and associated routines are used to write 359601Sbill * into one file at several places concurrently. Calling bopen 360601Sbill * with a biobuf structure sets it up to write ``biofd'' starting 361601Sbill * at the specified offset. You can then use ``bwrite'' and/or ``bputc'' 362601Sbill * to stuff characters in the stream, much like ``fwrite'' and ``fputc''. 363601Sbill * Calling bflush drains all the buffers and MUST be done before exit. 364601Sbill */ 365601Sbill struct biobuf { 366601Sbill short b_nleft; /* Number free spaces left in b_buf */ 367601Sbill /* Initialize to be less than BUFSIZ initially, to boundary align in file */ 368601Sbill char *b_ptr; /* Next place to stuff characters */ 369601Sbill char b_buf[BUFSIZ]; /* The buffer itself */ 370601Sbill off_t b_off; /* Current file offset */ 371601Sbill struct biobuf *b_link; /* Link in chain for bflush() */ 372601Sbill }; 373601Sbill #define bputc(c,b) ((b)->b_nleft ? (--(b)->b_nleft, *(b)->b_ptr++ = (c)) \ 374601Sbill : bflushc(b, c)) 375601Sbill #define BFILE struct biobuf 376601Sbill 377601Sbill extern BFILE *biobufs; /* head of the block I/O buffer chain */ 378601Sbill extern int biofd; /* file descriptor for block I/O file */ 379601Sbill extern off_t boffset; /* physical position in logical file */ 380601Sbill 381601Sbill /* 382601Sbill * For each of the named .text .data segments 383601Sbill * (introduced by .text <expr>), we maintain 384601Sbill * the current value of the dot, and the BFILE where 385601Sbill * the information for each of the segments is placed 386601Sbill * during the second pass. 387601Sbill */ 388601Sbill extern struct exp usedot[NLOC + NLOC]; 389601Sbill extern BFILE *usefile[NLOC + NLOC]; 390601Sbill extern BFILE *txtfil;/* file for text and data: into usefile */ 391601Sbill /* 392601Sbill * Relocation information for each segment is accumulated 393601Sbill * seperately from the others. Writing the relocation 394601Sbill * information is logically viewed as writing to one 395601Sbill * relocation saving file for each segment; physically 396601Sbill * we have a bunch of buffers allocated internally that 397601Sbill * contain the relocation information. 398601Sbill */ 399601Sbill struct relbufdesc *rusefile[NLOC + NLOC]; 400601Sbill struct relbufdesc *relfil; 401