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;