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