1*601Sbill /* Copyright (c) 1980 Regents of the University of California */ 2*601Sbill /* "@(#)as.h 4.1 08/13/80" */ 3*601Sbill #ifdef VMS 4*601Sbill # define vax 1 5*601Sbill # define VAX 1 6*601Sbill #endif VMS 7*601Sbill 8*601Sbill #define readonly 9*601Sbill 10*601Sbill #define NINST 300 11*601Sbill 12*601Sbill #define NEXP 20 /* max number of expr. terms per instruction */ 13*601Sbill #define NARG 6 /* max number of args per instruction */ 14*601Sbill #define NHASH 1103 /* hash table is dynamically extended */ 15*601Sbill #define TNAMESIZE 32 /* maximum length of temporary file names */ 16*601Sbill #define NLOC 4 /* number of location ctrs */ 17*601Sbill 18*601Sbill #ifdef UNIX 19*601Sbill # ifndef FLEXNAMES 20*601Sbill # ifndef NCPS 21*601Sbill # define NCPS 8 /* number of characters per symbol*/ 22*601Sbill # endif 23*601Sbill # else 24*601Sbill # ifdef NCPS 25*601Sbill # undef NCPS 26*601Sbill # endif 27*601Sbill # define NCPS BUFSIZ /* needed to allocate yytext */ 28*601Sbill # endif 29*601Sbill # endif UNIX 30*601Sbill 31*601Sbill # ifdef VMS 32*601Sbill # ifdef NCPS 33*601Sbill # undef NCPS 34*601Sbill # endif NCPS 35*601Sbill # define NCPS 15 36*601Sbill # endif VMS 37*601Sbill 38*601Sbill /* 39*601Sbill * Symbol types 40*601Sbill */ 41*601Sbill #define XUNDEF 0x0 42*601Sbill #define XABS 0x2 43*601Sbill #define XTEXT 0x4 44*601Sbill #define XDATA 0x6 45*601Sbill #define XBSS 0x8 46*601Sbill 47*601Sbill #define XXTRN 0x1 48*601Sbill #define XTYPE 0x1E 49*601Sbill 50*601Sbill #define XFORW 0x20 /* Was forward-referenced when undefined */ 51*601Sbill 52*601Sbill #define ERR (-1) 53*601Sbill #define NBPW 32 /* Bits per word */ 54*601Sbill 55*601Sbill #define AMASK 017 56*601Sbill 57*601Sbill /* 58*601Sbill * Actual argument syntax types 59*601Sbill */ 60*601Sbill #define AREG 1 /* %r */ 61*601Sbill #define ABASE 2 /* (%r) */ 62*601Sbill #define ADECR 3 /* -(%r) */ 63*601Sbill #define AINCR 4 /* (%r)+ */ 64*601Sbill #define ADISP 5 /* expr(%r) */ 65*601Sbill #define AEXP 6 /* expr */ 66*601Sbill #define AIMM 7 /* $ expr */ 67*601Sbill #define ASTAR 8 /* * */ 68*601Sbill #define AINDX 16 /* [%r] */ 69*601Sbill 70*601Sbill /* 71*601Sbill * Argument access types used to test validity of operands to operators 72*601Sbill */ 73*601Sbill #define ACCA (8<<3) /* address only */ 74*601Sbill #define ACCR (1<<3) /* read */ 75*601Sbill #define ACCW (2<<3) /* write */ 76*601Sbill #define ACCM (3<<3) /* modify */ 77*601Sbill #define ACCB (4<<3) /* branch displacement */ 78*601Sbill #define ACCI (5<<3) /* XFC code */ 79*601Sbill 80*601Sbill /* 81*601Sbill * Argument data types 82*601Sbill */ 83*601Sbill #define TYPB 0 /* byte */ 84*601Sbill #define TYPW 1 /* word */ 85*601Sbill #define TYPL 2 /* long */ 86*601Sbill #define TYPQ 3 /* quad */ 87*601Sbill #define TYPF 4 /* floating */ 88*601Sbill #define TYPD 5 /* double floating */ 89*601Sbill 90*601Sbill #define TYPMASK 7 91*601Sbill 92*601Sbill /* reference types for loader */ 93*601Sbill #define PCREL 1 94*601Sbill #define LEN1 2 95*601Sbill #define LEN2 4 96*601Sbill #define LEN4 6 97*601Sbill #define LEN8 8 98*601Sbill /* 99*601Sbill * reflen table converts between LEN* and PCREL to numbers 100*601Sbill * of bytes. 101*601Sbill * lgreflen table is the lg base 2 of the values in reflen. 102*601Sbill */ 103*601Sbill extern int reflen[]; /* reference lengths */ 104*601Sbill extern int lgrefltn[]; /* lg reference lengths */ 105*601Sbill 106*601Sbill #define TMPC 7 107*601Sbill #define HW 01 108*601Sbill #define FW 03 109*601Sbill #define DW 07 110*601Sbill 111*601Sbill #ifdef UNIX 112*601Sbill # include <pagsiz.h> 113*601Sbill #endif UNIX 114*601Sbill 115*601Sbill #ifdef VMS 116*601Sbill # define PAGRND 0x1FFL 117*601Sbill #endif VMS 118*601Sbill 119*601Sbill #define round(x,y) (((x)+(y)) & ~(y)) 120*601Sbill 121*601Sbill #define STABTYPS 0340 122*601Sbill #define STABFLAG 0200 123*601Sbill 124*601Sbill /* 125*601Sbill * Follows are the definitions for the symbol table tags, which are 126*601Sbill * all unsigned characters.. 127*601Sbill * High value tags are generated by the asembler for internal 128*601Sbill * use. 129*601Sbill * Low valued tags are the parser coded tokens the scanner returns. 130*601Sbill * There are several pertinant bounds in this ordering: 131*601Sbill * a) Symbols greater than JXQUESTIONABLE 132*601Sbill * are used by the jxxx bumper, indicating that 133*601Sbill * the symbol table entry is a jxxx entry 134*601Sbill * that has yet to be bumped. 135*601Sbill * b) Symbols greater than IGNOREBOUND are not 136*601Sbill * bequeathed to the loader; they are truly 137*601Sbill * for assembler internal use only. 138*601Sbill * c) Symbols greater than OKTOBUMP represent 139*601Sbill * indices into the program text that should 140*601Sbill * be changed in preceeding jumps or aligns 141*601Sbill * must get turned into their long form. 142*601Sbill */ 143*601Sbill 144*601Sbill #define TAGMASK 0xFF 145*601Sbill 146*601Sbill # define JXACTIVE 0xFF /*jxxx size unknown*/ 147*601Sbill # define JXNOTYET 0xFE /*jxxx size known, but not yet expanded*/ 148*601Sbill # define JXALIGN 0xFD /*align jxxx entry*/ 149*601Sbill # define JXINACTIVE 0xFC /*jxxx size known and expanded*/ 150*601Sbill 151*601Sbill #define JXQUESTIONABLE 0xFB 152*601Sbill 153*601Sbill # define JXTUNNEL 0xFA /*jxxx that jumps to another*/ 154*601Sbill # define OBSOLETE 0xF9 /*erroneously entered symbol*/ 155*601Sbill 156*601Sbill #define IGNOREBOUND 0xF8 /*symbols greater than this are ignored*/ 157*601Sbill # define STABFLOATING 0xF7 158*601Sbill # define LABELID 0xF6 159*601Sbill 160*601Sbill #define OKTOBUMP 0xF5 161*601Sbill # define STABFIXED 0xF4 162*601Sbill 163*601Sbill /* 164*601Sbill * astoks.h contains reserved word codings the parser should 165*601Sbill * know about 166*601Sbill */ 167*601Sbill #include "astoks.h" 168*601Sbill 169*601Sbill /* 170*601Sbill * The structure for one symbol table entry. 171*601Sbill * Symbol table entries are used for both user defined symbols, 172*601Sbill * and symbol slots generated to create the jxxx jump from 173*601Sbill * slots. 174*601Sbill */ 175*601Sbill 176*601Sbill #define symfirstfields char *name; unsigned char tag, type 177*601Sbill 178*601Sbill struct symtab{ 179*601Sbill symfirstfields; 180*601Sbill short ___hole; 181*601Sbill char ptype; /*tag == NAME*/ 182*601Sbill 183*601Sbill #define jxbump ptype /*tag == JX..., how far to expand*/ 184*601Sbill 185*601Sbill char other; /*for stab info*/ 186*601Sbill 187*601Sbill short desc; /*tag == NAME*/ 188*601Sbill 189*601Sbill #define jxfear desc /*how far needs to be bumped*/ 190*601Sbill 191*601Sbill long value; /*address in the segment*/ 192*601Sbill char jxoveralign; /*if a JXXX, jumped over an align*/ 193*601Sbill short index; /*which segment*/ 194*601Sbill struct symtab *dest; /*if JXXX, where going to*/ 195*601Sbill #ifdef DJXXX 196*601Sbill short jxline; /*source line of the jump from*/ 197*601Sbill #endif 198*601Sbill }; 199*601Sbill 200*601Sbill struct instab{ 201*601Sbill symfirstfields; 202*601Sbill 203*601Sbill #define opcode type /*use the same field as symtab.type*/ 204*601Sbill 205*601Sbill char nargs; /*how many arguments*/ 206*601Sbill char argtype[6]; /*argument type info*/ 207*601Sbill }; 208*601Sbill 209*601Sbill struct arg { /*one argument to an instruction*/ 210*601Sbill char atype; 211*601Sbill char areg1; 212*601Sbill char areg2; 213*601Sbill char dispsize; /*usually d124, unless have B^, etc*/ 214*601Sbill struct exp *xp; 215*601Sbill }; 216*601Sbill 217*601Sbill struct exp { 218*601Sbill long xvalue; /* MUST be the first field (look at union Double) */ 219*601Sbill long yvalue; /* MUST be second field; least sig word of a double */ 220*601Sbill char xtype; 221*601Sbill char xloc; 222*601Sbill struct symtab *xname; 223*601Sbill }; 224*601Sbill 225*601Sbill #define doub_MSW xvalue 226*601Sbill #define doub_LSW yvalue 227*601Sbill 228*601Sbill union Double { 229*601Sbill struct{ 230*601Sbill long doub_MSW; 231*601Sbill long doub_LSW; 232*601Sbill } dis_dvalue; 233*601Sbill double dvalue; 234*601Sbill }; 235*601Sbill 236*601Sbill struct Quad { 237*601Sbill long quad_low_long; 238*601Sbill long quad_high_long; 239*601Sbill }; 240*601Sbill 241*601Sbill /* 242*601Sbill * Magic layout macros 243*601Sbill */ 244*601Sbill #define MINBYTE -128 245*601Sbill #define MAXBYTE 127 246*601Sbill #define MINWORD -32768 247*601Sbill #define MAXWORD 32767 248*601Sbill 249*601Sbill #define LITFLTMASK 0x000043F0 /*really magic*/ 250*601Sbill /* 251*601Sbill * Is the floating point double word in xp a 252*601Sbill * short literal floating point number? 253*601Sbill */ 254*601Sbill #define slitflt(xp) \ 255*601Sbill ( (xp->doub_LSW == 0) \ 256*601Sbill && ( (xp->doub_MSW & LITFLTMASK) \ 257*601Sbill == xp->doub_MSW) ) 258*601Sbill /* 259*601Sbill * If it is a slitflt, then extract the 6 interesting bits 260*601Sbill */ 261*601Sbill #define extlitflt(xp) \ 262*601Sbill xp->doub_MSW >> 4 263*601Sbill 264*601Sbill extern struct arg arglist[NARG]; /*building operands in instructions*/ 265*601Sbill extern struct exp explist[NEXP]; /*building up a list of expressions*/ 266*601Sbill extern struct exp *xp; /*current free expression*/ 267*601Sbill /* 268*601Sbill * Communication between the scanner and the jxxx handlers. 269*601Sbill * lastnam: the last name seen on the input 270*601Sbill * lastjxxx: pointer to the last symbol table entry for 271*601Sbill * a jump from 272*601Sbill */ 273*601Sbill extern struct symtab *lastnam; 274*601Sbill extern struct symtab *lastjxxx; 275*601Sbill 276*601Sbill #ifdef VMS 277*601Sbill extern char *vms_obj_ptr; /* object buffer pointer */ 278*601Sbill extern char sobuf[]; /* object buffer */ 279*601Sbill extern int objfil; /* VMS object file descriptor */ 280*601Sbill #endif VMS 281*601Sbill 282*601Sbill /* 283*601Sbill * Lgensym is used to make up funny names for local labels. 284*601Sbill * lgensym[i] is the current funny number to put after 285*601Sbill * references to if, lgensym[i]-1 is for ib. 286*601Sbill * genref[i] is set when the label is referenced before 287*601Sbill * it is defined (i.e. 2f) so that we can be sure these 288*601Sbill * labels are always defined to avoid weird diagnostics 289*601Sbill * from the loader later. 290*601Sbill */ 291*601Sbill extern int lgensym[10]; 292*601Sbill extern char genref[10]; 293*601Sbill 294*601Sbill extern char tmpn1[TNAMESIZE]; /* Interpass temporary */ 295*601Sbill extern struct exp *dotp; /* the current dot location */ 296*601Sbill extern int loctr; 297*601Sbill 298*601Sbill extern struct exec hdr; /* a.out header */ 299*601Sbill extern u_long tsize; /* total text size */ 300*601Sbill extern u_long dsize; /* total data size */ 301*601Sbill extern u_long trsize; /* total text relocation size */ 302*601Sbill extern u_long drsize; /* total data relocation size */ 303*601Sbill extern u_long datbase; /* base of the data segment */ 304*601Sbill /* 305*601Sbill * Bitoff and bitfield keep track of the packing into 306*601Sbill * bytes mandated by the expression syntax <expr> ':' <expr> 307*601Sbill */ 308*601Sbill extern int bitoff; 309*601Sbill extern long bitfield; 310*601Sbill 311*601Sbill /* 312*601Sbill * The lexical analyzer builds up symbols in yytext. Lookup 313*601Sbill * expects its argument in this buffer 314*601Sbill */ 315*601Sbill extern char yytext[NCPS+2]; /* text buffer for lexical */ 316*601Sbill /* 317*601Sbill * Variables to manage the input assembler source file 318*601Sbill */ 319*601Sbill extern int lineno; /*the line number*/ 320*601Sbill extern char *dotsname; /*the name of the as source*/ 321*601Sbill 322*601Sbill extern FILE *tmpfil; /* interpass communication*/ 323*601Sbill 324*601Sbill extern int passno; /* 1 or 2 */ 325*601Sbill 326*601Sbill extern int anyerrs; /*errors assembling arguments*/ 327*601Sbill extern int silent; /*don't mention the errors*/ 328*601Sbill extern int savelabels; /*save labels in a.out*/ 329*601Sbill extern int orgwarn; /* questionable origin ? */ 330*601Sbill extern int useVM; /*use virtual memory temp file*/ 331*601Sbill #ifdef DEBUG 332*601Sbill extern int debug; 333*601Sbill extern int toktrace; 334*601Sbill #endif 335*601Sbill /* 336*601Sbill * Information about the instructions 337*601Sbill */ 338*601Sbill extern struct instab *itab[NINST]; /*maps opcodes to instructions*/ 339*601Sbill extern readonly struct instab instab[]; 340*601Sbill 341*601Sbill extern int curlen; /*current literal storage size*/ 342*601Sbill extern int d124; /*current pointer storage size*/ 343*601Sbill 344*601Sbill struct symtab **lookup(); /*argument in yytext*/ 345*601Sbill struct symtab *symalloc(); 346*601Sbill 347*601Sbill #define outb(val) {dotp->xvalue++; if (passno==2) bputc((val), (txtfil));} 348*601Sbill 349*601Sbill #define outs(cp, lg) dotp->xvalue += (lg); if (passno == 2) bwrite((cp), (lg), (txtfil)) 350*601Sbill 351*601Sbill /* 352*601Sbill * Most of the time, the argument to flushfield is a power of two constant, 353*601Sbill * the calculations involving it can be optimized to shifts. 354*601Sbill */ 355*601Sbill #define flushfield(n) if (bitoff != 0) Flushfield( ( (bitoff+n-1) /n ) * n) 356*601Sbill 357*601Sbill /* 358*601Sbill * The biobuf structure and associated routines are used to write 359*601Sbill * into one file at several places concurrently. Calling bopen 360*601Sbill * with a biobuf structure sets it up to write ``biofd'' starting 361*601Sbill * at the specified offset. You can then use ``bwrite'' and/or ``bputc'' 362*601Sbill * to stuff characters in the stream, much like ``fwrite'' and ``fputc''. 363*601Sbill * Calling bflush drains all the buffers and MUST be done before exit. 364*601Sbill */ 365*601Sbill struct biobuf { 366*601Sbill short b_nleft; /* Number free spaces left in b_buf */ 367*601Sbill /* Initialize to be less than BUFSIZ initially, to boundary align in file */ 368*601Sbill char *b_ptr; /* Next place to stuff characters */ 369*601Sbill char b_buf[BUFSIZ]; /* The buffer itself */ 370*601Sbill off_t b_off; /* Current file offset */ 371*601Sbill struct biobuf *b_link; /* Link in chain for bflush() */ 372*601Sbill }; 373*601Sbill #define bputc(c,b) ((b)->b_nleft ? (--(b)->b_nleft, *(b)->b_ptr++ = (c)) \ 374*601Sbill : bflushc(b, c)) 375*601Sbill #define BFILE struct biobuf 376*601Sbill 377*601Sbill extern BFILE *biobufs; /* head of the block I/O buffer chain */ 378*601Sbill extern int biofd; /* file descriptor for block I/O file */ 379*601Sbill extern off_t boffset; /* physical position in logical file */ 380*601Sbill 381*601Sbill /* 382*601Sbill * For each of the named .text .data segments 383*601Sbill * (introduced by .text <expr>), we maintain 384*601Sbill * the current value of the dot, and the BFILE where 385*601Sbill * the information for each of the segments is placed 386*601Sbill * during the second pass. 387*601Sbill */ 388*601Sbill extern struct exp usedot[NLOC + NLOC]; 389*601Sbill extern BFILE *usefile[NLOC + NLOC]; 390*601Sbill extern BFILE *txtfil;/* file for text and data: into usefile */ 391*601Sbill /* 392*601Sbill * Relocation information for each segment is accumulated 393*601Sbill * seperately from the others. Writing the relocation 394*601Sbill * information is logically viewed as writing to one 395*601Sbill * relocation saving file for each segment; physically 396*601Sbill * we have a bunch of buffers allocated internally that 397*601Sbill * contain the relocation information. 398*601Sbill */ 399*601Sbill struct relbufdesc *rusefile[NLOC + NLOC]; 400*601Sbill struct relbufdesc *relfil; 401