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