xref: /csrg-svn/old/as.vax/as.h (revision 13461)
15829Srrh /*
25829Srrh  *	Copyright (c) 1982 Regents of the University of California
3*13461Srrh  *	@(#)as.h 4.13 06/30/83
45829Srrh  */
5601Sbill #ifdef VMS
6601Sbill # define	vax	1
7601Sbill # define	VAX	1
8601Sbill #endif VMS
9601Sbill 
105829Srrh #define	reg	register
115829Srrh 
12635Shenry #include <sys/types.h>
13635Shenry #ifdef UNIX
14635Shenry 
15635Shenry #ifdef FLEXNAMES
16635Shenry #  include <a.out.h>
17635Shenry #  include <stab.h>
18635Shenry #else not FLEXNAMES
191745Shenry #  define ONLIST
201745Shenry #  include "a.out.h"
21635Shenry #  include <stab.h>
22635Shenry #endif FLEXNAMES
23635Shenry 
24635Shenry #endif UNIX
25635Shenry #ifdef VMS
26635Shenry 
27635Shenry #ifdef UNIXDEVEL
28635Shenry #  include <a.out.h>
29635Shenry #else not UNIXDEVEL
30635Shenry #  include <aout.h>
31635Shenry #endif not UNIXDEVEL
32635Shenry 
33635Shenry #endif VMS
34635Shenry 
35601Sbill #define readonly
36601Sbill #define	NINST		300
37601Sbill 
38601Sbill #define	NEXP		20	/* max number of expr. terms per instruction */
39601Sbill #define	NARG		6	/* max number of args per instruction */
40601Sbill #define	NHASH		1103	/* hash table is dynamically extended */
41626Shenry #define	TNAMESIZE	32	/* maximum length of temporary file names */
42601Sbill #define	NLOC		4	/* number of location ctrs */
43*13461Srrh /*
44*13461Srrh  *	Sizes for character buffers.
45*13461Srrh  *	what			size #define name	comments
46*13461Srrh  *
47*13461Srrh  *	source file reads	ASINBUFSIZ		integral of BUFSIZ
48*13461Srrh  *	string assembly		NCPString		large for .stabs
49*13461Srrh  *	name assembly		NCPName			depends on FLEXNAMES
50*13461Srrh  *	string save		STRPOOLDALLOP
51*13461Srrh  *
52*13461Srrh  *
53*13461Srrh  *	-source file reads should be integral of BUFSIZ for efficient reads
54*13461Srrh  *	-string saving is a simple first fit
55*13461Srrh  */
56*13461Srrh #ifndef ASINBUFSIZ
57*13461Srrh #	define	ASINBUFSIZ	4096
58*13461Srrh #endif not ASINBUFSIZ
59*13461Srrh #ifndef STRPOOLDALLOP
60*13461Srrh #	define STRPOOLDALLOP	8192
61*13461Srrh #endif not STRPOOLDALLOP
62*13461Srrh #ifndef NCPString
63*13461Srrh #	define	NCPString	4080
64*13461Srrh #endif not NCPString
65601Sbill 
66*13461Srrh #define	NCPName	NCPS
67601Sbill #ifdef UNIX
68*13461Srrh # ifndef FLEXNAMES
69*13461Srrh #	ifndef NCPS
70*13461Srrh #		undef	NCPName
71*13461Srrh #		define	NCPName	8
72*13461Srrh #	endif not NCPS
73*13461Srrh # else FLEXNAMES
74*13461Srrh #	ifndef NCPS
75*13461Srrh #		undef	NCPName
76*13461Srrh #		define	NCPName	4096
77*13461Srrh #	endif not NCPS
78*13461Srrh # endif FLEXNAMES
79601Sbill # endif UNIX
80601Sbill 
81601Sbill # ifdef VMS
82*13461Srrh #	define	NCPName	15
83601Sbill # endif VMS
84601Sbill 
85601Sbill /*
86*13461Srrh  *	Check sizes, and compiler error if sizes botch
87*13461Srrh  */
88*13461Srrh #if ((ASINBUFSIZ < NCPString) || (ASINBUFSIZ < NCPName) || (STRPOOLDALLOP < NCPString) || (STRPOOLDALLOP < NCPName))
89*13461Srrh 	$$$botch with definition sizes
90*13461Srrh #endif test botches
91*13461Srrh /*
92601Sbill  * Symbol types
93601Sbill  */
94601Sbill #define	XUNDEF	0x0
95601Sbill #define	XABS	0x2
96601Sbill #define	XTEXT	0x4
97601Sbill #define	XDATA	0x6
98601Sbill #define	XBSS	0x8
99601Sbill 
100601Sbill #define	XXTRN	0x1
101601Sbill #define	XTYPE	0x1E
102601Sbill 
103601Sbill #define	XFORW	0x20	/* Was forward-referenced when undefined */
104601Sbill 
105601Sbill #define	ERR	(-1)
106601Sbill #define	NBPW	32	/* Bits per word */
107601Sbill 
108601Sbill #define	AMASK	017
109601Sbill 
110601Sbill /*
111601Sbill  * Actual argument syntax types
112601Sbill  */
113626Shenry #define	AREG	1	/* %r */
114626Shenry #define	ABASE	2	/* (%r) */
115626Shenry #define	ADECR	3	/* -(%r) */
116626Shenry #define	AINCR	4	/* (%r)+ */
117626Shenry #define	ADISP	5	/* expr(%r) */
118626Shenry #define	AEXP	6	/* expr */
119626Shenry #define	AIMM	7	/* $ expr */
120626Shenry #define	ASTAR	8	/* * */
121626Shenry #define	AINDX	16	/* [%r] */
122601Sbill /*
1235829Srrh  *	Definitions for the things found in ``instrs''
124601Sbill  */
1255829Srrh #define	INSTTAB 1
1265829Srrh #include "instrs.h"
127601Sbill 
128601Sbill /*
1295829Srrh  *	Tells outrel what it is relocating
1305829Srrh  *	RELOC_PCREL is an implicit argument to outrel; it is or'ed in
1315829Srrh  *	with a TYPX
132601Sbill  */
1335829Srrh #define	RELOC_PCREL	(1<<TYPLG)
134672Shenry /*
135672Shenry  *	reference types for loader
136672Shenry  */
137626Shenry #define	PCREL	1
138626Shenry #define	LEN1	2
139626Shenry #define	LEN2	4
140626Shenry #define	LEN4	6
141626Shenry #define	LEN8	8
1425829Srrh #define	LEN16	10
143601Sbill 
144672Shenry extern	int	reflen[];	/* {LEN*+PCREL} ==> number of bytes */
145672Shenry extern	int	lgreflen[];	/* {LEN*+PCREL} ==> lg number of bytes */
1465829Srrh extern	int	len124[];	/* {1,2,4,8,16} ==> {LEN1, LEN2, LEN4, LEN8} */
1475829Srrh extern	char	mod124[];	/* {1,2,4,8,16} ==> {bits to construct operands */
1485829Srrh extern	int	type_124[];	/* {1,2,4,8,16} ==> {TYPB,TYPW,TYPL,TYPQ,TYPO} */
1495829Srrh extern	int	ty_NORELOC[];	/* {TYPB..TYPH} ==> {1 if relocation not OK */
1505829Srrh extern	int	ty_float[];	/* {TYPB..TYPH} ==> {1 if floating number */
1515829Srrh extern	int	ty_LEN[];	/* {TYPB..TYPH} ==> {LEN1..LEN16} */
1525829Srrh extern	int	ty_nbyte[];	/* {TYPB..TYPH} ==> {1,2,4,8,16} */
1535829Srrh extern	int	ty_nlg[];	/* {TYPB..TYPH} ==> lg{1,2,4,8,16} */
1545829Srrh extern	char	*ty_string[];	/* {TYPB..TYPH} ==> printable */
155672Shenry 
156601Sbill #define	TMPC	7
1575829Srrh #define	HW	0x1
1585829Srrh #define	FW	0x3
1595829Srrh #define	DW	0x7
1605829Srrh #define	OW	0xF
161601Sbill 
162601Sbill #ifdef VMS
163601Sbill #  define PAGRND	0x1FFL
164601Sbill #endif VMS
165601Sbill 
166601Sbill #define	round(x,y)	(((x)+(y)) & ~(y))
167601Sbill 
168601Sbill #define	STABTYPS	0340
169626Shenry #define	STABFLAG	0200
170601Sbill 
171601Sbill /*
172601Sbill  *	Follows are the definitions for the symbol table tags, which are
173601Sbill  *	all unsigned characters..
174601Sbill  *	High value tags are generated by the asembler for internal
175601Sbill  *	use.
176601Sbill  *	Low valued tags are the parser coded tokens the scanner returns.
177601Sbill  *	There are several pertinant bounds in this ordering:
178601Sbill  *		a)	Symbols greater than JXQUESTIONABLE
179601Sbill  *			are used by the jxxx bumper, indicating that
180601Sbill  *			the symbol table entry is a jxxx entry
181601Sbill  *			that has yet to be bumped.
182601Sbill  *		b)	Symbols greater than IGNOREBOUND are not
183601Sbill  *			bequeathed to the loader; they are truly
184601Sbill  *			for assembler internal use only.
185601Sbill  *		c)	Symbols greater than OKTOBUMP represent
186601Sbill  *			indices into the program text that should
187601Sbill  *			be changed in preceeding jumps or aligns
188601Sbill  *			must get turned into their long form.
189601Sbill  */
190601Sbill 
191626Shenry #define	TAGMASK		0xFF
192601Sbill 
193601Sbill #	define	JXACTIVE	0xFF	/*jxxx size unknown*/
194601Sbill #	define	JXNOTYET	0xFE	/*jxxx size known, but not yet expanded*/
195601Sbill #	define	JXALIGN		0xFD	/*align jxxx entry*/
196601Sbill #	define	JXINACTIVE	0xFC	/*jxxx size known and expanded*/
197601Sbill 
198626Shenry #define	JXQUESTIONABLE		0xFB
199601Sbill 
200601Sbill #	define	JXTUNNEL	0xFA	/*jxxx that jumps to another*/
201601Sbill #	define	OBSOLETE	0xF9	/*erroneously entered symbol*/
202601Sbill 
203601Sbill #define	IGNOREBOUND	0xF8		/*symbols greater than this are ignored*/
204601Sbill #	define	STABFLOATING	0xF7
205601Sbill #	define	LABELID		0xF6
206601Sbill 
207601Sbill #define	OKTOBUMP	0xF5
208601Sbill #	define	STABFIXED	0xF4
209601Sbill 
210601Sbill /*
211601Sbill  *	astoks.h contains reserved word codings the parser should
212601Sbill  *	know about
213601Sbill  */
214601Sbill #include "astoks.h"
215601Sbill 
216601Sbill /*
217601Sbill  *	The structure for one symbol table entry.
218601Sbill  *	Symbol table entries are used for both user defined symbols,
219601Sbill  *	and symbol slots generated to create the jxxx jump from
220601Sbill  *	slots.
221635Shenry  *	Caution: the instructions are stored in a shorter version
222635Shenry  *	of the struct symtab, using all fields in sym_nm and
223635Shenry  *	tag.  The fields used in sym_nm are carefully redeclared
224635Shenry  *	in struct Instab and struct instab (see below).
225635Shenry  *	If struct nlist gets changed, then Instab and instab may
226635Shenry  *	have to be changed.
227601Sbill  */
228601Sbill 
229601Sbill struct symtab{
230635Shenry 		struct	nlist	s_nm;
231635Shenry 		u_char	s_tag;		/* assembler tag */
232635Shenry 		u_char	s_ptype;	/* if tag == NAME */
233635Shenry 		u_char	s_jxoveralign;	/* if a JXXX, jumped over align */
234635Shenry 		short	s_index;	/* which segment */
235635Shenry 		struct	symtab *s_dest;	/* if JXXX, where going to */
236601Sbill #ifdef DJXXX
237635Shenry 		short	s_jxline;	/* source line of the jump from */
238601Sbill #endif
239601Sbill };
240635Shenry /*
241635Shenry  *	Redefinitions of the fields in symtab for
242635Shenry  *	use when the symbol table entry marks a jxxx instruction.
243635Shenry  */
244635Shenry #define	s_jxbump	s_ptype		/* tag == JX..., how far to expand */
245635Shenry #define	s_jxfear	s_desc		/* how far needs to be bumped */
246635Shenry /*
247635Shenry  *	Redefinitions of fields in the struct nlist for symbols so that
248635Shenry  *	one saves typing, and so that they conform
249635Shenry  *	with the old naming conventions.
250635Shenry  */
251635Shenry #ifdef	FLEXNAMES
252635Shenry #define	s_name	s_nm.n_un.n_name	/* name pointer */
253635Shenry #define	s_nmx	s_nm.n_un.n_strx	/* string table index */
254635Shenry #else 	not FLEXNAMES
255635Shenry #define	s_name	s_nm.n_name
256635Shenry #endif
257635Shenry #define	s_type	s_nm.n_type		/* type of the symbol */
258635Shenry #define	s_other	s_nm.n_other		/* other information for sdb */
259635Shenry #define	s_desc	s_nm.n_desc		/* type descriptor */
260635Shenry #define	s_value	s_nm.n_value		/* value of the symbol, or sdb delta */
261601Sbill 
262635Shenry struct	instab{
263635Shenry 	struct	nlist	s_nm;		/* instruction name, type (opcode) */
264635Shenry 	u_char	s_tag;
2655829Srrh 	u_char	s_eopcode;
2665829Srrh 	char	s_pad[2];		/* round to 20 bytes */
267601Sbill };
2685829Srrh typedef	struct	instab	*Iptr;
269635Shenry /*
270635Shenry  *	The fields nm.n_desc and nm.n_value total 6 bytes; this is
271635Shenry  *	just enough for the 6 bytes describing the argument types.
272635Shenry  *	We use a macro to define access to these 6 bytes, assuming that
273635Shenry  *	they are allocated adjacently.
274635Shenry  *	IF THE FORMAT OF STRUCT nlist CHANGES, THESE MAY HAVE TO BE CHANGED.
275635Shenry  *
2761745Shenry  *	Instab is cleverly declared to look very much like the combination of
277635Shenry  *	a struct symtab and a struct nlist.
278635Shenry  */
2795829Srrh /*
2805829Srrh  *	With the 1981 VAX architecture reference manual,
2815829Srrh  *	DEC defined and named two byte opcodes.
2825829Srrh  *	In addition, DEC defined four new one byte instructions for
2835829Srrh  *	queue manipulation.
2845829Srrh  *	The assembler was patched in 1982 to reflect this change.
2855829Srrh  *
2865829Srrh  *	The two byte opcodes are preceded with an escape byte
2875829Srrh  *	(usually an ESCD) and an opcode byte.
2885829Srrh  *	For one byte opcodes, the opcode is called the primary opcode.
2895829Srrh  *	For two byte opcodes, the second opcode is called the primary opcode.
2905829Srrh  *
2915829Srrh  *	We store the primary opcode in I_popcode,
2925829Srrh  *	and the escape opcode in I_eopcode.
2935829Srrh  *
2945829Srrh  *	For one byte opcodes in the basic arhitecture,
2955829Srrh  *		I_eopcode is CORE
2965829Srrh  *	For one byte opcodes in the new architecture definition,
2975829Srrh  *		I_eopcode is NEW
2985829Srrh  *	For the two byte opcodes, I_eopcode is the escape byte.
2995829Srrh  *
3005829Srrh  *	The assembler checks if a NEW or two byte opcode is used,
3015829Srrh  *	and issues a warning diagnostic.
3025829Srrh  */
3035829Srrh /*
3045829Srrh  *	For upward compatability reasons, we can't have the two opcodes
3055829Srrh  *	forming an operator specifier byte(s) be physically adjacent
3065829Srrh  *	in the instruction table.
3075829Srrh  *	We define a structure and a constructor that is used in
3085829Srrh  *	the instruction generator.
3095829Srrh  */
3105829Srrh struct Opcode{
3115829Srrh 	u_char	Op_eopcode;
3125829Srrh 	u_char	Op_popcode;
3135829Srrh };
3145829Srrh 
3155829Srrh #define	BADPOINT	0xAAAAAAAA
3165829Srrh /*
3175829Srrh  *	See if a structured opcode is bad
3185829Srrh  */
3195829Srrh #define	ITABCHECK(o)	((itab[o.Op_eopcode] != (Iptr*)BADPOINT) && (itab[o.Op_eopcode][o.Op_popcode] != (Iptr)BADPOINT))
3205829Srrh /*
3215829Srrh  *	Index the itab by a structured opcode
3225829Srrh  */
3235829Srrh #define	ITABFETCH(o)	itab[o.Op_eopcode][o.Op_popcode]
3245829Srrh 
325635Shenry struct	Instab{
326635Shenry #ifdef FLEXNAMES
327635Shenry 	char	*I_name;
328635Shenry #else not FLEXNAMES
329*13461Srrh 	char	I_name[NCPName];
330635Shenry #endif
3315829Srrh 	u_char	I_popcode;		/* basic op code */
332635Shenry 	char	I_nargs;
333635Shenry 	char	I_args[6];
334635Shenry 	u_char	I_s_tag;
3355829Srrh 	u_char	I_eopcode;
3365829Srrh 	char	I_pad[2];		/* round to 20 bytes */
337635Shenry };
338635Shenry /*
339635Shenry  *	Redefinitions of fields in the struct nlist for instructions so that
340635Shenry  *	one saves typing, and conforms to the old naming conventions
341635Shenry  */
3425829Srrh #define	i_popcode	s_nm.n_type	/* use the same field as symtab.type */
3435829Srrh #define	i_eopcode	s_eopcode
344635Shenry #define	i_nargs		s_nm.n_other	/* number of arguments */
345635Shenry #define	fetcharg(ptr, n) ((struct Instab *)ptr)->I_args[n]
346601Sbill 
347601Sbill struct	arg {				/*one argument to an instruction*/
348635Shenry 	char	a_atype;
349635Shenry 	char	a_areg1;
350635Shenry 	char	a_areg2;
351635Shenry 	char	a_dispsize;		/*usually d124, unless have B^, etc*/
352635Shenry 	struct	exp *a_xp;
353601Sbill };
3545829Srrh /*
3555829Srrh  *	Definitions for numbers and expressions.
3565829Srrh  */
3575829Srrh #include "asnumber.h"
358601Sbill struct	exp {
3595829Srrh 	Bignum	e_number;	/* 128 bits of #, plus tag */
360635Shenry 	char	e_xtype;
361635Shenry 	char	e_xloc;
3625829Srrh 	struct	symtab		*e_xname;
363601Sbill };
3645829Srrh #define	e_xvalue	e_number.num_num.numIl_int.Il_long
365601Sbill 
3665829Srrh #define		MINLIT		0
3675829Srrh #define		MAXLIT		63
368601Sbill 
3695829Srrh #define		MINBYTE		-128
3705829Srrh #define		MAXBYTE		127
3715829Srrh #define		MINUBYTE	0
3725829Srrh #define		MAXUBYTE	255
373601Sbill 
3745829Srrh #define		MINWORD		-32768
3755829Srrh #define		MAXWORD		32767
3765829Srrh #define		MINUWORD	0
3775829Srrh #define		MAXUWORD	65535
378601Sbill 
3795829Srrh #define		ISLIT(x)	(((x) >= MINLIT) && ((x) <= MAXLIT))
3805829Srrh #define		ISBYTE(x)	(((x) >= MINBYTE) && ((x) <= MAXBYTE))
3815829Srrh #define		ISUBYTE(x)	(((x) >= MINUBYTE) && ((x) <= MAXUBYTE))
3825829Srrh #define		ISWORD(x)	(((x) >= MINWORD) && ((x) <= MAXWORD))
3835829Srrh #define		ISUWORD(x)	(((x) >= MINUWORD) && ((x) <= MAXUWORD))
384601Sbill 
385601Sbill 	extern	struct	arg	arglist[NARG];	/*building operands in instructions*/
386601Sbill 	extern	struct	exp	explist[NEXP];	/*building up a list of expressions*/
387601Sbill 	extern	struct	exp	*xp;		/*current free expression*/
388601Sbill 	/*
389601Sbill 	 *	Communication between the scanner and the jxxx handlers.
390601Sbill 	 *	lastnam:	the last name seen on the input
391601Sbill 	 *	lastjxxx:	pointer to the last symbol table entry for
392601Sbill 	 *			a jump from
393601Sbill 	 */
394601Sbill 	extern	struct	symtab	*lastnam;
395601Sbill 	extern	struct	symtab	*lastjxxx;
396601Sbill 
397601Sbill #ifdef VMS
398635Shenry 	extern	char	*vms_obj_ptr;		/* object buffer pointer */
399635Shenry 	extern	char	sobuf[];		/* object buffer         */
400601Sbill 	extern	int	objfil;			/* VMS object file descriptor */
401601Sbill #endif VMS
402601Sbill 
403601Sbill 	/*
404601Sbill 	 *	Lgensym is used to make up funny names for local labels.
405601Sbill 	 *	lgensym[i] is the current funny number to put after
406601Sbill 	 *	references to if, lgensym[i]-1 is for ib.
407601Sbill 	 *	genref[i] is set when the label is referenced before
408601Sbill 	 *	it is defined (i.e. 2f) so that we can be sure these
409601Sbill 	 *	labels are always defined to avoid weird diagnostics
410601Sbill 	 *	from the loader later.
411601Sbill 	 */
412601Sbill 	extern	int	lgensym[10];
413601Sbill 	extern	char	genref[10];
414601Sbill 
415601Sbill 	extern	char	tmpn1[TNAMESIZE];	/* Interpass temporary */
416601Sbill 	extern	struct	exp	*dotp;		/* the current dot location */
417601Sbill 	extern	int	loctr;
418601Sbill 
419601Sbill 	extern	struct	exec	hdr;		/* a.out header */
420601Sbill 	extern	u_long	tsize;			/* total text size */
421601Sbill 	extern	u_long	dsize;			/* total data size */
422601Sbill 	extern	u_long	trsize;			/* total text relocation size */
423601Sbill 	extern	u_long	drsize;			/* total data relocation size */
424601Sbill 	extern	u_long	datbase;		/* base of the data segment */
425601Sbill 	/*
426601Sbill 	 *	Bitoff and bitfield keep track of the packing into
427601Sbill 	 *	bytes mandated by the expression syntax <expr> ':' <expr>
428601Sbill 	 */
429601Sbill 	extern	int	bitoff;
430601Sbill 	extern	long	bitfield;
431601Sbill 
432601Sbill 	/*
433601Sbill 	 *	The lexical analyzer builds up symbols in yytext.  Lookup
434601Sbill 	 *	expects its argument in this buffer
435601Sbill 	 */
436*13461Srrh 	extern	char	yytext[NCPName+2];	/* text buffer for lexical */
437601Sbill 	/*
438601Sbill 	 *	Variables to manage the input assembler source file
439601Sbill 	 */
440601Sbill 	extern	int	lineno;			/*the line number*/
441601Sbill 	extern	char	*dotsname;		/*the name of the as source*/
442601Sbill 
443601Sbill 	extern	FILE	*tmpfil;		/* interpass communication*/
444601Sbill 
445601Sbill 	extern	int	passno;			/* 1 or 2 */
446601Sbill 
4475829Srrh 	extern	int	anyerrs;		/*errors as'ing arguments*/
4485829Srrh 	extern	int	anywarnings;		/*warnings as'ing arguments*/
449601Sbill 	extern	int	silent;			/*don't mention the errors*/
450601Sbill 	extern	int	savelabels;		/*save labels in a.out*/
451601Sbill 	extern	int	orgwarn;		/* questionable origin ? */
452601Sbill 	extern	int	useVM;			/*use virtual memory temp file*/
453637Shenry 	extern	int	jxxxJUMP;		/*use jmp instead of brw for jxxx */
454639Sbill 	extern	int	readonlydata;		/*initialized data into text space*/
4555829Srrh 	extern	int	nGHnumbers;		/* GH numbers used */
4565829Srrh 	extern	int	nGHopcodes;		/* GH opcodes used */
4575829Srrh 	extern	int	nnewopcodes;		/* new opcodes used */
458601Sbill #ifdef DEBUG
459601Sbill 	extern	int	debug;
460601Sbill 	extern	int	toktrace;
461601Sbill #endif
462601Sbill 	/*
463601Sbill 	 *	Information about the instructions
464601Sbill 	 */
4655829Srrh 	extern	struct	instab	**itab[NINST];	/*maps opcodes to instructions*/
466635Shenry 	extern  readonly struct Instab instab[];
467601Sbill 
468601Sbill 	extern	int	curlen;			/*current literal storage size*/
469601Sbill 	extern	int	d124;			/*current pointer storage size*/
470601Sbill 
471601Sbill 	struct	symtab	**lookup();		/*argument in yytext*/
472601Sbill 	struct 	symtab	*symalloc();
473601Sbill 
4745829Srrh 	char	*Calloc();
4755829Srrh 	char	*ClearCalloc();
4765829Srrh 
477635Shenry #define outb(val) {dotp->e_xvalue++; if (passno==2) bputc((val), (txtfil));}
478601Sbill 
479635Shenry #define outs(cp, lg) dotp->e_xvalue += (lg); if (passno == 2) bwrite((cp), (lg), (txtfil))
480601Sbill 
4815829Srrh #ifdef UNIX
4825829Srrh #define	Outb(o)	outb(o)
4835829Srrh #endif UNIX
4845829Srrh 
4855829Srrh #ifdef VMS
4865829Srrh #define	Outb(o)	{*vms_obj_ptr++=-1;*vms_obj_ptr++=(char)o;dotp->e_xvalue+=1;}
4875829Srrh #endif VMS
4885829Srrh 
489601Sbill /*
490601Sbill  *	Most of the time, the argument to flushfield is a power of two constant,
491601Sbill  *	the calculations involving it can be optimized to shifts.
492601Sbill  */
493601Sbill #define flushfield(n) if (bitoff != 0)  Flushfield( ( (bitoff+n-1) /n ) * n)
494601Sbill 
495601Sbill /*
496601Sbill  * The biobuf structure and associated routines are used to write
497601Sbill  * into one file at several places concurrently.  Calling bopen
498601Sbill  * with a biobuf structure sets it up to write ``biofd'' starting
499601Sbill  * at the specified offset.  You can then use ``bwrite'' and/or ``bputc''
500601Sbill  * to stuff characters in the stream, much like ``fwrite'' and ``fputc''.
501601Sbill  * Calling bflush drains all the buffers and MUST be done before exit.
502601Sbill  */
503601Sbill struct	biobuf {
504601Sbill 	short	b_nleft;		/* Number free spaces left in b_buf */
505601Sbill /* Initialize to be less than BUFSIZ initially, to boundary align in file */
506601Sbill 	char	*b_ptr;			/* Next place to stuff characters */
507601Sbill 	char	b_buf[BUFSIZ];		/* The buffer itself */
508601Sbill 	off_t	b_off;			/* Current file offset */
509601Sbill 	struct	biobuf *b_link;		/* Link in chain for bflush() */
510601Sbill };
511601Sbill #define	bputc(c,b) ((b)->b_nleft ? (--(b)->b_nleft, *(b)->b_ptr++ = (c)) \
512601Sbill 		       : bflushc(b, c))
513601Sbill #define BFILE	struct biobuf
514601Sbill 
515601Sbill 	extern	BFILE	*biobufs;	/* head of the block I/O buffer chain */
516601Sbill 	extern	int	biofd;		/* file descriptor for block I/O file */
517601Sbill 	extern	off_t	boffset;	/* physical position in logical file */
518601Sbill 
519601Sbill 	/*
520601Sbill 	 *	For each of the named .text .data segments
521601Sbill 	 *	(introduced by .text <expr>), we maintain
522601Sbill 	 *	the current value of the dot, and the BFILE where
523601Sbill 	 *	the information for each of the segments is placed
524601Sbill 	 *	during the second pass.
525601Sbill 	 */
526601Sbill 	extern	struct	exp	usedot[NLOC + NLOC];
527601Sbill 	extern		BFILE	*usefile[NLOC + NLOC];
528601Sbill 	extern		BFILE	*txtfil;/* file for text and data: into usefile */
529601Sbill 	/*
530601Sbill 	 *	Relocation information for each segment is accumulated
531601Sbill 	 *	seperately from the others.  Writing the relocation
532601Sbill 	 *	information is logically viewed as writing to one
533601Sbill 	 *	relocation saving file for  each segment; physically
534601Sbill 	 *	we have a bunch of buffers allocated internally that
535601Sbill 	 *	contain the relocation information.
536601Sbill 	 */
537601Sbill 	struct	relbufdesc	*rusefile[NLOC + NLOC];
538601Sbill 	struct	relbufdesc	*relfil;
539