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