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