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