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