xref: /csrg-svn/old/as.vax/as.h (revision 672)
1601Sbill /* Copyright (c) 1980 Regents of the University of California */
2*672Shenry /* "@(#)as.h 4.7 08/20/80" */
3601Sbill #ifdef VMS
4601Sbill # define	vax	1
5601Sbill # define	VAX	1
6601Sbill #endif VMS
7601Sbill 
8635Shenry #include <sys/types.h>
9635Shenry #ifdef UNIX
10635Shenry 
11635Shenry #ifdef FLEXNAMES
12635Shenry #  include <a.out.h>
13635Shenry #  include <stab.h>
14635Shenry #else not FLEXNAMES
15635Shenry #  include <olda.out.h>
16635Shenry #  include <stab.h>
17635Shenry #endif FLEXNAMES
18635Shenry 
19635Shenry #endif UNIX
20635Shenry #ifdef VMS
21635Shenry 
22635Shenry #ifdef UNIXDEVEL
23635Shenry #  include <a.out.h>
24635Shenry #else not UNIXDEVEL
25635Shenry #  include <aout.h>
26635Shenry #endif not UNIXDEVEL
27635Shenry 
28635Shenry #endif VMS
29635Shenry 
30601Sbill #define readonly
31601Sbill #define	NINST		300
32601Sbill 
33601Sbill #define	NEXP		20	/* max number of expr. terms per instruction */
34601Sbill #define	NARG		6	/* max number of args per instruction */
35601Sbill #define	NHASH		1103	/* hash table is dynamically extended */
36626Shenry #define	TNAMESIZE	32	/* maximum length of temporary file names */
37601Sbill #define	NLOC		4	/* number of location ctrs */
38601Sbill 
39601Sbill #ifdef UNIX
40601Sbill # ifndef	FLEXNAMES
41601Sbill #	ifndef	NCPS
42601Sbill #		define	NCPS	8	/* number of characters per symbol*/
43601Sbill #	endif
44601Sbill # else
45601Sbill #	ifdef NCPS
46601Sbill #		undef	NCPS
47601Sbill #	endif
48601Sbill #	define	NCPS	BUFSIZ	/* needed to allocate yytext */
49601Sbill # endif
50601Sbill # endif UNIX
51601Sbill 
52601Sbill # ifdef VMS
53601Sbill # ifdef NCPS
54601Sbill #	undef	NCPS
55601Sbill # endif NCPS
56601Sbill #	define	NCPS	15
57601Sbill # endif VMS
58601Sbill 
59601Sbill /*
60601Sbill  * Symbol types
61601Sbill  */
62601Sbill #define	XUNDEF	0x0
63601Sbill #define	XABS	0x2
64601Sbill #define	XTEXT	0x4
65601Sbill #define	XDATA	0x6
66601Sbill #define	XBSS	0x8
67601Sbill 
68601Sbill #define	XXTRN	0x1
69601Sbill #define	XTYPE	0x1E
70601Sbill 
71601Sbill #define	XFORW	0x20	/* Was forward-referenced when undefined */
72601Sbill 
73601Sbill #define	ERR	(-1)
74601Sbill #define	NBPW	32	/* Bits per word */
75601Sbill 
76601Sbill #define	AMASK	017
77601Sbill 
78601Sbill /*
79601Sbill  * Actual argument syntax types
80601Sbill  */
81626Shenry #define	AREG	1	/* %r */
82626Shenry #define	ABASE	2	/* (%r) */
83626Shenry #define	ADECR	3	/* -(%r) */
84626Shenry #define	AINCR	4	/* (%r)+ */
85626Shenry #define	ADISP	5	/* expr(%r) */
86626Shenry #define	AEXP	6	/* expr */
87626Shenry #define	AIMM	7	/* $ expr */
88626Shenry #define	ASTAR	8	/* * */
89626Shenry #define	AINDX	16	/* [%r] */
90601Sbill 
91601Sbill /*
92601Sbill  * Argument access types used to test validity of operands to operators
93601Sbill  */
94666Shenry #define	ACCR	(1<<3)				/* read */
95666Shenry #define	ACCW	(2<<3)				/* write */
96666Shenry #define	ACCB	(4<<3)				/* branch displacement */
97666Shenry #define	ACCA	(8<<3)				/* address only */
98666Shenry #define	ACCM	(ACCR | ACCW)			/* modify */
99666Shenry #define	ACCI	(ACCB | ACCR)			/* XFC code */
100601Sbill 
101*672Shenry #define ACCESSMASK	(ACCA | ACCR | ACCW | ACCB)	/* the mask */
102666Shenry 
103601Sbill /*
104*672Shenry  *	Argument data types
105*672Shenry  *	Also used to tell outrel what it is relocating
106*672Shenry  *	(possibly in combination with RELOC_PCREL and TYPNONE)
107601Sbill  */
108*672Shenry #define	TYPB		0	/* byte */
109*672Shenry #define	TYPW		1	/* word */
110*672Shenry #define	TYPL		2	/* long */
111*672Shenry #define	TYPQ		3	/* quad */
112*672Shenry #define	TYPF		4	/* floating */
113*672Shenry #define	TYPD		5	/* double floating */
114*672Shenry #define	TYPNONE		6	/* when nothing */
115*672Shenry #define	RELOC_PCREL	8	/* implicit argument to outrel; ==> PCREL */
116601Sbill 
117626Shenry #define	TYPMASK	7
118601Sbill 
119*672Shenry /*
120*672Shenry  *	reference types for loader
121*672Shenry  */
122626Shenry #define	PCREL	1
123626Shenry #define	LEN1	2
124626Shenry #define	LEN2	4
125626Shenry #define	LEN4	6
126626Shenry #define	LEN8	8
127601Sbill 
128*672Shenry extern	int	reflen[];	/* {LEN*+PCREL} ==> number of bytes */
129*672Shenry extern	int	lgreflen[];	/* {LEN*+PCREL} ==> lg number of bytes */
130*672Shenry extern	int	len124[];	/* {1,2,4,8} ==> {LEN1, LEN2, LEN4, LEN8} */
131*672Shenry extern	char	mod124[];	/* {1,2,4,8} ==> {bits to construct operands */
132*672Shenry extern	int	type_124[];	/* {1,2,4,8} ==> {TYPB, TYPW, TYPL, TYPQ} */
133*672Shenry extern	int	ty_NORELOC[];	/* {TYPB..TYPD} ==> {1 if relocation not OK */
134*672Shenry extern	int	ty_LEN[];	/* {TYPB..TYPD} ==> {LEN1..LEN8} */
135*672Shenry extern	int	ty_nbyte[];	/* {TYPB..TYPD} ==> {1,2,4,8} */
136*672Shenry extern	int	ty_nlg[];	/* {TYPB..TYPD} ==> lg{1,2,4,8} */
137*672Shenry 
138601Sbill #define	TMPC	7
139601Sbill #define	HW	01
140601Sbill #define	FW	03
141601Sbill #define	DW	07
142601Sbill 
143601Sbill #ifdef UNIX
144601Sbill #  include <pagsiz.h>
145601Sbill #endif UNIX
146601Sbill 
147601Sbill #ifdef VMS
148601Sbill #  define PAGRND	0x1FFL
149601Sbill #endif VMS
150601Sbill 
151601Sbill #define	round(x,y)	(((x)+(y)) & ~(y))
152601Sbill 
153601Sbill #define	STABTYPS	0340
154626Shenry #define	STABFLAG	0200
155601Sbill 
156601Sbill /*
157601Sbill  *	Follows are the definitions for the symbol table tags, which are
158601Sbill  *	all unsigned characters..
159601Sbill  *	High value tags are generated by the asembler for internal
160601Sbill  *	use.
161601Sbill  *	Low valued tags are the parser coded tokens the scanner returns.
162601Sbill  *	There are several pertinant bounds in this ordering:
163601Sbill  *		a)	Symbols greater than JXQUESTIONABLE
164601Sbill  *			are used by the jxxx bumper, indicating that
165601Sbill  *			the symbol table entry is a jxxx entry
166601Sbill  *			that has yet to be bumped.
167601Sbill  *		b)	Symbols greater than IGNOREBOUND are not
168601Sbill  *			bequeathed to the loader; they are truly
169601Sbill  *			for assembler internal use only.
170601Sbill  *		c)	Symbols greater than OKTOBUMP represent
171601Sbill  *			indices into the program text that should
172601Sbill  *			be changed in preceeding jumps or aligns
173601Sbill  *			must get turned into their long form.
174601Sbill  */
175601Sbill 
176626Shenry #define	TAGMASK		0xFF
177601Sbill 
178601Sbill #	define	JXACTIVE	0xFF	/*jxxx size unknown*/
179601Sbill #	define	JXNOTYET	0xFE	/*jxxx size known, but not yet expanded*/
180601Sbill #	define	JXALIGN		0xFD	/*align jxxx entry*/
181601Sbill #	define	JXINACTIVE	0xFC	/*jxxx size known and expanded*/
182601Sbill 
183626Shenry #define	JXQUESTIONABLE		0xFB
184601Sbill 
185601Sbill #	define	JXTUNNEL	0xFA	/*jxxx that jumps to another*/
186601Sbill #	define	OBSOLETE	0xF9	/*erroneously entered symbol*/
187601Sbill 
188601Sbill #define	IGNOREBOUND	0xF8		/*symbols greater than this are ignored*/
189601Sbill #	define	STABFLOATING	0xF7
190601Sbill #	define	LABELID		0xF6
191601Sbill 
192601Sbill #define	OKTOBUMP	0xF5
193601Sbill #	define	STABFIXED	0xF4
194601Sbill 
195601Sbill /*
196601Sbill  *	astoks.h contains reserved word codings the parser should
197601Sbill  *	know about
198601Sbill  */
199601Sbill #include "astoks.h"
200601Sbill 
201601Sbill /*
202601Sbill  *	The structure for one symbol table entry.
203601Sbill  *	Symbol table entries are used for both user defined symbols,
204601Sbill  *	and symbol slots generated to create the jxxx jump from
205601Sbill  *	slots.
206635Shenry  *	Caution: the instructions are stored in a shorter version
207635Shenry  *	of the struct symtab, using all fields in sym_nm and
208635Shenry  *	tag.  The fields used in sym_nm are carefully redeclared
209635Shenry  *	in struct Instab and struct instab (see below).
210635Shenry  *	If struct nlist gets changed, then Instab and instab may
211635Shenry  *	have to be changed.
212601Sbill  */
213601Sbill 
214601Sbill struct symtab{
215635Shenry 		struct	nlist	s_nm;
216635Shenry 		u_char	s_tag;		/* assembler tag */
217635Shenry 		u_char	s_ptype;	/* if tag == NAME */
218635Shenry 		u_char	s_jxoveralign;	/* if a JXXX, jumped over align */
219635Shenry 		short	s_index;	/* which segment */
220635Shenry 		struct	symtab *s_dest;	/* if JXXX, where going to */
221601Sbill #ifdef DJXXX
222635Shenry 		short	s_jxline;	/* source line of the jump from */
223601Sbill #endif
224601Sbill };
225635Shenry /*
226635Shenry  *	Redefinitions of the fields in symtab for
227635Shenry  *	use when the symbol table entry marks a jxxx instruction.
228635Shenry  */
229635Shenry #define	s_jxbump	s_ptype		/* tag == JX..., how far to expand */
230635Shenry #define	s_jxfear	s_desc		/* how far needs to be bumped */
231635Shenry /*
232635Shenry  *	Redefinitions of fields in the struct nlist for symbols so that
233635Shenry  *	one saves typing, and so that they conform
234635Shenry  *	with the old naming conventions.
235635Shenry  */
236635Shenry #ifdef	FLEXNAMES
237635Shenry #define	s_name	s_nm.n_un.n_name	/* name pointer */
238635Shenry #define	s_nmx	s_nm.n_un.n_strx	/* string table index */
239635Shenry #else 	not FLEXNAMES
240635Shenry #define	s_name	s_nm.n_name
241635Shenry #endif
242635Shenry #define	s_type	s_nm.n_type		/* type of the symbol */
243635Shenry #define	s_other	s_nm.n_other		/* other information for sdb */
244635Shenry #define	s_desc	s_nm.n_desc		/* type descriptor */
245635Shenry #define	s_value	s_nm.n_value		/* value of the symbol, or sdb delta */
246601Sbill 
247635Shenry struct	instab{
248635Shenry 	struct	nlist	s_nm;		/* instruction name, type (opcode) */
249635Shenry 	u_char	s_tag;
250601Sbill };
251635Shenry /*
252635Shenry  *	The fields nm.n_desc and nm.n_value total 6 bytes; this is
253635Shenry  *	just enough for the 6 bytes describing the argument types.
254635Shenry  *	We use a macro to define access to these 6 bytes, assuming that
255635Shenry  *	they are allocated adjacently.
256635Shenry  *	IF THE FORMAT OF STRUCT nlist CHANGES, THESE MAY HAVE TO BE CHANGED.
257635Shenry  *
258635Shenry  *	Instab is cleverly declared to look very much the combination of
259635Shenry  *	a struct symtab and a struct nlist.
260635Shenry  */
261635Shenry struct	Instab{
262635Shenry #ifdef FLEXNAMES
263635Shenry 	char	*I_name;
264635Shenry #else not FLEXNAMES
265635Shenry 	char	I_name[NCPS];
266635Shenry #endif
267635Shenry 	u_char	I_opcode;
268635Shenry 	char	I_nargs;
269635Shenry 	char	I_args[6];
270635Shenry 	u_char	I_s_tag;
271635Shenry };
272635Shenry /*
273635Shenry  *	Redefinitions of fields in the struct nlist for instructions so that
274635Shenry  *	one saves typing, and conforms to the old naming conventions
275635Shenry  */
276635Shenry #define	i_opcode	s_nm.n_type	/* use the same field as symtab.type */
277635Shenry #define	i_nargs		s_nm.n_other	/* number of arguments */
278635Shenry #define	fetcharg(ptr, n) ((struct Instab *)ptr)->I_args[n]
279601Sbill 
280601Sbill struct	arg {				/*one argument to an instruction*/
281635Shenry 	char	a_atype;
282635Shenry 	char	a_areg1;
283635Shenry 	char	a_areg2;
284635Shenry 	char	a_dispsize;		/*usually d124, unless have B^, etc*/
285635Shenry 	struct	exp *a_xp;
286601Sbill };
287601Sbill 
288601Sbill struct	exp {
289635Shenry 	long	e_xvalue;		/* MUST be the first field (look at union Double) */
290635Shenry 	long	e_yvalue;		/* MUST be second field; least sig word of a double */
291635Shenry 	char	e_xtype;
292635Shenry 	char	e_xloc;
293635Shenry 	struct	symtab *e_xname;
294601Sbill };
295601Sbill 
296635Shenry #define doub_MSW e_xvalue
297635Shenry #define doub_LSW e_yvalue
298601Sbill 
299635Shenry union	Double {
300601Sbill 	struct{
301601Sbill 		long	doub_MSW;
302601Sbill 		long	doub_LSW;
303601Sbill 	} dis_dvalue;
304601Sbill 	double	dvalue;
305601Sbill };
306601Sbill 
307635Shenry struct	Quad {
308601Sbill 	long	quad_low_long;
309601Sbill 	long	quad_high_long;
310601Sbill };
311601Sbill 
312601Sbill /*
313601Sbill  *	Magic layout macros
314601Sbill  */
315601Sbill #define 	MINBYTE	-128
316601Sbill #define		MAXBYTE	127
317601Sbill #define		MINWORD	-32768
318601Sbill #define		MAXWORD	32767
319601Sbill 
320601Sbill #define		LITFLTMASK 0x000043F0	/*really magic*/
321601Sbill /*
322601Sbill  *		Is the floating point double word in xp a
323601Sbill  *		short literal floating point number?
324601Sbill  */
325601Sbill #define 	slitflt(xp) \
326601Sbill 			(    (xp->doub_LSW == 0) \
327601Sbill 			 &&  ( (xp->doub_MSW & LITFLTMASK) \
328601Sbill 			      == xp->doub_MSW) )
329601Sbill /*
330601Sbill  *	If it is a slitflt, then extract the 6 interesting bits
331601Sbill  */
332601Sbill #define		extlitflt(xp) \
333601Sbill 			xp->doub_MSW >> 4
334601Sbill 
335601Sbill 	extern	struct	arg	arglist[NARG];	/*building operands in instructions*/
336601Sbill 	extern	struct	exp	explist[NEXP];	/*building up a list of expressions*/
337601Sbill 	extern	struct	exp	*xp;		/*current free expression*/
338601Sbill 	/*
339601Sbill 	 *	Communication between the scanner and the jxxx handlers.
340601Sbill 	 *	lastnam:	the last name seen on the input
341601Sbill 	 *	lastjxxx:	pointer to the last symbol table entry for
342601Sbill 	 *			a jump from
343601Sbill 	 */
344601Sbill 	extern	struct	symtab	*lastnam;
345601Sbill 	extern	struct	symtab	*lastjxxx;
346601Sbill 
347601Sbill #ifdef VMS
348635Shenry 	extern	char	*vms_obj_ptr;		/* object buffer pointer */
349635Shenry 	extern	char	sobuf[];		/* object buffer         */
350601Sbill 	extern	int	objfil;			/* VMS object file descriptor */
351601Sbill #endif VMS
352601Sbill 
353601Sbill 	/*
354601Sbill 	 *	Lgensym is used to make up funny names for local labels.
355601Sbill 	 *	lgensym[i] is the current funny number to put after
356601Sbill 	 *	references to if, lgensym[i]-1 is for ib.
357601Sbill 	 *	genref[i] is set when the label is referenced before
358601Sbill 	 *	it is defined (i.e. 2f) so that we can be sure these
359601Sbill 	 *	labels are always defined to avoid weird diagnostics
360601Sbill 	 *	from the loader later.
361601Sbill 	 */
362601Sbill 	extern	int	lgensym[10];
363601Sbill 	extern	char	genref[10];
364601Sbill 
365601Sbill 	extern	char	tmpn1[TNAMESIZE];	/* Interpass temporary */
366601Sbill 	extern	struct	exp	*dotp;		/* the current dot location */
367601Sbill 	extern	int	loctr;
368601Sbill 
369601Sbill 	extern	struct	exec	hdr;		/* a.out header */
370601Sbill 	extern	u_long	tsize;			/* total text size */
371601Sbill 	extern	u_long	dsize;			/* total data size */
372601Sbill 	extern	u_long	trsize;			/* total text relocation size */
373601Sbill 	extern	u_long	drsize;			/* total data relocation size */
374601Sbill 	extern	u_long	datbase;		/* base of the data segment */
375601Sbill 	/*
376601Sbill 	 *	Bitoff and bitfield keep track of the packing into
377601Sbill 	 *	bytes mandated by the expression syntax <expr> ':' <expr>
378601Sbill 	 */
379601Sbill 	extern	int	bitoff;
380601Sbill 	extern	long	bitfield;
381601Sbill 
382601Sbill 	/*
383601Sbill 	 *	The lexical analyzer builds up symbols in yytext.  Lookup
384601Sbill 	 *	expects its argument in this buffer
385601Sbill 	 */
386601Sbill 	extern	char	yytext[NCPS+2];		/* text buffer for lexical */
387601Sbill 	/*
388601Sbill 	 *	Variables to manage the input assembler source file
389601Sbill 	 */
390601Sbill 	extern	int	lineno;			/*the line number*/
391601Sbill 	extern	char	*dotsname;		/*the name of the as source*/
392601Sbill 
393601Sbill 	extern	FILE	*tmpfil;		/* interpass communication*/
394601Sbill 
395601Sbill 	extern	int	passno;			/* 1 or 2 */
396601Sbill 
397601Sbill 	extern	int	anyerrs;		/*errors assembling arguments*/
398601Sbill 	extern	int	silent;			/*don't mention the errors*/
399601Sbill 	extern	int	savelabels;		/*save labels in a.out*/
400601Sbill 	extern	int	orgwarn;		/* questionable origin ? */
401601Sbill 	extern	int	useVM;			/*use virtual memory temp file*/
402637Shenry 	extern	int	jxxxJUMP;		/*use jmp instead of brw for jxxx */
403639Sbill 	extern	int	readonlydata;		/*initialized data into text space*/
404601Sbill #ifdef DEBUG
405601Sbill 	extern	int	debug;
406601Sbill 	extern	int	toktrace;
407601Sbill #endif
408601Sbill 	/*
409601Sbill 	 *	Information about the instructions
410601Sbill 	 */
411601Sbill 	extern	struct	instab	*itab[NINST];	/*maps opcodes to instructions*/
412635Shenry 	extern  readonly struct Instab instab[];
413601Sbill 
414601Sbill 	extern	int	curlen;			/*current literal storage size*/
415601Sbill 	extern	int	d124;			/*current pointer storage size*/
416601Sbill 
417601Sbill 	struct	symtab	**lookup();		/*argument in yytext*/
418601Sbill 	struct 	symtab	*symalloc();
419601Sbill 
420635Shenry #define outb(val) {dotp->e_xvalue++; if (passno==2) bputc((val), (txtfil));}
421601Sbill 
422635Shenry #define outs(cp, lg) dotp->e_xvalue += (lg); if (passno == 2) bwrite((cp), (lg), (txtfil))
423601Sbill 
424601Sbill /*
425601Sbill  *	Most of the time, the argument to flushfield is a power of two constant,
426601Sbill  *	the calculations involving it can be optimized to shifts.
427601Sbill  */
428601Sbill #define flushfield(n) if (bitoff != 0)  Flushfield( ( (bitoff+n-1) /n ) * n)
429601Sbill 
430601Sbill /*
431601Sbill  * The biobuf structure and associated routines are used to write
432601Sbill  * into one file at several places concurrently.  Calling bopen
433601Sbill  * with a biobuf structure sets it up to write ``biofd'' starting
434601Sbill  * at the specified offset.  You can then use ``bwrite'' and/or ``bputc''
435601Sbill  * to stuff characters in the stream, much like ``fwrite'' and ``fputc''.
436601Sbill  * Calling bflush drains all the buffers and MUST be done before exit.
437601Sbill  */
438601Sbill struct	biobuf {
439601Sbill 	short	b_nleft;		/* Number free spaces left in b_buf */
440601Sbill /* Initialize to be less than BUFSIZ initially, to boundary align in file */
441601Sbill 	char	*b_ptr;			/* Next place to stuff characters */
442601Sbill 	char	b_buf[BUFSIZ];		/* The buffer itself */
443601Sbill 	off_t	b_off;			/* Current file offset */
444601Sbill 	struct	biobuf *b_link;		/* Link in chain for bflush() */
445601Sbill };
446601Sbill #define	bputc(c,b) ((b)->b_nleft ? (--(b)->b_nleft, *(b)->b_ptr++ = (c)) \
447601Sbill 		       : bflushc(b, c))
448601Sbill #define BFILE	struct biobuf
449601Sbill 
450601Sbill 	extern	BFILE	*biobufs;	/* head of the block I/O buffer chain */
451601Sbill 	extern	int	biofd;		/* file descriptor for block I/O file */
452601Sbill 	extern	off_t	boffset;	/* physical position in logical file */
453601Sbill 
454601Sbill 	/*
455601Sbill 	 *	For each of the named .text .data segments
456601Sbill 	 *	(introduced by .text <expr>), we maintain
457601Sbill 	 *	the current value of the dot, and the BFILE where
458601Sbill 	 *	the information for each of the segments is placed
459601Sbill 	 *	during the second pass.
460601Sbill 	 */
461601Sbill 	extern	struct	exp	usedot[NLOC + NLOC];
462601Sbill 	extern		BFILE	*usefile[NLOC + NLOC];
463601Sbill 	extern		BFILE	*txtfil;/* file for text and data: into usefile */
464601Sbill 	/*
465601Sbill 	 *	Relocation information for each segment is accumulated
466601Sbill 	 *	seperately from the others.  Writing the relocation
467601Sbill 	 *	information is logically viewed as writing to one
468601Sbill 	 *	relocation saving file for  each segment; physically
469601Sbill 	 *	we have a bunch of buffers allocated internally that
470601Sbill 	 *	contain the relocation information.
471601Sbill 	 */
472601Sbill 	struct	relbufdesc	*rusefile[NLOC + NLOC];
473601Sbill 	struct	relbufdesc	*relfil;
474