xref: /original-bsd/usr.bin/pascal/src/fend.c (revision c621b5c6)
1b85afe43Sbostic /*-
2*c621b5c6Sbostic  * Copyright (c) 1980, 1993
3*c621b5c6Sbostic  *	The Regents of the University of California.  All rights reserved.
4b85afe43Sbostic  *
5b85afe43Sbostic  * %sccs.include.redist.c%
6e7cb9a4eSdist  */
7348a2a57Smckusick 
87b922cbeSmckusick #ifndef lint
9*c621b5c6Sbostic static char sccsid[] = "@(#)fend.c	8.1 (Berkeley) 06/06/93";
10b85afe43Sbostic #endif /* not lint */
11348a2a57Smckusick 
12348a2a57Smckusick #include "whoami.h"
13348a2a57Smckusick #include "0.h"
14348a2a57Smckusick #include "tree.h"
15348a2a57Smckusick #include "opcode.h"
16348a2a57Smckusick #include "objfmt.h"
17348a2a57Smckusick #include "align.h"
182b810895Speter #include "tmps.h"
19348a2a57Smckusick 
20348a2a57Smckusick /*
21348a2a57Smckusick  * this array keeps the pxp counters associated with
22348a2a57Smckusick  * functions and procedures, so that they can be output
23348a2a57Smckusick  * when their bodies are encountered
24348a2a57Smckusick  */
25348a2a57Smckusick int	bodycnts[ DSPLYSZ ];
26348a2a57Smckusick 
27348a2a57Smckusick #ifdef PC
28348a2a57Smckusick #   include "pc.h"
29aa1ee7daSralph #   include <pcc.h>
30348a2a57Smckusick #endif PC
31348a2a57Smckusick 
32348a2a57Smckusick #ifdef OBJ
33348a2a57Smckusick int	cntpatch;
34348a2a57Smckusick int	nfppatch;
35348a2a57Smckusick #endif OBJ
36348a2a57Smckusick 
377b922cbeSmckusick #include "tree_ty.h"
387b922cbeSmckusick 
39348a2a57Smckusick struct	nl *Fp;
40348a2a57Smckusick int	pnumcnt;
41348a2a57Smckusick /*
42348a2a57Smckusick  * Funcend is called to
43348a2a57Smckusick  * finish a block by generating
44348a2a57Smckusick  * the code for the statements.
45348a2a57Smckusick  * It then looks for unresolved declarations
46348a2a57Smckusick  * of labels, procedures and functions,
47348a2a57Smckusick  * and cleans up the name list.
48348a2a57Smckusick  * For the program, it checks the
49348a2a57Smckusick  * semantics of the program
50348a2a57Smckusick  * statement (yuchh).
51348a2a57Smckusick  */
52348a2a57Smckusick funcend(fp, bundle, endline)
53348a2a57Smckusick 	struct nl *fp;
547b922cbeSmckusick 	struct tnode *bundle;
55348a2a57Smckusick 	int endline;
56348a2a57Smckusick {
57348a2a57Smckusick 	register struct nl *p;
58348a2a57Smckusick 	register int i, b;
597b922cbeSmckusick 	int inp, out;
607b922cbeSmckusick 	struct tnode *blk;
61348a2a57Smckusick 	bool chkref;
62348a2a57Smckusick 	struct nl *iop;
63348a2a57Smckusick 	char *cp;
64348a2a57Smckusick 	extern int cntstat;
65348a2a57Smckusick #	ifdef PC
66f914b486Speter 	    struct entry_exit_cookie	eecookie;
67348a2a57Smckusick #	endif PC
687b922cbeSmckusick #	ifndef PC
697b922cbeSmckusick 	int var;
707b922cbeSmckusick #	endif PC
71348a2a57Smckusick 
72348a2a57Smckusick 	cntstat = 0;
73348a2a57Smckusick /*
74348a2a57Smckusick  *	yyoutline();
75348a2a57Smckusick  */
76348a2a57Smckusick 	if (program != NIL)
77348a2a57Smckusick 		line = program->value[3];
787b922cbeSmckusick 	blk = bundle->stmnt_blck.stmnt_list;
79348a2a57Smckusick 	if (fp == NIL) {
80348a2a57Smckusick 		cbn--;
81348a2a57Smckusick #		ifdef PTREE
82348a2a57Smckusick 		    nesting--;
83348a2a57Smckusick #		endif PTREE
84348a2a57Smckusick 		return;
85348a2a57Smckusick 	}
86348a2a57Smckusick #ifdef OBJ
87348a2a57Smckusick 	/*
88876ba528Smckusick 	 * Patch the branch to the entry point of the function.
89876ba528Smckusick 	 * Assure alignment of O_BEG structure.
90348a2a57Smckusick 	 */
91876ba528Smckusick 	if (((int)lc & 02) == 0)
92876ba528Smckusick 		word(0);
937b922cbeSmckusick 	patch4((PTR_DCL) fp->value[NL_ENTLOC]);
94348a2a57Smckusick 	/*
95348a2a57Smckusick 	 * Put out the block entrance code and the block name.
96348a2a57Smckusick 	 * HDRSZE is the number of bytes of info in the static
97348a2a57Smckusick 	 * BEG data area exclusive of the proc name. It is
98348a2a57Smckusick 	 * currently defined as:
99348a2a57Smckusick 	/*	struct hdr {
100348a2a57Smckusick 	/*		long framesze;	/* number of bytes of local vars */
101348a2a57Smckusick 	/*		long nargs;	/* number of bytes of arguments */
102348a2a57Smckusick 	/*		bool tests;	/* TRUE => perform runtime tests */
103348a2a57Smckusick 	/*		short offset;	/* offset of procedure in source file */
104348a2a57Smckusick 	/*		char name[1];	/* name of active procedure */
105348a2a57Smckusick 	/*	};
106348a2a57Smckusick 	 */
107348a2a57Smckusick #	define HDRSZE (2 * sizeof(long) + sizeof(short) + sizeof(bool))
108348a2a57Smckusick 	var = put(2, ((lenstr(fp->symbol,0) + HDRSZE) << 8)
109348a2a57Smckusick 		| (cbn == 1 && opt('p') == 0 ? O_NODUMP: O_BEG), (long)0);
110348a2a57Smckusick 	    /*
111348a2a57Smckusick 	     *  output the number of bytes of arguments
112348a2a57Smckusick 	     *  this is only checked on formal calls.
113348a2a57Smckusick 	     */
1147b922cbeSmckusick 	(void) put(2, O_CASE4, cbn == 1 ? (long)0 : (long)(fp->value[NL_OFFS]-DPOFF2));
115348a2a57Smckusick 	    /*
116348a2a57Smckusick 	     *	Output the runtime test mode for the routine
117348a2a57Smckusick 	     */
1187b922cbeSmckusick 	(void) put(2, sizeof(bool) == 2 ? O_CASE2 : O_CASE4, opt('t') ? TRUE : FALSE);
119348a2a57Smckusick 	    /*
120348a2a57Smckusick 	     *	Output line number and routine name
121348a2a57Smckusick 	     */
1227b922cbeSmckusick 	(void) put(2, O_CASE2, bundle->stmnt_blck.line_no);
123348a2a57Smckusick 	putstr(fp->symbol, 0);
124348a2a57Smckusick #endif OBJ
125348a2a57Smckusick #ifdef PC
126348a2a57Smckusick 	/*
127348a2a57Smckusick 	 * put out the procedure entry code
128348a2a57Smckusick 	 */
129f914b486Speter 	eecookie.nlp = fp;
130348a2a57Smckusick 	if ( fp -> class == PROG ) {
1312af84cc6Smckusick 		/*
1322af84cc6Smckusick 		 *	If there is a label declaration in the main routine
1332af84cc6Smckusick 		 *	then there may be a non-local goto to it that does
1342af84cc6Smckusick 		 *	not appear in this module. We have to assume that
1352af84cc6Smckusick 		 *	such a reference may occur and generate code to
1362af84cc6Smckusick 		 *	prepare for it.
1372af84cc6Smckusick 		 */
1382af84cc6Smckusick 	    if ( parts[ cbn ] & LPRT ) {
1392af84cc6Smckusick 		parts[ cbn ] |= ( NONLOCALVAR | NONLOCALGOTO );
1402af84cc6Smckusick 	    }
141f914b486Speter 	    codeformain();
1420d2b92aaSmckusick 	    ftnno = fp -> value[NL_ENTLOC];
143f914b486Speter 	    prog_prologue(&eecookie);
1447b922cbeSmckusick 	    stabline(bundle->stmnt_blck.line_no);
1457b922cbeSmckusick 	    stabfunc(fp, "program", bundle->stmnt_blck.line_no , (long) 0 );
146348a2a57Smckusick 	} else {
1470d2b92aaSmckusick 	    ftnno = fp -> value[NL_ENTLOC];
148f914b486Speter 	    fp_prologue(&eecookie);
1497b922cbeSmckusick 	    stabline(bundle->stmnt_blck.line_no);
1507b922cbeSmckusick 	    stabfunc(fp, fp->symbol, bundle->stmnt_blck.line_no,
1517b922cbeSmckusick 		(long)(cbn - 1));
152348a2a57Smckusick 	    for ( p = fp -> chain ; p != NIL ; p = p -> chain ) {
1537b922cbeSmckusick 		stabparam( p , p -> value[ NL_OFFS ] , (int) lwidth(p->type));
154348a2a57Smckusick 	    }
155348a2a57Smckusick 	    if ( fp -> class == FUNC ) {
156348a2a57Smckusick 		    /*
157348a2a57Smckusick 		     *	stab the function variable
158348a2a57Smckusick 		     */
159348a2a57Smckusick 		p = fp -> ptr[ NL_FVAR ];
1607b922cbeSmckusick 		stablvar( p , p -> value[ NL_OFFS ] , (int) lwidth( p -> type));
161348a2a57Smckusick 	    }
162348a2a57Smckusick 		/*
163348a2a57Smckusick 		 *	stab local variables
164348a2a57Smckusick 		 *	rummage down hash chain links.
165348a2a57Smckusick 		 */
166348a2a57Smckusick 	    for ( i = 0 ; i <= 077 ; i++ ) {
167348a2a57Smckusick 		for ( p = disptab[ i ] ; p != NIL ; p = p->nl_next) {
168348a2a57Smckusick 		    if ( ( p -> nl_block & 037 ) != cbn ) {
169348a2a57Smckusick 			break;
170348a2a57Smckusick 		    }
171348a2a57Smckusick 		    /*
172dd16f3e7Smckusick 		     *	stab locals (not parameters)
173348a2a57Smckusick 		     */
174dd16f3e7Smckusick 		    if ( p -> symbol != NIL ) {
175dd16f3e7Smckusick 			if ( p -> class == VAR && p -> value[ NL_OFFS ] < 0 ) {
1767b922cbeSmckusick 			    stablvar( p , p -> value[ NL_OFFS ] ,
1777b922cbeSmckusick 				(int) lwidth( p -> type ) );
178dd16f3e7Smckusick 			} else if ( p -> class == CONST ) {
179dd16f3e7Smckusick 			    stabconst( p );
180dd16f3e7Smckusick 			}
181348a2a57Smckusick 		    }
182348a2a57Smckusick 		}
183348a2a57Smckusick 	    }
184348a2a57Smckusick 	}
185348a2a57Smckusick 	stablbrac( cbn );
186348a2a57Smckusick 	    /*
187348a2a57Smckusick 	     *	ask second pass to allocate known locals
188348a2a57Smckusick 	     */
1892b810895Speter 	putlbracket(ftnno, &sizes[cbn]);
190f914b486Speter 	fp_entrycode(&eecookie);
191348a2a57Smckusick #endif PC
192348a2a57Smckusick 	if ( monflg ) {
193348a2a57Smckusick 		if ( fp -> value[ NL_CNTR ] != 0 ) {
194348a2a57Smckusick 			inccnt( fp -> value [ NL_CNTR ] );
195348a2a57Smckusick 		}
196348a2a57Smckusick 		inccnt( bodycnts[ fp -> nl_block & 037 ] );
197348a2a57Smckusick 	}
198348a2a57Smckusick 	if (fp->class == PROG) {
199348a2a57Smckusick 		/*
200348a2a57Smckusick 		 * The glorious buffers option.
201348a2a57Smckusick 		 *          0 = don't buffer output
202348a2a57Smckusick 		 *          1 = line buffer output
203348a2a57Smckusick 		 *          2 = 512 byte buffer output
204348a2a57Smckusick 		 */
205348a2a57Smckusick #		ifdef OBJ
206348a2a57Smckusick 		    if (opt('b') != 1)
2077b922cbeSmckusick 			    (void) put(1, O_BUFF | opt('b') << 8);
208348a2a57Smckusick #		endif OBJ
209348a2a57Smckusick #		ifdef PC
210348a2a57Smckusick 		    if ( opt( 'b' ) != 1 ) {
211aa1ee7daSralph 			putleaf( PCC_ICON , 0 , 0
212aa1ee7daSralph 				, PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) , "_BUFF" );
213aa1ee7daSralph 			putleaf( PCC_ICON , opt( 'b' ) , 0 , PCCT_INT , (char *) 0 );
214aa1ee7daSralph 			putop( PCC_CALL , PCCT_INT );
215348a2a57Smckusick 			putdot( filename , line );
216348a2a57Smckusick 		    }
217348a2a57Smckusick #		endif PC
2185d79f55fSpeter 		inp = 0;
219348a2a57Smckusick 		out = 0;
220348a2a57Smckusick 		for (p = fp->chain; p != NIL; p = p->chain) {
2217b922cbeSmckusick 			if (pstrcmp(p->symbol, input->symbol) == 0) {
222348a2a57Smckusick 				inp++;
223348a2a57Smckusick 				continue;
224348a2a57Smckusick 			}
2257b922cbeSmckusick 			if (pstrcmp(p->symbol, output->symbol) == 0) {
226348a2a57Smckusick 				out++;
227348a2a57Smckusick 				continue;
228348a2a57Smckusick 			}
229348a2a57Smckusick 			iop = lookup1(p->symbol);
230348a2a57Smckusick 			if (iop == NIL || bn != cbn) {
231348a2a57Smckusick 				error("File %s listed in program statement but not declared", p->symbol);
232348a2a57Smckusick 				continue;
233348a2a57Smckusick 			}
234348a2a57Smckusick 			if (iop->class != VAR) {
235348a2a57Smckusick 				error("File %s listed in program statement but declared as a %s", p->symbol, classes[iop->class]);
236348a2a57Smckusick 				continue;
237348a2a57Smckusick 			}
238348a2a57Smckusick 			if (iop->type == NIL)
239348a2a57Smckusick 				continue;
240348a2a57Smckusick 			if (iop->type->class != FILET) {
241348a2a57Smckusick 				error("File %s listed in program statement but defined as %s",
242348a2a57Smckusick 					p->symbol, nameof(iop->type));
243348a2a57Smckusick 				continue;
244348a2a57Smckusick 			}
245348a2a57Smckusick #			ifdef OBJ
2467b922cbeSmckusick 			    (void) put(2, O_CON24, text(iop->type) ? 0 : width(iop->type->type));
247348a2a57Smckusick 			    i = lenstr(p->symbol,0);
2487b922cbeSmckusick 			    (void) put(2, O_CON24, i);
2497b922cbeSmckusick 			    (void) put(2, O_LVCON, i);
250348a2a57Smckusick 			    putstr(p->symbol, 0);
2517b922cbeSmckusick 			    (void) put(2, O_LV | bn<<8+INDX, (int)iop->value[NL_OFFS]);
2527b922cbeSmckusick 			    (void) put(1, O_DEFNAME);
253348a2a57Smckusick #			endif OBJ
254348a2a57Smckusick #			ifdef PC
255aa1ee7daSralph 			    putleaf( PCC_ICON , 0 , 0
256aa1ee7daSralph 				    , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
257348a2a57Smckusick 				    , "_DEFNAME" );
258d3c14c5dSpeter 			    putLV( p -> symbol , bn , iop -> value[NL_OFFS] ,
259d3c14c5dSpeter 				    iop -> extra_flags , p2type( iop ) );
260348a2a57Smckusick 			    putCONG( p -> symbol , strlen( p -> symbol )
261348a2a57Smckusick 				    , LREQ );
262aa1ee7daSralph 			    putop( PCC_CM , PCCT_INT );
263aa1ee7daSralph 			    putleaf( PCC_ICON , strlen( p -> symbol )
264aa1ee7daSralph 				    , 0 , PCCT_INT , (char *) 0 );
265aa1ee7daSralph 			    putop( PCC_CM , PCCT_INT );
266aa1ee7daSralph 			    putleaf( PCC_ICON
267348a2a57Smckusick 				, text(iop->type) ? 0 : width(iop->type->type)
268aa1ee7daSralph 				, 0 , PCCT_INT , (char *) 0 );
269aa1ee7daSralph 			    putop( PCC_CM , PCCT_INT );
270aa1ee7daSralph 			    putop( PCC_CALL , PCCT_INT );
271348a2a57Smckusick 			    putdot( filename , line );
272348a2a57Smckusick #			endif PC
273348a2a57Smckusick 		}
274348a2a57Smckusick 	}
275348a2a57Smckusick 	/*
276348a2a57Smckusick 	 * Process the prog/proc/func body
277348a2a57Smckusick 	 */
2787b922cbeSmckusick 	noreach = FALSE;
2797b922cbeSmckusick 	line = bundle->stmnt_blck.line_no;
280348a2a57Smckusick 	statlist(blk);
281348a2a57Smckusick #	ifdef PTREE
282348a2a57Smckusick 	    {
283348a2a57Smckusick 		pPointer Body = tCopy( blk );
284348a2a57Smckusick 
285348a2a57Smckusick 		pDEF( PorFHeader[ nesting -- ] ).PorFBody = Body;
286348a2a57Smckusick 	    }
287348a2a57Smckusick #	endif PTREE
288348a2a57Smckusick #	ifdef OBJ
2897b922cbeSmckusick 	    if (cbn== 1 && monflg != FALSE) {
2907b922cbeSmckusick 		    patchfil((PTR_DCL) (cntpatch - 2), (long)cnts, 2);
2917b922cbeSmckusick 		    patchfil((PTR_DCL) (nfppatch - 2), (long)pfcnt, 2);
292348a2a57Smckusick 	    }
293348a2a57Smckusick #	endif OBJ
294348a2a57Smckusick #	ifdef PC
295348a2a57Smckusick 	    if ( fp -> class == PROG && monflg ) {
296aa1ee7daSralph 		putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
297348a2a57Smckusick 			, "_PMFLUSH" );
298aa1ee7daSralph 		putleaf( PCC_ICON , cnts , 0 , PCCT_INT , (char *) 0 );
299aa1ee7daSralph 		putleaf( PCC_ICON , pfcnt , 0 , PCCT_INT , (char *) 0 );
300aa1ee7daSralph 		putop( PCC_CM , PCCT_INT );
301aa1ee7daSralph 		putLV( PCPCOUNT , 0 , 0 , NGLOBAL , PCCT_INT );
302aa1ee7daSralph 		putop( PCC_CM , PCCT_INT );
303aa1ee7daSralph 		putop( PCC_CALL , PCCT_INT );
304348a2a57Smckusick 		putdot( filename , line );
305348a2a57Smckusick 	    }
306348a2a57Smckusick #	endif PC
307348a2a57Smckusick 	/*
308348a2a57Smckusick 	 * Clean up the symbol table displays and check for unresolves
309348a2a57Smckusick 	 */
310348a2a57Smckusick 	line = endline;
3115d79f55fSpeter 	if (fp->class == PROG && inp == 0 && (input->nl_flags & (NUSED|NMOD)) != 0) {
3125d79f55fSpeter 		recovered();
3135d79f55fSpeter 		error("Input is used but not defined in the program statement");
3145d79f55fSpeter 	}
3155d79f55fSpeter 	if (fp->class == PROG && out == 0 && (output->nl_flags & (NUSED|NMOD)) != 0) {
3165d79f55fSpeter 		recovered();
3175d79f55fSpeter 		error("Output is used but not defined in the program statement");
3185d79f55fSpeter 	}
319348a2a57Smckusick 	b = cbn;
320348a2a57Smckusick 	Fp = fp;
3217b922cbeSmckusick 	chkref = (syneflg == errcnt[cbn] && opt('w') == 0)?TRUE:FALSE;
322348a2a57Smckusick 	for (i = 0; i <= 077; i++) {
323348a2a57Smckusick 		for (p = disptab[i]; p != NIL && (p->nl_block & 037) == b; p = p->nl_next) {
324348a2a57Smckusick 			/*
325348a2a57Smckusick 			 * Check for variables defined
326348a2a57Smckusick 			 * but not referenced
327348a2a57Smckusick 			 */
328348a2a57Smckusick 			if (chkref && p->symbol != NIL)
329348a2a57Smckusick 			switch (p->class) {
330348a2a57Smckusick 				case FIELD:
331348a2a57Smckusick 					/*
332348a2a57Smckusick 					 * If the corresponding record is
333348a2a57Smckusick 					 * unused, we shouldn't complain about
334348a2a57Smckusick 					 * the fields.
335348a2a57Smckusick 					 */
336348a2a57Smckusick 				default:
337348a2a57Smckusick 					if ((p->nl_flags & (NUSED|NMOD)) == 0) {
338348a2a57Smckusick 						warning();
339348a2a57Smckusick 						nerror("%s %s is neither used nor set", classes[p->class], p->symbol);
340348a2a57Smckusick 						break;
341348a2a57Smckusick 					}
342348a2a57Smckusick 					/*
343348a2a57Smckusick 					 * If a var parameter is either
344348a2a57Smckusick 					 * modified or used that is enough.
345348a2a57Smckusick 					 */
346348a2a57Smckusick 					if (p->class == REF)
347348a2a57Smckusick 						continue;
348348a2a57Smckusick #					ifdef OBJ
349348a2a57Smckusick 					    if ((p->nl_flags & NUSED) == 0) {
350348a2a57Smckusick 						warning();
351348a2a57Smckusick 						nerror("%s %s is never used", classes[p->class], p->symbol);
352348a2a57Smckusick 						break;
353348a2a57Smckusick 					    }
354348a2a57Smckusick #					endif OBJ
355348a2a57Smckusick #					ifdef PC
356d3c14c5dSpeter 					    if (((p->nl_flags & NUSED) == 0) && ((p->extra_flags & NEXTERN) == 0)) {
357348a2a57Smckusick 						warning();
358348a2a57Smckusick 						nerror("%s %s is never used", classes[p->class], p->symbol);
359348a2a57Smckusick 						break;
360348a2a57Smckusick 					    }
361348a2a57Smckusick #					endif PC
362348a2a57Smckusick 					if ((p->nl_flags & NMOD) == 0) {
363348a2a57Smckusick 						warning();
364348a2a57Smckusick 						nerror("%s %s is used but never set", classes[p->class], p->symbol);
365348a2a57Smckusick 						break;
366348a2a57Smckusick 					}
367348a2a57Smckusick 				case LABEL:
368348a2a57Smckusick 				case FVAR:
369348a2a57Smckusick 				case BADUSE:
370348a2a57Smckusick 					break;
371348a2a57Smckusick 			}
372348a2a57Smckusick 			switch (p->class) {
373348a2a57Smckusick 				case BADUSE:
374348a2a57Smckusick 					cp = "s";
3757b922cbeSmckusick 					/* This used to say ud_next
3767b922cbeSmckusick 					   that is not a member of nl so
3777b922cbeSmckusick 					   i changed it to nl_next,
3787b922cbeSmckusick 					   which may be wrong */
3797b922cbeSmckusick 					if (p->chain->nl_next == NIL)
380348a2a57Smckusick 						cp++;
381348a2a57Smckusick 					eholdnl();
382348a2a57Smckusick 					if (p->value[NL_KINDS] & ISUNDEF)
383348a2a57Smckusick 						nerror("%s undefined on line%s", p->symbol, cp);
384348a2a57Smckusick 					else
385348a2a57Smckusick 						nerror("%s improperly used on line%s", p->symbol, cp);
386348a2a57Smckusick 					pnumcnt = 10;
3877b922cbeSmckusick 					pnums((struct udinfo *) p->chain);
388348a2a57Smckusick 					pchr('\n');
389348a2a57Smckusick 					break;
390348a2a57Smckusick 
391348a2a57Smckusick 				case FUNC:
392348a2a57Smckusick 				case PROC:
393348a2a57Smckusick #					ifdef OBJ
394348a2a57Smckusick 					    if ((p->nl_flags & NFORWD))
395348a2a57Smckusick 						nerror("Unresolved forward declaration of %s %s", classes[p->class], p->symbol);
396348a2a57Smckusick #					endif OBJ
397348a2a57Smckusick #					ifdef PC
398d3c14c5dSpeter 					    if ((p->nl_flags & NFORWD) && ((p->extra_flags & NEXTERN) == 0))
399348a2a57Smckusick 						nerror("Unresolved forward declaration of %s %s", classes[p->class], p->symbol);
400348a2a57Smckusick #					endif PC
401348a2a57Smckusick 					break;
402348a2a57Smckusick 
403348a2a57Smckusick 				case LABEL:
404348a2a57Smckusick 					if (p->nl_flags & NFORWD)
405348a2a57Smckusick 						nerror("label %s was declared but not defined", p->symbol);
406348a2a57Smckusick 					break;
407348a2a57Smckusick 				case FVAR:
408348a2a57Smckusick 					if ((p->nl_flags & NMOD) == 0)
409348a2a57Smckusick 						nerror("No assignment to the function variable");
410348a2a57Smckusick 					break;
411348a2a57Smckusick 			}
412348a2a57Smckusick 		}
413348a2a57Smckusick 		/*
414348a2a57Smckusick 		 * Pop this symbol
415348a2a57Smckusick 		 * table slot
416348a2a57Smckusick 		 */
417348a2a57Smckusick 		disptab[i] = p;
418348a2a57Smckusick 	}
419348a2a57Smckusick 
420348a2a57Smckusick #	ifdef OBJ
4217b922cbeSmckusick 	    (void) put(1, O_END);
422348a2a57Smckusick #	endif OBJ
423348a2a57Smckusick #	ifdef PC
424f914b486Speter 	    fp_exitcode(&eecookie);
425348a2a57Smckusick 	    stabrbrac(cbn);
426348a2a57Smckusick 	    putrbracket(ftnno);
427f914b486Speter 	    fp_epilogue(&eecookie);
428aece3f96Speter 	    if (fp -> class != PROG) {
429f914b486Speter 		fp_formalentry(&eecookie);
430aece3f96Speter 	    }
431aece3f96Speter 		/*
432348a2a57Smckusick 		 *	declare pcp counters, if any
433348a2a57Smckusick 		 */
434348a2a57Smckusick 	    if ( monflg && fp -> class == PROG ) {
435348a2a57Smckusick 		putprintf( "	.data" , 0 );
436aa1ee7daSralph 		aligndot(PCCT_INT);
437348a2a57Smckusick 		putprintf( "	.comm	" , 1 );
438348a2a57Smckusick 		putprintf( PCPCOUNT , 1 );
439348a2a57Smckusick 		putprintf( ",%d" , 0 , ( cnts + 1 ) * sizeof (long) );
440348a2a57Smckusick 		putprintf( "	.text" , 0 );
441348a2a57Smckusick 	    }
442348a2a57Smckusick #	endif PC
443348a2a57Smckusick #ifdef DEBUG
4447b922cbeSmckusick 	dumpnl(fp->ptr[2], (int) fp->symbol);
445348a2a57Smckusick #endif
44638345de8Slinton 
44738345de8Slinton #ifdef OBJ
44838345de8Slinton 	/*
44938345de8Slinton 	 * save the namelist for the debugger pdx
45038345de8Slinton 	 */
45138345de8Slinton 
4527b922cbeSmckusick 	savenl(fp->ptr[2], (int) fp->symbol);
45338345de8Slinton #endif
45438345de8Slinton 
455348a2a57Smckusick 	/*
456348a2a57Smckusick 	 * Restore the
457348a2a57Smckusick 	 * (virtual) name list
458348a2a57Smckusick 	 * position
459348a2a57Smckusick 	 */
460348a2a57Smckusick 	nlfree(fp->ptr[2]);
461348a2a57Smckusick 	/*
462348a2a57Smckusick 	 * Proc/func has been
463348a2a57Smckusick 	 * resolved
464348a2a57Smckusick 	 */
465348a2a57Smckusick 	fp->nl_flags &= ~NFORWD;
466348a2a57Smckusick 	/*
467348a2a57Smckusick 	 * Patch the beg
468348a2a57Smckusick 	 * of the proc/func to
469348a2a57Smckusick 	 * the proper variable size
470348a2a57Smckusick 	 */
471348a2a57Smckusick 	if (Fp == NIL)
472348a2a57Smckusick 		elineon();
473348a2a57Smckusick #	ifdef OBJ
47471395e85Smckusick 	    patchfil((PTR_DCL) var,
47571395e85Smckusick 		roundup(-sizes[cbn].om_max, (long) A_STACK), 2);
476348a2a57Smckusick #	endif OBJ
477348a2a57Smckusick 	cbn--;
478348a2a57Smckusick 	if (inpflist(fp->symbol)) {
479348a2a57Smckusick 		opop('l');
480348a2a57Smckusick 	}
481348a2a57Smckusick }
4825b396f44Speter 
4835b396f44Speter #ifdef PC
4845b396f44Speter     /*
4855b396f44Speter      *	construct the long name of a function based on it's static nesting.
4865b396f44Speter      *	into a caller-supplied buffer (that should be about BUFSIZ big).
4875b396f44Speter      */
sextname(buffer,name,level)4885b396f44Speter sextname( buffer , name , level )
4895b396f44Speter     char	buffer[];
4905b396f44Speter     char	*name;
4915b396f44Speter     int		level;
4925b396f44Speter {
4935b396f44Speter     char	*starthere;
4945b396f44Speter     int	i;
4955b396f44Speter 
4965b396f44Speter     starthere = &buffer[0];
4975b396f44Speter     for ( i = 1 ; i < level ; i++ ) {
4985b396f44Speter 	sprintf( starthere , EXTFORMAT , enclosing[ i ] );
4995b396f44Speter 	starthere += strlen( enclosing[ i ] ) + 1;
5005b396f44Speter     }
50175eeeb46Speter     sprintf( starthere , EXTFORMAT , name );
50275eeeb46Speter     starthere += strlen( name ) + 1;
5035b396f44Speter     if ( starthere >= &buffer[ BUFSIZ ] ) {
5045b396f44Speter 	panic( "sextname" );
5055b396f44Speter     }
5065b396f44Speter }
507f914b486Speter 
508f914b486Speter     /*
509f914b486Speter      *	code for main()
510f914b486Speter      */
511f914b486Speter #ifdef vax
512f914b486Speter 
codeformain()513f914b486Speter codeformain()
514f914b486Speter {
515f914b486Speter     putprintf("	.text" , 0 );
516f914b486Speter     putprintf("	.align	1" , 0 );
517f914b486Speter     putprintf("	.globl	_main" , 0 );
518f914b486Speter     putprintf("_main:" , 0 );
519f914b486Speter     putprintf("	.word	0" , 0 );
520f914b486Speter     if ( opt ( 't' ) ) {
521f914b486Speter 	putprintf("	pushl	$1" , 0 );
522f914b486Speter     } else {
523f914b486Speter 	putprintf("	pushl	$0" , 0 );
524f914b486Speter     }
525f914b486Speter     putprintf("	calls	$1,_PCSTART" , 0 );
526f914b486Speter     putprintf("	movl	4(ap),__argc" , 0 );
527f914b486Speter     putprintf("	movl	8(ap),__argv" , 0 );
528f914b486Speter     putprintf("	calls	$0,_program" , 0 );
529f914b486Speter     putprintf("	pushl	$0" , 0 );
530f914b486Speter     putprintf("	calls	$1,_PCEXIT" , 0 );
531f914b486Speter }
532876ba528Smckusick #endif vax
533876ba528Smckusick 
534876ba528Smckusick #ifdef tahoe
codeformain()535876ba528Smckusick codeformain()
536876ba528Smckusick {
537876ba528Smckusick     putprintf("	.text" , 0 );
538876ba528Smckusick     putprintf("	.align	1" , 0 );
539876ba528Smckusick     putprintf("	.globl	_main" , 0 );
540876ba528Smckusick     putprintf("_main:" , 0 );
541876ba528Smckusick     putprintf("	.word	0" , 0 );
542876ba528Smckusick     if ( opt ( 't' ) ) {
543876ba528Smckusick 	putprintf("	pushl	$1" , 0 );
544876ba528Smckusick     } else {
545876ba528Smckusick 	putprintf("	pushl	$0" , 0 );
546876ba528Smckusick     }
547876ba528Smckusick     putprintf("	callf	$8,_PCSTART" , 0 );
548876ba528Smckusick     putprintf("	movl	4(fp),__argc" , 0 );
549876ba528Smckusick     putprintf("	movl	8(fp),__argv" , 0 );
550876ba528Smckusick     putprintf("	callf	$4,_program" , 0 );
551876ba528Smckusick     putprintf("	pushl	$0" , 0 );
552876ba528Smckusick     putprintf("	callf	$8,_PCEXIT" , 0 );
553876ba528Smckusick }
554876ba528Smckusick #endif tahoe
555f914b486Speter 
556f914b486Speter     /*
557f914b486Speter      *	prologue for the program.
558f914b486Speter      *	different because it
559f914b486Speter      *		doesn't have formal entry point
560f914b486Speter      */
561876ba528Smckusick #if defined(vax) || defined(tahoe)
562f914b486Speter prog_prologue(eecookiep)
563f914b486Speter     struct entry_exit_cookie	*eecookiep;
564f914b486Speter {
565f914b486Speter     putprintf("	.text" , 0 );
566f914b486Speter     putprintf("	.align	1" , 0 );
567f914b486Speter     putprintf("	.globl	_program" , 0 );
568f914b486Speter     putprintf("_program:" , 0 );
569bf623ceeSpeter 	/*
570bf623ceeSpeter 	 *	register save mask
571bf623ceeSpeter 	 */
5727b922cbeSmckusick     eecookiep -> savlabel = (int) getlab();
5737b922cbeSmckusick     putprintf("	.word	%s%d", 0, (int) SAVE_MASK_LABEL , eecookiep -> savlabel );
574f914b486Speter }
575f914b486Speter 
576f914b486Speter fp_prologue(eecookiep)
577f914b486Speter     struct entry_exit_cookie	*eecookiep;
578f914b486Speter {
579f914b486Speter 
580f914b486Speter     sextname( eecookiep -> extname, eecookiep -> nlp -> symbol , cbn - 1 );
581f914b486Speter     putprintf( "	.text" , 0 );
582f914b486Speter     putprintf( "	.align	1" , 0 );
5837b922cbeSmckusick     putprintf( "	.globl	%s%s", 0, (int) FORMALPREFIX, (int) eecookiep -> extname );
5847b922cbeSmckusick     putprintf( "	.globl	%s" , 0 , (int) eecookiep -> extname );
5857b922cbeSmckusick     putprintf( "%s:" , 0 , (int) eecookiep -> extname );
586f914b486Speter 	/*
587f914b486Speter 	 *	register save mask
588f914b486Speter 	 */
5897b922cbeSmckusick     eecookiep -> savlabel = (int) getlab();
5907b922cbeSmckusick     putprintf("	.word	%s%d", 0, (int) SAVE_MASK_LABEL , eecookiep -> savlabel );
591f914b486Speter }
592876ba528Smckusick #endif vax || tahoe
593f914b486Speter 
594f914b486Speter     /*
595f914b486Speter      *	code before any user code.
596f914b486Speter      *	or code that is machine dependent.
597f914b486Speter      */
598876ba528Smckusick #ifdef vax
599f914b486Speter fp_entrycode(eecookiep)
600f914b486Speter     struct entry_exit_cookie	*eecookiep;
601f914b486Speter {
60284977374Speter     int	ftnno = eecookiep -> nlp -> value[NL_ENTLOC];
6037b922cbeSmckusick     int	proflabel = (int) getlab();
6047b922cbeSmckusick     int	setjmp0 = (int) getlab();
605f914b486Speter 
606f914b486Speter 	/*
607f914b486Speter 	 *	top of code;  destination of jump from formal entry code.
608f914b486Speter 	 */
6097b922cbeSmckusick     eecookiep -> toplabel = (int) getlab();
6107b922cbeSmckusick     (void) putlab( (char *) eecookiep -> toplabel );
6117b922cbeSmckusick     putprintf("	subl2	$%s%d,sp" , 0 , (int) FRAME_SIZE_LABEL, ftnno );
612f914b486Speter     if ( profflag ) {
613f914b486Speter 	    /*
614f914b486Speter 	     *	call mcount for profiling
615f914b486Speter 	     */
616f914b486Speter 	putprintf( "	moval	" , 1 );
6177b922cbeSmckusick 	putprintf( PREFIXFORMAT , 1 , (int) LABELPREFIX , proflabel );
618f914b486Speter 	putprintf( ",r0" , 0 );
619f914b486Speter 	putprintf( "	jsb	mcount" , 0 );
620f914b486Speter 	putprintf( "	.data" , 0 );
621f914b486Speter 	putprintf( "	.align	2" , 0 );
6227b922cbeSmckusick 	(void) putlab( (char *) proflabel );
623f914b486Speter 	putprintf( "	.long	0" , 0 );
624f914b486Speter 	putprintf( "	.text" , 0 );
625f914b486Speter     }
626f914b486Speter 	/*
627f914b486Speter 	 *	if there are nested procedures that access our variables
628f914b486Speter 	 *	we must save the display.
629f914b486Speter 	 */
630f914b486Speter     if ( parts[ cbn ] & NONLOCALVAR ) {
631f914b486Speter 	    /*
632f914b486Speter 	     *	save old display
633f914b486Speter 	     */
634f914b486Speter 	putprintf( "	movq	%s+%d,%d(%s)" , 0
6357b922cbeSmckusick 		, (int) DISPLAYNAME , cbn * sizeof(struct dispsave)
6367b922cbeSmckusick 		, DSAVEOFFSET , (int) P2FPNAME );
637f914b486Speter 	    /*
638f914b486Speter 	     *	set up new display by saving AP and FP in appropriate
639f914b486Speter 	     *	slot in display structure.
640f914b486Speter 	     */
641f914b486Speter 	putprintf( "	movq	%s,%s+%d" , 0
6427b922cbeSmckusick 		, (int) P2APNAME , (int) DISPLAYNAME , cbn * sizeof(struct dispsave) );
643f914b486Speter     }
644f914b486Speter 	/*
645f914b486Speter 	 *	set underflow checking if runtime tests
646f914b486Speter 	 */
647f914b486Speter     if ( opt( 't' ) ) {
648f914b486Speter 	putprintf( "	bispsw	$0xe0" , 0 );
649f914b486Speter     }
650f914b486Speter 	/*
651f914b486Speter 	 *	zero local variables if checking is on
652f914b486Speter 	 *	by calling blkclr( bytes of locals , starting local address );
653f914b486Speter 	 */
654f914b486Speter     if ( opt( 't' ) && ( -sizes[ cbn ].om_max ) > DPOFF1 ) {
655aa1ee7daSralph 	putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
656f914b486Speter 		, "_blkclr" );
657aa1ee7daSralph 	putLV((char *) 0 , cbn , (int) sizes[ cbn ].om_max , NLOCAL , PCCT_CHAR );
658aa1ee7daSralph 	putleaf( PCC_ICON ,  (int) (( -sizes[ cbn ].om_max ) - DPOFF1)
659aa1ee7daSralph 		, 0 , PCCT_INT ,(char *) 0 );
660aa1ee7daSralph 	putop( PCC_CM , PCCT_INT );
661aa1ee7daSralph 	putop( PCC_CALL , PCCT_INT );
662f914b486Speter 	putdot( filename , line );
663f914b486Speter     }
664f914b486Speter 	/*
665f914b486Speter 	 *  set up goto vector if non-local goto to this frame
666f914b486Speter 	 */
667f914b486Speter     if ( parts[ cbn ] & NONLOCALGOTO ) {
668aa1ee7daSralph 	putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
669f914b486Speter 		, "_setjmp" );
670aa1ee7daSralph 	putLV( (char *) 0 , cbn , GOTOENVOFFSET , NLOCAL , PCCTM_PTR|PCCT_STRTY );
671aa1ee7daSralph 	putop( PCC_CALL , PCCT_INT );
672aa1ee7daSralph 	putleaf( PCC_ICON , 0 , 0 , PCCT_INT , (char *) 0 );
673aa1ee7daSralph 	putop( PCC_NE , PCCT_INT );
674aa1ee7daSralph 	putleaf( PCC_ICON , setjmp0 , 0 , PCCT_INT , (char *) 0 );
675aa1ee7daSralph 	putop( PCC_CBRANCH , PCCT_INT );
676f914b486Speter 	putdot( filename , line );
677f914b486Speter 	    /*
678f914b486Speter 	     *	on non-local goto, setjmp returns with address to
679f914b486Speter 	     *	be branched to.
680f914b486Speter 	     */
681f914b486Speter 	putprintf( "	jmp	(r0)" , 0 );
6827b922cbeSmckusick 	(void) putlab((char *) setjmp0);
683f914b486Speter     }
684f914b486Speter }
685876ba528Smckusick #endif vax
686f914b486Speter 
687876ba528Smckusick #ifdef tahoe
688876ba528Smckusick fp_entrycode(eecookiep)
689876ba528Smckusick     struct entry_exit_cookie	*eecookiep;
690876ba528Smckusick {
691876ba528Smckusick     int	ftnno = eecookiep -> nlp -> value[NL_ENTLOC];
692876ba528Smckusick     int	proflabel = (int) getlab();
693876ba528Smckusick     int	setjmp0 = (int) getlab();
694876ba528Smckusick 
695876ba528Smckusick 	/*
696876ba528Smckusick 	 *	top of code;  destination of jump from formal entry code.
697876ba528Smckusick 	 */
698876ba528Smckusick     eecookiep -> toplabel = (int) getlab();
699876ba528Smckusick     (void) putlab( (char *) eecookiep -> toplabel );
700876ba528Smckusick     putprintf("	subl3	$%s%d,fp,sp" , 0 , (int) FRAME_SIZE_LABEL, ftnno );
701876ba528Smckusick     if ( profflag ) {
702876ba528Smckusick 	    /*
703876ba528Smckusick 	     *	call mcount for profiling
704876ba528Smckusick 	     */
705876ba528Smckusick 	putprintf( "	pushal	" , 1 );
706b2276f6cSmckusick 	putprintf( PREFIXFORMAT , 0 , (int) LABELPREFIX , proflabel );
707876ba528Smckusick 	putprintf( "	callf	$8,mcount" , 0 );
708876ba528Smckusick 	putprintf( "	.data" , 0 );
709876ba528Smckusick 	putprintf( "	.align	2" , 0 );
710876ba528Smckusick 	(void) putlab( (char *) proflabel );
711876ba528Smckusick 	putprintf( "	.long	0" , 0 );
712876ba528Smckusick 	putprintf( "	.text" , 0 );
713876ba528Smckusick     }
714876ba528Smckusick 	/*
715876ba528Smckusick 	 *	if there are nested procedures that access our variables
716876ba528Smckusick 	 *	we must save the display.
717876ba528Smckusick 	 */
718876ba528Smckusick     if ( parts[ cbn ] & NONLOCALVAR ) {
719876ba528Smckusick 	    /*
720876ba528Smckusick 	     *	save old display
721876ba528Smckusick 	     */
722876ba528Smckusick 	putprintf( "	movl	%s+%d,%d(%s)" , 0
723876ba528Smckusick 		, (int) DISPLAYNAME , cbn * sizeof(struct dispsave)
724876ba528Smckusick 		, DSAVEOFFSET , (int) P2FPNAME );
725876ba528Smckusick 	    /*
726876ba528Smckusick 	     *	set up new display by saving FP in appropriate
727876ba528Smckusick 	     *	slot in display structure.
728876ba528Smckusick 	     */
729876ba528Smckusick 	putprintf( "	movl	%s,%s+%d" , 0
730876ba528Smckusick 		, (int) P2FPNAME , (int) DISPLAYNAME , cbn * sizeof(struct dispsave) );
731876ba528Smckusick     }
732876ba528Smckusick 	/*
733876ba528Smckusick 	 *	set underflow checking if runtime tests
734876ba528Smckusick 	 */
735876ba528Smckusick     if ( opt( 't' ) ) {
736876ba528Smckusick 	putprintf( "	bicpsw	$0x20" , 0 );
737876ba528Smckusick     }
738876ba528Smckusick 	/*
739876ba528Smckusick 	 *	zero local variables if checking is on
740876ba528Smckusick 	 *	by calling blkclr( bytes of locals , starting local address );
741876ba528Smckusick 	 */
742876ba528Smckusick     if ( opt( 't' ) && ( -sizes[ cbn ].om_max ) > DPOFF1 ) {
743876ba528Smckusick 	putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
744876ba528Smckusick 		, "_blkclr" );
745876ba528Smckusick 	putLV((char *) 0 , cbn , (int) sizes[ cbn ].om_max , NLOCAL , PCCT_CHAR );
746876ba528Smckusick 	putleaf( PCC_ICON ,  (int) (( -sizes[ cbn ].om_max ) - DPOFF1)
747876ba528Smckusick 		, 0 , PCCT_INT ,(char *) 0 );
748876ba528Smckusick 	putop( PCC_CM , PCCT_INT );
749876ba528Smckusick 	putop( PCC_CALL , PCCT_INT );
750876ba528Smckusick 	putdot( filename , line );
751876ba528Smckusick     }
752876ba528Smckusick 	/*
753876ba528Smckusick 	 *  set up goto vector if non-local goto to this frame
754876ba528Smckusick 	 */
755876ba528Smckusick     if ( parts[ cbn ] & NONLOCALGOTO ) {
756876ba528Smckusick 	putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
757876ba528Smckusick 		, "_setjmp" );
758876ba528Smckusick 	putLV( (char *) 0 , cbn , GOTOENVOFFSET , NLOCAL , PCCTM_PTR|PCCT_STRTY );
759876ba528Smckusick 	putop( PCC_CALL , PCCT_INT );
760876ba528Smckusick 	putleaf( PCC_ICON , 0 , 0 , PCCT_INT , (char *) 0 );
761876ba528Smckusick 	putop( PCC_NE , PCCT_INT );
762876ba528Smckusick 	putleaf( PCC_ICON , setjmp0 , 0 , PCCT_INT , (char *) 0 );
763876ba528Smckusick 	putop( PCC_CBRANCH , PCCT_INT );
764876ba528Smckusick 	putdot( filename , line );
765876ba528Smckusick 	    /*
766876ba528Smckusick 	     *	on non-local goto, setjmp returns with address to
767876ba528Smckusick 	     *	be branched to.
768876ba528Smckusick 	     */
769876ba528Smckusick 	putprintf( "	jmp	(r0)" , 0 );
770876ba528Smckusick 	(void) putlab((char *) setjmp0);
771876ba528Smckusick     }
772876ba528Smckusick }
773876ba528Smckusick #endif tahoe
774876ba528Smckusick 
775876ba528Smckusick #if defined(vax) || defined(tahoe)
776f914b486Speter fp_exitcode(eecookiep)
777f914b486Speter     struct entry_exit_cookie	*eecookiep;
778f914b486Speter {
779f914b486Speter 	/*
780f914b486Speter 	 *	if there were file variables declared at this level
781f914b486Speter 	 *	call PCLOSE( ap ) to clean them up.
782f914b486Speter 	 */
783f914b486Speter     if ( dfiles[ cbn ] ) {
784aa1ee7daSralph 	putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
785f914b486Speter 		, "_PCLOSE" );
786aa1ee7daSralph 	putleaf( PCC_REG , 0 , P2AP , PCCM_ADDTYPE( PCCT_CHAR , PCCTM_PTR ) , (char *) 0 );
787aa1ee7daSralph 	putop( PCC_CALL , PCCT_INT );
788f914b486Speter 	putdot( filename , line );
789f914b486Speter     }
790f914b486Speter 	/*
791f914b486Speter 	 *	if this is a function,
792f914b486Speter 	 *	the function variable is the return value.
793f914b486Speter 	 *	if it's a scalar valued function, return scalar,
794f914b486Speter 	 *	else, return a pointer to the structure value.
795f914b486Speter 	 */
796f914b486Speter     if ( eecookiep-> nlp -> class == FUNC ) {
797f914b486Speter 	struct nl	*fvar = eecookiep-> nlp -> ptr[ NL_FVAR ];
798f914b486Speter 	long		fvartype = p2type( fvar -> type );
799f914b486Speter 	long		label;
800f914b486Speter 	char		labelname[ BUFSIZ ];
801f914b486Speter 
802f914b486Speter 	switch ( classify( fvar -> type ) ) {
803f914b486Speter 	    case TBOOL:
804f914b486Speter 	    case TCHAR:
805f914b486Speter 	    case TINT:
806f914b486Speter 	    case TSCAL:
807f914b486Speter 	    case TDOUBLE:
808f914b486Speter 	    case TPTR:
809f914b486Speter 		putRV( fvar -> symbol , ( fvar -> nl_block ) & 037 ,
810f914b486Speter 			fvar -> value[ NL_OFFS ] ,
811f914b486Speter 			fvar -> extra_flags ,
8127b922cbeSmckusick 			(int) fvartype );
813aa1ee7daSralph 		putop( PCC_FORCE , (int) fvartype );
814f914b486Speter 		break;
815f914b486Speter 	    default:
8167b922cbeSmckusick 		label = (int) getlab();
817f914b486Speter 		sprintf( labelname , PREFIXFORMAT , LABELPREFIX , label );
818f914b486Speter 		putprintf( "	.data" , 0 );
819f914b486Speter 		aligndot(A_STRUCT);
820f914b486Speter 		putprintf( "	.lcomm	%s,%d" , 0 ,
8217b922cbeSmckusick 			    (int) labelname , (int) lwidth( fvar -> type ) );
822f914b486Speter 		putprintf( "	.text" , 0 );
823aa1ee7daSralph 		putleaf( PCC_NAME , 0 , 0 , (int) fvartype , labelname );
824f914b486Speter 		putLV( fvar -> symbol , ( fvar -> nl_block ) & 037 ,
825f914b486Speter 			fvar -> value[ NL_OFFS ] ,
826f914b486Speter 			fvar -> extra_flags ,
8277b922cbeSmckusick 			(int) fvartype );
828aa1ee7daSralph 		putstrop( PCC_STASG , (int) PCCM_ADDTYPE(fvartype, PCCTM_PTR) ,
8297b922cbeSmckusick 			(int) lwidth( fvar -> type ) ,
830f914b486Speter 			align( fvar -> type ) );
831f914b486Speter 		putdot( filename , line );
832aa1ee7daSralph 		putleaf( PCC_ICON , 0 , 0 , (int) PCCM_ADDTYPE(fvartype, PCCTM_PTR), labelname );
833aa1ee7daSralph 		putop( PCC_FORCE , (int) PCCM_ADDTYPE(fvartype, PCCTM_PTR) );
834f914b486Speter 		break;
835f914b486Speter 	}
836f914b486Speter 	putdot( filename , line );
837f914b486Speter     }
838f914b486Speter 	/*
839f914b486Speter 	 *	if there are nested procedures we must save the display.
840f914b486Speter 	 */
841f914b486Speter     if ( parts[ cbn ] & NONLOCALVAR ) {
842f914b486Speter 	    /*
843f914b486Speter 	     *	restore old display entry from save area
844f914b486Speter 	     */
845876ba528Smckusick #ifdef vax
846f914b486Speter 	putprintf( "	movq	%d(%s),%s+%d" , 0
8477b922cbeSmckusick 	    , DSAVEOFFSET , (int) P2FPNAME
8487b922cbeSmckusick 	    , (int) DISPLAYNAME , cbn * sizeof(struct dispsave) );
849876ba528Smckusick #endif
850876ba528Smckusick #ifdef tahoe
851876ba528Smckusick 	putprintf( "	movl	%d(%s),%s+%d" , 0
852876ba528Smckusick 	    , DSAVEOFFSET , (int) P2FPNAME
853876ba528Smckusick 	    , (int) DISPLAYNAME , cbn * sizeof(struct dispsave) );
854876ba528Smckusick #endif
855f914b486Speter     }
856f914b486Speter }
857876ba528Smckusick #endif vax || tahoe
858f914b486Speter 
859876ba528Smckusick #if defined(vax) || defined(tahoe)
860f914b486Speter fp_epilogue(eecookiep)
861f914b486Speter     struct entry_exit_cookie	*eecookiep;
862f914b486Speter {
863dd16f3e7Smckusick     stabline(line);
864f914b486Speter     putprintf("	ret" , 0 );
865f914b486Speter 	/*
866f914b486Speter 	 *	set the register save mask.
867f914b486Speter 	 */
868f914b486Speter     putprintf("	.set	%s%d,0x%x", 0,
8697b922cbeSmckusick 		(int) SAVE_MASK_LABEL, eecookiep -> savlabel, savmask());
870f914b486Speter }
871876ba528Smckusick #endif vax || tahoe
872f914b486Speter 
873876ba528Smckusick #if defined(vax) || defined(tahoe)
874f914b486Speter fp_formalentry(eecookiep)
875f914b486Speter     struct entry_exit_cookie	*eecookiep;
876f914b486Speter {
877f914b486Speter 
878c475f75aSpeter     putprintf("	.align 1", 0);
8797b922cbeSmckusick     putprintf("%s%s:" , 0 , (int) FORMALPREFIX , (int) eecookiep -> extname );
8807b922cbeSmckusick     putprintf("	.word	%s%d", 0, (int) SAVE_MASK_LABEL, eecookiep -> savlabel );
881aa1ee7daSralph     putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) , "_FCALL" );
8827b922cbeSmckusick     putRV((char *) 0 , cbn ,
883f914b486Speter 	eecookiep -> nlp -> value[ NL_OFFS ] + sizeof( struct formalrtn * ) ,
884aa1ee7daSralph 	NPARAM , PCCTM_PTR | PCCT_STRTY );
885aa1ee7daSralph     putRV((char *) 0, cbn, eecookiep -> nlp -> value[NL_OFFS], NPARAM, PCCTM_PTR|PCCT_STRTY);
886aa1ee7daSralph     putop( PCC_CM , PCCT_INT );
887aa1ee7daSralph     putop( PCC_CALL , PCCT_INT );
888f914b486Speter     putdot( filename , line );
8897b922cbeSmckusick     putjbr( (long) eecookiep -> toplabel );
890f914b486Speter }
891876ba528Smckusick #endif vax || tahoe
892f914b486Speter 
893f914b486Speter #ifdef mc68000
894f914b486Speter 
codeformain()895f914b486Speter codeformain()
896f914b486Speter {
897f914b486Speter     putprintf("	.text", 0);
898f914b486Speter     putprintf("	.globl	_main", 0);
899f914b486Speter     putprintf("_main:", 0);
900f914b486Speter     putprintf("	link	%s,#0", 0, P2FPNAME);
901f914b486Speter     if (opt('t')) {
902f914b486Speter 	putprintf("	pea	1", 0);
903f914b486Speter     } else {
904f914b486Speter 	putprintf("	pea	0", 0);
905f914b486Speter     }
906f914b486Speter     putprintf("	jbsr	_PCSTART", 0);
907f914b486Speter     putprintf("	addql	#4,sp", 0);
908f914b486Speter     putprintf("	movl	%s@(8),__argc", 0, P2FPNAME);
909f914b486Speter     putprintf("	movl	%s@(12),__argv", 0, P2FPNAME);
910f914b486Speter     putprintf("	jbsr	_program", 0);
911f914b486Speter     putprintf("	pea	0", 0);
912f914b486Speter     putprintf("	jbsr	_PCEXIT", 0);
913f914b486Speter }
914f914b486Speter 
915f914b486Speter prog_prologue(eecookiep)
916f914b486Speter     struct entry_exit_cookie	*eecookiep;
917f914b486Speter {
918f914b486Speter     int	ftnno = eecookiep -> nlp -> value[NL_ENTLOC];
919f914b486Speter 
920f914b486Speter     putprintf("	.text", 0);
921f914b486Speter     putprintf("	.globl	_program", 0);
922f914b486Speter     putprintf("_program:", 0);
923f914b486Speter     putprintf("	link	%s,#0", 0, P2FPNAME);
924f914b486Speter     putprintf("	addl	#-%s%d,sp", 0, FRAME_SIZE_LABEL, ftnno);
925f914b486Speter 	/* touch new end of stack, to break more stack space */
926f914b486Speter     putprintf("	tstb	sp@(-%s%d)", 0, PAGE_BREAK_LABEL, ftnno);
927f914b486Speter     putprintf("	moveml	#%s%d,sp@", 0, SAVE_MASK_LABEL, ftnno);
928f914b486Speter }
929f914b486Speter 
930f914b486Speter fp_prologue(eecookiep)
931f914b486Speter     struct entry_exit_cookie	*eecookiep;
932f914b486Speter {
933f914b486Speter     int		ftnno = eecookiep -> nlp -> value[NL_ENTLOC];
934f914b486Speter 
935f914b486Speter     sextname(eecookiep -> extname, eecookiep -> nlp -> symbol, cbn - 1);
936f914b486Speter     putprintf("	.text", 0);
937f914b486Speter     putprintf("	.globl	%s%s", 0, FORMALPREFIX, eecookiep -> extname);
938f914b486Speter     putprintf("	.globl	%s", 0, eecookiep -> extname);
939f914b486Speter     putprintf("%s:", 0, eecookiep -> extname);
940f914b486Speter     putprintf("	link	%s,#0", 0, P2FPNAME);
941f914b486Speter     putprintf("	addl	#-%s%d,sp", 0, FRAME_SIZE_LABEL, ftnno);
942f914b486Speter 	/* touch new end of stack, to break more stack space */
943f914b486Speter     putprintf("	tstb	sp@(-%s%d)", 0, PAGE_BREAK_LABEL, ftnno);
944f914b486Speter     putprintf("	moveml	#%s%d,sp@", 0, SAVE_MASK_LABEL, ftnno);
945f914b486Speter }
946f914b486Speter 
947f914b486Speter fp_entrycode(eecookiep)
948f914b486Speter     struct entry_exit_cookie	*eecookiep;
949f914b486Speter {
9507b922cbeSmckusick     char *proflabel = getlab();
9517b922cbeSmckusick     char *setjmp0 = getlab();
952f914b486Speter 
953f914b486Speter 	/*
954f914b486Speter 	 *	fill in the label cookie
955f914b486Speter 	 */
956f914b486Speter     eecookiep -> toplabel = getlab();
9577b922cbeSmckusick     (void) putlab(eecookiep -> toplabel);
958f914b486Speter 	/*
959f914b486Speter 	 *	call mcount if we are profiling.
960f914b486Speter 	 */
961f914b486Speter     if ( profflag ) {
962f914b486Speter 	putprintf("	movl	#%s%d,a0", 0, LABELPREFIX,  proflabel);
963f914b486Speter 	putprintf("	jsr	mcount", 0);
964f914b486Speter 	putprintf("	.data", 0);
965f914b486Speter 	putprintf("	.even", 0);
9667b922cbeSmckusick 	(void) putlab(proflabel);
967f914b486Speter 	putprintf("	.long	0", 0);
968f914b486Speter 	putprintf("	.text", 0);
969f914b486Speter     }
970f914b486Speter 	/*
971f914b486Speter 	 *	if there are nested procedures that access our variables
972f914b486Speter 	 *	we must save the display
973f914b486Speter 	 */
974f914b486Speter     if (parts[cbn] & NONLOCALVAR) {
975f914b486Speter 	    /*
976f914b486Speter 	     *	save the old display
977f914b486Speter 	     */
978f914b486Speter 	putprintf("	movl	%s+%d,%s@(%d)", 0,
979f914b486Speter 		    DISPLAYNAME, cbn * sizeof(struct dispsave),
980f914b486Speter 		    P2FPNAME, DSAVEOFFSET);
981f914b486Speter 	    /*
982f914b486Speter 	     *	set up the new display by saving the framepointer
983f914b486Speter 	     *	in the display structure.
984f914b486Speter 	     */
985f914b486Speter 	putprintf("	movl	%s,%s+%d", 0,
986f914b486Speter 		    P2FPNAME, DISPLAYNAME, cbn * sizeof(struct dispsave));
987f914b486Speter     }
988f914b486Speter 	/*
989f914b486Speter 	 *	zero local variables if checking is on
990f914b486Speter 	 *	by calling blkclr( bytes of locals , starting local address );
991f914b486Speter 	 */
992f914b486Speter     if ( opt( 't' ) && ( -sizes[ cbn ].om_max ) > DPOFF1 ) {
993aa1ee7daSralph 	putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
994f914b486Speter 		, "_blkclr" );
995aa1ee7daSralph 	putLV( 0 , cbn , sizes[ cbn ].om_max , NLOCAL , PCCT_CHAR );
996aa1ee7daSralph 	putleaf( PCC_ICON ,  ( -sizes[ cbn ].om_max ) - DPOFF1
997aa1ee7daSralph 		, 0 , PCCT_INT , 0 );
998aa1ee7daSralph 	putop( PCC_CM , PCCT_INT );
999aa1ee7daSralph 	putop( PCC_CALL , PCCT_INT );
1000f914b486Speter 	putdot( filename , line );
1001f914b486Speter     }
1002f914b486Speter 	/*
1003f914b486Speter 	 *  set up goto vector if non-local goto to this frame
1004f914b486Speter 	 */
1005f914b486Speter     if ( parts[ cbn ] & NONLOCALGOTO ) {
1006aa1ee7daSralph 	putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
1007f914b486Speter 		, "_setjmp" );
1008aa1ee7daSralph 	putLV( 0 , cbn , GOTOENVOFFSET , NLOCAL , PCCTM_PTR|PCCT_STRTY );
1009aa1ee7daSralph 	putop( PCC_CALL , PCCT_INT );
1010aa1ee7daSralph 	putleaf( PCC_ICON , 0 , 0 , PCCT_INT , 0 );
1011aa1ee7daSralph 	putop( PCC_NE , PCCT_INT );
1012aa1ee7daSralph 	putleaf( PCC_ICON , setjmp0 , 0 , PCCT_INT , 0 );
1013aa1ee7daSralph 	putop( PCC_CBRANCH , PCCT_INT );
1014f914b486Speter 	putdot( filename , line );
1015f914b486Speter 	    /*
1016f914b486Speter 	     *	on non-local goto, setjmp returns with address to
1017f914b486Speter 	     *	be branched to.
1018f914b486Speter 	     */
1019f914b486Speter 	putprintf("	movl	d0,a0", 0);
1020f914b486Speter 	putprintf("	jmp	a0@", 0);
10217b922cbeSmckusick 	(void) putlab(setjmp0);
1022f914b486Speter     }
1023f914b486Speter }
1024f914b486Speter 
1025f914b486Speter fp_exitcode(eecookiep)
1026f914b486Speter     struct entry_exit_cookie	*eecookiep;
1027f914b486Speter {
1028f914b486Speter 	/*
1029f914b486Speter 	 *	if there were file variables declared at this level
1030f914b486Speter 	 *	call PCLOSE( ap ) to clean them up.
1031f914b486Speter 	 */
1032f914b486Speter     if ( dfiles[ cbn ] ) {
1033aa1ee7daSralph 	putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
1034f914b486Speter 		, "_PCLOSE" );
1035aa1ee7daSralph 	putleaf( PCC_REG , 0 , P2AP , PCCM_ADDTYPE( PCCT_CHAR , PCCTM_PTR ) , 0 );
1036aa1ee7daSralph 	putop( PCC_CALL , PCCT_INT );
1037f914b486Speter 	putdot( filename , line );
1038f914b486Speter     }
1039f914b486Speter 	/*
1040f914b486Speter 	 *	if this is a function,
1041f914b486Speter 	 *	the function variable is the return value.
1042f914b486Speter 	 *	if it's a scalar valued function, return scalar,
1043f914b486Speter 	 *	else, return a pointer to the structure value.
1044f914b486Speter 	 */
1045f914b486Speter     if ( eecookiep -> nlp -> class == FUNC ) {
1046f914b486Speter 	struct nl	*fvar = eecookiep -> nlp -> ptr[ NL_FVAR ];
1047f914b486Speter 	long		fvartype = p2type( fvar -> type );
10487b922cbeSmckusick 	char		*label;
1049f914b486Speter 	char		labelname[ BUFSIZ ];
1050f914b486Speter 
1051f914b486Speter 	switch ( classify( fvar -> type ) ) {
1052f914b486Speter 	    case TBOOL:
1053f914b486Speter 	    case TCHAR:
1054f914b486Speter 	    case TINT:
1055f914b486Speter 	    case TSCAL:
1056f914b486Speter 	    case TDOUBLE:
1057f914b486Speter 	    case TPTR:
1058f914b486Speter 		putRV( fvar -> symbol , ( fvar -> nl_block ) & 037 ,
1059f914b486Speter 			fvar -> value[ NL_OFFS ] ,
1060f914b486Speter 			fvar -> extra_flags ,
1061f914b486Speter 			fvartype );
1062aa1ee7daSralph 		putop( PCC_FORCE , fvartype );
1063f914b486Speter 		break;
1064f914b486Speter 	    default:
1065f914b486Speter 		label = getlab();
1066f914b486Speter 		sprintf( labelname , PREFIXFORMAT , LABELPREFIX , label );
1067f914b486Speter 		putprintf("	.lcomm	%s,%d", 0,
1068f914b486Speter 			labelname, lwidth(fvar -> type));
1069aa1ee7daSralph 		putleaf( PCC_NAME , 0 , 0 , fvartype , labelname );
1070f914b486Speter 		putLV( fvar -> symbol , ( fvar -> nl_block ) & 037 ,
1071f914b486Speter 			fvar -> value[ NL_OFFS ] ,
1072f914b486Speter 			fvar -> extra_flags ,
1073f914b486Speter 			fvartype );
1074aa1ee7daSralph 		putstrop( PCC_STASG , PCCM_ADDTYPE(fvartype, PCCTM_PTR) ,
1075c475f75aSpeter 			lwidth( fvar -> type ) ,
1076f914b486Speter 			align( fvar -> type ) );
1077f914b486Speter 		putdot( filename , line );
1078aa1ee7daSralph 		putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE(fvartype, PCCTM_PTR), labelname );
1079aa1ee7daSralph 		putop( PCC_FORCE , PCCM_ADDTYPE(fvartype, PCCTM_PTR) );
1080f914b486Speter 		break;
1081f914b486Speter 	}
1082f914b486Speter 	putdot( filename , line );
1083f914b486Speter     }
1084f914b486Speter 	/*
1085f914b486Speter 	 *	if we saved a display, we must restore it.
1086f914b486Speter 	 */
1087f914b486Speter     if ( parts[ cbn ] & NONLOCALVAR ) {
1088f914b486Speter 	    /*
1089f914b486Speter 	     *	restore old display entry from save area
1090f914b486Speter 	     */
1091f914b486Speter 	putprintf("	movl	%s@(%d),%s+%d", 0,
1092f914b486Speter 		    P2FPNAME, DSAVEOFFSET,
1093f914b486Speter 		    DISPLAYNAME, cbn * sizeof(struct dispsave));
1094f914b486Speter     }
1095f914b486Speter }
1096f914b486Speter 
1097f914b486Speter fp_epilogue(eecookiep)
1098f914b486Speter     struct entry_exit_cookie	*eecookiep;
1099f914b486Speter {
1100f914b486Speter     /*
1101f914b486Speter      *	all done by the second pass.
1102f914b486Speter      */
1103f914b486Speter }
1104f914b486Speter 
1105f914b486Speter fp_formalentry(eecookiep)
1106f914b486Speter     struct entry_exit_cookie	*eecookiep;
1107f914b486Speter {
1108f914b486Speter     putprintf( "%s%s:" , 0 , FORMALPREFIX , eecookiep -> extname );
1109f914b486Speter     putprintf("	link	%s,#0", 0, P2FPNAME);
1110f914b486Speter     putprintf("	addl	#-%s%d,sp", 0, FRAME_SIZE_LABEL, ftnno);
1111f914b486Speter 	/* touch new end of stack, to break more stack space */
1112f914b486Speter     putprintf("	tstb	sp@(-%s%d)", 0, PAGE_BREAK_LABEL, ftnno);
1113f914b486Speter     putprintf("	moveml	#%s%d,sp@", 0, SAVE_MASK_LABEL, ftnno);
1114aa1ee7daSralph     putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) , "_FCALL" );
1115f914b486Speter     putRV( 0 , cbn ,
1116f914b486Speter 	eecookiep -> nlp -> value[ NL_OFFS ] + sizeof( struct formalrtn * ) ,
1117aa1ee7daSralph 	NPARAM , PCCTM_PTR | PCCT_STRTY );
1118aa1ee7daSralph     putRV(0, cbn, eecookiep -> nlp -> value[NL_OFFS], NPARAM, PCCTM_PTR|PCCT_STRTY);
1119aa1ee7daSralph     putop( PCC_CM , PCCT_INT );
1120aa1ee7daSralph     putop( PCC_CALL , PCCT_INT );
1121f914b486Speter     putdot( filename , line );
1122f914b486Speter     putjbr( eecookiep -> toplabel );
1123f914b486Speter }
1124f914b486Speter #endif mc68000
11255b396f44Speter #endif PC
1126