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