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