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