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