|
|
1.1 root 1: /*
2: * Copyright (c) 1982 Regents of the University of California
3: * @(#)as.h 4.19 8/11/83
4: */
5: #define reg register
6:
7: #include <sys/types.h>
8: #include <a.out.h>
9: #include <stab.h>
10:
11: #define readonly
12: #define NINST 300
13:
14: #define NEXP 20 /* max number of expr. terms per instruction */
15: #define NARG 6 /* max number of args per instruction */
16: #define NHASH 1103 /* hash table is dynamically extended */
17: #define TNAMESIZE 32 /* maximum length of temporary file names */
18: #define NLOC 4 /* number of location ctrs */
19: /*
20: * Sizes for character buffers.
21: * what size #define name comments
22: *
23: * name assembly NCPName
24: * name save STRPOOLDALLOP
25: *
26: * -name saving is a simple first fit
27: */
28: #ifndef STRPOOLDALLOP
29: # define STRPOOLDALLOP 8192
30: #endif not STRPOOLDALLOP
31:
32: #define NCPName NCPS
33: #ifndef NCPS
34: # undef NCPName
35: # define NCPName 4096
36: #endif not NCPS
37: /*
38: * Check sizes, and compiler error if sizes botch
39: */
40: #if STRPOOLDALLOP < NCPName
41: $$$botch with definition sizes
42: #endif test botches
43: /*
44: * Symbol types
45: */
46: #define XUNDEF 0x0
47: #define XABS 0x2
48: #define XTEXT 0x4
49: #define XDATA 0x6
50: #define XBSS 0x8
51:
52: #define XXTRN 0x1
53: #define XTYPE 0x1E
54:
55: #define XFORW 0x20 /* Was forward-referenced when undefined */
56:
57: #define ERR (-1)
58: #define NBPW 32 /* Bits per word */
59:
60: #define AMASK 017
61:
62: /*
63: * Actual argument syntax types
64: */
65: #define AREG 1 /* %r */
66: #define ABASE 2 /* (%r) */
67: #define ADECR 3 /* -(%r) */
68: #define AINCR 4 /* (%r)+ */
69: #define ADISP 5 /* expr(%r) */
70: #define AEXP 6 /* expr */
71: #define AIMM 7 /* $ expr */
72: #define ASTAR 8 /* * */
73: #define AINDX 16 /* [%r] */
74: /*
75: * Definitions for the things found in ``instrs''
76: */
77: #define INSTTAB 1
78: #include "instrs.h"
79:
80: /*
81: * Tells outrel what it is relocating
82: * RELOC_PCREL is an implicit argument to outrel; it is or'ed in
83: * with a TYPX
84: */
85: #define RELOC_PCREL (1<<TYPLG)
86: /*
87: * reference types for loader
88: */
89: #define PCREL 1
90: #define LEN1 2
91: #define LEN2 4
92: #define LEN4 6
93: #define LEN8 8
94: #define LEN16 10
95:
96: extern int reflen[]; /* {LEN*+PCREL} ==> number of bytes */
97: extern int lgreflen[]; /* {LEN*+PCREL} ==> lg number of bytes */
98: extern int len124[]; /* {1,2,4,8,16} ==> {LEN1, LEN2, LEN4, LEN8} */
99: extern char mod124[]; /* {1,2,4,8,16} ==> {bits to construct operands */
100: extern int type_124[]; /* {1,2,4,8,16} ==> {TYPB,TYPW,TYPL,TYPQ,TYPO} */
101: extern int ty_NORELOC[]; /* {TYPB..TYPH} ==> {1 if relocation not OK */
102: extern int ty_float[]; /* {TYPB..TYPH} ==> {1 if floating number */
103: extern int ty_LEN[]; /* {TYPB..TYPH} ==> {LEN1..LEN16} */
104: extern int ty_nbyte[]; /* {TYPB..TYPH} ==> {1,2,4,8,16} */
105: extern int ty_nlg[]; /* {TYPB..TYPH} ==> lg{1,2,4,8,16} */
106: extern char *ty_string[]; /* {TYPB..TYPH} ==> printable */
107:
108: #define TMPC 7
109: #define HW 0x1
110: #define FW 0x3
111: #define DW 0x7
112: #define OW 0xF
113:
114: #define round(x,y) (((x)+(y)) & ~(y))
115:
116: #define STABTYPS 0340
117: #define STABFLAG 0200
118:
119: /*
120: * Follows are the definitions for the symbol table tags, which are
121: * all unsigned characters..
122: * High value tags are generated by the asembler for internal
123: * use.
124: * Low valued tags are the parser coded tokens the scanner returns.
125: * There are several pertinant bounds in this ordering:
126: * a) Symbols greater than JXQUESTIONABLE
127: * are used by the jxxx bumper, indicating that
128: * the symbol table entry is a jxxx entry
129: * that has yet to be bumped.
130: * b) Symbols greater than IGNOREBOUND are not
131: * bequeathed to the loader; they are truly
132: * for assembler internal use only.
133: * c) Symbols greater than OKTOBUMP represent
134: * indices into the program text that should
135: * be changed in preceeding jumps or aligns
136: * must get turned into their long form.
137: */
138:
139: #define TAGMASK 0xFF
140:
141: # define JXACTIVE 0xFF /*jxxx size unknown*/
142: # define JXNOTYET 0xFE /*jxxx size known, but not yet expanded*/
143: # define JXALIGN 0xFD /*align jxxx entry*/
144: # define JXINACTIVE 0xFC /*jxxx size known and expanded*/
145:
146: #define JXQUESTIONABLE 0xFB
147:
148: # define JXTUNNEL 0xFA /*jxxx that jumps to another*/
149: # define OBSOLETE 0xF9 /*erroneously entered symbol*/
150:
151: #define IGNOREBOUND 0xF8 /*symbols greater than this are ignored*/
152: # define STABFLOATING 0xF7
153: # define LABELID 0xF6
154:
155: #define OKTOBUMP 0xF5
156: # define STABFIXED 0xF4
157:
158: /*
159: * astoks.h contains reserved word codings the parser should
160: * know about
161: */
162: #include "astoks.h"
163:
164: /*
165: * The structure for one symbol table entry.
166: * Symbol table entries are used for both user defined symbols,
167: * and symbol slots generated to create the jxxx jump from
168: * slots.
169: * Caution: the instructions are stored in a shorter version
170: * of the struct symtab, using all fields in sym_nm and
171: * tag. The fields used in sym_nm are carefully redeclared
172: * in struct Instab and struct instab (see below).
173: * If struct nlist gets changed, then Instab and instab may
174: * have to be changed.
175: */
176:
177: struct symtab{
178: struct nlist s_nm;
179: u_char s_tag; /* assembler tag */
180: u_char s_ptype; /* if tag == NAME */
181: u_char s_jxoveralign; /* if a JXXX, jumped over align */
182: short s_index; /* which segment */
183: struct symtab *s_dest; /* if JXXX, where going to */
184: #ifdef DJXXX
185: short s_jxline; /* source line of the jump from */
186: #endif
187: };
188: /*
189: * Redefinitions of the fields in symtab for
190: * use when the symbol table entry marks a jxxx instruction.
191: */
192: #define s_jxbump s_ptype /* tag == JX..., how far to expand */
193: #define s_jxfear s_desc /* how far needs to be bumped */
194: /*
195: * Redefinitions of fields in the struct nlist for symbols so that
196: * one saves typing, and so that they conform
197: * with the old naming conventions.
198: */
199: #define s_name s_nm.n_un.n_name
200: #define i_name s_name
201: #define FETCHNAME(sp) (((struct strdesc *)(sp)->s_name)->sd_string)
202: #define STRLEN(sp) (((struct strdesc *)(sp)->s_name)->sd_strlen)
203: #define STROFF(sp) (((struct strdesc *)(sp)->s_name)->sd_stroff)
204: #define STRPLACE(sp) (((struct strdesc *)(sp)->s_name)->sd_place)
205: #define s_nmx s_nm.n_un.n_strx /* string table index */
206: #define s_type s_nm.n_type /* type of the symbol */
207: #define s_other s_nm.n_other /* other information for sdb */
208: #define s_desc s_nm.n_desc /* type descriptor */
209: #define s_value s_nm.n_value /* value of the symbol, or sdb delta */
210:
211: struct instab{
212: struct nlist s_nm; /* instruction name, type (opcode) */
213: u_char s_tag;
214: u_char s_eopcode;
215: char s_pad[2]; /* round to 20 bytes */
216: };
217: typedef struct instab *Iptr;
218: /*
219: * The fields nm.n_desc and nm.n_value total 6 bytes; this is
220: * just enough for the 6 bytes describing the argument types.
221: * We use a macro to define access to these 6 bytes, assuming that
222: * they are allocated adjacently.
223: * IF THE FORMAT OF STRUCT nlist CHANGES, THESE MAY HAVE TO BE CHANGED.
224: *
225: * Instab is cleverly declared to look very much like the combination of
226: * a struct symtab and a struct nlist.
227: */
228: /*
229: * With the 1981 VAX architecture reference manual,
230: * DEC defined and named two byte opcodes.
231: * In addition, DEC defined four new one byte instructions for
232: * queue manipulation.
233: * The assembler was patched in 1982 to reflect this change.
234: *
235: * The two byte opcodes are preceded with an escape byte
236: * (usually an ESCD) and an opcode byte.
237: * For one byte opcodes, the opcode is called the primary opcode.
238: * For two byte opcodes, the second opcode is called the primary opcode.
239: *
240: * We store the primary opcode in I_popcode,
241: * and the escape opcode in I_eopcode.
242: *
243: * For one byte opcodes in the basic arhitecture,
244: * I_eopcode is CORE
245: * For one byte opcodes in the new architecture definition,
246: * I_eopcode is NEW
247: * For the two byte opcodes, I_eopcode is the escape byte.
248: *
249: * The assembler checks if a NEW or two byte opcode is used,
250: * and issues a warning diagnostic.
251: */
252: /*
253: * For upward compatability reasons, we can't have the two opcodes
254: * forming an operator specifier byte(s) be physically adjacent
255: * in the instruction table.
256: * We define a structure and a constructor that is used in
257: * the instruction generator.
258: */
259: struct Opcode{
260: u_char Op_eopcode;
261: u_char Op_popcode;
262: };
263:
264: #define BADPOINT 0xAAAAAAAA
265: /*
266: * See if a structured opcode is bad
267: */
268: #define ITABCHECK(o) ((itab[o.Op_eopcode] != (Iptr*)BADPOINT) && (itab[o.Op_eopcode][o.Op_popcode] != (Iptr)BADPOINT))
269: /*
270: * Index the itab by a structured opcode
271: */
272: #define ITABFETCH(o) itab[o.Op_eopcode][o.Op_popcode]
273:
274: struct Instab{
275: char *I_name;
276: u_char I_popcode; /* basic op code */
277: char I_nargs;
278: char I_args[6];
279: u_char I_s_tag;
280: u_char I_eopcode;
281: char I_pad[2]; /* round to 20 bytes */
282: };
283: /*
284: * Redefinitions of fields in the struct nlist for instructions so that
285: * one saves typing, and conforms to the old naming conventions
286: */
287: #define i_popcode s_nm.n_type /* use the same field as symtab.type */
288: #define i_eopcode s_eopcode
289: #define i_nargs s_nm.n_other /* number of arguments */
290: #define fetcharg(ptr, n) ((struct Instab *)ptr)->I_args[n]
291:
292: struct arg { /*one argument to an instruction*/
293: char a_atype;
294: char a_areg1;
295: char a_areg2;
296: char a_dispsize; /*usually d124, unless have B^, etc*/
297: struct exp *a_xp;
298: };
299: /*
300: * Definitions for numbers and expressions.
301: */
302: #include "asnumber.h"
303: struct exp {
304: Bignum e_number; /* 128 bits of #, plus tag */
305: char e_xtype;
306: char e_xloc;
307: struct symtab *e_xname;
308: };
309: #define e_xvalue e_number.num_num.numIl_int.Il_long
310:
311: #define MINLIT 0
312: #define MAXLIT 63
313:
314: #define MINBYTE -128
315: #define MAXBYTE 127
316: #define MINUBYTE 0
317: #define MAXUBYTE 255
318:
319: #define MINWORD -32768
320: #define MAXWORD 32767
321: #define MINUWORD 0
322: #define MAXUWORD 65535
323:
324: #define ISLIT(x) (((x) >= MINLIT) && ((x) <= MAXLIT))
325: #define ISBYTE(x) (((x) >= MINBYTE) && ((x) <= MAXBYTE))
326: #define ISUBYTE(x) (((x) >= MINUBYTE) && ((x) <= MAXUBYTE))
327: #define ISWORD(x) (((x) >= MINWORD) && ((x) <= MAXWORD))
328: #define ISUWORD(x) (((x) >= MINUWORD) && ((x) <= MAXUWORD))
329: /*
330: * Definitions for strings.
331: *
332: * Strings are stored in the string pool; see strsave(str, length)
333: * Strings are known by their length and values.
334: * A string pointer points to the beginning of the value bytes;
335: *
336: * If this structure is changed, change insts also.
337: */
338: struct strdesc{
339: int sd_stroff; /* offset into string file */
340: short sd_place; /* where string is */
341: u_short sd_strlen; /* string length */
342: char sd_string[1]; /* the string itself, flexible length */
343: };
344: /*
345: * Where a string can be. If these are changed, also change instrs.
346: */
347: #define STR_FILE 0x1
348: #define STR_CORE 0x2
349: #define STR_BOTH 0x3
350:
351: struct strdesc *savestr();
352:
353: /*
354: * Global variables
355: */
356: extern struct arg arglist[NARG]; /*building operands in instructions*/
357: extern struct exp explist[NEXP]; /*building up a list of expressions*/
358: extern struct exp *xp; /*current free expression*/
359: /*
360: * Communication between the scanner and the jxxx handlers.
361: * lastnam: the last name seen on the input
362: * lastjxxx: pointer to the last symbol table entry for
363: * a jump from
364: */
365: extern struct symtab *lastnam;
366: extern struct symtab *lastjxxx;
367: /*
368: * Lgensym is used to make up funny names for local labels.
369: * lgensym[i] is the current funny number to put after
370: * references to if, lgensym[i]-1 is for ib.
371: * genref[i] is set when the label is referenced before
372: * it is defined (i.e. 2f) so that we can be sure these
373: * labels are always defined to avoid weird diagnostics
374: * from the loader later.
375: */
376: extern int lgensym[10];
377: extern char genref[10];
378:
379: extern struct exp *dotp; /* the current dot location */
380: extern int loctr;
381:
382: extern struct exec hdr; /* a.out header */
383: extern u_long tsize; /* total text size */
384: extern u_long dsize; /* total data size */
385: extern u_long trsize; /* total text relocation size */
386: extern u_long drsize; /* total data relocation size */
387: extern u_long datbase; /* base of the data segment */
388: /*
389: * Bitoff and bitfield keep track of the packing into
390: * bytes mandated by the expression syntax <expr> ':' <expr>
391: */
392: extern int bitoff;
393: extern long bitfield;
394:
395: /*
396: * The lexical analyzer builds up symbols in yytext. Lookup
397: * expects its argument in this buffer
398: */
399: extern char yytext[NCPName+2]; /* text buffer for lexical */
400: /*
401: * Variables to manage the input assembler source file
402: */
403: extern int lineno; /*the line number*/
404: extern char *dotsname; /*the name of the as source*/
405:
406: extern FILE *tokfile; /* temp token communication*/
407: extern FILE *strfile; /* temp string file*/
408: extern char tokfilename[TNAMESIZE]; /* token file name */
409: extern char strfilename[TNAMESIZE]; /* string file name */
410: extern int strfilepos; /* position in string file */
411:
412: extern int passno; /* 1 or 2 */
413:
414: extern int anyerrs; /*errors as'ing arguments*/
415: extern int anywarnings; /*warnings as'ing arguments*/
416: extern int silent; /*don't mention the errors*/
417: extern int savelabels; /*save labels in a.out*/
418: extern int orgwarn; /* questionable origin ? */
419: extern int useVM; /*use virtual memory temp file*/
420: extern int jxxxJUMP; /*use jmp instead of brw for jxxx */
421: extern int readonlydata; /*initialized data into text space*/
422: extern int nGHnumbers; /* GH numbers used */
423: extern int nGHopcodes; /* GH opcodes used */
424: extern int nnewopcodes; /* new opcodes used */
425: #ifdef DEBUG
426: extern int debug;
427: extern int toktrace;
428: #endif
429: /*
430: * Information about the instructions
431: */
432: extern struct instab **itab[NINST]; /*maps opcodes to instructions*/
433: extern readonly struct Instab instab[];
434:
435: extern int curlen; /*current literal storage size*/
436: extern int d124; /*current pointer storage size*/
437:
438: struct symtab **lookup(); /*argument in yytext*/
439: struct symtab *symalloc();
440:
441: char *Calloc();
442: char *ClearCalloc();
443:
444: #define outb(val) {dotp->e_xvalue++; if (passno==2) bputc((val), (txtfil));}
445:
446: #define outs(cp, lg) dotp->e_xvalue += (lg); if (passno == 2) bwrite((cp), (lg), (txtfil))
447:
448: #define Outb(o) outb(o)
449: /*
450: * Most of the time, the argument to flushfield is a power of two constant,
451: * the calculations involving it can be optimized to shifts.
452: */
453: #define flushfield(n) if (bitoff != 0) Flushfield( ( (bitoff+n-1) /n ) * n)
454:
455: /*
456: * The biobuf structure and associated routines are used to write
457: * into one file at several places concurrently. Calling bopen
458: * with a biobuf structure sets it up to write ``biofd'' starting
459: * at the specified offset. You can then use ``bwrite'' and/or ``bputc''
460: * to stuff characters in the stream, much like ``fwrite'' and ``fputc''.
461: * Calling bflush drains all the buffers and MUST be done before exit.
462: */
463: struct biobuf {
464: short b_nleft; /* Number free spaces left in b_buf */
465: /* Initialize to be less than BUFSIZ initially, to boundary align in file */
466: char *b_ptr; /* Next place to stuff characters */
467: char b_buf[BUFSIZ]; /* The buffer itself */
468: off_t b_off; /* Current file offset */
469: struct biobuf *b_link; /* Link in chain for bflush() */
470: };
471: #define bputc(c,b) ((b)->b_nleft ? (--(b)->b_nleft, *(b)->b_ptr++ = (c)) \
472: : bflushc(b, c))
473: #define BFILE struct biobuf
474:
475: extern BFILE *biobufs; /* head of the block I/O buffer chain */
476: extern int biofd; /* file descriptor for block I/O file */
477: extern off_t boffset; /* physical position in logical file */
478:
479: /*
480: * For each of the named .text .data segments
481: * (introduced by .text <expr>), we maintain
482: * the current value of the dot, and the BFILE where
483: * the information for each of the segments is placed
484: * during the second pass.
485: */
486: extern struct exp usedot[NLOC + NLOC];
487: extern BFILE *usefile[NLOC + NLOC];
488: extern BFILE *txtfil;/* file for text and data: into usefile */
489: /*
490: * Relocation information for each segment is accumulated
491: * seperately from the others. Writing the relocation
492: * information is logically viewed as writing to one
493: * relocation saving file for each segment; physically
494: * we have a bunch of buffers allocated internally that
495: * contain the relocation information.
496: */
497: struct relbufdesc *rusefile[NLOC + NLOC];
498: struct relbufdesc *relfil;
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.