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