1601Sbill /* Copyright (c) 1980 Regents of the University of California */ 2*672Shenry /* "@(#)as.h 4.7 08/20/80" */ 3601Sbill #ifdef VMS 4601Sbill # define vax 1 5601Sbill # define VAX 1 6601Sbill #endif VMS 7601Sbill 8635Shenry #include <sys/types.h> 9635Shenry #ifdef UNIX 10635Shenry 11635Shenry #ifdef FLEXNAMES 12635Shenry # include <a.out.h> 13635Shenry # include <stab.h> 14635Shenry #else not FLEXNAMES 15635Shenry # include <olda.out.h> 16635Shenry # include <stab.h> 17635Shenry #endif FLEXNAMES 18635Shenry 19635Shenry #endif UNIX 20635Shenry #ifdef VMS 21635Shenry 22635Shenry #ifdef UNIXDEVEL 23635Shenry # include <a.out.h> 24635Shenry #else not UNIXDEVEL 25635Shenry # include <aout.h> 26635Shenry #endif not UNIXDEVEL 27635Shenry 28635Shenry #endif VMS 29635Shenry 30601Sbill #define readonly 31601Sbill #define NINST 300 32601Sbill 33601Sbill #define NEXP 20 /* max number of expr. terms per instruction */ 34601Sbill #define NARG 6 /* max number of args per instruction */ 35601Sbill #define NHASH 1103 /* hash table is dynamically extended */ 36626Shenry #define TNAMESIZE 32 /* maximum length of temporary file names */ 37601Sbill #define NLOC 4 /* number of location ctrs */ 38601Sbill 39601Sbill #ifdef UNIX 40601Sbill # ifndef FLEXNAMES 41601Sbill # ifndef NCPS 42601Sbill # define NCPS 8 /* number of characters per symbol*/ 43601Sbill # endif 44601Sbill # else 45601Sbill # ifdef NCPS 46601Sbill # undef NCPS 47601Sbill # endif 48601Sbill # define NCPS BUFSIZ /* needed to allocate yytext */ 49601Sbill # endif 50601Sbill # endif UNIX 51601Sbill 52601Sbill # ifdef VMS 53601Sbill # ifdef NCPS 54601Sbill # undef NCPS 55601Sbill # endif NCPS 56601Sbill # define NCPS 15 57601Sbill # endif VMS 58601Sbill 59601Sbill /* 60601Sbill * Symbol types 61601Sbill */ 62601Sbill #define XUNDEF 0x0 63601Sbill #define XABS 0x2 64601Sbill #define XTEXT 0x4 65601Sbill #define XDATA 0x6 66601Sbill #define XBSS 0x8 67601Sbill 68601Sbill #define XXTRN 0x1 69601Sbill #define XTYPE 0x1E 70601Sbill 71601Sbill #define XFORW 0x20 /* Was forward-referenced when undefined */ 72601Sbill 73601Sbill #define ERR (-1) 74601Sbill #define NBPW 32 /* Bits per word */ 75601Sbill 76601Sbill #define AMASK 017 77601Sbill 78601Sbill /* 79601Sbill * Actual argument syntax types 80601Sbill */ 81626Shenry #define AREG 1 /* %r */ 82626Shenry #define ABASE 2 /* (%r) */ 83626Shenry #define ADECR 3 /* -(%r) */ 84626Shenry #define AINCR 4 /* (%r)+ */ 85626Shenry #define ADISP 5 /* expr(%r) */ 86626Shenry #define AEXP 6 /* expr */ 87626Shenry #define AIMM 7 /* $ expr */ 88626Shenry #define ASTAR 8 /* * */ 89626Shenry #define AINDX 16 /* [%r] */ 90601Sbill 91601Sbill /* 92601Sbill * Argument access types used to test validity of operands to operators 93601Sbill */ 94666Shenry #define ACCR (1<<3) /* read */ 95666Shenry #define ACCW (2<<3) /* write */ 96666Shenry #define ACCB (4<<3) /* branch displacement */ 97666Shenry #define ACCA (8<<3) /* address only */ 98666Shenry #define ACCM (ACCR | ACCW) /* modify */ 99666Shenry #define ACCI (ACCB | ACCR) /* XFC code */ 100601Sbill 101*672Shenry #define ACCESSMASK (ACCA | ACCR | ACCW | ACCB) /* the mask */ 102666Shenry 103601Sbill /* 104*672Shenry * Argument data types 105*672Shenry * Also used to tell outrel what it is relocating 106*672Shenry * (possibly in combination with RELOC_PCREL and TYPNONE) 107601Sbill */ 108*672Shenry #define TYPB 0 /* byte */ 109*672Shenry #define TYPW 1 /* word */ 110*672Shenry #define TYPL 2 /* long */ 111*672Shenry #define TYPQ 3 /* quad */ 112*672Shenry #define TYPF 4 /* floating */ 113*672Shenry #define TYPD 5 /* double floating */ 114*672Shenry #define TYPNONE 6 /* when nothing */ 115*672Shenry #define RELOC_PCREL 8 /* implicit argument to outrel; ==> PCREL */ 116601Sbill 117626Shenry #define TYPMASK 7 118601Sbill 119*672Shenry /* 120*672Shenry * reference types for loader 121*672Shenry */ 122626Shenry #define PCREL 1 123626Shenry #define LEN1 2 124626Shenry #define LEN2 4 125626Shenry #define LEN4 6 126626Shenry #define LEN8 8 127601Sbill 128*672Shenry extern int reflen[]; /* {LEN*+PCREL} ==> number of bytes */ 129*672Shenry extern int lgreflen[]; /* {LEN*+PCREL} ==> lg number of bytes */ 130*672Shenry extern int len124[]; /* {1,2,4,8} ==> {LEN1, LEN2, LEN4, LEN8} */ 131*672Shenry extern char mod124[]; /* {1,2,4,8} ==> {bits to construct operands */ 132*672Shenry extern int type_124[]; /* {1,2,4,8} ==> {TYPB, TYPW, TYPL, TYPQ} */ 133*672Shenry extern int ty_NORELOC[]; /* {TYPB..TYPD} ==> {1 if relocation not OK */ 134*672Shenry extern int ty_LEN[]; /* {TYPB..TYPD} ==> {LEN1..LEN8} */ 135*672Shenry extern int ty_nbyte[]; /* {TYPB..TYPD} ==> {1,2,4,8} */ 136*672Shenry extern int ty_nlg[]; /* {TYPB..TYPD} ==> lg{1,2,4,8} */ 137*672Shenry 138601Sbill #define TMPC 7 139601Sbill #define HW 01 140601Sbill #define FW 03 141601Sbill #define DW 07 142601Sbill 143601Sbill #ifdef UNIX 144601Sbill # include <pagsiz.h> 145601Sbill #endif UNIX 146601Sbill 147601Sbill #ifdef VMS 148601Sbill # define PAGRND 0x1FFL 149601Sbill #endif VMS 150601Sbill 151601Sbill #define round(x,y) (((x)+(y)) & ~(y)) 152601Sbill 153601Sbill #define STABTYPS 0340 154626Shenry #define STABFLAG 0200 155601Sbill 156601Sbill /* 157601Sbill * Follows are the definitions for the symbol table tags, which are 158601Sbill * all unsigned characters.. 159601Sbill * High value tags are generated by the asembler for internal 160601Sbill * use. 161601Sbill * Low valued tags are the parser coded tokens the scanner returns. 162601Sbill * There are several pertinant bounds in this ordering: 163601Sbill * a) Symbols greater than JXQUESTIONABLE 164601Sbill * are used by the jxxx bumper, indicating that 165601Sbill * the symbol table entry is a jxxx entry 166601Sbill * that has yet to be bumped. 167601Sbill * b) Symbols greater than IGNOREBOUND are not 168601Sbill * bequeathed to the loader; they are truly 169601Sbill * for assembler internal use only. 170601Sbill * c) Symbols greater than OKTOBUMP represent 171601Sbill * indices into the program text that should 172601Sbill * be changed in preceeding jumps or aligns 173601Sbill * must get turned into their long form. 174601Sbill */ 175601Sbill 176626Shenry #define TAGMASK 0xFF 177601Sbill 178601Sbill # define JXACTIVE 0xFF /*jxxx size unknown*/ 179601Sbill # define JXNOTYET 0xFE /*jxxx size known, but not yet expanded*/ 180601Sbill # define JXALIGN 0xFD /*align jxxx entry*/ 181601Sbill # define JXINACTIVE 0xFC /*jxxx size known and expanded*/ 182601Sbill 183626Shenry #define JXQUESTIONABLE 0xFB 184601Sbill 185601Sbill # define JXTUNNEL 0xFA /*jxxx that jumps to another*/ 186601Sbill # define OBSOLETE 0xF9 /*erroneously entered symbol*/ 187601Sbill 188601Sbill #define IGNOREBOUND 0xF8 /*symbols greater than this are ignored*/ 189601Sbill # define STABFLOATING 0xF7 190601Sbill # define LABELID 0xF6 191601Sbill 192601Sbill #define OKTOBUMP 0xF5 193601Sbill # define STABFIXED 0xF4 194601Sbill 195601Sbill /* 196601Sbill * astoks.h contains reserved word codings the parser should 197601Sbill * know about 198601Sbill */ 199601Sbill #include "astoks.h" 200601Sbill 201601Sbill /* 202601Sbill * The structure for one symbol table entry. 203601Sbill * Symbol table entries are used for both user defined symbols, 204601Sbill * and symbol slots generated to create the jxxx jump from 205601Sbill * slots. 206635Shenry * Caution: the instructions are stored in a shorter version 207635Shenry * of the struct symtab, using all fields in sym_nm and 208635Shenry * tag. The fields used in sym_nm are carefully redeclared 209635Shenry * in struct Instab and struct instab (see below). 210635Shenry * If struct nlist gets changed, then Instab and instab may 211635Shenry * have to be changed. 212601Sbill */ 213601Sbill 214601Sbill struct symtab{ 215635Shenry struct nlist s_nm; 216635Shenry u_char s_tag; /* assembler tag */ 217635Shenry u_char s_ptype; /* if tag == NAME */ 218635Shenry u_char s_jxoveralign; /* if a JXXX, jumped over align */ 219635Shenry short s_index; /* which segment */ 220635Shenry struct symtab *s_dest; /* if JXXX, where going to */ 221601Sbill #ifdef DJXXX 222635Shenry short s_jxline; /* source line of the jump from */ 223601Sbill #endif 224601Sbill }; 225635Shenry /* 226635Shenry * Redefinitions of the fields in symtab for 227635Shenry * use when the symbol table entry marks a jxxx instruction. 228635Shenry */ 229635Shenry #define s_jxbump s_ptype /* tag == JX..., how far to expand */ 230635Shenry #define s_jxfear s_desc /* how far needs to be bumped */ 231635Shenry /* 232635Shenry * Redefinitions of fields in the struct nlist for symbols so that 233635Shenry * one saves typing, and so that they conform 234635Shenry * with the old naming conventions. 235635Shenry */ 236635Shenry #ifdef FLEXNAMES 237635Shenry #define s_name s_nm.n_un.n_name /* name pointer */ 238635Shenry #define s_nmx s_nm.n_un.n_strx /* string table index */ 239635Shenry #else not FLEXNAMES 240635Shenry #define s_name s_nm.n_name 241635Shenry #endif 242635Shenry #define s_type s_nm.n_type /* type of the symbol */ 243635Shenry #define s_other s_nm.n_other /* other information for sdb */ 244635Shenry #define s_desc s_nm.n_desc /* type descriptor */ 245635Shenry #define s_value s_nm.n_value /* value of the symbol, or sdb delta */ 246601Sbill 247635Shenry struct instab{ 248635Shenry struct nlist s_nm; /* instruction name, type (opcode) */ 249635Shenry u_char s_tag; 250601Sbill }; 251635Shenry /* 252635Shenry * The fields nm.n_desc and nm.n_value total 6 bytes; this is 253635Shenry * just enough for the 6 bytes describing the argument types. 254635Shenry * We use a macro to define access to these 6 bytes, assuming that 255635Shenry * they are allocated adjacently. 256635Shenry * IF THE FORMAT OF STRUCT nlist CHANGES, THESE MAY HAVE TO BE CHANGED. 257635Shenry * 258635Shenry * Instab is cleverly declared to look very much the combination of 259635Shenry * a struct symtab and a struct nlist. 260635Shenry */ 261635Shenry struct Instab{ 262635Shenry #ifdef FLEXNAMES 263635Shenry char *I_name; 264635Shenry #else not FLEXNAMES 265635Shenry char I_name[NCPS]; 266635Shenry #endif 267635Shenry u_char I_opcode; 268635Shenry char I_nargs; 269635Shenry char I_args[6]; 270635Shenry u_char I_s_tag; 271635Shenry }; 272635Shenry /* 273635Shenry * Redefinitions of fields in the struct nlist for instructions so that 274635Shenry * one saves typing, and conforms to the old naming conventions 275635Shenry */ 276635Shenry #define i_opcode s_nm.n_type /* use the same field as symtab.type */ 277635Shenry #define i_nargs s_nm.n_other /* number of arguments */ 278635Shenry #define fetcharg(ptr, n) ((struct Instab *)ptr)->I_args[n] 279601Sbill 280601Sbill struct arg { /*one argument to an instruction*/ 281635Shenry char a_atype; 282635Shenry char a_areg1; 283635Shenry char a_areg2; 284635Shenry char a_dispsize; /*usually d124, unless have B^, etc*/ 285635Shenry struct exp *a_xp; 286601Sbill }; 287601Sbill 288601Sbill struct exp { 289635Shenry long e_xvalue; /* MUST be the first field (look at union Double) */ 290635Shenry long e_yvalue; /* MUST be second field; least sig word of a double */ 291635Shenry char e_xtype; 292635Shenry char e_xloc; 293635Shenry struct symtab *e_xname; 294601Sbill }; 295601Sbill 296635Shenry #define doub_MSW e_xvalue 297635Shenry #define doub_LSW e_yvalue 298601Sbill 299635Shenry union Double { 300601Sbill struct{ 301601Sbill long doub_MSW; 302601Sbill long doub_LSW; 303601Sbill } dis_dvalue; 304601Sbill double dvalue; 305601Sbill }; 306601Sbill 307635Shenry struct Quad { 308601Sbill long quad_low_long; 309601Sbill long quad_high_long; 310601Sbill }; 311601Sbill 312601Sbill /* 313601Sbill * Magic layout macros 314601Sbill */ 315601Sbill #define MINBYTE -128 316601Sbill #define MAXBYTE 127 317601Sbill #define MINWORD -32768 318601Sbill #define MAXWORD 32767 319601Sbill 320601Sbill #define LITFLTMASK 0x000043F0 /*really magic*/ 321601Sbill /* 322601Sbill * Is the floating point double word in xp a 323601Sbill * short literal floating point number? 324601Sbill */ 325601Sbill #define slitflt(xp) \ 326601Sbill ( (xp->doub_LSW == 0) \ 327601Sbill && ( (xp->doub_MSW & LITFLTMASK) \ 328601Sbill == xp->doub_MSW) ) 329601Sbill /* 330601Sbill * If it is a slitflt, then extract the 6 interesting bits 331601Sbill */ 332601Sbill #define extlitflt(xp) \ 333601Sbill xp->doub_MSW >> 4 334601Sbill 335601Sbill extern struct arg arglist[NARG]; /*building operands in instructions*/ 336601Sbill extern struct exp explist[NEXP]; /*building up a list of expressions*/ 337601Sbill extern struct exp *xp; /*current free expression*/ 338601Sbill /* 339601Sbill * Communication between the scanner and the jxxx handlers. 340601Sbill * lastnam: the last name seen on the input 341601Sbill * lastjxxx: pointer to the last symbol table entry for 342601Sbill * a jump from 343601Sbill */ 344601Sbill extern struct symtab *lastnam; 345601Sbill extern struct symtab *lastjxxx; 346601Sbill 347601Sbill #ifdef VMS 348635Shenry extern char *vms_obj_ptr; /* object buffer pointer */ 349635Shenry extern char sobuf[]; /* object buffer */ 350601Sbill extern int objfil; /* VMS object file descriptor */ 351601Sbill #endif VMS 352601Sbill 353601Sbill /* 354601Sbill * Lgensym is used to make up funny names for local labels. 355601Sbill * lgensym[i] is the current funny number to put after 356601Sbill * references to if, lgensym[i]-1 is for ib. 357601Sbill * genref[i] is set when the label is referenced before 358601Sbill * it is defined (i.e. 2f) so that we can be sure these 359601Sbill * labels are always defined to avoid weird diagnostics 360601Sbill * from the loader later. 361601Sbill */ 362601Sbill extern int lgensym[10]; 363601Sbill extern char genref[10]; 364601Sbill 365601Sbill extern char tmpn1[TNAMESIZE]; /* Interpass temporary */ 366601Sbill extern struct exp *dotp; /* the current dot location */ 367601Sbill extern int loctr; 368601Sbill 369601Sbill extern struct exec hdr; /* a.out header */ 370601Sbill extern u_long tsize; /* total text size */ 371601Sbill extern u_long dsize; /* total data size */ 372601Sbill extern u_long trsize; /* total text relocation size */ 373601Sbill extern u_long drsize; /* total data relocation size */ 374601Sbill extern u_long datbase; /* base of the data segment */ 375601Sbill /* 376601Sbill * Bitoff and bitfield keep track of the packing into 377601Sbill * bytes mandated by the expression syntax <expr> ':' <expr> 378601Sbill */ 379601Sbill extern int bitoff; 380601Sbill extern long bitfield; 381601Sbill 382601Sbill /* 383601Sbill * The lexical analyzer builds up symbols in yytext. Lookup 384601Sbill * expects its argument in this buffer 385601Sbill */ 386601Sbill extern char yytext[NCPS+2]; /* text buffer for lexical */ 387601Sbill /* 388601Sbill * Variables to manage the input assembler source file 389601Sbill */ 390601Sbill extern int lineno; /*the line number*/ 391601Sbill extern char *dotsname; /*the name of the as source*/ 392601Sbill 393601Sbill extern FILE *tmpfil; /* interpass communication*/ 394601Sbill 395601Sbill extern int passno; /* 1 or 2 */ 396601Sbill 397601Sbill extern int anyerrs; /*errors assembling arguments*/ 398601Sbill extern int silent; /*don't mention the errors*/ 399601Sbill extern int savelabels; /*save labels in a.out*/ 400601Sbill extern int orgwarn; /* questionable origin ? */ 401601Sbill extern int useVM; /*use virtual memory temp file*/ 402637Shenry extern int jxxxJUMP; /*use jmp instead of brw for jxxx */ 403639Sbill extern int readonlydata; /*initialized data into text space*/ 404601Sbill #ifdef DEBUG 405601Sbill extern int debug; 406601Sbill extern int toktrace; 407601Sbill #endif 408601Sbill /* 409601Sbill * Information about the instructions 410601Sbill */ 411601Sbill extern struct instab *itab[NINST]; /*maps opcodes to instructions*/ 412635Shenry extern readonly struct Instab instab[]; 413601Sbill 414601Sbill extern int curlen; /*current literal storage size*/ 415601Sbill extern int d124; /*current pointer storage size*/ 416601Sbill 417601Sbill struct symtab **lookup(); /*argument in yytext*/ 418601Sbill struct symtab *symalloc(); 419601Sbill 420635Shenry #define outb(val) {dotp->e_xvalue++; if (passno==2) bputc((val), (txtfil));} 421601Sbill 422635Shenry #define outs(cp, lg) dotp->e_xvalue += (lg); if (passno == 2) bwrite((cp), (lg), (txtfil)) 423601Sbill 424601Sbill /* 425601Sbill * Most of the time, the argument to flushfield is a power of two constant, 426601Sbill * the calculations involving it can be optimized to shifts. 427601Sbill */ 428601Sbill #define flushfield(n) if (bitoff != 0) Flushfield( ( (bitoff+n-1) /n ) * n) 429601Sbill 430601Sbill /* 431601Sbill * The biobuf structure and associated routines are used to write 432601Sbill * into one file at several places concurrently. Calling bopen 433601Sbill * with a biobuf structure sets it up to write ``biofd'' starting 434601Sbill * at the specified offset. You can then use ``bwrite'' and/or ``bputc'' 435601Sbill * to stuff characters in the stream, much like ``fwrite'' and ``fputc''. 436601Sbill * Calling bflush drains all the buffers and MUST be done before exit. 437601Sbill */ 438601Sbill struct biobuf { 439601Sbill short b_nleft; /* Number free spaces left in b_buf */ 440601Sbill /* Initialize to be less than BUFSIZ initially, to boundary align in file */ 441601Sbill char *b_ptr; /* Next place to stuff characters */ 442601Sbill char b_buf[BUFSIZ]; /* The buffer itself */ 443601Sbill off_t b_off; /* Current file offset */ 444601Sbill struct biobuf *b_link; /* Link in chain for bflush() */ 445601Sbill }; 446601Sbill #define bputc(c,b) ((b)->b_nleft ? (--(b)->b_nleft, *(b)->b_ptr++ = (c)) \ 447601Sbill : bflushc(b, c)) 448601Sbill #define BFILE struct biobuf 449601Sbill 450601Sbill extern BFILE *biobufs; /* head of the block I/O buffer chain */ 451601Sbill extern int biofd; /* file descriptor for block I/O file */ 452601Sbill extern off_t boffset; /* physical position in logical file */ 453601Sbill 454601Sbill /* 455601Sbill * For each of the named .text .data segments 456601Sbill * (introduced by .text <expr>), we maintain 457601Sbill * the current value of the dot, and the BFILE where 458601Sbill * the information for each of the segments is placed 459601Sbill * during the second pass. 460601Sbill */ 461601Sbill extern struct exp usedot[NLOC + NLOC]; 462601Sbill extern BFILE *usefile[NLOC + NLOC]; 463601Sbill extern BFILE *txtfil;/* file for text and data: into usefile */ 464601Sbill /* 465601Sbill * Relocation information for each segment is accumulated 466601Sbill * seperately from the others. Writing the relocation 467601Sbill * information is logically viewed as writing to one 468601Sbill * relocation saving file for each segment; physically 469601Sbill * we have a bunch of buffers allocated internally that 470601Sbill * contain the relocation information. 471601Sbill */ 472601Sbill struct relbufdesc *rusefile[NLOC + NLOC]; 473601Sbill struct relbufdesc *relfil; 474