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