xref: /csrg-svn/old/as.vax/as.h (revision 16069)
15829Srrh /*
25829Srrh  *	Copyright (c) 1982 Regents of the University of California
3*16069Sralph  *	@(#)as.h 4.22 02/17/84
45829Srrh  */
55829Srrh #define	reg	register
65829Srrh 
7635Shenry #include <sys/types.h>
813523Srrh #include <a.out.h>
913523Srrh #include <stab.h>
10635Shenry 
11601Sbill #define readonly
12601Sbill #define	NINST		300
13601Sbill 
14601Sbill #define	NEXP		20	/* max number of expr. terms per instruction */
15601Sbill #define	NARG		6	/* max number of args per instruction */
16601Sbill #define	NHASH		1103	/* hash table is dynamically extended */
17626Shenry #define	TNAMESIZE	32	/* maximum length of temporary file names */
18601Sbill #define	NLOC		4	/* number of location ctrs */
1913461Srrh /*
2013461Srrh  *	Sizes for character buffers.
2113461Srrh  *	what			size #define name	comments
2213461Srrh  *
2313523Srrh  *	name assembly		NCPName
2413574Srrh  *	name save		STRPOOLDALLOP
2513461Srrh  *
2613574Srrh  *	-name saving is a simple first fit
2713461Srrh  */
2813461Srrh #ifndef STRPOOLDALLOP
2913461Srrh #	define STRPOOLDALLOP	8192
3013461Srrh #endif not STRPOOLDALLOP
31601Sbill 
3213461Srrh #define	NCPName	NCPS
3313523Srrh #ifndef NCPS
3413523Srrh #	undef	NCPName
3513523Srrh #	define	NCPName	4096
3613523Srrh #endif not NCPS
37601Sbill /*
3813461Srrh  *	Check sizes, and compiler error if sizes botch
3913461Srrh  */
4013574Srrh #if STRPOOLDALLOP < NCPName
4113461Srrh 	$$$botch with definition sizes
4213461Srrh #endif test botches
4313461Srrh /*
44601Sbill  * Symbol types
45601Sbill  */
46601Sbill #define	XUNDEF	0x0
47601Sbill #define	XABS	0x2
48601Sbill #define	XTEXT	0x4
49601Sbill #define	XDATA	0x6
50601Sbill #define	XBSS	0x8
51601Sbill 
52601Sbill #define	XXTRN	0x1
53601Sbill #define	XTYPE	0x1E
54601Sbill 
55601Sbill #define	XFORW	0x20	/* Was forward-referenced when undefined */
56601Sbill 
57601Sbill #define	ERR	(-1)
58601Sbill #define	NBPW	32	/* Bits per word */
59601Sbill 
60601Sbill #define	AMASK	017
61601Sbill 
62601Sbill /*
63601Sbill  * Actual argument syntax types
64601Sbill  */
65626Shenry #define	AREG	1	/* %r */
66626Shenry #define	ABASE	2	/* (%r) */
67626Shenry #define	ADECR	3	/* -(%r) */
68626Shenry #define	AINCR	4	/* (%r)+ */
69626Shenry #define	ADISP	5	/* expr(%r) */
70626Shenry #define	AEXP	6	/* expr */
71626Shenry #define	AIMM	7	/* $ expr */
72626Shenry #define	ASTAR	8	/* * */
73626Shenry #define	AINDX	16	/* [%r] */
74601Sbill /*
755829Srrh  *	Definitions for the things found in ``instrs''
76601Sbill  */
775829Srrh #define	INSTTAB 1
785829Srrh #include "instrs.h"
79601Sbill 
80601Sbill /*
815829Srrh  *	Tells outrel what it is relocating
825829Srrh  *	RELOC_PCREL is an implicit argument to outrel; it is or'ed in
835829Srrh  *	with a TYPX
84601Sbill  */
855829Srrh #define	RELOC_PCREL	(1<<TYPLG)
86672Shenry /*
87672Shenry  *	reference types for loader
88672Shenry  */
89626Shenry #define	PCREL	1
90626Shenry #define	LEN1	2
91626Shenry #define	LEN2	4
92626Shenry #define	LEN4	6
93626Shenry #define	LEN8	8
945829Srrh #define	LEN16	10
95601Sbill 
96672Shenry extern	int	reflen[];	/* {LEN*+PCREL} ==> number of bytes */
97672Shenry extern	int	lgreflen[];	/* {LEN*+PCREL} ==> lg number of bytes */
985829Srrh extern	int	len124[];	/* {1,2,4,8,16} ==> {LEN1, LEN2, LEN4, LEN8} */
995829Srrh extern	char	mod124[];	/* {1,2,4,8,16} ==> {bits to construct operands */
1005829Srrh extern	int	type_124[];	/* {1,2,4,8,16} ==> {TYPB,TYPW,TYPL,TYPQ,TYPO} */
1015829Srrh extern	int	ty_NORELOC[];	/* {TYPB..TYPH} ==> {1 if relocation not OK */
1025829Srrh extern	int	ty_float[];	/* {TYPB..TYPH} ==> {1 if floating number */
1035829Srrh extern	int	ty_LEN[];	/* {TYPB..TYPH} ==> {LEN1..LEN16} */
1045829Srrh extern	int	ty_nbyte[];	/* {TYPB..TYPH} ==> {1,2,4,8,16} */
1055829Srrh extern	int	ty_nlg[];	/* {TYPB..TYPH} ==> lg{1,2,4,8,16} */
1065829Srrh extern	char	*ty_string[];	/* {TYPB..TYPH} ==> printable */
107672Shenry 
108601Sbill #define	TMPC	7
1095829Srrh #define	HW	0x1
1105829Srrh #define	FW	0x3
1115829Srrh #define	DW	0x7
1125829Srrh #define	OW	0xF
113601Sbill 
114601Sbill #define	round(x,y)	(((x)+(y)) & ~(y))
115601Sbill 
116601Sbill #define	STABTYPS	0340
117626Shenry #define	STABFLAG	0200
118601Sbill 
119601Sbill /*
120601Sbill  *	Follows are the definitions for the symbol table tags, which are
121601Sbill  *	all unsigned characters..
122601Sbill  *	High value tags are generated by the asembler for internal
123601Sbill  *	use.
124601Sbill  *	Low valued tags are the parser coded tokens the scanner returns.
125601Sbill  *	There are several pertinant bounds in this ordering:
126601Sbill  *		a)	Symbols greater than JXQUESTIONABLE
127601Sbill  *			are used by the jxxx bumper, indicating that
128601Sbill  *			the symbol table entry is a jxxx entry
129601Sbill  *			that has yet to be bumped.
130601Sbill  *		b)	Symbols greater than IGNOREBOUND are not
131601Sbill  *			bequeathed to the loader; they are truly
132601Sbill  *			for assembler internal use only.
133601Sbill  *		c)	Symbols greater than OKTOBUMP represent
134601Sbill  *			indices into the program text that should
135601Sbill  *			be changed in preceeding jumps or aligns
136601Sbill  *			must get turned into their long form.
137601Sbill  */
138601Sbill 
139626Shenry #define	TAGMASK		0xFF
140601Sbill 
141601Sbill #	define	JXACTIVE	0xFF	/*jxxx size unknown*/
142601Sbill #	define	JXNOTYET	0xFE	/*jxxx size known, but not yet expanded*/
143601Sbill #	define	JXALIGN		0xFD	/*align jxxx entry*/
144601Sbill #	define	JXINACTIVE	0xFC	/*jxxx size known and expanded*/
145601Sbill 
146626Shenry #define	JXQUESTIONABLE		0xFB
147601Sbill 
148601Sbill #	define	JXTUNNEL	0xFA	/*jxxx that jumps to another*/
149601Sbill #	define	OBSOLETE	0xF9	/*erroneously entered symbol*/
150601Sbill 
151601Sbill #define	IGNOREBOUND	0xF8		/*symbols greater than this are ignored*/
152601Sbill #	define	STABFLOATING	0xF7
153601Sbill #	define	LABELID		0xF6
154601Sbill 
155601Sbill #define	OKTOBUMP	0xF5
156601Sbill #	define	STABFIXED	0xF4
157601Sbill 
158601Sbill /*
159601Sbill  *	astoks.h contains reserved word codings the parser should
160601Sbill  *	know about
161601Sbill  */
162601Sbill #include "astoks.h"
163601Sbill 
164601Sbill /*
165601Sbill  *	The structure for one symbol table entry.
166601Sbill  *	Symbol table entries are used for both user defined symbols,
167601Sbill  *	and symbol slots generated to create the jxxx jump from
168601Sbill  *	slots.
169635Shenry  *	Caution: the instructions are stored in a shorter version
170635Shenry  *	of the struct symtab, using all fields in sym_nm and
171635Shenry  *	tag.  The fields used in sym_nm are carefully redeclared
172635Shenry  *	in struct Instab and struct instab (see below).
173635Shenry  *	If struct nlist gets changed, then Instab and instab may
174635Shenry  *	have to be changed.
175601Sbill  */
176601Sbill 
177601Sbill struct symtab{
178635Shenry 		struct	nlist	s_nm;
179635Shenry 		u_char	s_tag;		/* assembler tag */
180635Shenry 		u_char	s_ptype;	/* if tag == NAME */
181635Shenry 		u_char	s_jxoveralign;	/* if a JXXX, jumped over align */
182635Shenry 		short	s_index;	/* which segment */
183635Shenry 		struct	symtab *s_dest;	/* if JXXX, where going to */
18415233Sralph #ifdef DEBUG
185635Shenry 		short	s_jxline;	/* source line of the jump from */
186601Sbill #endif
187601Sbill };
188635Shenry /*
189635Shenry  *	Redefinitions of the fields in symtab for
190635Shenry  *	use when the symbol table entry marks a jxxx instruction.
191635Shenry  */
192635Shenry #define	s_jxbump	s_ptype		/* tag == JX..., how far to expand */
193635Shenry #define	s_jxfear	s_desc		/* how far needs to be bumped */
194635Shenry /*
195635Shenry  *	Redefinitions of fields in the struct nlist for symbols so that
196635Shenry  *	one saves typing, and so that they conform
197635Shenry  *	with the old naming conventions.
198635Shenry  */
19913515Srrh #define	s_name	s_nm.n_un.n_name
20013515Srrh #define	i_name	s_name
20113515Srrh #define	FETCHNAME(sp)	(((struct strdesc *)(sp)->s_name)->sd_string)
20213515Srrh #define	STRLEN(sp)	(((struct strdesc *)(sp)->s_name)->sd_strlen)
20313515Srrh #define	STROFF(sp)	(((struct strdesc *)(sp)->s_name)->sd_stroff)
20414449Srrh #define	STRPLACE(sp)	(((struct strdesc *)(sp)->s_name)->sd_place)
205635Shenry #define	s_nmx	s_nm.n_un.n_strx	/* string table index */
206635Shenry #define	s_type	s_nm.n_type		/* type of the symbol */
207635Shenry #define	s_other	s_nm.n_other		/* other information for sdb */
208635Shenry #define	s_desc	s_nm.n_desc		/* type descriptor */
209635Shenry #define	s_value	s_nm.n_value		/* value of the symbol, or sdb delta */
210601Sbill 
211635Shenry struct	instab{
212635Shenry 	struct	nlist	s_nm;		/* instruction name, type (opcode) */
213635Shenry 	u_char	s_tag;
2145829Srrh 	u_char	s_eopcode;
2155829Srrh 	char	s_pad[2];		/* round to 20 bytes */
216601Sbill };
2175829Srrh typedef	struct	instab	*Iptr;
218635Shenry /*
219635Shenry  *	The fields nm.n_desc and nm.n_value total 6 bytes; this is
220635Shenry  *	just enough for the 6 bytes describing the argument types.
221635Shenry  *	We use a macro to define access to these 6 bytes, assuming that
222635Shenry  *	they are allocated adjacently.
223635Shenry  *	IF THE FORMAT OF STRUCT nlist CHANGES, THESE MAY HAVE TO BE CHANGED.
224635Shenry  *
2251745Shenry  *	Instab is cleverly declared to look very much like the combination of
226635Shenry  *	a struct symtab and a struct nlist.
227635Shenry  */
2285829Srrh /*
2295829Srrh  *	With the 1981 VAX architecture reference manual,
2305829Srrh  *	DEC defined and named two byte opcodes.
2315829Srrh  *	In addition, DEC defined four new one byte instructions for
2325829Srrh  *	queue manipulation.
2335829Srrh  *	The assembler was patched in 1982 to reflect this change.
2345829Srrh  *
2355829Srrh  *	The two byte opcodes are preceded with an escape byte
2365829Srrh  *	(usually an ESCD) and an opcode byte.
2375829Srrh  *	For one byte opcodes, the opcode is called the primary opcode.
2385829Srrh  *	For two byte opcodes, the second opcode is called the primary opcode.
2395829Srrh  *
2405829Srrh  *	We store the primary opcode in I_popcode,
2415829Srrh  *	and the escape opcode in I_eopcode.
2425829Srrh  *
2435829Srrh  *	For one byte opcodes in the basic arhitecture,
2445829Srrh  *		I_eopcode is CORE
2455829Srrh  *	For one byte opcodes in the new architecture definition,
2465829Srrh  *		I_eopcode is NEW
2475829Srrh  *	For the two byte opcodes, I_eopcode is the escape byte.
2485829Srrh  *
2495829Srrh  *	The assembler checks if a NEW or two byte opcode is used,
2505829Srrh  *	and issues a warning diagnostic.
2515829Srrh  */
2525829Srrh /*
2535829Srrh  *	For upward compatability reasons, we can't have the two opcodes
2545829Srrh  *	forming an operator specifier byte(s) be physically adjacent
2555829Srrh  *	in the instruction table.
2565829Srrh  *	We define a structure and a constructor that is used in
2575829Srrh  *	the instruction generator.
2585829Srrh  */
2595829Srrh struct Opcode{
2605829Srrh 	u_char	Op_eopcode;
2615829Srrh 	u_char	Op_popcode;
2625829Srrh };
2635829Srrh 
2645829Srrh #define	BADPOINT	0xAAAAAAAA
2655829Srrh /*
2665829Srrh  *	See if a structured opcode is bad
2675829Srrh  */
2685829Srrh #define	ITABCHECK(o)	((itab[o.Op_eopcode] != (Iptr*)BADPOINT) && (itab[o.Op_eopcode][o.Op_popcode] != (Iptr)BADPOINT))
2695829Srrh /*
2705829Srrh  *	Index the itab by a structured opcode
2715829Srrh  */
2725829Srrh #define	ITABFETCH(o)	itab[o.Op_eopcode][o.Op_popcode]
2735829Srrh 
274635Shenry struct	Instab{
275635Shenry 	char	*I_name;
2765829Srrh 	u_char	I_popcode;		/* basic op code */
277635Shenry 	char	I_nargs;
278635Shenry 	char	I_args[6];
279635Shenry 	u_char	I_s_tag;
2805829Srrh 	u_char	I_eopcode;
2815829Srrh 	char	I_pad[2];		/* round to 20 bytes */
282635Shenry };
283635Shenry /*
284635Shenry  *	Redefinitions of fields in the struct nlist for instructions so that
285635Shenry  *	one saves typing, and conforms to the old naming conventions
286635Shenry  */
2875829Srrh #define	i_popcode	s_nm.n_type	/* use the same field as symtab.type */
2885829Srrh #define	i_eopcode	s_eopcode
289635Shenry #define	i_nargs		s_nm.n_other	/* number of arguments */
290635Shenry #define	fetcharg(ptr, n) ((struct Instab *)ptr)->I_args[n]
291601Sbill 
292601Sbill struct	arg {				/*one argument to an instruction*/
293635Shenry 	char	a_atype;
294635Shenry 	char	a_areg1;
295635Shenry 	char	a_areg2;
296635Shenry 	char	a_dispsize;		/*usually d124, unless have B^, etc*/
297635Shenry 	struct	exp *a_xp;
298601Sbill };
2995829Srrh /*
3005829Srrh  *	Definitions for numbers and expressions.
3015829Srrh  */
3025829Srrh #include "asnumber.h"
303601Sbill struct	exp {
3045829Srrh 	Bignum	e_number;	/* 128 bits of #, plus tag */
305635Shenry 	char	e_xtype;
306635Shenry 	char	e_xloc;
3075829Srrh 	struct	symtab		*e_xname;
308601Sbill };
3095829Srrh #define	e_xvalue	e_number.num_num.numIl_int.Il_long
310601Sbill 
3115829Srrh #define		MINLIT		0
3125829Srrh #define		MAXLIT		63
313601Sbill 
3145829Srrh #define		MINBYTE		-128
3155829Srrh #define		MAXBYTE		127
3165829Srrh #define		MINUBYTE	0
3175829Srrh #define		MAXUBYTE	255
318601Sbill 
3195829Srrh #define		MINWORD		-32768
3205829Srrh #define		MAXWORD		32767
3215829Srrh #define		MINUWORD	0
3225829Srrh #define		MAXUWORD	65535
323601Sbill 
3245829Srrh #define		ISLIT(x)	(((x) >= MINLIT) && ((x) <= MAXLIT))
3255829Srrh #define		ISBYTE(x)	(((x) >= MINBYTE) && ((x) <= MAXBYTE))
3265829Srrh #define		ISUBYTE(x)	(((x) >= MINUBYTE) && ((x) <= MAXUBYTE))
3275829Srrh #define		ISWORD(x)	(((x) >= MINWORD) && ((x) <= MAXWORD))
3285829Srrh #define		ISUWORD(x)	(((x) >= MINUWORD) && ((x) <= MAXUWORD))
32913515Srrh /*
33013515Srrh  *	Definitions for strings.
33113515Srrh  *
33213515Srrh  *	Strings are stored in the string pool; see strsave(str, length)
33313515Srrh  *	Strings are known by their length and values.
33413515Srrh  *	A string pointer points to the beginning of the value bytes;
33513515Srrh  *
33613515Srrh  *	If this structure is changed, change insts also.
33713515Srrh  */
33813515Srrh struct	strdesc{
33913515Srrh 	int	sd_stroff;	/* offset into string file */
34013515Srrh 	short	sd_place;	/* where string is */
34113515Srrh 	u_short	sd_strlen;	/* string length */
34213515Srrh 	char	sd_string[1];	/* the string itself, flexible length */
34313515Srrh };
34413515Srrh /*
34513515Srrh  *	Where a string can be.  If these are changed, also change instrs.
34613515Srrh  */
34713515Srrh #define	STR_FILE	0x1
34813515Srrh #define	STR_CORE	0x2
34913515Srrh #define	STR_BOTH	0x3
350601Sbill 
35113515Srrh struct strdesc *savestr();
35213515Srrh 
35313515Srrh /*
35413515Srrh  *	Global variables
35513515Srrh  */
356601Sbill 	extern	struct	arg	arglist[NARG];	/*building operands in instructions*/
357601Sbill 	extern	struct	exp	explist[NEXP];	/*building up a list of expressions*/
358601Sbill 	extern	struct	exp	*xp;		/*current free expression*/
359601Sbill 	/*
360601Sbill 	 *	Communication between the scanner and the jxxx handlers.
361601Sbill 	 *	lastnam:	the last name seen on the input
362601Sbill 	 *	lastjxxx:	pointer to the last symbol table entry for
363601Sbill 	 *			a jump from
364601Sbill 	 */
365601Sbill 	extern	struct	symtab	*lastnam;
366601Sbill 	extern	struct	symtab	*lastjxxx;
367601Sbill 	/*
368601Sbill 	 *	Lgensym is used to make up funny names for local labels.
369601Sbill 	 *	lgensym[i] is the current funny number to put after
370601Sbill 	 *	references to if, lgensym[i]-1 is for ib.
371601Sbill 	 *	genref[i] is set when the label is referenced before
372601Sbill 	 *	it is defined (i.e. 2f) so that we can be sure these
373601Sbill 	 *	labels are always defined to avoid weird diagnostics
374601Sbill 	 *	from the loader later.
375601Sbill 	 */
376601Sbill 	extern	int	lgensym[10];
377601Sbill 	extern	char	genref[10];
378601Sbill 
379601Sbill 	extern	struct	exp	*dotp;		/* the current dot location */
380601Sbill 	extern	int	loctr;
381601Sbill 
382601Sbill 	extern	struct	exec	hdr;		/* a.out header */
383601Sbill 	extern	u_long	tsize;			/* total text size */
384601Sbill 	extern	u_long	dsize;			/* total data size */
385601Sbill 	extern	u_long	trsize;			/* total text relocation size */
386601Sbill 	extern	u_long	drsize;			/* total data relocation size */
387601Sbill 	extern	u_long	datbase;		/* base of the data segment */
388601Sbill 	/*
389601Sbill 	 *	Bitoff and bitfield keep track of the packing into
390601Sbill 	 *	bytes mandated by the expression syntax <expr> ':' <expr>
391601Sbill 	 */
392601Sbill 	extern	int	bitoff;
393601Sbill 	extern	long	bitfield;
394601Sbill 
395601Sbill 	/*
396601Sbill 	 *	The lexical analyzer builds up symbols in yytext.  Lookup
397601Sbill 	 *	expects its argument in this buffer
398601Sbill 	 */
39913461Srrh 	extern	char	yytext[NCPName+2];	/* text buffer for lexical */
400601Sbill 	/*
401601Sbill 	 *	Variables to manage the input assembler source file
402601Sbill 	 */
403601Sbill 	extern	int	lineno;			/*the line number*/
404601Sbill 	extern	char	*dotsname;		/*the name of the as source*/
405601Sbill 
40613515Srrh 	extern	FILE	*tokfile;		/* temp token communication*/
40713515Srrh 	extern	FILE	*strfile;		/* temp string file*/
40813515Srrh 	extern	char	tokfilename[TNAMESIZE];	/* token file name */
40913515Srrh 	extern	char	strfilename[TNAMESIZE];	/* string file name */
41013515Srrh 	extern	int	strfilepos;		/* position in string file */
411601Sbill 
412601Sbill 	extern	int	passno;			/* 1 or 2 */
413601Sbill 
4145829Srrh 	extern	int	anyerrs;		/*errors as'ing arguments*/
4155829Srrh 	extern	int	anywarnings;		/*warnings as'ing arguments*/
416601Sbill 	extern	int	silent;			/*don't mention the errors*/
417601Sbill 	extern	int	savelabels;		/*save labels in a.out*/
418601Sbill 	extern	int	orgwarn;		/* questionable origin ? */
419601Sbill 	extern	int	useVM;			/*use virtual memory temp file*/
420637Shenry 	extern	int	jxxxJUMP;		/*use jmp instead of brw for jxxx */
421639Sbill 	extern	int	readonlydata;		/*initialized data into text space*/
4225829Srrh 	extern	int	nGHnumbers;		/* GH numbers used */
4235829Srrh 	extern	int	nGHopcodes;		/* GH opcodes used */
4245829Srrh 	extern	int	nnewopcodes;		/* new opcodes used */
425601Sbill #ifdef DEBUG
426601Sbill 	extern	int	debug;
427601Sbill 	extern	int	toktrace;
428601Sbill #endif
429601Sbill 	/*
430601Sbill 	 *	Information about the instructions
431601Sbill 	 */
4325829Srrh 	extern	struct	instab	**itab[NINST];	/*maps opcodes to instructions*/
433635Shenry 	extern  readonly struct Instab instab[];
434601Sbill 
435601Sbill 	extern	int	curlen;			/*current literal storage size*/
436601Sbill 	extern	int	d124;			/*current pointer storage size*/
43715561Srrh 	extern	int	maxalign;		/*maximum .align allowed*/
438601Sbill 
439601Sbill 	struct	symtab	**lookup();		/*argument in yytext*/
440601Sbill 	struct 	symtab	*symalloc();
441601Sbill 
4425829Srrh 	char	*Calloc();
4435829Srrh 	char	*ClearCalloc();
4445829Srrh 
445635Shenry #define outb(val) {dotp->e_xvalue++; if (passno==2) bputc((val), (txtfil));}
446601Sbill 
447635Shenry #define outs(cp, lg) dotp->e_xvalue += (lg); if (passno == 2) bwrite((cp), (lg), (txtfil))
448601Sbill 
4495829Srrh #define	Outb(o)	outb(o)
450601Sbill /*
451601Sbill  *	Most of the time, the argument to flushfield is a power of two constant,
452601Sbill  *	the calculations involving it can be optimized to shifts.
453601Sbill  */
454601Sbill #define flushfield(n) if (bitoff != 0)  Flushfield( ( (bitoff+n-1) /n ) * n)
455601Sbill 
456601Sbill /*
457601Sbill  * The biobuf structure and associated routines are used to write
458601Sbill  * into one file at several places concurrently.  Calling bopen
459601Sbill  * with a biobuf structure sets it up to write ``biofd'' starting
460601Sbill  * at the specified offset.  You can then use ``bwrite'' and/or ``bputc''
461601Sbill  * to stuff characters in the stream, much like ``fwrite'' and ``fputc''.
462601Sbill  * Calling bflush drains all the buffers and MUST be done before exit.
463601Sbill  */
464601Sbill struct	biobuf {
465601Sbill 	short	b_nleft;		/* Number free spaces left in b_buf */
466601Sbill /* Initialize to be less than BUFSIZ initially, to boundary align in file */
467601Sbill 	char	*b_ptr;			/* Next place to stuff characters */
468*16069Sralph 	char	*b_buf;			/* Pointer to the buffer */
469601Sbill 	off_t	b_off;			/* Current file offset */
470601Sbill 	struct	biobuf *b_link;		/* Link in chain for bflush() */
471601Sbill };
472601Sbill #define	bputc(c,b) ((b)->b_nleft ? (--(b)->b_nleft, *(b)->b_ptr++ = (c)) \
473601Sbill 		       : bflushc(b, c))
474601Sbill #define BFILE	struct biobuf
475601Sbill 
476601Sbill 	extern	BFILE	*biobufs;	/* head of the block I/O buffer chain */
477601Sbill 	extern	int	biofd;		/* file descriptor for block I/O file */
478*16069Sralph 	extern	int	biobufsize;	/* optimal block size for I/O */
479601Sbill 	extern	off_t	boffset;	/* physical position in logical file */
480601Sbill 
481601Sbill 	/*
482601Sbill 	 *	For each of the named .text .data segments
483601Sbill 	 *	(introduced by .text <expr>), we maintain
484601Sbill 	 *	the current value of the dot, and the BFILE where
485601Sbill 	 *	the information for each of the segments is placed
486601Sbill 	 *	during the second pass.
487601Sbill 	 */
488601Sbill 	extern	struct	exp	usedot[NLOC + NLOC];
489601Sbill 	extern		BFILE	*usefile[NLOC + NLOC];
490601Sbill 	extern		BFILE	*txtfil;/* file for text and data: into usefile */
491601Sbill 	/*
492601Sbill 	 *	Relocation information for each segment is accumulated
493601Sbill 	 *	seperately from the others.  Writing the relocation
494601Sbill 	 *	information is logically viewed as writing to one
495601Sbill 	 *	relocation saving file for  each segment; physically
496601Sbill 	 *	we have a bunch of buffers allocated internally that
497601Sbill 	 *	contain the relocation information.
498601Sbill 	 */
499601Sbill 	struct	relbufdesc	*rusefile[NLOC + NLOC];
500601Sbill 	struct	relbufdesc	*relfil;
501