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