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