xref: /csrg-svn/usr.bin/pascal/src/fend.c (revision 18457)
13192Smckusick /* Copyright (c) 1979 Regents of the University of California */
23192Smckusick 
318347Smckusick #ifndef lint
4*18457Sralph static char sccsid[] = "@(#)fend.c 2.3 03/20/85";
518347Smckusick #endif
63192Smckusick 
73192Smckusick #include "whoami.h"
83192Smckusick #include "0.h"
93192Smckusick #include "tree.h"
103192Smckusick #include "opcode.h"
113192Smckusick #include "objfmt.h"
123192Smckusick #include "align.h"
1311337Speter #include "tmps.h"
143192Smckusick 
153192Smckusick /*
163192Smckusick  * this array keeps the pxp counters associated with
173192Smckusick  * functions and procedures, so that they can be output
183192Smckusick  * when their bodies are encountered
193192Smckusick  */
203192Smckusick int	bodycnts[ DSPLYSZ ];
213192Smckusick 
223192Smckusick #ifdef PC
233192Smckusick #   include "pc.h"
24*18457Sralph #   include <pcc.h>
253192Smckusick #endif PC
263192Smckusick 
273192Smckusick #ifdef OBJ
283192Smckusick int	cntpatch;
293192Smckusick int	nfppatch;
303192Smckusick #endif OBJ
313192Smckusick 
3218347Smckusick #include "tree_ty.h"
3318347Smckusick 
343192Smckusick struct	nl *Fp;
353192Smckusick int	pnumcnt;
363192Smckusick /*
373192Smckusick  * Funcend is called to
383192Smckusick  * finish a block by generating
393192Smckusick  * the code for the statements.
403192Smckusick  * It then looks for unresolved declarations
413192Smckusick  * of labels, procedures and functions,
423192Smckusick  * and cleans up the name list.
433192Smckusick  * For the program, it checks the
443192Smckusick  * semantics of the program
453192Smckusick  * statement (yuchh).
463192Smckusick  */
473192Smckusick funcend(fp, bundle, endline)
483192Smckusick 	struct nl *fp;
4918347Smckusick 	struct tnode *bundle;
503192Smckusick 	int endline;
513192Smckusick {
523192Smckusick 	register struct nl *p;
533192Smckusick 	register int i, b;
5418347Smckusick 	int inp, out;
5518347Smckusick 	struct tnode *blk;
563192Smckusick 	bool chkref;
573192Smckusick 	struct nl *iop;
583192Smckusick 	char *cp;
593192Smckusick 	extern int cntstat;
603192Smckusick #	ifdef PC
6110671Speter 	    struct entry_exit_cookie	eecookie;
623192Smckusick #	endif PC
6318347Smckusick #	ifndef PC
6418347Smckusick 	int var;
6518347Smckusick #	endif PC
663192Smckusick 
673192Smckusick 	cntstat = 0;
683192Smckusick /*
693192Smckusick  *	yyoutline();
703192Smckusick  */
713192Smckusick 	if (program != NIL)
723192Smckusick 		line = program->value[3];
7318347Smckusick 	blk = bundle->stmnt_blck.stmnt_list;
743192Smckusick 	if (fp == NIL) {
753192Smckusick 		cbn--;
763192Smckusick #		ifdef PTREE
773192Smckusick 		    nesting--;
783192Smckusick #		endif PTREE
793192Smckusick 		return;
803192Smckusick 	}
813192Smckusick #ifdef OBJ
823192Smckusick 	/*
833192Smckusick 	 * Patch the branch to the
843192Smckusick 	 * entry point of the function
853192Smckusick 	 */
8618347Smckusick 	patch4((PTR_DCL) fp->value[NL_ENTLOC]);
873192Smckusick 	/*
883192Smckusick 	 * Put out the block entrance code and the block name.
893192Smckusick 	 * HDRSZE is the number of bytes of info in the static
903192Smckusick 	 * BEG data area exclusive of the proc name. It is
913192Smckusick 	 * currently defined as:
923192Smckusick 	/*	struct hdr {
933192Smckusick 	/*		long framesze;	/* number of bytes of local vars */
943192Smckusick 	/*		long nargs;	/* number of bytes of arguments */
953192Smckusick 	/*		bool tests;	/* TRUE => perform runtime tests */
963192Smckusick 	/*		short offset;	/* offset of procedure in source file */
973192Smckusick 	/*		char name[1];	/* name of active procedure */
983192Smckusick 	/*	};
993192Smckusick 	 */
1003192Smckusick #	define HDRSZE (2 * sizeof(long) + sizeof(short) + sizeof(bool))
1013192Smckusick 	var = put(2, ((lenstr(fp->symbol,0) + HDRSZE) << 8)
1023192Smckusick 		| (cbn == 1 && opt('p') == 0 ? O_NODUMP: O_BEG), (long)0);
1033192Smckusick 	    /*
1043192Smckusick 	     *  output the number of bytes of arguments
1053192Smckusick 	     *  this is only checked on formal calls.
1063192Smckusick 	     */
10718347Smckusick 	(void) put(2, O_CASE4, cbn == 1 ? (long)0 : (long)(fp->value[NL_OFFS]-DPOFF2));
1083192Smckusick 	    /*
1093192Smckusick 	     *	Output the runtime test mode for the routine
1103192Smckusick 	     */
11118347Smckusick 	(void) put(2, sizeof(bool) == 2 ? O_CASE2 : O_CASE4, opt('t') ? TRUE : FALSE);
1123192Smckusick 	    /*
1133192Smckusick 	     *	Output line number and routine name
1143192Smckusick 	     */
11518347Smckusick 	(void) put(2, O_CASE2, bundle->stmnt_blck.line_no);
1163192Smckusick 	putstr(fp->symbol, 0);
1173192Smckusick #endif OBJ
1183192Smckusick #ifdef PC
1193192Smckusick 	/*
1203192Smckusick 	 * put out the procedure entry code
1213192Smckusick 	 */
12210671Speter 	eecookie.nlp = fp;
1233192Smckusick 	if ( fp -> class == PROG ) {
1249129Smckusick 		/*
1259129Smckusick 		 *	If there is a label declaration in the main routine
1269129Smckusick 		 *	then there may be a non-local goto to it that does
1279129Smckusick 		 *	not appear in this module. We have to assume that
1289129Smckusick 		 *	such a reference may occur and generate code to
1299129Smckusick 		 *	prepare for it.
1309129Smckusick 		 */
1319129Smckusick 	    if ( parts[ cbn ] & LPRT ) {
1329129Smckusick 		parts[ cbn ] |= ( NONLOCALVAR | NONLOCALGOTO );
1339129Smckusick 	    }
13410671Speter 	    codeformain();
1357917Smckusick 	    ftnno = fp -> value[NL_ENTLOC];
13610671Speter 	    prog_prologue(&eecookie);
13718347Smckusick 	    stabline(bundle->stmnt_blck.line_no);
13818347Smckusick 	    stabfunc(fp, "program", bundle->stmnt_blck.line_no , (long) 0 );
1393192Smckusick 	} else {
1407917Smckusick 	    ftnno = fp -> value[NL_ENTLOC];
14110671Speter 	    fp_prologue(&eecookie);
14218347Smckusick 	    stabline(bundle->stmnt_blck.line_no);
14318347Smckusick 	    stabfunc(fp, fp->symbol, bundle->stmnt_blck.line_no,
14418347Smckusick 		(long)(cbn - 1));
1453192Smckusick 	    for ( p = fp -> chain ; p != NIL ; p = p -> chain ) {
14618347Smckusick 		stabparam( p , p -> value[ NL_OFFS ] , (int) lwidth(p->type));
1473192Smckusick 	    }
1483192Smckusick 	    if ( fp -> class == FUNC ) {
1493192Smckusick 		    /*
1503192Smckusick 		     *	stab the function variable
1513192Smckusick 		     */
1523192Smckusick 		p = fp -> ptr[ NL_FVAR ];
15318347Smckusick 		stablvar( p , p -> value[ NL_OFFS ] , (int) lwidth( p -> type));
1543192Smckusick 	    }
1553192Smckusick 		/*
1563192Smckusick 		 *	stab local variables
1573192Smckusick 		 *	rummage down hash chain links.
1583192Smckusick 		 */
1593192Smckusick 	    for ( i = 0 ; i <= 077 ; i++ ) {
1603192Smckusick 		for ( p = disptab[ i ] ; p != NIL ; p = p->nl_next) {
1613192Smckusick 		    if ( ( p -> nl_block & 037 ) != cbn ) {
1623192Smckusick 			break;
1633192Smckusick 		    }
1643192Smckusick 		    /*
16518346Smckusick 		     *	stab locals (not parameters)
1663192Smckusick 		     */
16718347Smckusick 		    if ( p -> symbol != NIL ) {
16818347Smckusick 			if ( p -> class == VAR && p -> value[ NL_OFFS ] < 0 ) {
16918347Smckusick 			    stablvar( p , p -> value[ NL_OFFS ] ,
17018347Smckusick 				(int) lwidth( p -> type ) );
17118347Smckusick 			} else if ( p -> class == CONST ) {
17218347Smckusick 			    stabconst( p );
17318346Smckusick 			}
1743192Smckusick 		    }
1753192Smckusick 		}
1763192Smckusick 	    }
1773192Smckusick 	}
1783192Smckusick 	stablbrac( cbn );
1793192Smckusick 	    /*
1803192Smckusick 	     *	ask second pass to allocate known locals
1813192Smckusick 	     */
18211337Speter 	putlbracket(ftnno, &sizes[cbn]);
18310671Speter 	fp_entrycode(&eecookie);
1843192Smckusick #endif PC
1853192Smckusick 	if ( monflg ) {
1863192Smckusick 		if ( fp -> value[ NL_CNTR ] != 0 ) {
1873192Smckusick 			inccnt( fp -> value [ NL_CNTR ] );
1883192Smckusick 		}
1893192Smckusick 		inccnt( bodycnts[ fp -> nl_block & 037 ] );
1903192Smckusick 	}
1913192Smckusick 	if (fp->class == PROG) {
1923192Smckusick 		/*
1933192Smckusick 		 * The glorious buffers option.
1943192Smckusick 		 *          0 = don't buffer output
1953192Smckusick 		 *          1 = line buffer output
1963192Smckusick 		 *          2 = 512 byte buffer output
1973192Smckusick 		 */
1983192Smckusick #		ifdef OBJ
1993192Smckusick 		    if (opt('b') != 1)
20018347Smckusick 			    (void) put(1, O_BUFF | opt('b') << 8);
2013192Smckusick #		endif OBJ
2023192Smckusick #		ifdef PC
2033192Smckusick 		    if ( opt( 'b' ) != 1 ) {
204*18457Sralph 			putleaf( PCC_ICON , 0 , 0
205*18457Sralph 				, PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) , "_BUFF" );
206*18457Sralph 			putleaf( PCC_ICON , opt( 'b' ) , 0 , PCCT_INT , (char *) 0 );
207*18457Sralph 			putop( PCC_CALL , PCCT_INT );
2083192Smckusick 			putdot( filename , line );
2093192Smckusick 		    }
2103192Smckusick #		endif PC
2117953Speter 		inp = 0;
2123192Smckusick 		out = 0;
2133192Smckusick 		for (p = fp->chain; p != NIL; p = p->chain) {
21418347Smckusick 			if (pstrcmp(p->symbol, input->symbol) == 0) {
2153192Smckusick 				inp++;
2163192Smckusick 				continue;
2173192Smckusick 			}
21818347Smckusick 			if (pstrcmp(p->symbol, output->symbol) == 0) {
2193192Smckusick 				out++;
2203192Smckusick 				continue;
2213192Smckusick 			}
2223192Smckusick 			iop = lookup1(p->symbol);
2233192Smckusick 			if (iop == NIL || bn != cbn) {
2243192Smckusick 				error("File %s listed in program statement but not declared", p->symbol);
2253192Smckusick 				continue;
2263192Smckusick 			}
2273192Smckusick 			if (iop->class != VAR) {
2283192Smckusick 				error("File %s listed in program statement but declared as a %s", p->symbol, classes[iop->class]);
2293192Smckusick 				continue;
2303192Smckusick 			}
2313192Smckusick 			if (iop->type == NIL)
2323192Smckusick 				continue;
2333192Smckusick 			if (iop->type->class != FILET) {
2343192Smckusick 				error("File %s listed in program statement but defined as %s",
2353192Smckusick 					p->symbol, nameof(iop->type));
2363192Smckusick 				continue;
2373192Smckusick 			}
2383192Smckusick #			ifdef OBJ
23918347Smckusick 			    (void) put(2, O_CON24, text(iop->type) ? 0 : width(iop->type->type));
2403192Smckusick 			    i = lenstr(p->symbol,0);
24118347Smckusick 			    (void) put(2, O_CON24, i);
24218347Smckusick 			    (void) put(2, O_LVCON, i);
2433192Smckusick 			    putstr(p->symbol, 0);
24418347Smckusick 			    (void) put(2, O_LV | bn<<8+INDX, (int)iop->value[NL_OFFS]);
24518347Smckusick 			    (void) put(1, O_DEFNAME);
2463192Smckusick #			endif OBJ
2473192Smckusick #			ifdef PC
248*18457Sralph 			    putleaf( PCC_ICON , 0 , 0
249*18457Sralph 				    , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
2503192Smckusick 				    , "_DEFNAME" );
2513837Speter 			    putLV( p -> symbol , bn , iop -> value[NL_OFFS] ,
2523837Speter 				    iop -> extra_flags , p2type( iop ) );
2533192Smckusick 			    putCONG( p -> symbol , strlen( p -> symbol )
2543192Smckusick 				    , LREQ );
255*18457Sralph 			    putop( PCC_CM , PCCT_INT );
256*18457Sralph 			    putleaf( PCC_ICON , strlen( p -> symbol )
257*18457Sralph 				    , 0 , PCCT_INT , (char *) 0 );
258*18457Sralph 			    putop( PCC_CM , PCCT_INT );
259*18457Sralph 			    putleaf( PCC_ICON
2603192Smckusick 				, text(iop->type) ? 0 : width(iop->type->type)
261*18457Sralph 				, 0 , PCCT_INT , (char *) 0 );
262*18457Sralph 			    putop( PCC_CM , PCCT_INT );
263*18457Sralph 			    putop( PCC_CALL , PCCT_INT );
2643192Smckusick 			    putdot( filename , line );
2653192Smckusick #			endif PC
2663192Smckusick 		}
2673192Smckusick 	}
2683192Smckusick 	/*
2693192Smckusick 	 * Process the prog/proc/func body
2703192Smckusick 	 */
27118347Smckusick 	noreach = FALSE;
27218347Smckusick 	line = bundle->stmnt_blck.line_no;
2733192Smckusick 	statlist(blk);
2743192Smckusick #	ifdef PTREE
2753192Smckusick 	    {
2763192Smckusick 		pPointer Body = tCopy( blk );
2773192Smckusick 
2783192Smckusick 		pDEF( PorFHeader[ nesting -- ] ).PorFBody = Body;
2793192Smckusick 	    }
2803192Smckusick #	endif PTREE
2813192Smckusick #	ifdef OBJ
28218347Smckusick 	    if (cbn== 1 && monflg != FALSE) {
28318347Smckusick 		    patchfil((PTR_DCL) (cntpatch - 2), (long)cnts, 2);
28418347Smckusick 		    patchfil((PTR_DCL) (nfppatch - 2), (long)pfcnt, 2);
2853192Smckusick 	    }
2863192Smckusick #	endif OBJ
2873192Smckusick #	ifdef PC
2883192Smckusick 	    if ( fp -> class == PROG && monflg ) {
289*18457Sralph 		putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
2903192Smckusick 			, "_PMFLUSH" );
291*18457Sralph 		putleaf( PCC_ICON , cnts , 0 , PCCT_INT , (char *) 0 );
292*18457Sralph 		putleaf( PCC_ICON , pfcnt , 0 , PCCT_INT , (char *) 0 );
293*18457Sralph 		putop( PCC_CM , PCCT_INT );
294*18457Sralph 		putLV( PCPCOUNT , 0 , 0 , NGLOBAL , PCCT_INT );
295*18457Sralph 		putop( PCC_CM , PCCT_INT );
296*18457Sralph 		putop( PCC_CALL , PCCT_INT );
2973192Smckusick 		putdot( filename , line );
2983192Smckusick 	    }
2993192Smckusick #	endif PC
3007953Speter 	/*
3017953Speter 	 * Clean up the symbol table displays and check for unresolves
3027953Speter 	 */
3037953Speter 	line = endline;
3043192Smckusick 	if (fp->class == PROG && inp == 0 && (input->nl_flags & (NUSED|NMOD)) != 0) {
3053192Smckusick 		recovered();
3063192Smckusick 		error("Input is used but not defined in the program statement");
3073192Smckusick 	}
3087953Speter 	if (fp->class == PROG && out == 0 && (output->nl_flags & (NUSED|NMOD)) != 0) {
3097953Speter 		recovered();
3107953Speter 		error("Output is used but not defined in the program statement");
3117953Speter 	}
3123192Smckusick 	b = cbn;
3133192Smckusick 	Fp = fp;
31418347Smckusick 	chkref = (syneflg == errcnt[cbn] && opt('w') == 0)?TRUE:FALSE;
3153192Smckusick 	for (i = 0; i <= 077; i++) {
3163192Smckusick 		for (p = disptab[i]; p != NIL && (p->nl_block & 037) == b; p = p->nl_next) {
3173192Smckusick 			/*
3183192Smckusick 			 * Check for variables defined
3193192Smckusick 			 * but not referenced
3203192Smckusick 			 */
3213192Smckusick 			if (chkref && p->symbol != NIL)
3223192Smckusick 			switch (p->class) {
3233192Smckusick 				case FIELD:
3243192Smckusick 					/*
3253192Smckusick 					 * If the corresponding record is
3263192Smckusick 					 * unused, we shouldn't complain about
3273192Smckusick 					 * the fields.
3283192Smckusick 					 */
3293192Smckusick 				default:
3303192Smckusick 					if ((p->nl_flags & (NUSED|NMOD)) == 0) {
3313192Smckusick 						warning();
3323192Smckusick 						nerror("%s %s is neither used nor set", classes[p->class], p->symbol);
3333192Smckusick 						break;
3343192Smckusick 					}
3353192Smckusick 					/*
3363192Smckusick 					 * If a var parameter is either
3373192Smckusick 					 * modified or used that is enough.
3383192Smckusick 					 */
3393192Smckusick 					if (p->class == REF)
3403192Smckusick 						continue;
3413192Smckusick #					ifdef OBJ
3423192Smckusick 					    if ((p->nl_flags & NUSED) == 0) {
3433192Smckusick 						warning();
3443192Smckusick 						nerror("%s %s is never used", classes[p->class], p->symbol);
3453192Smckusick 						break;
3463192Smckusick 					    }
3473192Smckusick #					endif OBJ
3483192Smckusick #					ifdef PC
3493837Speter 					    if (((p->nl_flags & NUSED) == 0) && ((p->extra_flags & NEXTERN) == 0)) {
3503192Smckusick 						warning();
3513192Smckusick 						nerror("%s %s is never used", classes[p->class], p->symbol);
3523192Smckusick 						break;
3533192Smckusick 					    }
3543192Smckusick #					endif PC
3553192Smckusick 					if ((p->nl_flags & NMOD) == 0) {
3563192Smckusick 						warning();
3573192Smckusick 						nerror("%s %s is used but never set", classes[p->class], p->symbol);
3583192Smckusick 						break;
3593192Smckusick 					}
3603192Smckusick 				case LABEL:
3613192Smckusick 				case FVAR:
3623192Smckusick 				case BADUSE:
3633192Smckusick 					break;
3643192Smckusick 			}
3653192Smckusick 			switch (p->class) {
3663192Smckusick 				case BADUSE:
3673192Smckusick 					cp = "s";
36818347Smckusick 					/* This used to say ud_next
36918347Smckusick 					   that is not a member of nl so
37018347Smckusick 					   i changed it to nl_next,
37118347Smckusick 					   which may be wrong */
37218347Smckusick 					if (p->chain->nl_next == NIL)
3733192Smckusick 						cp++;
3743192Smckusick 					eholdnl();
3753192Smckusick 					if (p->value[NL_KINDS] & ISUNDEF)
3763192Smckusick 						nerror("%s undefined on line%s", p->symbol, cp);
3773192Smckusick 					else
3783192Smckusick 						nerror("%s improperly used on line%s", p->symbol, cp);
3793192Smckusick 					pnumcnt = 10;
38018347Smckusick 					pnums((struct udinfo *) p->chain);
3813192Smckusick 					pchr('\n');
3823192Smckusick 					break;
3833192Smckusick 
3843192Smckusick 				case FUNC:
3853192Smckusick 				case PROC:
3863192Smckusick #					ifdef OBJ
3873192Smckusick 					    if ((p->nl_flags & NFORWD))
3883192Smckusick 						nerror("Unresolved forward declaration of %s %s", classes[p->class], p->symbol);
3893192Smckusick #					endif OBJ
3903192Smckusick #					ifdef PC
3913837Speter 					    if ((p->nl_flags & NFORWD) && ((p->extra_flags & NEXTERN) == 0))
3923192Smckusick 						nerror("Unresolved forward declaration of %s %s", classes[p->class], p->symbol);
3933192Smckusick #					endif PC
3943192Smckusick 					break;
3953192Smckusick 
3963192Smckusick 				case LABEL:
3973192Smckusick 					if (p->nl_flags & NFORWD)
3983192Smckusick 						nerror("label %s was declared but not defined", p->symbol);
3993192Smckusick 					break;
4003192Smckusick 				case FVAR:
4013192Smckusick 					if ((p->nl_flags & NMOD) == 0)
4023192Smckusick 						nerror("No assignment to the function variable");
4033192Smckusick 					break;
4043192Smckusick 			}
4053192Smckusick 		}
4063192Smckusick 		/*
4073192Smckusick 		 * Pop this symbol
4083192Smckusick 		 * table slot
4093192Smckusick 		 */
4103192Smckusick 		disptab[i] = p;
4113192Smckusick 	}
4123192Smckusick 
4133192Smckusick #	ifdef OBJ
41418347Smckusick 	    (void) put(1, O_END);
4153192Smckusick #	endif OBJ
4163192Smckusick #	ifdef PC
41710671Speter 	    fp_exitcode(&eecookie);
41810671Speter 	    stabrbrac(cbn);
41910671Speter 	    putrbracket(ftnno);
42010671Speter 	    fp_epilogue(&eecookie);
42110671Speter 	    if (fp -> class != PROG) {
42210671Speter 		fp_formalentry(&eecookie);
4233192Smckusick 	    }
4243192Smckusick 		/*
4253192Smckusick 		 *	declare pcp counters, if any
4263192Smckusick 		 */
4273192Smckusick 	    if ( monflg && fp -> class == PROG ) {
4283192Smckusick 		putprintf( "	.data" , 0 );
429*18457Sralph 		aligndot(PCCT_INT);
4303192Smckusick 		putprintf( "	.comm	" , 1 );
4313192Smckusick 		putprintf( PCPCOUNT , 1 );
4323192Smckusick 		putprintf( ",%d" , 0 , ( cnts + 1 ) * sizeof (long) );
4333192Smckusick 		putprintf( "	.text" , 0 );
4343192Smckusick 	    }
4353192Smckusick #	endif PC
4363192Smckusick #ifdef DEBUG
43718347Smckusick 	dumpnl(fp->ptr[2], (int) fp->symbol);
4383192Smckusick #endif
4395654Slinton 
4405654Slinton #ifdef OBJ
4413192Smckusick 	/*
4425654Slinton 	 * save the namelist for the debugger pdx
4435654Slinton 	 */
4445654Slinton 
44518347Smckusick 	savenl(fp->ptr[2], (int) fp->symbol);
4465654Slinton #endif
4475654Slinton 
4485654Slinton 	/*
4493192Smckusick 	 * Restore the
4503192Smckusick 	 * (virtual) name list
4513192Smckusick 	 * position
4523192Smckusick 	 */
4533192Smckusick 	nlfree(fp->ptr[2]);
4543192Smckusick 	/*
4553192Smckusick 	 * Proc/func has been
4563192Smckusick 	 * resolved
4573192Smckusick 	 */
4583192Smckusick 	fp->nl_flags &= ~NFORWD;
4593192Smckusick 	/*
4603192Smckusick 	 * Patch the beg
4613192Smckusick 	 * of the proc/func to
4623192Smckusick 	 * the proper variable size
4633192Smckusick 	 */
4643192Smckusick 	if (Fp == NIL)
4653192Smckusick 		elineon();
4663192Smckusick #	ifdef OBJ
46718347Smckusick 	    patchfil((PTR_DCL) var, leven(-sizes[cbn].om_max), 2);
4683192Smckusick #	endif OBJ
4693192Smckusick 	cbn--;
4703192Smckusick 	if (inpflist(fp->symbol)) {
4713192Smckusick 		opop('l');
4723192Smckusick 	}
4733192Smckusick }
4743363Speter 
4753363Speter #ifdef PC
4763363Speter     /*
4773363Speter      *	construct the long name of a function based on it's static nesting.
4783363Speter      *	into a caller-supplied buffer (that should be about BUFSIZ big).
4793363Speter      */
4803363Speter sextname( buffer , name , level )
4813363Speter     char	buffer[];
4823363Speter     char	*name;
4833363Speter     int		level;
4843363Speter {
4853363Speter     char	*starthere;
4863363Speter     int	i;
4873363Speter 
4883363Speter     starthere = &buffer[0];
4893363Speter     for ( i = 1 ; i < level ; i++ ) {
4903363Speter 	sprintf( starthere , EXTFORMAT , enclosing[ i ] );
4913363Speter 	starthere += strlen( enclosing[ i ] ) + 1;
4923363Speter     }
4933367Speter     sprintf( starthere , EXTFORMAT , name );
4943367Speter     starthere += strlen( name ) + 1;
4953363Speter     if ( starthere >= &buffer[ BUFSIZ ] ) {
4963363Speter 	panic( "sextname" );
4973363Speter     }
4983363Speter }
49910671Speter 
50010671Speter     /*
50110671Speter      *	code for main()
50210671Speter      */
50310671Speter #ifdef vax
50410671Speter 
50510671Speter codeformain()
50610671Speter {
50710671Speter     putprintf("	.text" , 0 );
50810671Speter     putprintf("	.align	1" , 0 );
50910671Speter     putprintf("	.globl	_main" , 0 );
51010671Speter     putprintf("_main:" , 0 );
51110671Speter     putprintf("	.word	0" , 0 );
51210671Speter     if ( opt ( 't' ) ) {
51310671Speter 	putprintf("	pushl	$1" , 0 );
51410671Speter     } else {
51510671Speter 	putprintf("	pushl	$0" , 0 );
51610671Speter     }
51710671Speter     putprintf("	calls	$1,_PCSTART" , 0 );
51810671Speter     putprintf("	movl	4(ap),__argc" , 0 );
51910671Speter     putprintf("	movl	8(ap),__argv" , 0 );
52010671Speter     putprintf("	calls	$0,_program" , 0 );
52110671Speter     putprintf("	pushl	$0" , 0 );
52210671Speter     putprintf("	calls	$1,_PCEXIT" , 0 );
52310671Speter }
52410671Speter 
52510671Speter     /*
52610671Speter      *	prologue for the program.
52710671Speter      *	different because it
52810671Speter      *		doesn't have formal entry point
52910671Speter      */
53010671Speter prog_prologue(eecookiep)
53110671Speter     struct entry_exit_cookie	*eecookiep;
53210671Speter {
53310671Speter     putprintf("	.text" , 0 );
53410671Speter     putprintf("	.align	1" , 0 );
53510671Speter     putprintf("	.globl	_program" , 0 );
53610671Speter     putprintf("_program:" , 0 );
53710716Speter 	/*
53810716Speter 	 *	register save mask
53910716Speter 	 */
54018347Smckusick     eecookiep -> savlabel = (int) getlab();
54118347Smckusick     putprintf("	.word	%s%d", 0, (int) SAVE_MASK_LABEL , eecookiep -> savlabel );
54210671Speter }
54310671Speter 
54410671Speter fp_prologue(eecookiep)
54510671Speter     struct entry_exit_cookie	*eecookiep;
54610671Speter {
54710671Speter 
54810671Speter     sextname( eecookiep -> extname, eecookiep -> nlp -> symbol , cbn - 1 );
54910671Speter     putprintf( "	.text" , 0 );
55010671Speter     putprintf( "	.align	1" , 0 );
55118347Smckusick     putprintf( "	.globl	%s%s", 0, (int) FORMALPREFIX, (int) eecookiep -> extname );
55218347Smckusick     putprintf( "	.globl	%s" , 0 , (int) eecookiep -> extname );
55318347Smckusick     putprintf( "%s:" , 0 , (int) eecookiep -> extname );
55410671Speter 	/*
55510671Speter 	 *	register save mask
55610671Speter 	 */
55718347Smckusick     eecookiep -> savlabel = (int) getlab();
55818347Smckusick     putprintf("	.word	%s%d", 0, (int) SAVE_MASK_LABEL , eecookiep -> savlabel );
55910671Speter }
56010671Speter 
56110671Speter     /*
56210671Speter      *	code before any user code.
56310671Speter      *	or code that is machine dependent.
56410671Speter      */
56510671Speter fp_entrycode(eecookiep)
56610671Speter     struct entry_exit_cookie	*eecookiep;
56710671Speter {
56810714Speter     int	ftnno = eecookiep -> nlp -> value[NL_ENTLOC];
56918347Smckusick     int	proflabel = (int) getlab();
57018347Smckusick     int	setjmp0 = (int) getlab();
57110671Speter 
57210671Speter 	/*
57310671Speter 	 *	top of code;  destination of jump from formal entry code.
57410671Speter 	 */
57518347Smckusick     eecookiep -> toplabel = (int) getlab();
57618347Smckusick     (void) putlab( (char *) eecookiep -> toplabel );
57718347Smckusick     putprintf("	subl2	$%s%d,sp" , 0 , (int) FRAME_SIZE_LABEL, ftnno );
57810671Speter     if ( profflag ) {
57910671Speter 	    /*
58010671Speter 	     *	call mcount for profiling
58110671Speter 	     */
58210671Speter 	putprintf( "	moval	" , 1 );
58318347Smckusick 	putprintf( PREFIXFORMAT , 1 , (int) LABELPREFIX , proflabel );
58410671Speter 	putprintf( ",r0" , 0 );
58510671Speter 	putprintf( "	jsb	mcount" , 0 );
58610671Speter 	putprintf( "	.data" , 0 );
58710671Speter 	putprintf( "	.align	2" , 0 );
58818347Smckusick 	(void) putlab( (char *) proflabel );
58910671Speter 	putprintf( "	.long	0" , 0 );
59010671Speter 	putprintf( "	.text" , 0 );
59110671Speter     }
59210671Speter 	/*
59310671Speter 	 *	if there are nested procedures that access our variables
59410671Speter 	 *	we must save the display.
59510671Speter 	 */
59610671Speter     if ( parts[ cbn ] & NONLOCALVAR ) {
59710671Speter 	    /*
59810671Speter 	     *	save old display
59910671Speter 	     */
60010671Speter 	putprintf( "	movq	%s+%d,%d(%s)" , 0
60118347Smckusick 		, (int) DISPLAYNAME , cbn * sizeof(struct dispsave)
60218347Smckusick 		, DSAVEOFFSET , (int) P2FPNAME );
60310671Speter 	    /*
60410671Speter 	     *	set up new display by saving AP and FP in appropriate
60510671Speter 	     *	slot in display structure.
60610671Speter 	     */
60710671Speter 	putprintf( "	movq	%s,%s+%d" , 0
60818347Smckusick 		, (int) P2APNAME , (int) DISPLAYNAME , cbn * sizeof(struct dispsave) );
60910671Speter     }
61010671Speter 	/*
61110671Speter 	 *	set underflow checking if runtime tests
61210671Speter 	 */
61310671Speter     if ( opt( 't' ) ) {
61410671Speter 	putprintf( "	bispsw	$0xe0" , 0 );
61510671Speter     }
61610671Speter 	/*
61710671Speter 	 *	zero local variables if checking is on
61810671Speter 	 *	by calling blkclr( bytes of locals , starting local address );
61910671Speter 	 */
62010671Speter     if ( opt( 't' ) && ( -sizes[ cbn ].om_max ) > DPOFF1 ) {
621*18457Sralph 	putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
62210671Speter 		, "_blkclr" );
623*18457Sralph 	putLV((char *) 0 , cbn , (int) sizes[ cbn ].om_max , NLOCAL , PCCT_CHAR );
624*18457Sralph 	putleaf( PCC_ICON ,  (int) (( -sizes[ cbn ].om_max ) - DPOFF1)
625*18457Sralph 		, 0 , PCCT_INT ,(char *) 0 );
626*18457Sralph 	putop( PCC_CM , PCCT_INT );
627*18457Sralph 	putop( PCC_CALL , PCCT_INT );
62810671Speter 	putdot( filename , line );
62910671Speter     }
63010671Speter 	/*
63110671Speter 	 *  set up goto vector if non-local goto to this frame
63210671Speter 	 */
63310671Speter     if ( parts[ cbn ] & NONLOCALGOTO ) {
634*18457Sralph 	putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
63510671Speter 		, "_setjmp" );
636*18457Sralph 	putLV( (char *) 0 , cbn , GOTOENVOFFSET , NLOCAL , PCCTM_PTR|PCCT_STRTY );
637*18457Sralph 	putop( PCC_CALL , PCCT_INT );
638*18457Sralph 	putleaf( PCC_ICON , 0 , 0 , PCCT_INT , (char *) 0 );
639*18457Sralph 	putop( PCC_NE , PCCT_INT );
640*18457Sralph 	putleaf( PCC_ICON , setjmp0 , 0 , PCCT_INT , (char *) 0 );
641*18457Sralph 	putop( PCC_CBRANCH , PCCT_INT );
64210671Speter 	putdot( filename , line );
64310671Speter 	    /*
64410671Speter 	     *	on non-local goto, setjmp returns with address to
64510671Speter 	     *	be branched to.
64610671Speter 	     */
64710671Speter 	putprintf( "	jmp	(r0)" , 0 );
64818347Smckusick 	(void) putlab((char *) setjmp0);
64910671Speter     }
65010671Speter }
65110671Speter 
65210671Speter fp_exitcode(eecookiep)
65310671Speter     struct entry_exit_cookie	*eecookiep;
65410671Speter {
65510671Speter 	/*
65610671Speter 	 *	if there were file variables declared at this level
65710671Speter 	 *	call PCLOSE( ap ) to clean them up.
65810671Speter 	 */
65910671Speter     if ( dfiles[ cbn ] ) {
660*18457Sralph 	putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
66110671Speter 		, "_PCLOSE" );
662*18457Sralph 	putleaf( PCC_REG , 0 , P2AP , PCCM_ADDTYPE( PCCT_CHAR , PCCTM_PTR ) , (char *) 0 );
663*18457Sralph 	putop( PCC_CALL , PCCT_INT );
66410671Speter 	putdot( filename , line );
66510671Speter     }
66610671Speter 	/*
66710671Speter 	 *	if this is a function,
66810671Speter 	 *	the function variable is the return value.
66910671Speter 	 *	if it's a scalar valued function, return scalar,
67010671Speter 	 *	else, return a pointer to the structure value.
67110671Speter 	 */
67210671Speter     if ( eecookiep-> nlp -> class == FUNC ) {
67310671Speter 	struct nl	*fvar = eecookiep-> nlp -> ptr[ NL_FVAR ];
67410671Speter 	long		fvartype = p2type( fvar -> type );
67510671Speter 	long		label;
67610671Speter 	char		labelname[ BUFSIZ ];
67710671Speter 
67810671Speter 	switch ( classify( fvar -> type ) ) {
67910671Speter 	    case TBOOL:
68010671Speter 	    case TCHAR:
68110671Speter 	    case TINT:
68210671Speter 	    case TSCAL:
68310671Speter 	    case TDOUBLE:
68410671Speter 	    case TPTR:
68510671Speter 		putRV( fvar -> symbol , ( fvar -> nl_block ) & 037 ,
68610671Speter 			fvar -> value[ NL_OFFS ] ,
68710671Speter 			fvar -> extra_flags ,
68818347Smckusick 			(int) fvartype );
689*18457Sralph 		putop( PCC_FORCE , (int) fvartype );
69010671Speter 		break;
69110671Speter 	    default:
69218347Smckusick 		label = (int) getlab();
69310671Speter 		sprintf( labelname , PREFIXFORMAT , LABELPREFIX , label );
69410671Speter 		putprintf( "	.data" , 0 );
69510671Speter 		aligndot(A_STRUCT);
69610671Speter 		putprintf( "	.lcomm	%s,%d" , 0 ,
69718347Smckusick 			    (int) labelname , (int) lwidth( fvar -> type ) );
69810671Speter 		putprintf( "	.text" , 0 );
699*18457Sralph 		putleaf( PCC_NAME , 0 , 0 , (int) fvartype , labelname );
70010671Speter 		putLV( fvar -> symbol , ( fvar -> nl_block ) & 037 ,
70110671Speter 			fvar -> value[ NL_OFFS ] ,
70210671Speter 			fvar -> extra_flags ,
70318347Smckusick 			(int) fvartype );
704*18457Sralph 		putstrop( PCC_STASG , (int) PCCM_ADDTYPE(fvartype, PCCTM_PTR) ,
70518347Smckusick 			(int) lwidth( fvar -> type ) ,
70610671Speter 			align( fvar -> type ) );
70710671Speter 		putdot( filename , line );
708*18457Sralph 		putleaf( PCC_ICON , 0 , 0 , (int) PCCM_ADDTYPE(fvartype, PCCTM_PTR), labelname );
709*18457Sralph 		putop( PCC_FORCE , (int) PCCM_ADDTYPE(fvartype, PCCTM_PTR) );
71010671Speter 		break;
71110671Speter 	}
71210671Speter 	putdot( filename , line );
71310671Speter     }
71410671Speter 	/*
71510671Speter 	 *	if there are nested procedures we must save the display.
71610671Speter 	 */
71710671Speter     if ( parts[ cbn ] & NONLOCALVAR ) {
71810671Speter 	    /*
71910671Speter 	     *	restore old display entry from save area
72010671Speter 	     */
72110671Speter 	putprintf( "	movq	%d(%s),%s+%d" , 0
72218347Smckusick 	    , DSAVEOFFSET , (int) P2FPNAME
72318347Smckusick 	    , (int) DISPLAYNAME , cbn * sizeof(struct dispsave) );
72410671Speter     }
72510671Speter }
72610671Speter 
72710671Speter fp_epilogue(eecookiep)
72810671Speter     struct entry_exit_cookie	*eecookiep;
72910671Speter {
73018346Smckusick     stabline(line);
73110671Speter     putprintf("	ret" , 0 );
73210671Speter 	/*
73310671Speter 	 *	set the register save mask.
73410671Speter 	 */
73510671Speter     putprintf("	.set	%s%d,0x%x", 0,
73618347Smckusick 		(int) SAVE_MASK_LABEL, eecookiep -> savlabel, savmask());
73710671Speter }
73810671Speter 
73910671Speter fp_formalentry(eecookiep)
74010671Speter     struct entry_exit_cookie	*eecookiep;
74110671Speter {
74210671Speter 
74311857Speter     putprintf("	.align 1", 0);
74418347Smckusick     putprintf("%s%s:" , 0 , (int) FORMALPREFIX , (int) eecookiep -> extname );
74518347Smckusick     putprintf("	.word	%s%d", 0, (int) SAVE_MASK_LABEL, eecookiep -> savlabel );
746*18457Sralph     putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) , "_FCALL" );
74718347Smckusick     putRV((char *) 0 , cbn ,
74810671Speter 	eecookiep -> nlp -> value[ NL_OFFS ] + sizeof( struct formalrtn * ) ,
749*18457Sralph 	NPARAM , PCCTM_PTR | PCCT_STRTY );
750*18457Sralph     putRV((char *) 0, cbn, eecookiep -> nlp -> value[NL_OFFS], NPARAM, PCCTM_PTR|PCCT_STRTY);
751*18457Sralph     putop( PCC_CM , PCCT_INT );
752*18457Sralph     putop( PCC_CALL , PCCT_INT );
75310671Speter     putdot( filename , line );
75418347Smckusick     putjbr( (long) eecookiep -> toplabel );
75510671Speter }
75610671Speter #endif vax
75710671Speter 
75810671Speter #ifdef mc68000
75910671Speter 
76010671Speter codeformain()
76110671Speter {
76210671Speter     putprintf("	.text", 0);
76310671Speter     putprintf("	.globl	_main", 0);
76410671Speter     putprintf("_main:", 0);
76510671Speter     putprintf("	link	%s,#0", 0, P2FPNAME);
76610671Speter     if (opt('t')) {
76710671Speter 	putprintf("	pea	1", 0);
76810671Speter     } else {
76910671Speter 	putprintf("	pea	0", 0);
77010671Speter     }
77110671Speter     putprintf("	jbsr	_PCSTART", 0);
77210671Speter     putprintf("	addql	#4,sp", 0);
77310671Speter     putprintf("	movl	%s@(8),__argc", 0, P2FPNAME);
77410671Speter     putprintf("	movl	%s@(12),__argv", 0, P2FPNAME);
77510671Speter     putprintf("	jbsr	_program", 0);
77610671Speter     putprintf("	pea	0", 0);
77710671Speter     putprintf("	jbsr	_PCEXIT", 0);
77810671Speter }
77910671Speter 
78010671Speter prog_prologue(eecookiep)
78110671Speter     struct entry_exit_cookie	*eecookiep;
78210671Speter {
78310671Speter     int	ftnno = eecookiep -> nlp -> value[NL_ENTLOC];
78410671Speter 
78510671Speter     putprintf("	.text", 0);
78610671Speter     putprintf("	.globl	_program", 0);
78710671Speter     putprintf("_program:", 0);
78810671Speter     putprintf("	link	%s,#0", 0, P2FPNAME);
78910671Speter     putprintf("	addl	#-%s%d,sp", 0, FRAME_SIZE_LABEL, ftnno);
79010671Speter 	/* touch new end of stack, to break more stack space */
79110671Speter     putprintf("	tstb	sp@(-%s%d)", 0, PAGE_BREAK_LABEL, ftnno);
79210671Speter     putprintf("	moveml	#%s%d,sp@", 0, SAVE_MASK_LABEL, ftnno);
79310671Speter }
79410671Speter 
79510671Speter fp_prologue(eecookiep)
79610671Speter     struct entry_exit_cookie	*eecookiep;
79710671Speter {
79810671Speter     int		ftnno = eecookiep -> nlp -> value[NL_ENTLOC];
79910671Speter 
80010671Speter     sextname(eecookiep -> extname, eecookiep -> nlp -> symbol, cbn - 1);
80110671Speter     putprintf("	.text", 0);
80210671Speter     putprintf("	.globl	%s%s", 0, FORMALPREFIX, eecookiep -> extname);
80310671Speter     putprintf("	.globl	%s", 0, eecookiep -> extname);
80410671Speter     putprintf("%s:", 0, eecookiep -> extname);
80510671Speter     putprintf("	link	%s,#0", 0, P2FPNAME);
80610671Speter     putprintf("	addl	#-%s%d,sp", 0, FRAME_SIZE_LABEL, ftnno);
80710671Speter 	/* touch new end of stack, to break more stack space */
80810671Speter     putprintf("	tstb	sp@(-%s%d)", 0, PAGE_BREAK_LABEL, ftnno);
80910671Speter     putprintf("	moveml	#%s%d,sp@", 0, SAVE_MASK_LABEL, ftnno);
81010671Speter }
81110671Speter 
81210671Speter fp_entrycode(eecookiep)
81310671Speter     struct entry_exit_cookie	*eecookiep;
81410671Speter {
81518347Smckusick     char *proflabel = getlab();
81618347Smckusick     char *setjmp0 = getlab();
81710671Speter 
81810671Speter 	/*
81910671Speter 	 *	fill in the label cookie
82010671Speter 	 */
82110671Speter     eecookiep -> toplabel = getlab();
82218347Smckusick     (void) putlab(eecookiep -> toplabel);
82310671Speter 	/*
82410671Speter 	 *	call mcount if we are profiling.
82510671Speter 	 */
82610671Speter     if ( profflag ) {
82710671Speter 	putprintf("	movl	#%s%d,a0", 0, LABELPREFIX,  proflabel);
82810671Speter 	putprintf("	jsr	mcount", 0);
82910671Speter 	putprintf("	.data", 0);
83010671Speter 	putprintf("	.even", 0);
83118347Smckusick 	(void) putlab(proflabel);
83210671Speter 	putprintf("	.long	0", 0);
83310671Speter 	putprintf("	.text", 0);
83410671Speter     }
83510671Speter 	/*
83610671Speter 	 *	if there are nested procedures that access our variables
83710671Speter 	 *	we must save the display
83810671Speter 	 */
83910671Speter     if (parts[cbn] & NONLOCALVAR) {
84010671Speter 	    /*
84110671Speter 	     *	save the old display
84210671Speter 	     */
84310671Speter 	putprintf("	movl	%s+%d,%s@(%d)", 0,
84410671Speter 		    DISPLAYNAME, cbn * sizeof(struct dispsave),
84510671Speter 		    P2FPNAME, DSAVEOFFSET);
84610671Speter 	    /*
84710671Speter 	     *	set up the new display by saving the framepointer
84810671Speter 	     *	in the display structure.
84910671Speter 	     */
85010671Speter 	putprintf("	movl	%s,%s+%d", 0,
85110671Speter 		    P2FPNAME, DISPLAYNAME, cbn * sizeof(struct dispsave));
85210671Speter     }
85310671Speter 	/*
85410671Speter 	 *	zero local variables if checking is on
85510671Speter 	 *	by calling blkclr( bytes of locals , starting local address );
85610671Speter 	 */
85710671Speter     if ( opt( 't' ) && ( -sizes[ cbn ].om_max ) > DPOFF1 ) {
858*18457Sralph 	putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
85910671Speter 		, "_blkclr" );
860*18457Sralph 	putLV( 0 , cbn , sizes[ cbn ].om_max , NLOCAL , PCCT_CHAR );
861*18457Sralph 	putleaf( PCC_ICON ,  ( -sizes[ cbn ].om_max ) - DPOFF1
862*18457Sralph 		, 0 , PCCT_INT , 0 );
863*18457Sralph 	putop( PCC_CM , PCCT_INT );
864*18457Sralph 	putop( PCC_CALL , PCCT_INT );
86510671Speter 	putdot( filename , line );
86610671Speter     }
86710671Speter 	/*
86810671Speter 	 *  set up goto vector if non-local goto to this frame
86910671Speter 	 */
87010671Speter     if ( parts[ cbn ] & NONLOCALGOTO ) {
871*18457Sralph 	putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
87210671Speter 		, "_setjmp" );
873*18457Sralph 	putLV( 0 , cbn , GOTOENVOFFSET , NLOCAL , PCCTM_PTR|PCCT_STRTY );
874*18457Sralph 	putop( PCC_CALL , PCCT_INT );
875*18457Sralph 	putleaf( PCC_ICON , 0 , 0 , PCCT_INT , 0 );
876*18457Sralph 	putop( PCC_NE , PCCT_INT );
877*18457Sralph 	putleaf( PCC_ICON , setjmp0 , 0 , PCCT_INT , 0 );
878*18457Sralph 	putop( PCC_CBRANCH , PCCT_INT );
87910671Speter 	putdot( filename , line );
88010671Speter 	    /*
88110671Speter 	     *	on non-local goto, setjmp returns with address to
88210671Speter 	     *	be branched to.
88310671Speter 	     */
88410671Speter 	putprintf("	movl	d0,a0", 0);
88510671Speter 	putprintf("	jmp	a0@", 0);
88618347Smckusick 	(void) putlab(setjmp0);
88710671Speter     }
88810671Speter }
88910671Speter 
89010671Speter fp_exitcode(eecookiep)
89110671Speter     struct entry_exit_cookie	*eecookiep;
89210671Speter {
89310671Speter 	/*
89410671Speter 	 *	if there were file variables declared at this level
89510671Speter 	 *	call PCLOSE( ap ) to clean them up.
89610671Speter 	 */
89710671Speter     if ( dfiles[ cbn ] ) {
898*18457Sralph 	putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
89910671Speter 		, "_PCLOSE" );
900*18457Sralph 	putleaf( PCC_REG , 0 , P2AP , PCCM_ADDTYPE( PCCT_CHAR , PCCTM_PTR ) , 0 );
901*18457Sralph 	putop( PCC_CALL , PCCT_INT );
90210671Speter 	putdot( filename , line );
90310671Speter     }
90410671Speter 	/*
90510671Speter 	 *	if this is a function,
90610671Speter 	 *	the function variable is the return value.
90710671Speter 	 *	if it's a scalar valued function, return scalar,
90810671Speter 	 *	else, return a pointer to the structure value.
90910671Speter 	 */
91010671Speter     if ( eecookiep -> nlp -> class == FUNC ) {
91110671Speter 	struct nl	*fvar = eecookiep -> nlp -> ptr[ NL_FVAR ];
91210671Speter 	long		fvartype = p2type( fvar -> type );
91318347Smckusick 	char		*label;
91410671Speter 	char		labelname[ BUFSIZ ];
91510671Speter 
91610671Speter 	switch ( classify( fvar -> type ) ) {
91710671Speter 	    case TBOOL:
91810671Speter 	    case TCHAR:
91910671Speter 	    case TINT:
92010671Speter 	    case TSCAL:
92110671Speter 	    case TDOUBLE:
92210671Speter 	    case TPTR:
92310671Speter 		putRV( fvar -> symbol , ( fvar -> nl_block ) & 037 ,
92410671Speter 			fvar -> value[ NL_OFFS ] ,
92510671Speter 			fvar -> extra_flags ,
92610671Speter 			fvartype );
927*18457Sralph 		putop( PCC_FORCE , fvartype );
92810671Speter 		break;
92910671Speter 	    default:
93010671Speter 		label = getlab();
93110671Speter 		sprintf( labelname , PREFIXFORMAT , LABELPREFIX , label );
93210671Speter 		putprintf("	.lcomm	%s,%d", 0,
93310671Speter 			labelname, lwidth(fvar -> type));
934*18457Sralph 		putleaf( PCC_NAME , 0 , 0 , fvartype , labelname );
93510671Speter 		putLV( fvar -> symbol , ( fvar -> nl_block ) & 037 ,
93610671Speter 			fvar -> value[ NL_OFFS ] ,
93710671Speter 			fvar -> extra_flags ,
93810671Speter 			fvartype );
939*18457Sralph 		putstrop( PCC_STASG , PCCM_ADDTYPE(fvartype, PCCTM_PTR) ,
94011857Speter 			lwidth( fvar -> type ) ,
94110671Speter 			align( fvar -> type ) );
94210671Speter 		putdot( filename , line );
943*18457Sralph 		putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE(fvartype, PCCTM_PTR), labelname );
944*18457Sralph 		putop( PCC_FORCE , PCCM_ADDTYPE(fvartype, PCCTM_PTR) );
94510671Speter 		break;
94610671Speter 	}
94710671Speter 	putdot( filename , line );
94810671Speter     }
94910671Speter 	/*
95010671Speter 	 *	if we saved a display, we must restore it.
95110671Speter 	 */
95210671Speter     if ( parts[ cbn ] & NONLOCALVAR ) {
95310671Speter 	    /*
95410671Speter 	     *	restore old display entry from save area
95510671Speter 	     */
95610671Speter 	putprintf("	movl	%s@(%d),%s+%d", 0,
95710671Speter 		    P2FPNAME, DSAVEOFFSET,
95810671Speter 		    DISPLAYNAME, cbn * sizeof(struct dispsave));
95910671Speter     }
96010671Speter }
96110671Speter 
96210671Speter fp_epilogue(eecookiep)
96310671Speter     struct entry_exit_cookie	*eecookiep;
96410671Speter {
96510671Speter     /*
96610671Speter      *	all done by the second pass.
96710671Speter      */
96810671Speter }
96910671Speter 
97010671Speter fp_formalentry(eecookiep)
97110671Speter     struct entry_exit_cookie	*eecookiep;
97210671Speter {
97310671Speter     putprintf( "%s%s:" , 0 , FORMALPREFIX , eecookiep -> extname );
97410671Speter     putprintf("	link	%s,#0", 0, P2FPNAME);
97510671Speter     putprintf("	addl	#-%s%d,sp", 0, FRAME_SIZE_LABEL, ftnno);
97610671Speter 	/* touch new end of stack, to break more stack space */
97710671Speter     putprintf("	tstb	sp@(-%s%d)", 0, PAGE_BREAK_LABEL, ftnno);
97810671Speter     putprintf("	moveml	#%s%d,sp@", 0, SAVE_MASK_LABEL, ftnno);
979*18457Sralph     putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) , "_FCALL" );
98010671Speter     putRV( 0 , cbn ,
98110671Speter 	eecookiep -> nlp -> value[ NL_OFFS ] + sizeof( struct formalrtn * ) ,
982*18457Sralph 	NPARAM , PCCTM_PTR | PCCT_STRTY );
983*18457Sralph     putRV(0, cbn, eecookiep -> nlp -> value[NL_OFFS], NPARAM, PCCTM_PTR|PCCT_STRTY);
984*18457Sralph     putop( PCC_CM , PCCT_INT );
985*18457Sralph     putop( PCC_CALL , PCCT_INT );
98610671Speter     putdot( filename , line );
98710671Speter     putjbr( eecookiep -> toplabel );
98810671Speter }
98910671Speter #endif mc68000
9903363Speter #endif PC
991