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