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