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