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