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