1601Sbill /* Copyright (c) 1980 Regents of the University of California */ 2*666Shenry /* "@(#)as.h 4.6 08/19/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 */ 94*666Shenry #define ACCR (1<<3) /* read */ 95*666Shenry #define ACCW (2<<3) /* write */ 96*666Shenry #define ACCB (4<<3) /* branch displacement */ 97*666Shenry #define ACCA (8<<3) /* address only */ 98*666Shenry #define ACCM (ACCR | ACCW) /* modify */ 99*666Shenry #define ACCI (ACCB | ACCR) /* XFC code */ 100601Sbill 101*666Shenry #define AMASK (ACCA | ACCR | ACCW | ACCB) /* the mask */ 102*666Shenry 103601Sbill /* 104601Sbill * Argument data types 105601Sbill */ 106626Shenry #define TYPB 0 /* byte */ 107626Shenry #define TYPW 1 /* word */ 108626Shenry #define TYPL 2 /* long */ 109626Shenry #define TYPQ 3 /* quad */ 110626Shenry #define TYPF 4 /* floating */ 111626Shenry #define TYPD 5 /* double floating */ 112601Sbill 113626Shenry #define TYPMASK 7 114601Sbill 115601Sbill /* reference types for loader */ 116626Shenry #define PCREL 1 117626Shenry #define LEN1 2 118626Shenry #define LEN2 4 119626Shenry #define LEN4 6 120626Shenry #define LEN8 8 121601Sbill /* 122601Sbill * reflen table converts between LEN* and PCREL to numbers 123601Sbill * of bytes. 124601Sbill * lgreflen table is the lg base 2 of the values in reflen. 125601Sbill */ 126601Sbill extern int reflen[]; /* reference lengths */ 127626Shenry extern int lgreflen[]; /* lg reference lengths */ 128601Sbill 129601Sbill #define TMPC 7 130601Sbill #define HW 01 131601Sbill #define FW 03 132601Sbill #define DW 07 133601Sbill 134601Sbill #ifdef UNIX 135601Sbill # include <pagsiz.h> 136601Sbill #endif UNIX 137601Sbill 138601Sbill #ifdef VMS 139601Sbill # define PAGRND 0x1FFL 140601Sbill #endif VMS 141601Sbill 142601Sbill #define round(x,y) (((x)+(y)) & ~(y)) 143601Sbill 144601Sbill #define STABTYPS 0340 145626Shenry #define STABFLAG 0200 146601Sbill 147601Sbill /* 148601Sbill * Follows are the definitions for the symbol table tags, which are 149601Sbill * all unsigned characters.. 150601Sbill * High value tags are generated by the asembler for internal 151601Sbill * use. 152601Sbill * Low valued tags are the parser coded tokens the scanner returns. 153601Sbill * There are several pertinant bounds in this ordering: 154601Sbill * a) Symbols greater than JXQUESTIONABLE 155601Sbill * are used by the jxxx bumper, indicating that 156601Sbill * the symbol table entry is a jxxx entry 157601Sbill * that has yet to be bumped. 158601Sbill * b) Symbols greater than IGNOREBOUND are not 159601Sbill * bequeathed to the loader; they are truly 160601Sbill * for assembler internal use only. 161601Sbill * c) Symbols greater than OKTOBUMP represent 162601Sbill * indices into the program text that should 163601Sbill * be changed in preceeding jumps or aligns 164601Sbill * must get turned into their long form. 165601Sbill */ 166601Sbill 167626Shenry #define TAGMASK 0xFF 168601Sbill 169601Sbill # define JXACTIVE 0xFF /*jxxx size unknown*/ 170601Sbill # define JXNOTYET 0xFE /*jxxx size known, but not yet expanded*/ 171601Sbill # define JXALIGN 0xFD /*align jxxx entry*/ 172601Sbill # define JXINACTIVE 0xFC /*jxxx size known and expanded*/ 173601Sbill 174626Shenry #define JXQUESTIONABLE 0xFB 175601Sbill 176601Sbill # define JXTUNNEL 0xFA /*jxxx that jumps to another*/ 177601Sbill # define OBSOLETE 0xF9 /*erroneously entered symbol*/ 178601Sbill 179601Sbill #define IGNOREBOUND 0xF8 /*symbols greater than this are ignored*/ 180601Sbill # define STABFLOATING 0xF7 181601Sbill # define LABELID 0xF6 182601Sbill 183601Sbill #define OKTOBUMP 0xF5 184601Sbill # define STABFIXED 0xF4 185601Sbill 186601Sbill /* 187601Sbill * astoks.h contains reserved word codings the parser should 188601Sbill * know about 189601Sbill */ 190601Sbill #include "astoks.h" 191601Sbill 192601Sbill /* 193601Sbill * The structure for one symbol table entry. 194601Sbill * Symbol table entries are used for both user defined symbols, 195601Sbill * and symbol slots generated to create the jxxx jump from 196601Sbill * slots. 197635Shenry * Caution: the instructions are stored in a shorter version 198635Shenry * of the struct symtab, using all fields in sym_nm and 199635Shenry * tag. The fields used in sym_nm are carefully redeclared 200635Shenry * in struct Instab and struct instab (see below). 201635Shenry * If struct nlist gets changed, then Instab and instab may 202635Shenry * have to be changed. 203601Sbill */ 204601Sbill 205601Sbill struct symtab{ 206635Shenry struct nlist s_nm; 207635Shenry u_char s_tag; /* assembler tag */ 208635Shenry u_char s_ptype; /* if tag == NAME */ 209635Shenry u_char s_jxoveralign; /* if a JXXX, jumped over align */ 210635Shenry short s_index; /* which segment */ 211635Shenry struct symtab *s_dest; /* if JXXX, where going to */ 212601Sbill #ifdef DJXXX 213635Shenry short s_jxline; /* source line of the jump from */ 214601Sbill #endif 215601Sbill }; 216635Shenry /* 217635Shenry * Redefinitions of the fields in symtab for 218635Shenry * use when the symbol table entry marks a jxxx instruction. 219635Shenry */ 220635Shenry #define s_jxbump s_ptype /* tag == JX..., how far to expand */ 221635Shenry #define s_jxfear s_desc /* how far needs to be bumped */ 222635Shenry /* 223635Shenry * Redefinitions of fields in the struct nlist for symbols so that 224635Shenry * one saves typing, and so that they conform 225635Shenry * with the old naming conventions. 226635Shenry */ 227635Shenry #ifdef FLEXNAMES 228635Shenry #define s_name s_nm.n_un.n_name /* name pointer */ 229635Shenry #define s_nmx s_nm.n_un.n_strx /* string table index */ 230635Shenry #else not FLEXNAMES 231635Shenry #define s_name s_nm.n_name 232635Shenry #endif 233635Shenry #define s_type s_nm.n_type /* type of the symbol */ 234635Shenry #define s_other s_nm.n_other /* other information for sdb */ 235635Shenry #define s_desc s_nm.n_desc /* type descriptor */ 236635Shenry #define s_value s_nm.n_value /* value of the symbol, or sdb delta */ 237601Sbill 238635Shenry struct instab{ 239635Shenry struct nlist s_nm; /* instruction name, type (opcode) */ 240635Shenry u_char s_tag; 241601Sbill }; 242635Shenry /* 243635Shenry * The fields nm.n_desc and nm.n_value total 6 bytes; this is 244635Shenry * just enough for the 6 bytes describing the argument types. 245635Shenry * We use a macro to define access to these 6 bytes, assuming that 246635Shenry * they are allocated adjacently. 247635Shenry * IF THE FORMAT OF STRUCT nlist CHANGES, THESE MAY HAVE TO BE CHANGED. 248635Shenry * 249635Shenry * Instab is cleverly declared to look very much the combination of 250635Shenry * a struct symtab and a struct nlist. 251635Shenry */ 252635Shenry struct Instab{ 253635Shenry #ifdef FLEXNAMES 254635Shenry char *I_name; 255635Shenry #else not FLEXNAMES 256635Shenry char I_name[NCPS]; 257635Shenry #endif 258635Shenry u_char I_opcode; 259635Shenry char I_nargs; 260635Shenry char I_args[6]; 261635Shenry u_char I_s_tag; 262635Shenry }; 263635Shenry /* 264635Shenry * Redefinitions of fields in the struct nlist for instructions so that 265635Shenry * one saves typing, and conforms to the old naming conventions 266635Shenry */ 267635Shenry #define i_opcode s_nm.n_type /* use the same field as symtab.type */ 268635Shenry #define i_nargs s_nm.n_other /* number of arguments */ 269635Shenry #define fetcharg(ptr, n) ((struct Instab *)ptr)->I_args[n] 270601Sbill 271601Sbill struct arg { /*one argument to an instruction*/ 272635Shenry char a_atype; 273635Shenry char a_areg1; 274635Shenry char a_areg2; 275635Shenry char a_dispsize; /*usually d124, unless have B^, etc*/ 276635Shenry struct exp *a_xp; 277601Sbill }; 278601Sbill 279601Sbill struct exp { 280635Shenry long e_xvalue; /* MUST be the first field (look at union Double) */ 281635Shenry long e_yvalue; /* MUST be second field; least sig word of a double */ 282635Shenry char e_xtype; 283635Shenry char e_xloc; 284635Shenry struct symtab *e_xname; 285601Sbill }; 286601Sbill 287635Shenry #define doub_MSW e_xvalue 288635Shenry #define doub_LSW e_yvalue 289601Sbill 290635Shenry union Double { 291601Sbill struct{ 292601Sbill long doub_MSW; 293601Sbill long doub_LSW; 294601Sbill } dis_dvalue; 295601Sbill double dvalue; 296601Sbill }; 297601Sbill 298635Shenry struct Quad { 299601Sbill long quad_low_long; 300601Sbill long quad_high_long; 301601Sbill }; 302601Sbill 303601Sbill /* 304601Sbill * Magic layout macros 305601Sbill */ 306601Sbill #define MINBYTE -128 307601Sbill #define MAXBYTE 127 308601Sbill #define MINWORD -32768 309601Sbill #define MAXWORD 32767 310601Sbill 311601Sbill #define LITFLTMASK 0x000043F0 /*really magic*/ 312601Sbill /* 313601Sbill * Is the floating point double word in xp a 314601Sbill * short literal floating point number? 315601Sbill */ 316601Sbill #define slitflt(xp) \ 317601Sbill ( (xp->doub_LSW == 0) \ 318601Sbill && ( (xp->doub_MSW & LITFLTMASK) \ 319601Sbill == xp->doub_MSW) ) 320601Sbill /* 321601Sbill * If it is a slitflt, then extract the 6 interesting bits 322601Sbill */ 323601Sbill #define extlitflt(xp) \ 324601Sbill xp->doub_MSW >> 4 325601Sbill 326601Sbill extern struct arg arglist[NARG]; /*building operands in instructions*/ 327601Sbill extern struct exp explist[NEXP]; /*building up a list of expressions*/ 328601Sbill extern struct exp *xp; /*current free expression*/ 329601Sbill /* 330601Sbill * Communication between the scanner and the jxxx handlers. 331601Sbill * lastnam: the last name seen on the input 332601Sbill * lastjxxx: pointer to the last symbol table entry for 333601Sbill * a jump from 334601Sbill */ 335601Sbill extern struct symtab *lastnam; 336601Sbill extern struct symtab *lastjxxx; 337601Sbill 338601Sbill #ifdef VMS 339635Shenry extern char *vms_obj_ptr; /* object buffer pointer */ 340635Shenry extern char sobuf[]; /* object buffer */ 341601Sbill extern int objfil; /* VMS object file descriptor */ 342601Sbill #endif VMS 343601Sbill 344601Sbill /* 345601Sbill * Lgensym is used to make up funny names for local labels. 346601Sbill * lgensym[i] is the current funny number to put after 347601Sbill * references to if, lgensym[i]-1 is for ib. 348601Sbill * genref[i] is set when the label is referenced before 349601Sbill * it is defined (i.e. 2f) so that we can be sure these 350601Sbill * labels are always defined to avoid weird diagnostics 351601Sbill * from the loader later. 352601Sbill */ 353601Sbill extern int lgensym[10]; 354601Sbill extern char genref[10]; 355601Sbill 356601Sbill extern char tmpn1[TNAMESIZE]; /* Interpass temporary */ 357601Sbill extern struct exp *dotp; /* the current dot location */ 358601Sbill extern int loctr; 359601Sbill 360601Sbill extern struct exec hdr; /* a.out header */ 361601Sbill extern u_long tsize; /* total text size */ 362601Sbill extern u_long dsize; /* total data size */ 363601Sbill extern u_long trsize; /* total text relocation size */ 364601Sbill extern u_long drsize; /* total data relocation size */ 365601Sbill extern u_long datbase; /* base of the data segment */ 366601Sbill /* 367601Sbill * Bitoff and bitfield keep track of the packing into 368601Sbill * bytes mandated by the expression syntax <expr> ':' <expr> 369601Sbill */ 370601Sbill extern int bitoff; 371601Sbill extern long bitfield; 372601Sbill 373601Sbill /* 374601Sbill * The lexical analyzer builds up symbols in yytext. Lookup 375601Sbill * expects its argument in this buffer 376601Sbill */ 377601Sbill extern char yytext[NCPS+2]; /* text buffer for lexical */ 378601Sbill /* 379601Sbill * Variables to manage the input assembler source file 380601Sbill */ 381601Sbill extern int lineno; /*the line number*/ 382601Sbill extern char *dotsname; /*the name of the as source*/ 383601Sbill 384601Sbill extern FILE *tmpfil; /* interpass communication*/ 385601Sbill 386601Sbill extern int passno; /* 1 or 2 */ 387601Sbill 388601Sbill extern int anyerrs; /*errors assembling arguments*/ 389601Sbill extern int silent; /*don't mention the errors*/ 390601Sbill extern int savelabels; /*save labels in a.out*/ 391601Sbill extern int orgwarn; /* questionable origin ? */ 392601Sbill extern int useVM; /*use virtual memory temp file*/ 393637Shenry extern int jxxxJUMP; /*use jmp instead of brw for jxxx */ 394639Sbill extern int readonlydata; /*initialized data into text space*/ 395601Sbill #ifdef DEBUG 396601Sbill extern int debug; 397601Sbill extern int toktrace; 398601Sbill #endif 399601Sbill /* 400601Sbill * Information about the instructions 401601Sbill */ 402601Sbill extern struct instab *itab[NINST]; /*maps opcodes to instructions*/ 403635Shenry extern readonly struct Instab instab[]; 404601Sbill 405601Sbill extern int curlen; /*current literal storage size*/ 406601Sbill extern int d124; /*current pointer storage size*/ 407601Sbill 408601Sbill struct symtab **lookup(); /*argument in yytext*/ 409601Sbill struct symtab *symalloc(); 410601Sbill 411635Shenry #define outb(val) {dotp->e_xvalue++; if (passno==2) bputc((val), (txtfil));} 412601Sbill 413635Shenry #define outs(cp, lg) dotp->e_xvalue += (lg); if (passno == 2) bwrite((cp), (lg), (txtfil)) 414601Sbill 415601Sbill /* 416601Sbill * Most of the time, the argument to flushfield is a power of two constant, 417601Sbill * the calculations involving it can be optimized to shifts. 418601Sbill */ 419601Sbill #define flushfield(n) if (bitoff != 0) Flushfield( ( (bitoff+n-1) /n ) * n) 420601Sbill 421601Sbill /* 422601Sbill * The biobuf structure and associated routines are used to write 423601Sbill * into one file at several places concurrently. Calling bopen 424601Sbill * with a biobuf structure sets it up to write ``biofd'' starting 425601Sbill * at the specified offset. You can then use ``bwrite'' and/or ``bputc'' 426601Sbill * to stuff characters in the stream, much like ``fwrite'' and ``fputc''. 427601Sbill * Calling bflush drains all the buffers and MUST be done before exit. 428601Sbill */ 429601Sbill struct biobuf { 430601Sbill short b_nleft; /* Number free spaces left in b_buf */ 431601Sbill /* Initialize to be less than BUFSIZ initially, to boundary align in file */ 432601Sbill char *b_ptr; /* Next place to stuff characters */ 433601Sbill char b_buf[BUFSIZ]; /* The buffer itself */ 434601Sbill off_t b_off; /* Current file offset */ 435601Sbill struct biobuf *b_link; /* Link in chain for bflush() */ 436601Sbill }; 437601Sbill #define bputc(c,b) ((b)->b_nleft ? (--(b)->b_nleft, *(b)->b_ptr++ = (c)) \ 438601Sbill : bflushc(b, c)) 439601Sbill #define BFILE struct biobuf 440601Sbill 441601Sbill extern BFILE *biobufs; /* head of the block I/O buffer chain */ 442601Sbill extern int biofd; /* file descriptor for block I/O file */ 443601Sbill extern off_t boffset; /* physical position in logical file */ 444601Sbill 445601Sbill /* 446601Sbill * For each of the named .text .data segments 447601Sbill * (introduced by .text <expr>), we maintain 448601Sbill * the current value of the dot, and the BFILE where 449601Sbill * the information for each of the segments is placed 450601Sbill * during the second pass. 451601Sbill */ 452601Sbill extern struct exp usedot[NLOC + NLOC]; 453601Sbill extern BFILE *usefile[NLOC + NLOC]; 454601Sbill extern BFILE *txtfil;/* file for text and data: into usefile */ 455601Sbill /* 456601Sbill * Relocation information for each segment is accumulated 457601Sbill * seperately from the others. Writing the relocation 458601Sbill * information is logically viewed as writing to one 459601Sbill * relocation saving file for each segment; physically 460601Sbill * we have a bunch of buffers allocated internally that 461601Sbill * contain the relocation information. 462601Sbill */ 463601Sbill struct relbufdesc *rusefile[NLOC + NLOC]; 464601Sbill struct relbufdesc *relfil; 465