xref: /original-bsd/old/as.vax/as.h (revision 56abee86)
1 /* Copyright (c) 1980 Regents of the University of California */
2 /* "@(#)as.h 4.8 11/05/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;
477