xref: /csrg-svn/usr.bin/pascal/src/fend.c (revision 10671)
13192Smckusick /* Copyright (c) 1979 Regents of the University of California */
23192Smckusick 
3*10671Speter static char sccsid[] = "@(#)fend.c 1.18 02/01/83";
43192Smckusick 
53192Smckusick #include "whoami.h"
63192Smckusick #include "0.h"
73192Smckusick #include "tree.h"
83192Smckusick #include "opcode.h"
93192Smckusick #include "objfmt.h"
103192Smckusick #include "align.h"
113192Smckusick 
123192Smckusick /*
133192Smckusick  * this array keeps the pxp counters associated with
143192Smckusick  * functions and procedures, so that they can be output
153192Smckusick  * when their bodies are encountered
163192Smckusick  */
173192Smckusick int	bodycnts[ DSPLYSZ ];
183192Smckusick 
193192Smckusick #ifdef PC
203192Smckusick #   include "pc.h"
213192Smckusick #   include "pcops.h"
223192Smckusick #endif PC
233192Smckusick 
243192Smckusick #ifdef OBJ
253192Smckusick int	cntpatch;
263192Smckusick int	nfppatch;
273192Smckusick #endif OBJ
283192Smckusick 
293192Smckusick struct	nl *Fp;
303192Smckusick int	pnumcnt;
313192Smckusick /*
323192Smckusick  * Funcend is called to
333192Smckusick  * finish a block by generating
343192Smckusick  * the code for the statements.
353192Smckusick  * It then looks for unresolved declarations
363192Smckusick  * of labels, procedures and functions,
373192Smckusick  * and cleans up the name list.
383192Smckusick  * For the program, it checks the
393192Smckusick  * semantics of the program
403192Smckusick  * statement (yuchh).
413192Smckusick  */
423192Smckusick funcend(fp, bundle, endline)
433192Smckusick 	struct nl *fp;
443192Smckusick 	int *bundle;
453192Smckusick 	int endline;
463192Smckusick {
473192Smckusick 	register struct nl *p;
483192Smckusick 	register int i, b;
493192Smckusick 	int var, inp, out, *blk;
503192Smckusick 	bool chkref;
513192Smckusick 	struct nl *iop;
523192Smckusick 	char *cp;
533192Smckusick 	extern int cntstat;
543192Smckusick #	ifdef PC
55*10671Speter 	    struct entry_exit_cookie	eecookie;
563192Smckusick #	endif PC
573192Smckusick 
583192Smckusick 	cntstat = 0;
593192Smckusick /*
603192Smckusick  *	yyoutline();
613192Smckusick  */
623192Smckusick 	if (program != NIL)
633192Smckusick 		line = program->value[3];
643192Smckusick 	blk = bundle[2];
653192Smckusick 	if (fp == NIL) {
663192Smckusick 		cbn--;
673192Smckusick #		ifdef PTREE
683192Smckusick 		    nesting--;
693192Smckusick #		endif PTREE
703192Smckusick 		return;
713192Smckusick 	}
723192Smckusick #ifdef OBJ
733192Smckusick 	/*
743192Smckusick 	 * Patch the branch to the
753192Smckusick 	 * entry point of the function
763192Smckusick 	 */
777917Smckusick 	patch4(fp->value[NL_ENTLOC]);
783192Smckusick 	/*
793192Smckusick 	 * Put out the block entrance code and the block name.
803192Smckusick 	 * HDRSZE is the number of bytes of info in the static
813192Smckusick 	 * BEG data area exclusive of the proc name. It is
823192Smckusick 	 * currently defined as:
833192Smckusick 	/*	struct hdr {
843192Smckusick 	/*		long framesze;	/* number of bytes of local vars */
853192Smckusick 	/*		long nargs;	/* number of bytes of arguments */
863192Smckusick 	/*		bool tests;	/* TRUE => perform runtime tests */
873192Smckusick 	/*		short offset;	/* offset of procedure in source file */
883192Smckusick 	/*		char name[1];	/* name of active procedure */
893192Smckusick 	/*	};
903192Smckusick 	 */
913192Smckusick #	define HDRSZE (2 * sizeof(long) + sizeof(short) + sizeof(bool))
923192Smckusick 	var = put(2, ((lenstr(fp->symbol,0) + HDRSZE) << 8)
933192Smckusick 		| (cbn == 1 && opt('p') == 0 ? O_NODUMP: O_BEG), (long)0);
943192Smckusick 	    /*
953192Smckusick 	     *  output the number of bytes of arguments
963192Smckusick 	     *  this is only checked on formal calls.
973192Smckusick 	     */
983192Smckusick 	put(2, O_CASE4, cbn == 1 ? (long)0 : (long)(fp->value[NL_OFFS]-DPOFF2));
993192Smckusick 	    /*
1003192Smckusick 	     *	Output the runtime test mode for the routine
1013192Smckusick 	     */
1023192Smckusick 	put(2, sizeof(bool) == 2 ? O_CASE2 : O_CASE4, opt('t') ? TRUE : FALSE);
1033192Smckusick 	    /*
1043192Smckusick 	     *	Output line number and routine name
1053192Smckusick 	     */
1063192Smckusick 	put(2, O_CASE2, bundle[1]);
1073192Smckusick 	putstr(fp->symbol, 0);
1083192Smckusick #endif OBJ
1093192Smckusick #ifdef PC
1103192Smckusick 	/*
1113192Smckusick 	 * put out the procedure entry code
1123192Smckusick 	 */
113*10671Speter 	eecookie.nlp = fp;
1143192Smckusick 	if ( fp -> class == PROG ) {
1159129Smckusick 		/*
1169129Smckusick 		 *	If there is a label declaration in the main routine
1179129Smckusick 		 *	then there may be a non-local goto to it that does
1189129Smckusick 		 *	not appear in this module. We have to assume that
1199129Smckusick 		 *	such a reference may occur and generate code to
1209129Smckusick 		 *	prepare for it.
1219129Smckusick 		 */
1229129Smckusick 	    if ( parts[ cbn ] & LPRT ) {
1239129Smckusick 		parts[ cbn ] |= ( NONLOCALVAR | NONLOCALGOTO );
1249129Smckusick 	    }
125*10671Speter 	    codeformain();
1267917Smckusick 	    ftnno = fp -> value[NL_ENTLOC];
127*10671Speter 	    prog_prologue(&eecookie);
1283192Smckusick 	    stabfunc( "program" , fp -> class , bundle[1] , 0 );
1293192Smckusick 	} else {
1307917Smckusick 	    ftnno = fp -> value[NL_ENTLOC];
131*10671Speter 	    fp_prologue(&eecookie);
1323192Smckusick 	    stabfunc( fp -> symbol , fp -> class , bundle[1] , cbn - 1 );
1333192Smckusick 	    for ( p = fp -> chain ; p != NIL ; p = p -> chain ) {
1343192Smckusick 		stabparam( p -> symbol , p2type( p -> type )
1353192Smckusick 			    , p -> value[ NL_OFFS ] , lwidth( p -> type ) );
1363192Smckusick 	    }
1373192Smckusick 	    if ( fp -> class == FUNC ) {
1383192Smckusick 		    /*
1393192Smckusick 		     *	stab the function variable
1403192Smckusick 		     */
1413192Smckusick 		p = fp -> ptr[ NL_FVAR ];
1423192Smckusick 		stablvar( p -> symbol , p2type( p -> type ) , cbn
1433192Smckusick 			, p -> value[ NL_OFFS ] , lwidth( p -> type ) );
1443192Smckusick 	    }
1453192Smckusick 		/*
1463192Smckusick 		 *	stab local variables
1473192Smckusick 		 *	rummage down hash chain links.
1483192Smckusick 		 */
1493192Smckusick 	    for ( i = 0 ; i <= 077 ; i++ ) {
1503192Smckusick 		for ( p = disptab[ i ] ; p != NIL ; p = p->nl_next) {
1513192Smckusick 		    if ( ( p -> nl_block & 037 ) != cbn ) {
1523192Smckusick 			break;
1533192Smckusick 		    }
1543192Smckusick 		    /*
1553192Smckusick 		     *	stab local variables
1563192Smckusick 		     *	that's named variables, but not params
1573192Smckusick 		     */
1583192Smckusick 		    if (   ( p -> symbol != NIL )
1593192Smckusick 			&& ( p -> class == VAR )
1603192Smckusick 			&& ( p -> value[ NL_OFFS ] < 0 ) ) {
1613192Smckusick 			stablvar( p -> symbol , p2type( p -> type ) , cbn
1623192Smckusick 			    , p -> value[ NL_OFFS ] , lwidth( p -> type ) );
1633192Smckusick 		    }
1643192Smckusick 		}
1653192Smckusick 	    }
1663192Smckusick 	}
1673192Smckusick 	stablbrac( cbn );
1683192Smckusick 	    /*
1693192Smckusick 	     *	ask second pass to allocate known locals
1703192Smckusick 	     */
1713192Smckusick 	putlbracket( ftnno , -sizes[ cbn ].om_max );
172*10671Speter 	fp_entrycode(&eecookie);
1733192Smckusick #endif PC
1743192Smckusick 	if ( monflg ) {
1753192Smckusick 		if ( fp -> value[ NL_CNTR ] != 0 ) {
1763192Smckusick 			inccnt( fp -> value [ NL_CNTR ] );
1773192Smckusick 		}
1783192Smckusick 		inccnt( bodycnts[ fp -> nl_block & 037 ] );
1793192Smckusick 	}
1803192Smckusick 	if (fp->class == PROG) {
1813192Smckusick 		/*
1823192Smckusick 		 * The glorious buffers option.
1833192Smckusick 		 *          0 = don't buffer output
1843192Smckusick 		 *          1 = line buffer output
1853192Smckusick 		 *          2 = 512 byte buffer output
1863192Smckusick 		 */
1873192Smckusick #		ifdef OBJ
1883192Smckusick 		    if (opt('b') != 1)
1893192Smckusick 			    put(1, O_BUFF | opt('b') << 8);
1903192Smckusick #		endif OBJ
1913192Smckusick #		ifdef PC
1923192Smckusick 		    if ( opt( 'b' ) != 1 ) {
1933192Smckusick 			putleaf( P2ICON , 0 , 0
1943192Smckusick 				, ADDTYPE( P2FTN | P2INT , P2PTR ) , "_BUFF" );
1953192Smckusick 			putleaf( P2ICON , opt( 'b' ) , 0 , P2INT , 0 );
1963192Smckusick 			putop( P2CALL , P2INT );
1973192Smckusick 			putdot( filename , line );
1983192Smckusick 		    }
1993192Smckusick #		endif PC
2007953Speter 		inp = 0;
2013192Smckusick 		out = 0;
2023192Smckusick 		for (p = fp->chain; p != NIL; p = p->chain) {
2037953Speter 			if (strcmp(p->symbol, input->symbol) == 0) {
2043192Smckusick 				inp++;
2053192Smckusick 				continue;
2063192Smckusick 			}
2077953Speter 			if (strcmp(p->symbol, output->symbol) == 0) {
2083192Smckusick 				out++;
2093192Smckusick 				continue;
2103192Smckusick 			}
2113192Smckusick 			iop = lookup1(p->symbol);
2123192Smckusick 			if (iop == NIL || bn != cbn) {
2133192Smckusick 				error("File %s listed in program statement but not declared", p->symbol);
2143192Smckusick 				continue;
2153192Smckusick 			}
2163192Smckusick 			if (iop->class != VAR) {
2173192Smckusick 				error("File %s listed in program statement but declared as a %s", p->symbol, classes[iop->class]);
2183192Smckusick 				continue;
2193192Smckusick 			}
2203192Smckusick 			if (iop->type == NIL)
2213192Smckusick 				continue;
2223192Smckusick 			if (iop->type->class != FILET) {
2233192Smckusick 				error("File %s listed in program statement but defined as %s",
2243192Smckusick 					p->symbol, nameof(iop->type));
2253192Smckusick 				continue;
2263192Smckusick 			}
2273192Smckusick #			ifdef OBJ
2283192Smckusick 			    put(2, O_CON24, text(iop->type) ? 0 : width(iop->type->type));
2293192Smckusick 			    i = lenstr(p->symbol,0);
2303192Smckusick 			    put(2, O_CON24, i);
2313192Smckusick 			    put(2, O_LVCON, i);
2323192Smckusick 			    putstr(p->symbol, 0);
2333192Smckusick 			    put(2, O_LV | bn<<8+INDX, (int)iop->value[NL_OFFS]);
2343192Smckusick 			    put(1, O_DEFNAME);
2353192Smckusick #			endif OBJ
2363192Smckusick #			ifdef PC
2373192Smckusick 			    putleaf( P2ICON , 0 , 0
2383192Smckusick 				    , ADDTYPE( P2FTN | P2INT , P2PTR )
2393192Smckusick 				    , "_DEFNAME" );
2403837Speter 			    putLV( p -> symbol , bn , iop -> value[NL_OFFS] ,
2413837Speter 				    iop -> extra_flags , p2type( iop ) );
2423192Smckusick 			    putCONG( p -> symbol , strlen( p -> symbol )
2433192Smckusick 				    , LREQ );
2443192Smckusick 			    putop( P2LISTOP , P2INT );
2453192Smckusick 			    putleaf( P2ICON , strlen( p -> symbol )
2463192Smckusick 				    , 0 , P2INT , 0 );
2473192Smckusick 			    putop( P2LISTOP , P2INT );
2483192Smckusick 			    putleaf( P2ICON
2493192Smckusick 				, text(iop->type) ? 0 : width(iop->type->type)
2503192Smckusick 				, 0 , P2INT , 0 );
2513192Smckusick 			    putop( P2LISTOP , P2INT );
2523192Smckusick 			    putop( P2CALL , P2INT );
2533192Smckusick 			    putdot( filename , line );
2543192Smckusick #			endif PC
2553192Smckusick 		}
2563192Smckusick 	}
2573192Smckusick 	/*
2583192Smckusick 	 * Process the prog/proc/func body
2593192Smckusick 	 */
2603192Smckusick 	noreach = 0;
2613192Smckusick 	line = bundle[1];
2623192Smckusick 	statlist(blk);
2633192Smckusick #	ifdef PTREE
2643192Smckusick 	    {
2653192Smckusick 		pPointer Body = tCopy( blk );
2663192Smckusick 
2673192Smckusick 		pDEF( PorFHeader[ nesting -- ] ).PorFBody = Body;
2683192Smckusick 	    }
2693192Smckusick #	endif PTREE
2703192Smckusick #	ifdef OBJ
2713192Smckusick 	    if (cbn== 1 && monflg != 0) {
2723192Smckusick 		    patchfil(cntpatch - 2, (long)cnts, 2);
2733192Smckusick 		    patchfil(nfppatch - 2, (long)pfcnt, 2);
2743192Smckusick 	    }
2753192Smckusick #	endif OBJ
2763192Smckusick #	ifdef PC
2773192Smckusick 	    if ( fp -> class == PROG && monflg ) {
2783192Smckusick 		putleaf( P2ICON , 0 , 0 , ADDTYPE( P2FTN | P2INT , P2PTR )
2793192Smckusick 			, "_PMFLUSH" );
2803192Smckusick 		putleaf( P2ICON , cnts , 0 , P2INT , 0 );
2813192Smckusick 		putleaf( P2ICON , pfcnt , 0 , P2INT , 0 );
2823192Smckusick 		putop( P2LISTOP , P2INT );
2833837Speter 		putLV( PCPCOUNT , 0 , 0 , NGLOBAL , P2INT );
2843192Smckusick 		putop( P2LISTOP , P2INT );
2853192Smckusick 		putop( P2CALL , P2INT );
2863192Smckusick 		putdot( filename , line );
2873192Smckusick 	    }
2883192Smckusick #	endif PC
2897953Speter 	/*
2907953Speter 	 * Clean up the symbol table displays and check for unresolves
2917953Speter 	 */
2927953Speter 	line = endline;
2933192Smckusick 	if (fp->class == PROG && inp == 0 && (input->nl_flags & (NUSED|NMOD)) != 0) {
2943192Smckusick 		recovered();
2953192Smckusick 		error("Input is used but not defined in the program statement");
2963192Smckusick 	}
2977953Speter 	if (fp->class == PROG && out == 0 && (output->nl_flags & (NUSED|NMOD)) != 0) {
2987953Speter 		recovered();
2997953Speter 		error("Output is used but not defined in the program statement");
3007953Speter 	}
3013192Smckusick 	b = cbn;
3023192Smckusick 	Fp = fp;
3033192Smckusick 	chkref = syneflg == errcnt[cbn] && opt('w') == 0;
3043192Smckusick 	for (i = 0; i <= 077; i++) {
3053192Smckusick 		for (p = disptab[i]; p != NIL && (p->nl_block & 037) == b; p = p->nl_next) {
3063192Smckusick 			/*
3073192Smckusick 			 * Check for variables defined
3083192Smckusick 			 * but not referenced
3093192Smckusick 			 */
3103192Smckusick 			if (chkref && p->symbol != NIL)
3113192Smckusick 			switch (p->class) {
3123192Smckusick 				case FIELD:
3133192Smckusick 					/*
3143192Smckusick 					 * If the corresponding record is
3153192Smckusick 					 * unused, we shouldn't complain about
3163192Smckusick 					 * the fields.
3173192Smckusick 					 */
3183192Smckusick 				default:
3193192Smckusick 					if ((p->nl_flags & (NUSED|NMOD)) == 0) {
3203192Smckusick 						warning();
3213192Smckusick 						nerror("%s %s is neither used nor set", classes[p->class], p->symbol);
3223192Smckusick 						break;
3233192Smckusick 					}
3243192Smckusick 					/*
3253192Smckusick 					 * If a var parameter is either
3263192Smckusick 					 * modified or used that is enough.
3273192Smckusick 					 */
3283192Smckusick 					if (p->class == REF)
3293192Smckusick 						continue;
3303192Smckusick #					ifdef OBJ
3313192Smckusick 					    if ((p->nl_flags & NUSED) == 0) {
3323192Smckusick 						warning();
3333192Smckusick 						nerror("%s %s is never used", classes[p->class], p->symbol);
3343192Smckusick 						break;
3353192Smckusick 					    }
3363192Smckusick #					endif OBJ
3373192Smckusick #					ifdef PC
3383837Speter 					    if (((p->nl_flags & NUSED) == 0) && ((p->extra_flags & NEXTERN) == 0)) {
3393192Smckusick 						warning();
3403192Smckusick 						nerror("%s %s is never used", classes[p->class], p->symbol);
3413192Smckusick 						break;
3423192Smckusick 					    }
3433192Smckusick #					endif PC
3443192Smckusick 					if ((p->nl_flags & NMOD) == 0) {
3453192Smckusick 						warning();
3463192Smckusick 						nerror("%s %s is used but never set", classes[p->class], p->symbol);
3473192Smckusick 						break;
3483192Smckusick 					}
3493192Smckusick 				case LABEL:
3503192Smckusick 				case FVAR:
3513192Smckusick 				case BADUSE:
3523192Smckusick 					break;
3533192Smckusick 			}
3543192Smckusick 			switch (p->class) {
3553192Smckusick 				case BADUSE:
3563192Smckusick 					cp = "s";
3573192Smckusick 					if (p->chain->ud_next == NIL)
3583192Smckusick 						cp++;
3593192Smckusick 					eholdnl();
3603192Smckusick 					if (p->value[NL_KINDS] & ISUNDEF)
3613192Smckusick 						nerror("%s undefined on line%s", p->symbol, cp);
3623192Smckusick 					else
3633192Smckusick 						nerror("%s improperly used on line%s", p->symbol, cp);
3643192Smckusick 					pnumcnt = 10;
3653192Smckusick 					pnums(p->chain);
3663192Smckusick 					pchr('\n');
3673192Smckusick 					break;
3683192Smckusick 
3693192Smckusick 				case FUNC:
3703192Smckusick 				case PROC:
3713192Smckusick #					ifdef OBJ
3723192Smckusick 					    if ((p->nl_flags & NFORWD))
3733192Smckusick 						nerror("Unresolved forward declaration of %s %s", classes[p->class], p->symbol);
3743192Smckusick #					endif OBJ
3753192Smckusick #					ifdef PC
3763837Speter 					    if ((p->nl_flags & NFORWD) && ((p->extra_flags & NEXTERN) == 0))
3773192Smckusick 						nerror("Unresolved forward declaration of %s %s", classes[p->class], p->symbol);
3783192Smckusick #					endif PC
3793192Smckusick 					break;
3803192Smckusick 
3813192Smckusick 				case LABEL:
3823192Smckusick 					if (p->nl_flags & NFORWD)
3833192Smckusick 						nerror("label %s was declared but not defined", p->symbol);
3843192Smckusick 					break;
3853192Smckusick 				case FVAR:
3863192Smckusick 					if ((p->nl_flags & NMOD) == 0)
3873192Smckusick 						nerror("No assignment to the function variable");
3883192Smckusick 					break;
3893192Smckusick 			}
3903192Smckusick 		}
3913192Smckusick 		/*
3923192Smckusick 		 * Pop this symbol
3933192Smckusick 		 * table slot
3943192Smckusick 		 */
3953192Smckusick 		disptab[i] = p;
3963192Smckusick 	}
3973192Smckusick 
3983192Smckusick #	ifdef OBJ
3993192Smckusick 	    put(1, O_END);
4003192Smckusick #	endif OBJ
4013192Smckusick #	ifdef PC
402*10671Speter 	    fp_exitcode(&eecookie);
403*10671Speter 	    stabrbrac(cbn);
404*10671Speter 	    putrbracket(ftnno);
405*10671Speter 	    fp_epilogue(&eecookie);
406*10671Speter 	    if (fp -> class != PROG) {
407*10671Speter 		fp_formalentry(&eecookie);
4083192Smckusick 	    }
4093192Smckusick 		/*
4103192Smckusick 		 *	declare pcp counters, if any
4113192Smckusick 		 */
4123192Smckusick 	    if ( monflg && fp -> class == PROG ) {
4133192Smckusick 		putprintf( "	.data" , 0 );
414*10671Speter 		aligndot(P2INT);
4153192Smckusick 		putprintf( "	.comm	" , 1 );
4163192Smckusick 		putprintf( PCPCOUNT , 1 );
4173192Smckusick 		putprintf( ",%d" , 0 , ( cnts + 1 ) * sizeof (long) );
4183192Smckusick 		putprintf( "	.text" , 0 );
4193192Smckusick 	    }
4203192Smckusick #	endif PC
4213192Smckusick #ifdef DEBUG
4223192Smckusick 	dumpnl(fp->ptr[2], fp->symbol);
4233192Smckusick #endif
4245654Slinton 
4255654Slinton #ifdef OBJ
4263192Smckusick 	/*
4275654Slinton 	 * save the namelist for the debugger pdx
4285654Slinton 	 */
4295654Slinton 
4305654Slinton 	savenl(fp->ptr[2], fp->symbol);
4315654Slinton #endif
4325654Slinton 
4335654Slinton 	/*
4343192Smckusick 	 * Restore the
4353192Smckusick 	 * (virtual) name list
4363192Smckusick 	 * position
4373192Smckusick 	 */
4383192Smckusick 	nlfree(fp->ptr[2]);
4393192Smckusick 	/*
4403192Smckusick 	 * Proc/func has been
4413192Smckusick 	 * resolved
4423192Smckusick 	 */
4433192Smckusick 	fp->nl_flags &= ~NFORWD;
4443192Smckusick 	/*
4453192Smckusick 	 * Patch the beg
4463192Smckusick 	 * of the proc/func to
4473192Smckusick 	 * the proper variable size
4483192Smckusick 	 */
4493192Smckusick 	if (Fp == NIL)
4503192Smckusick 		elineon();
4513192Smckusick #	ifdef OBJ
452*10671Speter 	    patchfil(var, leven(-sizes[cbn].om_max), 2);
4533192Smckusick #	endif OBJ
4543192Smckusick 	cbn--;
4553192Smckusick 	if (inpflist(fp->symbol)) {
4563192Smckusick 		opop('l');
4573192Smckusick 	}
4583192Smckusick }
4593363Speter 
4603363Speter #ifdef PC
4613363Speter     /*
4623363Speter      *	construct the long name of a function based on it's static nesting.
4633363Speter      *	into a caller-supplied buffer (that should be about BUFSIZ big).
4643363Speter      */
4653363Speter sextname( buffer , name , level )
4663363Speter     char	buffer[];
4673363Speter     char	*name;
4683363Speter     int		level;
4693363Speter {
4703363Speter     char	*starthere;
4713363Speter     int	i;
4723363Speter 
4733363Speter     starthere = &buffer[0];
4743363Speter     for ( i = 1 ; i < level ; i++ ) {
4753363Speter 	sprintf( starthere , EXTFORMAT , enclosing[ i ] );
4763363Speter 	starthere += strlen( enclosing[ i ] ) + 1;
4773363Speter     }
4783367Speter     sprintf( starthere , EXTFORMAT , name );
4793367Speter     starthere += strlen( name ) + 1;
4803363Speter     if ( starthere >= &buffer[ BUFSIZ ] ) {
4813363Speter 	panic( "sextname" );
4823363Speter     }
4833363Speter }
484*10671Speter 
485*10671Speter     /*
486*10671Speter      *	code for main()
487*10671Speter      */
488*10671Speter #ifdef vax
489*10671Speter 
490*10671Speter codeformain()
491*10671Speter {
492*10671Speter     putprintf("	.text" , 0 );
493*10671Speter     putprintf("	.align	1" , 0 );
494*10671Speter     putprintf("	.globl	_main" , 0 );
495*10671Speter     putprintf("_main:" , 0 );
496*10671Speter     putprintf("	.word	0" , 0 );
497*10671Speter     if ( opt ( 't' ) ) {
498*10671Speter 	putprintf("	pushl	$1" , 0 );
499*10671Speter     } else {
500*10671Speter 	putprintf("	pushl	$0" , 0 );
501*10671Speter     }
502*10671Speter     putprintf("	calls	$1,_PCSTART" , 0 );
503*10671Speter     putprintf("	movl	4(ap),__argc" , 0 );
504*10671Speter     putprintf("	movl	8(ap),__argv" , 0 );
505*10671Speter     putprintf("	calls	$0,_program" , 0 );
506*10671Speter     putprintf("	pushl	$0" , 0 );
507*10671Speter     putprintf("	calls	$1,_PCEXIT" , 0 );
508*10671Speter }
509*10671Speter 
510*10671Speter     /*
511*10671Speter      *	prologue for the program.
512*10671Speter      *	different because it
513*10671Speter      *		doesn't have formal entry point
514*10671Speter      */
515*10671Speter prog_prologue(eecookiep)
516*10671Speter     struct entry_exit_cookie	*eecookiep;
517*10671Speter {
518*10671Speter     putprintf("	.text" , 0 );
519*10671Speter     putprintf("	.align	1" , 0 );
520*10671Speter     putprintf("	.globl	_program" , 0 );
521*10671Speter     putprintf("_program:" , 0 );
522*10671Speter }
523*10671Speter 
524*10671Speter fp_prologue(eecookiep)
525*10671Speter     struct entry_exit_cookie	*eecookiep;
526*10671Speter {
527*10671Speter     int		ftnno = eecookiep -> nlp -> value[NL_ENTLOC];
528*10671Speter 
529*10671Speter     sextname( eecookiep -> extname, eecookiep -> nlp -> symbol , cbn - 1 );
530*10671Speter     putprintf( "	.text" , 0 );
531*10671Speter     putprintf( "	.align	1" , 0 );
532*10671Speter     putprintf( "	.globl	%s%s", 0, FORMALPREFIX, eecookiep -> extname );
533*10671Speter     putprintf( "	.globl	%s" , 0 , eecookiep -> extname );
534*10671Speter     putprintf( "%s:" , 0 , eecookiep -> extname );
535*10671Speter 	/*
536*10671Speter 	 *	register save mask
537*10671Speter 	 */
538*10671Speter     eecookiep -> savlabel = getlab();
539*10671Speter     putprintf("	.word	%s%d", 0, SAVE_MASK_LABEL , eecookiep -> savlabel );
540*10671Speter }
541*10671Speter 
542*10671Speter     /*
543*10671Speter      *	code before any user code.
544*10671Speter      *	or code that is machine dependent.
545*10671Speter      */
546*10671Speter fp_entrycode(eecookiep)
547*10671Speter     struct entry_exit_cookie	*eecookiep;
548*10671Speter {
549*10671Speter     int	ftnno = eecookiep -> nlp -> nl_value[ENTLOC];
550*10671Speter     int	proflabel = getlab();
551*10671Speter     int	setjmp0 = getlab();
552*10671Speter 
553*10671Speter 	/*
554*10671Speter 	 *	top of code;  destination of jump from formal entry code.
555*10671Speter 	 */
556*10671Speter     eecookiep -> toplabel = getlab();
557*10671Speter     putlab( eecookiep -> toplabel );
558*10671Speter     putprintf("	subl2	$%s%d,sp" , 0 , FRAME_SIZE_LABEL, ftnno );
559*10671Speter     if ( profflag ) {
560*10671Speter 	    /*
561*10671Speter 	     *	call mcount for profiling
562*10671Speter 	     */
563*10671Speter 	putprintf( "	moval	" , 1 );
564*10671Speter 	putprintf( PREFIXFORMAT , 1 , LABELPREFIX , proflabel );
565*10671Speter 	putprintf( ",r0" , 0 );
566*10671Speter 	putprintf( "	jsb	mcount" , 0 );
567*10671Speter 	putprintf( "	.data" , 0 );
568*10671Speter 	putprintf( "	.align	2" , 0 );
569*10671Speter 	putlab( proflabel );
570*10671Speter 	putprintf( "	.long	0" , 0 );
571*10671Speter 	putprintf( "	.text" , 0 );
572*10671Speter     }
573*10671Speter 	/*
574*10671Speter 	 *	if there are nested procedures that access our variables
575*10671Speter 	 *	we must save the display.
576*10671Speter 	 */
577*10671Speter     if ( parts[ cbn ] & NONLOCALVAR ) {
578*10671Speter 	    /*
579*10671Speter 	     *	save old display
580*10671Speter 	     */
581*10671Speter 	putprintf( "	movq	%s+%d,%d(%s)" , 0
582*10671Speter 		, DISPLAYNAME , cbn * sizeof(struct dispsave)
583*10671Speter 		, DSAVEOFFSET , P2FPNAME );
584*10671Speter 	    /*
585*10671Speter 	     *	set up new display by saving AP and FP in appropriate
586*10671Speter 	     *	slot in display structure.
587*10671Speter 	     */
588*10671Speter 	putprintf( "	movq	%s,%s+%d" , 0
589*10671Speter 		, P2APNAME , DISPLAYNAME , cbn * sizeof(struct dispsave) );
590*10671Speter     }
591*10671Speter 	/*
592*10671Speter 	 *	set underflow checking if runtime tests
593*10671Speter 	 */
594*10671Speter     if ( opt( 't' ) ) {
595*10671Speter 	putprintf( "	bispsw	$0xe0" , 0 );
596*10671Speter     }
597*10671Speter 	/*
598*10671Speter 	 *	zero local variables if checking is on
599*10671Speter 	 *	by calling blkclr( bytes of locals , starting local address );
600*10671Speter 	 */
601*10671Speter     if ( opt( 't' ) && ( -sizes[ cbn ].om_max ) > DPOFF1 ) {
602*10671Speter 	putleaf( P2ICON , 0 , 0 , ADDTYPE( P2FTN | P2INT , P2PTR )
603*10671Speter 		, "_blkclr" );
604*10671Speter 	putLV( 0 , cbn , sizes[ cbn ].om_max , NLOCAL , P2CHAR );
605*10671Speter 	putleaf( P2ICON ,  ( -sizes[ cbn ].om_max ) - DPOFF1
606*10671Speter 		, 0 , P2INT , 0 );
607*10671Speter 	putop( P2LISTOP , P2INT );
608*10671Speter 	putop( P2CALL , P2INT );
609*10671Speter 	putdot( filename , line );
610*10671Speter     }
611*10671Speter 	/*
612*10671Speter 	 *  set up goto vector if non-local goto to this frame
613*10671Speter 	 */
614*10671Speter     if ( parts[ cbn ] & NONLOCALGOTO ) {
615*10671Speter 	putleaf( P2ICON , 0 , 0 , ADDTYPE( P2FTN | P2INT , P2PTR )
616*10671Speter 		, "_setjmp" );
617*10671Speter 	putLV( 0 , cbn , GOTOENVOFFSET , NLOCAL , P2PTR|P2STRTY );
618*10671Speter 	putop( P2CALL , P2INT );
619*10671Speter 	putleaf( P2ICON , 0 , 0 , P2INT , 0 );
620*10671Speter 	putop( P2NE , P2INT );
621*10671Speter 	putleaf( P2ICON , setjmp0 , 0 , P2INT , 0 );
622*10671Speter 	putop( P2CBRANCH , P2INT );
623*10671Speter 	putdot( filename , line );
624*10671Speter 	    /*
625*10671Speter 	     *	on non-local goto, setjmp returns with address to
626*10671Speter 	     *	be branched to.
627*10671Speter 	     */
628*10671Speter 	putprintf( "	jmp	(r0)" , 0 );
629*10671Speter 	putlab(setjmp0);
630*10671Speter     }
631*10671Speter }
632*10671Speter 
633*10671Speter fp_exitcode(eecookiep)
634*10671Speter     struct entry_exit_cookie	*eecookiep;
635*10671Speter {
636*10671Speter 	/*
637*10671Speter 	 *	if there were file variables declared at this level
638*10671Speter 	 *	call PCLOSE( ap ) to clean them up.
639*10671Speter 	 */
640*10671Speter     if ( dfiles[ cbn ] ) {
641*10671Speter 	putleaf( P2ICON , 0 , 0 , ADDTYPE( P2FTN | P2INT , P2PTR )
642*10671Speter 		, "_PCLOSE" );
643*10671Speter 	putleaf( P2REG , 0 , P2AP , ADDTYPE( P2CHAR , P2PTR ) , 0 );
644*10671Speter 	putop( P2CALL , P2INT );
645*10671Speter 	putdot( filename , line );
646*10671Speter     }
647*10671Speter 	/*
648*10671Speter 	 *	if this is a function,
649*10671Speter 	 *	the function variable is the return value.
650*10671Speter 	 *	if it's a scalar valued function, return scalar,
651*10671Speter 	 *	else, return a pointer to the structure value.
652*10671Speter 	 */
653*10671Speter     if ( eecookiep-> nlp -> class == FUNC ) {
654*10671Speter 	struct nl	*fvar = eecookiep-> nlp -> ptr[ NL_FVAR ];
655*10671Speter 	long		fvartype = p2type( fvar -> type );
656*10671Speter 	long		label;
657*10671Speter 	char		labelname[ BUFSIZ ];
658*10671Speter 
659*10671Speter 	switch ( classify( fvar -> type ) ) {
660*10671Speter 	    case TBOOL:
661*10671Speter 	    case TCHAR:
662*10671Speter 	    case TINT:
663*10671Speter 	    case TSCAL:
664*10671Speter 	    case TDOUBLE:
665*10671Speter 	    case TPTR:
666*10671Speter 		putRV( fvar -> symbol , ( fvar -> nl_block ) & 037 ,
667*10671Speter 			fvar -> value[ NL_OFFS ] ,
668*10671Speter 			fvar -> extra_flags ,
669*10671Speter 			fvartype );
670*10671Speter 		break;
671*10671Speter 	    default:
672*10671Speter 		label = getlab();
673*10671Speter 		sprintf( labelname , PREFIXFORMAT , LABELPREFIX , label );
674*10671Speter 		putprintf( "	.data" , 0 );
675*10671Speter 		aligndot(A_STRUCT);
676*10671Speter 		putprintf( "	.lcomm	%s,%d" , 0 ,
677*10671Speter 			    labelname , lwidth( fvar -> type ) );
678*10671Speter 		putprintf( "	.text" , 0 );
679*10671Speter 		putleaf( P2NAME , 0 , 0 , fvartype , labelname );
680*10671Speter 		putLV( fvar -> symbol , ( fvar -> nl_block ) & 037 ,
681*10671Speter 			fvar -> value[ NL_OFFS ] ,
682*10671Speter 			fvar -> extra_flags ,
683*10671Speter 			fvartype );
684*10671Speter 		putstrop( P2STASG , fvartype , lwidth( fvar -> type ) ,
685*10671Speter 			align( fvar -> type ) );
686*10671Speter 		putdot( filename , line );
687*10671Speter 		putleaf( P2ICON , 0 , 0 , fvartype , labelname );
688*10671Speter 		break;
689*10671Speter 	}
690*10671Speter 	putop( P2FORCE , fvartype );
691*10671Speter 	putdot( filename , line );
692*10671Speter     }
693*10671Speter 	/*
694*10671Speter 	 *	if there are nested procedures we must save the display.
695*10671Speter 	 */
696*10671Speter     if ( parts[ cbn ] & NONLOCALVAR ) {
697*10671Speter 	    /*
698*10671Speter 	     *	restore old display entry from save area
699*10671Speter 	     */
700*10671Speter 	putprintf( "	movq	%d(%s),%s+%d" , 0
701*10671Speter 	    , DSAVEOFFSET , P2FPNAME
702*10671Speter 	    , DISPLAYNAME , cbn * sizeof(struct dispsave) );
703*10671Speter     }
704*10671Speter }
705*10671Speter 
706*10671Speter fp_epilogue(eecookiep)
707*10671Speter     struct entry_exit_cookie	*eecookiep;
708*10671Speter {
709*10671Speter     putprintf("	ret" , 0 );
710*10671Speter 	/*
711*10671Speter 	 *	set the register save mask.
712*10671Speter 	 */
713*10671Speter     putprintf("	.set	%s%d,0x%x", 0,
714*10671Speter 		SAVE_MASK_LABEL, eecookiep -> savlabel, savmask());
715*10671Speter }
716*10671Speter 
717*10671Speter fp_formalentry(eecookiep)
718*10671Speter     struct entry_exit_cookie	*eecookiep;
719*10671Speter {
720*10671Speter 
721*10671Speter     putprintf("%s%s:" , 0 , FORMALPREFIX , eecookiep -> extname );
722*10671Speter     putprintf("	.word	%s%d", 0, SAVE_MASK_LABEL, eecookiep -> savlabel );
723*10671Speter     putleaf( P2ICON , 0 , 0 , ADDTYPE( P2FTN | P2INT , P2PTR ) , "_FCALL" );
724*10671Speter     putRV( 0 , cbn ,
725*10671Speter 	eecookiep -> nlp -> value[ NL_OFFS ] + sizeof( struct formalrtn * ) ,
726*10671Speter 	NPARAM , P2PTR | P2STRTY );
727*10671Speter     putRV(0, cbn, eecookiep -> nlp -> value[NL_OFFS], NPARAM, P2PTR|P2STRTY);
728*10671Speter     putop( P2LISTOP , P2INT );
729*10671Speter     putop( P2CALL , P2INT );
730*10671Speter     putdot( filename , line );
731*10671Speter     putjbr( eecookiep -> toplabel );
732*10671Speter }
733*10671Speter #endif vax
734*10671Speter 
735*10671Speter #ifdef mc68000
736*10671Speter 
737*10671Speter codeformain()
738*10671Speter {
739*10671Speter     putprintf("	.text", 0);
740*10671Speter     putprintf("	.globl	_main", 0);
741*10671Speter     putprintf("_main:", 0);
742*10671Speter     putprintf("	link	%s,#0", 0, P2FPNAME);
743*10671Speter     if (opt('t')) {
744*10671Speter 	putprintf("	pea	1", 0);
745*10671Speter     } else {
746*10671Speter 	putprintf("	pea	0", 0);
747*10671Speter     }
748*10671Speter     putprintf("	jbsr	_PCSTART", 0);
749*10671Speter     putprintf("	addql	#4,sp", 0);
750*10671Speter     putprintf("	movl	%s@(8),__argc", 0, P2FPNAME);
751*10671Speter     putprintf("	movl	%s@(12),__argv", 0, P2FPNAME);
752*10671Speter     putprintf("	jbsr	_program", 0);
753*10671Speter     putprintf("	pea	0", 0);
754*10671Speter     putprintf("	jbsr	_PCEXIT", 0);
755*10671Speter }
756*10671Speter 
757*10671Speter prog_prologue(eecookiep)
758*10671Speter     struct entry_exit_cookie	*eecookiep;
759*10671Speter {
760*10671Speter     int	ftnno = eecookiep -> nlp -> value[NL_ENTLOC];
761*10671Speter 
762*10671Speter     putprintf("	.text", 0);
763*10671Speter     putprintf("	.globl	_program", 0);
764*10671Speter     putprintf("_program:", 0);
765*10671Speter     putprintf("	link	%s,#0", 0, P2FPNAME);
766*10671Speter     putprintf("	addl	#-%s%d,sp", 0, FRAME_SIZE_LABEL, ftnno);
767*10671Speter 	/* touch new end of stack, to break more stack space */
768*10671Speter     putprintf("	tstb	sp@(-%s%d)", 0, PAGE_BREAK_LABEL, ftnno);
769*10671Speter     putprintf("	moveml	#%s%d,sp@", 0, SAVE_MASK_LABEL, ftnno);
770*10671Speter }
771*10671Speter 
772*10671Speter fp_prologue(eecookiep)
773*10671Speter     struct entry_exit_cookie	*eecookiep;
774*10671Speter {
775*10671Speter     int		ftnno = eecookiep -> nlp -> value[NL_ENTLOC];
776*10671Speter 
777*10671Speter     sextname(eecookiep -> extname, eecookiep -> nlp -> symbol, cbn - 1);
778*10671Speter     putprintf("	.text", 0);
779*10671Speter     putprintf("	.globl	%s%s", 0, FORMALPREFIX, eecookiep -> extname);
780*10671Speter     putprintf("	.globl	%s", 0, eecookiep -> extname);
781*10671Speter     putprintf("%s:", 0, eecookiep -> extname);
782*10671Speter     putprintf("	link	%s,#0", 0, P2FPNAME);
783*10671Speter     putprintf("	addl	#-%s%d,sp", 0, FRAME_SIZE_LABEL, ftnno);
784*10671Speter 	/* touch new end of stack, to break more stack space */
785*10671Speter     putprintf("	tstb	sp@(-%s%d)", 0, PAGE_BREAK_LABEL, ftnno);
786*10671Speter     putprintf("	moveml	#%s%d,sp@", 0, SAVE_MASK_LABEL, ftnno);
787*10671Speter }
788*10671Speter 
789*10671Speter fp_entrycode(eecookiep)
790*10671Speter     struct entry_exit_cookie	*eecookiep;
791*10671Speter {
792*10671Speter     int	proflabel = getlab();
793*10671Speter     int	setjmp0 = getlab();
794*10671Speter 
795*10671Speter 	/*
796*10671Speter 	 *	fill in the label cookie
797*10671Speter 	 */
798*10671Speter     eecookiep -> toplabel = getlab();
799*10671Speter     putlab(eecookiep -> toplabel);
800*10671Speter 	/*
801*10671Speter 	 *	call mcount if we are profiling.
802*10671Speter 	 */
803*10671Speter     if ( profflag ) {
804*10671Speter 	putprintf("	movl	#%s%d,a0", 0, LABELPREFIX,  proflabel);
805*10671Speter 	putprintf("	jsr	mcount", 0);
806*10671Speter 	putprintf("	.data", 0);
807*10671Speter 	putprintf("	.even", 0);
808*10671Speter 	putlab(proflabel);
809*10671Speter 	putprintf("	.long	0", 0);
810*10671Speter 	putprintf("	.text", 0);
811*10671Speter     }
812*10671Speter 	/*
813*10671Speter 	 *	if there are nested procedures that access our variables
814*10671Speter 	 *	we must save the display
815*10671Speter 	 */
816*10671Speter     if (parts[cbn] & NONLOCALVAR) {
817*10671Speter 	    /*
818*10671Speter 	     *	save the old display
819*10671Speter 	     */
820*10671Speter 	putprintf("	movl	%s+%d,%s@(%d)", 0,
821*10671Speter 		    DISPLAYNAME, cbn * sizeof(struct dispsave),
822*10671Speter 		    P2FPNAME, DSAVEOFFSET);
823*10671Speter 	    /*
824*10671Speter 	     *	set up the new display by saving the framepointer
825*10671Speter 	     *	in the display structure.
826*10671Speter 	     */
827*10671Speter 	putprintf("	movl	%s,%s+%d", 0,
828*10671Speter 		    P2FPNAME, DISPLAYNAME, cbn * sizeof(struct dispsave));
829*10671Speter     }
830*10671Speter 	/*
831*10671Speter 	 *	zero local variables if checking is on
832*10671Speter 	 *	by calling blkclr( bytes of locals , starting local address );
833*10671Speter 	 */
834*10671Speter     if ( opt( 't' ) && ( -sizes[ cbn ].om_max ) > DPOFF1 ) {
835*10671Speter 	putleaf( P2ICON , 0 , 0 , ADDTYPE( P2FTN | P2INT , P2PTR )
836*10671Speter 		, "_blkclr" );
837*10671Speter 	putLV( 0 , cbn , sizes[ cbn ].om_max , NLOCAL , P2CHAR );
838*10671Speter 	putleaf( P2ICON ,  ( -sizes[ cbn ].om_max ) - DPOFF1
839*10671Speter 		, 0 , P2INT , 0 );
840*10671Speter 	putop( P2LISTOP , P2INT );
841*10671Speter 	putop( P2CALL , P2INT );
842*10671Speter 	putdot( filename , line );
843*10671Speter     }
844*10671Speter 	/*
845*10671Speter 	 *  set up goto vector if non-local goto to this frame
846*10671Speter 	 */
847*10671Speter     if ( parts[ cbn ] & NONLOCALGOTO ) {
848*10671Speter 	putleaf( P2ICON , 0 , 0 , ADDTYPE( P2FTN | P2INT , P2PTR )
849*10671Speter 		, "_setjmp" );
850*10671Speter 	putLV( 0 , cbn , GOTOENVOFFSET , NLOCAL , P2PTR|P2STRTY );
851*10671Speter 	putop( P2CALL , P2INT );
852*10671Speter 	putleaf( P2ICON , 0 , 0 , P2INT , 0 );
853*10671Speter 	putop( P2NE , P2INT );
854*10671Speter 	putleaf( P2ICON , setjmp0 , 0 , P2INT , 0 );
855*10671Speter 	putop( P2CBRANCH , P2INT );
856*10671Speter 	putdot( filename , line );
857*10671Speter 	    /*
858*10671Speter 	     *	on non-local goto, setjmp returns with address to
859*10671Speter 	     *	be branched to.
860*10671Speter 	     */
861*10671Speter 	putprintf("	movl	d0,a0", 0);
862*10671Speter 	putprintf("	jmp	a0@", 0);
863*10671Speter 	putlab(setjmp0);
864*10671Speter     }
865*10671Speter }
866*10671Speter 
867*10671Speter fp_exitcode(eecookiep)
868*10671Speter     struct entry_exit_cookie	*eecookiep;
869*10671Speter {
870*10671Speter 	/*
871*10671Speter 	 *	if there were file variables declared at this level
872*10671Speter 	 *	call PCLOSE( ap ) to clean them up.
873*10671Speter 	 */
874*10671Speter     if ( dfiles[ cbn ] ) {
875*10671Speter 	putleaf( P2ICON , 0 , 0 , ADDTYPE( P2FTN | P2INT , P2PTR )
876*10671Speter 		, "_PCLOSE" );
877*10671Speter 	putleaf( P2REG , 0 , P2AP , ADDTYPE( P2CHAR , P2PTR ) , 0 );
878*10671Speter 	putop( P2CALL , P2INT );
879*10671Speter 	putdot( filename , line );
880*10671Speter     }
881*10671Speter 	/*
882*10671Speter 	 *	if this is a function,
883*10671Speter 	 *	the function variable is the return value.
884*10671Speter 	 *	if it's a scalar valued function, return scalar,
885*10671Speter 	 *	else, return a pointer to the structure value.
886*10671Speter 	 */
887*10671Speter     if ( eecookiep -> nlp -> class == FUNC ) {
888*10671Speter 	struct nl	*fvar = eecookiep -> nlp -> ptr[ NL_FVAR ];
889*10671Speter 	long		fvartype = p2type( fvar -> type );
890*10671Speter 	long		label;
891*10671Speter 	char		labelname[ BUFSIZ ];
892*10671Speter 
893*10671Speter 	switch ( classify( fvar -> type ) ) {
894*10671Speter 	    case TBOOL:
895*10671Speter 	    case TCHAR:
896*10671Speter 	    case TINT:
897*10671Speter 	    case TSCAL:
898*10671Speter 	    case TDOUBLE:
899*10671Speter 	    case TPTR:
900*10671Speter 		putRV( fvar -> symbol , ( fvar -> nl_block ) & 037 ,
901*10671Speter 			fvar -> value[ NL_OFFS ] ,
902*10671Speter 			fvar -> extra_flags ,
903*10671Speter 			fvartype );
904*10671Speter 		break;
905*10671Speter 	    default:
906*10671Speter 		label = getlab();
907*10671Speter 		sprintf( labelname , PREFIXFORMAT , LABELPREFIX , label );
908*10671Speter 		putprintf("	.lcomm	%s,%d", 0,
909*10671Speter 			labelname, lwidth(fvar -> type));
910*10671Speter 		putleaf( P2NAME , 0 , 0 , fvartype , labelname );
911*10671Speter 		putLV( fvar -> symbol , ( fvar -> nl_block ) & 037 ,
912*10671Speter 			fvar -> value[ NL_OFFS ] ,
913*10671Speter 			fvar -> extra_flags ,
914*10671Speter 			fvartype );
915*10671Speter 		putstrop( P2STASG , fvartype , lwidth( fvar -> type ) ,
916*10671Speter 			align( fvar -> type ) );
917*10671Speter 		putdot( filename , line );
918*10671Speter 		putleaf( P2ICON , 0 , 0 , fvartype , labelname );
919*10671Speter 		break;
920*10671Speter 	}
921*10671Speter 	putop( P2FORCE , fvartype );
922*10671Speter 	putdot( filename , line );
923*10671Speter     }
924*10671Speter 	/*
925*10671Speter 	 *	if we saved a display, we must restore it.
926*10671Speter 	 */
927*10671Speter     if ( parts[ cbn ] & NONLOCALVAR ) {
928*10671Speter 	    /*
929*10671Speter 	     *	restore old display entry from save area
930*10671Speter 	     */
931*10671Speter 	putprintf("	movl	%s@(%d),%s+%d", 0,
932*10671Speter 		    P2FPNAME, DSAVEOFFSET,
933*10671Speter 		    DISPLAYNAME, cbn * sizeof(struct dispsave));
934*10671Speter     }
935*10671Speter }
936*10671Speter 
937*10671Speter fp_epilogue(eecookiep)
938*10671Speter     struct entry_exit_cookie	*eecookiep;
939*10671Speter {
940*10671Speter     /*
941*10671Speter      *	all done by the second pass.
942*10671Speter      */
943*10671Speter }
944*10671Speter 
945*10671Speter fp_formalentry(eecookiep)
946*10671Speter     struct entry_exit_cookie	*eecookiep;
947*10671Speter {
948*10671Speter     putprintf( "%s%s:" , 0 , FORMALPREFIX , eecookiep -> extname );
949*10671Speter     putprintf("	link	%s,#0", 0, P2FPNAME);
950*10671Speter     putprintf("	addl	#-%s%d,sp", 0, FRAME_SIZE_LABEL, ftnno);
951*10671Speter 	/* touch new end of stack, to break more stack space */
952*10671Speter     putprintf("	tstb	sp@(-%s%d)", 0, PAGE_BREAK_LABEL, ftnno);
953*10671Speter     putprintf("	moveml	#%s%d,sp@", 0, SAVE_MASK_LABEL, ftnno);
954*10671Speter     putleaf( P2ICON , 0 , 0 , ADDTYPE( P2FTN | P2INT , P2PTR ) , "_FCALL" );
955*10671Speter     putRV( 0 , cbn ,
956*10671Speter 	eecookiep -> nlp -> value[ NL_OFFS ] + sizeof( struct formalrtn * ) ,
957*10671Speter 	NPARAM , P2PTR | P2STRTY );
958*10671Speter     putRV(0, cbn, eecookiep -> nlp -> value[NL_OFFS], NPARAM, P2PTR|P2STRTY);
959*10671Speter     putop( P2LISTOP , P2INT );
960*10671Speter     putop( P2CALL , P2INT );
961*10671Speter     putdot( filename , line );
962*10671Speter     putjbr( eecookiep -> toplabel );
963*10671Speter }
964*10671Speter #endif mc68000
9653363Speter #endif PC
966