xref: /csrg-svn/usr.bin/pascal/src/fend.c (revision 30039)
122164Sdist /*
222164Sdist  * Copyright (c) 1980 Regents of the University of California.
322164Sdist  * All rights reserved.  The Berkeley software License Agreement
422164Sdist  * specifies the terms and conditions for redistribution.
522164Sdist  */
63192Smckusick 
718347Smckusick #ifndef lint
8*30039Smckusick static char sccsid[] = "@(#)fend.c	5.3 (Berkeley) 11/12/86";
922164Sdist #endif not lint
103192Smckusick 
113192Smckusick #include "whoami.h"
123192Smckusick #include "0.h"
133192Smckusick #include "tree.h"
143192Smckusick #include "opcode.h"
153192Smckusick #include "objfmt.h"
163192Smckusick #include "align.h"
1711337Speter #include "tmps.h"
183192Smckusick 
193192Smckusick /*
203192Smckusick  * this array keeps the pxp counters associated with
213192Smckusick  * functions and procedures, so that they can be output
223192Smckusick  * when their bodies are encountered
233192Smckusick  */
243192Smckusick int	bodycnts[ DSPLYSZ ];
253192Smckusick 
263192Smckusick #ifdef PC
273192Smckusick #   include "pc.h"
2818457Sralph #   include <pcc.h>
293192Smckusick #endif PC
303192Smckusick 
313192Smckusick #ifdef OBJ
323192Smckusick int	cntpatch;
333192Smckusick int	nfppatch;
343192Smckusick #endif OBJ
353192Smckusick 
3618347Smckusick #include "tree_ty.h"
3718347Smckusick 
383192Smckusick struct	nl *Fp;
393192Smckusick int	pnumcnt;
403192Smckusick /*
413192Smckusick  * Funcend is called to
423192Smckusick  * finish a block by generating
433192Smckusick  * the code for the statements.
443192Smckusick  * It then looks for unresolved declarations
453192Smckusick  * of labels, procedures and functions,
463192Smckusick  * and cleans up the name list.
473192Smckusick  * For the program, it checks the
483192Smckusick  * semantics of the program
493192Smckusick  * statement (yuchh).
503192Smckusick  */
513192Smckusick funcend(fp, bundle, endline)
523192Smckusick 	struct nl *fp;
5318347Smckusick 	struct tnode *bundle;
543192Smckusick 	int endline;
553192Smckusick {
563192Smckusick 	register struct nl *p;
573192Smckusick 	register int i, b;
5818347Smckusick 	int inp, out;
5918347Smckusick 	struct tnode *blk;
603192Smckusick 	bool chkref;
613192Smckusick 	struct nl *iop;
623192Smckusick 	char *cp;
633192Smckusick 	extern int cntstat;
643192Smckusick #	ifdef PC
6510671Speter 	    struct entry_exit_cookie	eecookie;
663192Smckusick #	endif PC
6718347Smckusick #	ifndef PC
6818347Smckusick 	int var;
6918347Smckusick #	endif PC
703192Smckusick 
713192Smckusick 	cntstat = 0;
723192Smckusick /*
733192Smckusick  *	yyoutline();
743192Smckusick  */
753192Smckusick 	if (program != NIL)
763192Smckusick 		line = program->value[3];
7718347Smckusick 	blk = bundle->stmnt_blck.stmnt_list;
783192Smckusick 	if (fp == NIL) {
793192Smckusick 		cbn--;
803192Smckusick #		ifdef PTREE
813192Smckusick 		    nesting--;
823192Smckusick #		endif PTREE
833192Smckusick 		return;
843192Smckusick 	}
853192Smckusick #ifdef OBJ
863192Smckusick 	/*
87*30039Smckusick 	 * Patch the branch to the entry point of the function.
88*30039Smckusick 	 * Assure alignment of O_BEG structure.
893192Smckusick 	 */
90*30039Smckusick 	if (((int)lc & 02) == 0)
91*30039Smckusick 		word(0);
9218347Smckusick 	patch4((PTR_DCL) fp->value[NL_ENTLOC]);
933192Smckusick 	/*
943192Smckusick 	 * Put out the block entrance code and the block name.
953192Smckusick 	 * HDRSZE is the number of bytes of info in the static
963192Smckusick 	 * BEG data area exclusive of the proc name. It is
973192Smckusick 	 * currently defined as:
983192Smckusick 	/*	struct hdr {
993192Smckusick 	/*		long framesze;	/* number of bytes of local vars */
1003192Smckusick 	/*		long nargs;	/* number of bytes of arguments */
1013192Smckusick 	/*		bool tests;	/* TRUE => perform runtime tests */
1023192Smckusick 	/*		short offset;	/* offset of procedure in source file */
1033192Smckusick 	/*		char name[1];	/* name of active procedure */
1043192Smckusick 	/*	};
1053192Smckusick 	 */
1063192Smckusick #	define HDRSZE (2 * sizeof(long) + sizeof(short) + sizeof(bool))
1073192Smckusick 	var = put(2, ((lenstr(fp->symbol,0) + HDRSZE) << 8)
1083192Smckusick 		| (cbn == 1 && opt('p') == 0 ? O_NODUMP: O_BEG), (long)0);
1093192Smckusick 	    /*
1103192Smckusick 	     *  output the number of bytes of arguments
1113192Smckusick 	     *  this is only checked on formal calls.
1123192Smckusick 	     */
11318347Smckusick 	(void) put(2, O_CASE4, cbn == 1 ? (long)0 : (long)(fp->value[NL_OFFS]-DPOFF2));
1143192Smckusick 	    /*
1153192Smckusick 	     *	Output the runtime test mode for the routine
1163192Smckusick 	     */
11718347Smckusick 	(void) put(2, sizeof(bool) == 2 ? O_CASE2 : O_CASE4, opt('t') ? TRUE : FALSE);
1183192Smckusick 	    /*
1193192Smckusick 	     *	Output line number and routine name
1203192Smckusick 	     */
12118347Smckusick 	(void) put(2, O_CASE2, bundle->stmnt_blck.line_no);
1223192Smckusick 	putstr(fp->symbol, 0);
1233192Smckusick #endif OBJ
1243192Smckusick #ifdef PC
1253192Smckusick 	/*
1263192Smckusick 	 * put out the procedure entry code
1273192Smckusick 	 */
12810671Speter 	eecookie.nlp = fp;
1293192Smckusick 	if ( fp -> class == PROG ) {
1309129Smckusick 		/*
1319129Smckusick 		 *	If there is a label declaration in the main routine
1329129Smckusick 		 *	then there may be a non-local goto to it that does
1339129Smckusick 		 *	not appear in this module. We have to assume that
1349129Smckusick 		 *	such a reference may occur and generate code to
1359129Smckusick 		 *	prepare for it.
1369129Smckusick 		 */
1379129Smckusick 	    if ( parts[ cbn ] & LPRT ) {
1389129Smckusick 		parts[ cbn ] |= ( NONLOCALVAR | NONLOCALGOTO );
1399129Smckusick 	    }
14010671Speter 	    codeformain();
1417917Smckusick 	    ftnno = fp -> value[NL_ENTLOC];
14210671Speter 	    prog_prologue(&eecookie);
14318347Smckusick 	    stabline(bundle->stmnt_blck.line_no);
14418347Smckusick 	    stabfunc(fp, "program", bundle->stmnt_blck.line_no , (long) 0 );
1453192Smckusick 	} else {
1467917Smckusick 	    ftnno = fp -> value[NL_ENTLOC];
14710671Speter 	    fp_prologue(&eecookie);
14818347Smckusick 	    stabline(bundle->stmnt_blck.line_no);
14918347Smckusick 	    stabfunc(fp, fp->symbol, bundle->stmnt_blck.line_no,
15018347Smckusick 		(long)(cbn - 1));
1513192Smckusick 	    for ( p = fp -> chain ; p != NIL ; p = p -> chain ) {
15218347Smckusick 		stabparam( p , p -> value[ NL_OFFS ] , (int) lwidth(p->type));
1533192Smckusick 	    }
1543192Smckusick 	    if ( fp -> class == FUNC ) {
1553192Smckusick 		    /*
1563192Smckusick 		     *	stab the function variable
1573192Smckusick 		     */
1583192Smckusick 		p = fp -> ptr[ NL_FVAR ];
15918347Smckusick 		stablvar( p , p -> value[ NL_OFFS ] , (int) lwidth( p -> type));
1603192Smckusick 	    }
1613192Smckusick 		/*
1623192Smckusick 		 *	stab local variables
1633192Smckusick 		 *	rummage down hash chain links.
1643192Smckusick 		 */
1653192Smckusick 	    for ( i = 0 ; i <= 077 ; i++ ) {
1663192Smckusick 		for ( p = disptab[ i ] ; p != NIL ; p = p->nl_next) {
1673192Smckusick 		    if ( ( p -> nl_block & 037 ) != cbn ) {
1683192Smckusick 			break;
1693192Smckusick 		    }
1703192Smckusick 		    /*
17118346Smckusick 		     *	stab locals (not parameters)
1723192Smckusick 		     */
17318347Smckusick 		    if ( p -> symbol != NIL ) {
17418347Smckusick 			if ( p -> class == VAR && p -> value[ NL_OFFS ] < 0 ) {
17518347Smckusick 			    stablvar( p , p -> value[ NL_OFFS ] ,
17618347Smckusick 				(int) lwidth( p -> type ) );
17718347Smckusick 			} else if ( p -> class == CONST ) {
17818347Smckusick 			    stabconst( p );
17918346Smckusick 			}
1803192Smckusick 		    }
1813192Smckusick 		}
1823192Smckusick 	    }
1833192Smckusick 	}
1843192Smckusick 	stablbrac( cbn );
1853192Smckusick 	    /*
1863192Smckusick 	     *	ask second pass to allocate known locals
1873192Smckusick 	     */
18811337Speter 	putlbracket(ftnno, &sizes[cbn]);
18910671Speter 	fp_entrycode(&eecookie);
1903192Smckusick #endif PC
1913192Smckusick 	if ( monflg ) {
1923192Smckusick 		if ( fp -> value[ NL_CNTR ] != 0 ) {
1933192Smckusick 			inccnt( fp -> value [ NL_CNTR ] );
1943192Smckusick 		}
1953192Smckusick 		inccnt( bodycnts[ fp -> nl_block & 037 ] );
1963192Smckusick 	}
1973192Smckusick 	if (fp->class == PROG) {
1983192Smckusick 		/*
1993192Smckusick 		 * The glorious buffers option.
2003192Smckusick 		 *          0 = don't buffer output
2013192Smckusick 		 *          1 = line buffer output
2023192Smckusick 		 *          2 = 512 byte buffer output
2033192Smckusick 		 */
2043192Smckusick #		ifdef OBJ
2053192Smckusick 		    if (opt('b') != 1)
20618347Smckusick 			    (void) put(1, O_BUFF | opt('b') << 8);
2073192Smckusick #		endif OBJ
2083192Smckusick #		ifdef PC
2093192Smckusick 		    if ( opt( 'b' ) != 1 ) {
21018457Sralph 			putleaf( PCC_ICON , 0 , 0
21118457Sralph 				, PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) , "_BUFF" );
21218457Sralph 			putleaf( PCC_ICON , opt( 'b' ) , 0 , PCCT_INT , (char *) 0 );
21318457Sralph 			putop( PCC_CALL , PCCT_INT );
2143192Smckusick 			putdot( filename , line );
2153192Smckusick 		    }
2163192Smckusick #		endif PC
2177953Speter 		inp = 0;
2183192Smckusick 		out = 0;
2193192Smckusick 		for (p = fp->chain; p != NIL; p = p->chain) {
22018347Smckusick 			if (pstrcmp(p->symbol, input->symbol) == 0) {
2213192Smckusick 				inp++;
2223192Smckusick 				continue;
2233192Smckusick 			}
22418347Smckusick 			if (pstrcmp(p->symbol, output->symbol) == 0) {
2253192Smckusick 				out++;
2263192Smckusick 				continue;
2273192Smckusick 			}
2283192Smckusick 			iop = lookup1(p->symbol);
2293192Smckusick 			if (iop == NIL || bn != cbn) {
2303192Smckusick 				error("File %s listed in program statement but not declared", p->symbol);
2313192Smckusick 				continue;
2323192Smckusick 			}
2333192Smckusick 			if (iop->class != VAR) {
2343192Smckusick 				error("File %s listed in program statement but declared as a %s", p->symbol, classes[iop->class]);
2353192Smckusick 				continue;
2363192Smckusick 			}
2373192Smckusick 			if (iop->type == NIL)
2383192Smckusick 				continue;
2393192Smckusick 			if (iop->type->class != FILET) {
2403192Smckusick 				error("File %s listed in program statement but defined as %s",
2413192Smckusick 					p->symbol, nameof(iop->type));
2423192Smckusick 				continue;
2433192Smckusick 			}
2443192Smckusick #			ifdef OBJ
24518347Smckusick 			    (void) put(2, O_CON24, text(iop->type) ? 0 : width(iop->type->type));
2463192Smckusick 			    i = lenstr(p->symbol,0);
24718347Smckusick 			    (void) put(2, O_CON24, i);
24818347Smckusick 			    (void) put(2, O_LVCON, i);
2493192Smckusick 			    putstr(p->symbol, 0);
25018347Smckusick 			    (void) put(2, O_LV | bn<<8+INDX, (int)iop->value[NL_OFFS]);
25118347Smckusick 			    (void) put(1, O_DEFNAME);
2523192Smckusick #			endif OBJ
2533192Smckusick #			ifdef PC
25418457Sralph 			    putleaf( PCC_ICON , 0 , 0
25518457Sralph 				    , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
2563192Smckusick 				    , "_DEFNAME" );
2573837Speter 			    putLV( p -> symbol , bn , iop -> value[NL_OFFS] ,
2583837Speter 				    iop -> extra_flags , p2type( iop ) );
2593192Smckusick 			    putCONG( p -> symbol , strlen( p -> symbol )
2603192Smckusick 				    , LREQ );
26118457Sralph 			    putop( PCC_CM , PCCT_INT );
26218457Sralph 			    putleaf( PCC_ICON , strlen( p -> symbol )
26318457Sralph 				    , 0 , PCCT_INT , (char *) 0 );
26418457Sralph 			    putop( PCC_CM , PCCT_INT );
26518457Sralph 			    putleaf( PCC_ICON
2663192Smckusick 				, text(iop->type) ? 0 : width(iop->type->type)
26718457Sralph 				, 0 , PCCT_INT , (char *) 0 );
26818457Sralph 			    putop( PCC_CM , PCCT_INT );
26918457Sralph 			    putop( PCC_CALL , PCCT_INT );
2703192Smckusick 			    putdot( filename , line );
2713192Smckusick #			endif PC
2723192Smckusick 		}
2733192Smckusick 	}
2743192Smckusick 	/*
2753192Smckusick 	 * Process the prog/proc/func body
2763192Smckusick 	 */
27718347Smckusick 	noreach = FALSE;
27818347Smckusick 	line = bundle->stmnt_blck.line_no;
2793192Smckusick 	statlist(blk);
2803192Smckusick #	ifdef PTREE
2813192Smckusick 	    {
2823192Smckusick 		pPointer Body = tCopy( blk );
2833192Smckusick 
2843192Smckusick 		pDEF( PorFHeader[ nesting -- ] ).PorFBody = Body;
2853192Smckusick 	    }
2863192Smckusick #	endif PTREE
2873192Smckusick #	ifdef OBJ
28818347Smckusick 	    if (cbn== 1 && monflg != FALSE) {
28918347Smckusick 		    patchfil((PTR_DCL) (cntpatch - 2), (long)cnts, 2);
29018347Smckusick 		    patchfil((PTR_DCL) (nfppatch - 2), (long)pfcnt, 2);
2913192Smckusick 	    }
2923192Smckusick #	endif OBJ
2933192Smckusick #	ifdef PC
2943192Smckusick 	    if ( fp -> class == PROG && monflg ) {
29518457Sralph 		putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
2963192Smckusick 			, "_PMFLUSH" );
29718457Sralph 		putleaf( PCC_ICON , cnts , 0 , PCCT_INT , (char *) 0 );
29818457Sralph 		putleaf( PCC_ICON , pfcnt , 0 , PCCT_INT , (char *) 0 );
29918457Sralph 		putop( PCC_CM , PCCT_INT );
30018457Sralph 		putLV( PCPCOUNT , 0 , 0 , NGLOBAL , PCCT_INT );
30118457Sralph 		putop( PCC_CM , PCCT_INT );
30218457Sralph 		putop( PCC_CALL , PCCT_INT );
3033192Smckusick 		putdot( filename , line );
3043192Smckusick 	    }
3053192Smckusick #	endif PC
3067953Speter 	/*
3077953Speter 	 * Clean up the symbol table displays and check for unresolves
3087953Speter 	 */
3097953Speter 	line = endline;
3103192Smckusick 	if (fp->class == PROG && inp == 0 && (input->nl_flags & (NUSED|NMOD)) != 0) {
3113192Smckusick 		recovered();
3123192Smckusick 		error("Input is used but not defined in the program statement");
3133192Smckusick 	}
3147953Speter 	if (fp->class == PROG && out == 0 && (output->nl_flags & (NUSED|NMOD)) != 0) {
3157953Speter 		recovered();
3167953Speter 		error("Output is used but not defined in the program statement");
3177953Speter 	}
3183192Smckusick 	b = cbn;
3193192Smckusick 	Fp = fp;
32018347Smckusick 	chkref = (syneflg == errcnt[cbn] && opt('w') == 0)?TRUE:FALSE;
3213192Smckusick 	for (i = 0; i <= 077; i++) {
3223192Smckusick 		for (p = disptab[i]; p != NIL && (p->nl_block & 037) == b; p = p->nl_next) {
3233192Smckusick 			/*
3243192Smckusick 			 * Check for variables defined
3253192Smckusick 			 * but not referenced
3263192Smckusick 			 */
3273192Smckusick 			if (chkref && p->symbol != NIL)
3283192Smckusick 			switch (p->class) {
3293192Smckusick 				case FIELD:
3303192Smckusick 					/*
3313192Smckusick 					 * If the corresponding record is
3323192Smckusick 					 * unused, we shouldn't complain about
3333192Smckusick 					 * the fields.
3343192Smckusick 					 */
3353192Smckusick 				default:
3363192Smckusick 					if ((p->nl_flags & (NUSED|NMOD)) == 0) {
3373192Smckusick 						warning();
3383192Smckusick 						nerror("%s %s is neither used nor set", classes[p->class], p->symbol);
3393192Smckusick 						break;
3403192Smckusick 					}
3413192Smckusick 					/*
3423192Smckusick 					 * If a var parameter is either
3433192Smckusick 					 * modified or used that is enough.
3443192Smckusick 					 */
3453192Smckusick 					if (p->class == REF)
3463192Smckusick 						continue;
3473192Smckusick #					ifdef OBJ
3483192Smckusick 					    if ((p->nl_flags & NUSED) == 0) {
3493192Smckusick 						warning();
3503192Smckusick 						nerror("%s %s is never used", classes[p->class], p->symbol);
3513192Smckusick 						break;
3523192Smckusick 					    }
3533192Smckusick #					endif OBJ
3543192Smckusick #					ifdef PC
3553837Speter 					    if (((p->nl_flags & NUSED) == 0) && ((p->extra_flags & NEXTERN) == 0)) {
3563192Smckusick 						warning();
3573192Smckusick 						nerror("%s %s is never used", classes[p->class], p->symbol);
3583192Smckusick 						break;
3593192Smckusick 					    }
3603192Smckusick #					endif PC
3613192Smckusick 					if ((p->nl_flags & NMOD) == 0) {
3623192Smckusick 						warning();
3633192Smckusick 						nerror("%s %s is used but never set", classes[p->class], p->symbol);
3643192Smckusick 						break;
3653192Smckusick 					}
3663192Smckusick 				case LABEL:
3673192Smckusick 				case FVAR:
3683192Smckusick 				case BADUSE:
3693192Smckusick 					break;
3703192Smckusick 			}
3713192Smckusick 			switch (p->class) {
3723192Smckusick 				case BADUSE:
3733192Smckusick 					cp = "s";
37418347Smckusick 					/* This used to say ud_next
37518347Smckusick 					   that is not a member of nl so
37618347Smckusick 					   i changed it to nl_next,
37718347Smckusick 					   which may be wrong */
37818347Smckusick 					if (p->chain->nl_next == NIL)
3793192Smckusick 						cp++;
3803192Smckusick 					eholdnl();
3813192Smckusick 					if (p->value[NL_KINDS] & ISUNDEF)
3823192Smckusick 						nerror("%s undefined on line%s", p->symbol, cp);
3833192Smckusick 					else
3843192Smckusick 						nerror("%s improperly used on line%s", p->symbol, cp);
3853192Smckusick 					pnumcnt = 10;
38618347Smckusick 					pnums((struct udinfo *) p->chain);
3873192Smckusick 					pchr('\n');
3883192Smckusick 					break;
3893192Smckusick 
3903192Smckusick 				case FUNC:
3913192Smckusick 				case PROC:
3923192Smckusick #					ifdef OBJ
3933192Smckusick 					    if ((p->nl_flags & NFORWD))
3943192Smckusick 						nerror("Unresolved forward declaration of %s %s", classes[p->class], p->symbol);
3953192Smckusick #					endif OBJ
3963192Smckusick #					ifdef PC
3973837Speter 					    if ((p->nl_flags & NFORWD) && ((p->extra_flags & NEXTERN) == 0))
3983192Smckusick 						nerror("Unresolved forward declaration of %s %s", classes[p->class], p->symbol);
3993192Smckusick #					endif PC
4003192Smckusick 					break;
4013192Smckusick 
4023192Smckusick 				case LABEL:
4033192Smckusick 					if (p->nl_flags & NFORWD)
4043192Smckusick 						nerror("label %s was declared but not defined", p->symbol);
4053192Smckusick 					break;
4063192Smckusick 				case FVAR:
4073192Smckusick 					if ((p->nl_flags & NMOD) == 0)
4083192Smckusick 						nerror("No assignment to the function variable");
4093192Smckusick 					break;
4103192Smckusick 			}
4113192Smckusick 		}
4123192Smckusick 		/*
4133192Smckusick 		 * Pop this symbol
4143192Smckusick 		 * table slot
4153192Smckusick 		 */
4163192Smckusick 		disptab[i] = p;
4173192Smckusick 	}
4183192Smckusick 
4193192Smckusick #	ifdef OBJ
42018347Smckusick 	    (void) put(1, O_END);
4213192Smckusick #	endif OBJ
4223192Smckusick #	ifdef PC
42310671Speter 	    fp_exitcode(&eecookie);
42410671Speter 	    stabrbrac(cbn);
42510671Speter 	    putrbracket(ftnno);
42610671Speter 	    fp_epilogue(&eecookie);
42710671Speter 	    if (fp -> class != PROG) {
42810671Speter 		fp_formalentry(&eecookie);
4293192Smckusick 	    }
4303192Smckusick 		/*
4313192Smckusick 		 *	declare pcp counters, if any
4323192Smckusick 		 */
4333192Smckusick 	    if ( monflg && fp -> class == PROG ) {
4343192Smckusick 		putprintf( "	.data" , 0 );
43518457Sralph 		aligndot(PCCT_INT);
4363192Smckusick 		putprintf( "	.comm	" , 1 );
4373192Smckusick 		putprintf( PCPCOUNT , 1 );
4383192Smckusick 		putprintf( ",%d" , 0 , ( cnts + 1 ) * sizeof (long) );
4393192Smckusick 		putprintf( "	.text" , 0 );
4403192Smckusick 	    }
4413192Smckusick #	endif PC
4423192Smckusick #ifdef DEBUG
44318347Smckusick 	dumpnl(fp->ptr[2], (int) fp->symbol);
4443192Smckusick #endif
4455654Slinton 
4465654Slinton #ifdef OBJ
4473192Smckusick 	/*
4485654Slinton 	 * save the namelist for the debugger pdx
4495654Slinton 	 */
4505654Slinton 
45118347Smckusick 	savenl(fp->ptr[2], (int) fp->symbol);
4525654Slinton #endif
4535654Slinton 
4545654Slinton 	/*
4553192Smckusick 	 * Restore the
4563192Smckusick 	 * (virtual) name list
4573192Smckusick 	 * position
4583192Smckusick 	 */
4593192Smckusick 	nlfree(fp->ptr[2]);
4603192Smckusick 	/*
4613192Smckusick 	 * Proc/func has been
4623192Smckusick 	 * resolved
4633192Smckusick 	 */
4643192Smckusick 	fp->nl_flags &= ~NFORWD;
4653192Smckusick 	/*
4663192Smckusick 	 * Patch the beg
4673192Smckusick 	 * of the proc/func to
4683192Smckusick 	 * the proper variable size
4693192Smckusick 	 */
4703192Smckusick 	if (Fp == NIL)
4713192Smckusick 		elineon();
4723192Smckusick #	ifdef OBJ
47330037Smckusick 	    patchfil((PTR_DCL) var,
47430037Smckusick 		roundup(-sizes[cbn].om_max, (long) A_STACK), 2);
4753192Smckusick #	endif OBJ
4763192Smckusick 	cbn--;
4773192Smckusick 	if (inpflist(fp->symbol)) {
4783192Smckusick 		opop('l');
4793192Smckusick 	}
4803192Smckusick }
4813363Speter 
4823363Speter #ifdef PC
4833363Speter     /*
4843363Speter      *	construct the long name of a function based on it's static nesting.
4853363Speter      *	into a caller-supplied buffer (that should be about BUFSIZ big).
4863363Speter      */
4873363Speter sextname( buffer , name , level )
4883363Speter     char	buffer[];
4893363Speter     char	*name;
4903363Speter     int		level;
4913363Speter {
4923363Speter     char	*starthere;
4933363Speter     int	i;
4943363Speter 
4953363Speter     starthere = &buffer[0];
4963363Speter     for ( i = 1 ; i < level ; i++ ) {
4973363Speter 	sprintf( starthere , EXTFORMAT , enclosing[ i ] );
4983363Speter 	starthere += strlen( enclosing[ i ] ) + 1;
4993363Speter     }
5003367Speter     sprintf( starthere , EXTFORMAT , name );
5013367Speter     starthere += strlen( name ) + 1;
5023363Speter     if ( starthere >= &buffer[ BUFSIZ ] ) {
5033363Speter 	panic( "sextname" );
5043363Speter     }
5053363Speter }
50610671Speter 
50710671Speter     /*
50810671Speter      *	code for main()
50910671Speter      */
51010671Speter #ifdef vax
51110671Speter 
51210671Speter codeformain()
51310671Speter {
51410671Speter     putprintf("	.text" , 0 );
51510671Speter     putprintf("	.align	1" , 0 );
51610671Speter     putprintf("	.globl	_main" , 0 );
51710671Speter     putprintf("_main:" , 0 );
51810671Speter     putprintf("	.word	0" , 0 );
51910671Speter     if ( opt ( 't' ) ) {
52010671Speter 	putprintf("	pushl	$1" , 0 );
52110671Speter     } else {
52210671Speter 	putprintf("	pushl	$0" , 0 );
52310671Speter     }
52410671Speter     putprintf("	calls	$1,_PCSTART" , 0 );
52510671Speter     putprintf("	movl	4(ap),__argc" , 0 );
52610671Speter     putprintf("	movl	8(ap),__argv" , 0 );
52710671Speter     putprintf("	calls	$0,_program" , 0 );
52810671Speter     putprintf("	pushl	$0" , 0 );
52910671Speter     putprintf("	calls	$1,_PCEXIT" , 0 );
53010671Speter }
531*30039Smckusick #endif vax
53210671Speter 
533*30039Smckusick #ifdef tahoe
534*30039Smckusick codeformain()
535*30039Smckusick {
536*30039Smckusick     putprintf("	.text" , 0 );
537*30039Smckusick     putprintf("	.align	1" , 0 );
538*30039Smckusick     putprintf("	.globl	_main" , 0 );
539*30039Smckusick     putprintf("_main:" , 0 );
540*30039Smckusick     putprintf("	.word	0" , 0 );
541*30039Smckusick     if ( opt ( 't' ) ) {
542*30039Smckusick 	putprintf("	pushl	$1" , 0 );
543*30039Smckusick     } else {
544*30039Smckusick 	putprintf("	pushl	$0" , 0 );
545*30039Smckusick     }
546*30039Smckusick     putprintf("	callf	$8,_PCSTART" , 0 );
547*30039Smckusick     putprintf("	movl	4(fp),__argc" , 0 );
548*30039Smckusick     putprintf("	movl	8(fp),__argv" , 0 );
549*30039Smckusick     putprintf("	callf	$4,_program" , 0 );
550*30039Smckusick     putprintf("	pushl	$0" , 0 );
551*30039Smckusick     putprintf("	callf	$8,_PCEXIT" , 0 );
552*30039Smckusick }
553*30039Smckusick #endif tahoe
554*30039Smckusick 
55510671Speter     /*
55610671Speter      *	prologue for the program.
55710671Speter      *	different because it
55810671Speter      *		doesn't have formal entry point
55910671Speter      */
560*30039Smckusick #if defined(vax) || defined(tahoe)
56110671Speter prog_prologue(eecookiep)
56210671Speter     struct entry_exit_cookie	*eecookiep;
56310671Speter {
56410671Speter     putprintf("	.text" , 0 );
56510671Speter     putprintf("	.align	1" , 0 );
56610671Speter     putprintf("	.globl	_program" , 0 );
56710671Speter     putprintf("_program:" , 0 );
56810716Speter 	/*
56910716Speter 	 *	register save mask
57010716Speter 	 */
57118347Smckusick     eecookiep -> savlabel = (int) getlab();
57218347Smckusick     putprintf("	.word	%s%d", 0, (int) SAVE_MASK_LABEL , eecookiep -> savlabel );
57310671Speter }
57410671Speter 
57510671Speter fp_prologue(eecookiep)
57610671Speter     struct entry_exit_cookie	*eecookiep;
57710671Speter {
57810671Speter 
57910671Speter     sextname( eecookiep -> extname, eecookiep -> nlp -> symbol , cbn - 1 );
58010671Speter     putprintf( "	.text" , 0 );
58110671Speter     putprintf( "	.align	1" , 0 );
58218347Smckusick     putprintf( "	.globl	%s%s", 0, (int) FORMALPREFIX, (int) eecookiep -> extname );
58318347Smckusick     putprintf( "	.globl	%s" , 0 , (int) eecookiep -> extname );
58418347Smckusick     putprintf( "%s:" , 0 , (int) eecookiep -> extname );
58510671Speter 	/*
58610671Speter 	 *	register save mask
58710671Speter 	 */
58818347Smckusick     eecookiep -> savlabel = (int) getlab();
58918347Smckusick     putprintf("	.word	%s%d", 0, (int) SAVE_MASK_LABEL , eecookiep -> savlabel );
59010671Speter }
591*30039Smckusick #endif vax || tahoe
59210671Speter 
59310671Speter     /*
59410671Speter      *	code before any user code.
59510671Speter      *	or code that is machine dependent.
59610671Speter      */
597*30039Smckusick #ifdef vax
59810671Speter fp_entrycode(eecookiep)
59910671Speter     struct entry_exit_cookie	*eecookiep;
60010671Speter {
60110714Speter     int	ftnno = eecookiep -> nlp -> value[NL_ENTLOC];
60218347Smckusick     int	proflabel = (int) getlab();
60318347Smckusick     int	setjmp0 = (int) getlab();
60410671Speter 
60510671Speter 	/*
60610671Speter 	 *	top of code;  destination of jump from formal entry code.
60710671Speter 	 */
60818347Smckusick     eecookiep -> toplabel = (int) getlab();
60918347Smckusick     (void) putlab( (char *) eecookiep -> toplabel );
61018347Smckusick     putprintf("	subl2	$%s%d,sp" , 0 , (int) FRAME_SIZE_LABEL, ftnno );
61110671Speter     if ( profflag ) {
61210671Speter 	    /*
61310671Speter 	     *	call mcount for profiling
61410671Speter 	     */
61510671Speter 	putprintf( "	moval	" , 1 );
61618347Smckusick 	putprintf( PREFIXFORMAT , 1 , (int) LABELPREFIX , proflabel );
61710671Speter 	putprintf( ",r0" , 0 );
61810671Speter 	putprintf( "	jsb	mcount" , 0 );
61910671Speter 	putprintf( "	.data" , 0 );
62010671Speter 	putprintf( "	.align	2" , 0 );
62118347Smckusick 	(void) putlab( (char *) proflabel );
62210671Speter 	putprintf( "	.long	0" , 0 );
62310671Speter 	putprintf( "	.text" , 0 );
62410671Speter     }
62510671Speter 	/*
62610671Speter 	 *	if there are nested procedures that access our variables
62710671Speter 	 *	we must save the display.
62810671Speter 	 */
62910671Speter     if ( parts[ cbn ] & NONLOCALVAR ) {
63010671Speter 	    /*
63110671Speter 	     *	save old display
63210671Speter 	     */
63310671Speter 	putprintf( "	movq	%s+%d,%d(%s)" , 0
63418347Smckusick 		, (int) DISPLAYNAME , cbn * sizeof(struct dispsave)
63518347Smckusick 		, DSAVEOFFSET , (int) P2FPNAME );
63610671Speter 	    /*
63710671Speter 	     *	set up new display by saving AP and FP in appropriate
63810671Speter 	     *	slot in display structure.
63910671Speter 	     */
64010671Speter 	putprintf( "	movq	%s,%s+%d" , 0
64118347Smckusick 		, (int) P2APNAME , (int) DISPLAYNAME , cbn * sizeof(struct dispsave) );
64210671Speter     }
64310671Speter 	/*
64410671Speter 	 *	set underflow checking if runtime tests
64510671Speter 	 */
64610671Speter     if ( opt( 't' ) ) {
64710671Speter 	putprintf( "	bispsw	$0xe0" , 0 );
64810671Speter     }
64910671Speter 	/*
65010671Speter 	 *	zero local variables if checking is on
65110671Speter 	 *	by calling blkclr( bytes of locals , starting local address );
65210671Speter 	 */
65310671Speter     if ( opt( 't' ) && ( -sizes[ cbn ].om_max ) > DPOFF1 ) {
65418457Sralph 	putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
65510671Speter 		, "_blkclr" );
65618457Sralph 	putLV((char *) 0 , cbn , (int) sizes[ cbn ].om_max , NLOCAL , PCCT_CHAR );
65718457Sralph 	putleaf( PCC_ICON ,  (int) (( -sizes[ cbn ].om_max ) - DPOFF1)
65818457Sralph 		, 0 , PCCT_INT ,(char *) 0 );
65918457Sralph 	putop( PCC_CM , PCCT_INT );
66018457Sralph 	putop( PCC_CALL , PCCT_INT );
66110671Speter 	putdot( filename , line );
66210671Speter     }
66310671Speter 	/*
66410671Speter 	 *  set up goto vector if non-local goto to this frame
66510671Speter 	 */
66610671Speter     if ( parts[ cbn ] & NONLOCALGOTO ) {
66718457Sralph 	putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
66810671Speter 		, "_setjmp" );
66918457Sralph 	putLV( (char *) 0 , cbn , GOTOENVOFFSET , NLOCAL , PCCTM_PTR|PCCT_STRTY );
67018457Sralph 	putop( PCC_CALL , PCCT_INT );
67118457Sralph 	putleaf( PCC_ICON , 0 , 0 , PCCT_INT , (char *) 0 );
67218457Sralph 	putop( PCC_NE , PCCT_INT );
67318457Sralph 	putleaf( PCC_ICON , setjmp0 , 0 , PCCT_INT , (char *) 0 );
67418457Sralph 	putop( PCC_CBRANCH , PCCT_INT );
67510671Speter 	putdot( filename , line );
67610671Speter 	    /*
67710671Speter 	     *	on non-local goto, setjmp returns with address to
67810671Speter 	     *	be branched to.
67910671Speter 	     */
68010671Speter 	putprintf( "	jmp	(r0)" , 0 );
68118347Smckusick 	(void) putlab((char *) setjmp0);
68210671Speter     }
68310671Speter }
684*30039Smckusick #endif vax
68510671Speter 
686*30039Smckusick #ifdef tahoe
687*30039Smckusick fp_entrycode(eecookiep)
688*30039Smckusick     struct entry_exit_cookie	*eecookiep;
689*30039Smckusick {
690*30039Smckusick     int	ftnno = eecookiep -> nlp -> value[NL_ENTLOC];
691*30039Smckusick     int	proflabel = (int) getlab();
692*30039Smckusick     int	setjmp0 = (int) getlab();
693*30039Smckusick 
694*30039Smckusick 	/*
695*30039Smckusick 	 *	top of code;  destination of jump from formal entry code.
696*30039Smckusick 	 */
697*30039Smckusick     eecookiep -> toplabel = (int) getlab();
698*30039Smckusick     (void) putlab( (char *) eecookiep -> toplabel );
699*30039Smckusick     putprintf("	subl3	$%s%d,fp,sp" , 0 , (int) FRAME_SIZE_LABEL, ftnno );
700*30039Smckusick     if ( profflag ) {
701*30039Smckusick 	    /*
702*30039Smckusick 	     *	call mcount for profiling
703*30039Smckusick 	     */
704*30039Smckusick 	putprintf( "	pushal	" , 1 );
705*30039Smckusick 	putprintf( PREFIXFORMAT , 1 , (int) LABELPREFIX , proflabel, 0 );
706*30039Smckusick 	putprintf( "	callf	$8,mcount" , 0 );
707*30039Smckusick 	putprintf( "	.data" , 0 );
708*30039Smckusick 	putprintf( "	.align	2" , 0 );
709*30039Smckusick 	(void) putlab( (char *) proflabel );
710*30039Smckusick 	putprintf( "	.long	0" , 0 );
711*30039Smckusick 	putprintf( "	.text" , 0 );
712*30039Smckusick     }
713*30039Smckusick 	/*
714*30039Smckusick 	 *	if there are nested procedures that access our variables
715*30039Smckusick 	 *	we must save the display.
716*30039Smckusick 	 */
717*30039Smckusick     if ( parts[ cbn ] & NONLOCALVAR ) {
718*30039Smckusick 	    /*
719*30039Smckusick 	     *	save old display
720*30039Smckusick 	     */
721*30039Smckusick 	putprintf( "	movl	%s+%d,%d(%s)" , 0
722*30039Smckusick 		, (int) DISPLAYNAME , cbn * sizeof(struct dispsave)
723*30039Smckusick 		, DSAVEOFFSET , (int) P2FPNAME );
724*30039Smckusick 	    /*
725*30039Smckusick 	     *	set up new display by saving FP in appropriate
726*30039Smckusick 	     *	slot in display structure.
727*30039Smckusick 	     */
728*30039Smckusick 	putprintf( "	movl	%s,%s+%d" , 0
729*30039Smckusick 		, (int) P2FPNAME , (int) DISPLAYNAME , cbn * sizeof(struct dispsave) );
730*30039Smckusick     }
731*30039Smckusick 	/*
732*30039Smckusick 	 *	set underflow checking if runtime tests
733*30039Smckusick 	 */
734*30039Smckusick     if ( opt( 't' ) ) {
735*30039Smckusick 	putprintf( "	bicpsw	$0x20" , 0 );
736*30039Smckusick     }
737*30039Smckusick 	/*
738*30039Smckusick 	 *	zero local variables if checking is on
739*30039Smckusick 	 *	by calling blkclr( bytes of locals , starting local address );
740*30039Smckusick 	 */
741*30039Smckusick     if ( opt( 't' ) && ( -sizes[ cbn ].om_max ) > DPOFF1 ) {
742*30039Smckusick 	putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
743*30039Smckusick 		, "_blkclr" );
744*30039Smckusick 	putLV((char *) 0 , cbn , (int) sizes[ cbn ].om_max , NLOCAL , PCCT_CHAR );
745*30039Smckusick 	putleaf( PCC_ICON ,  (int) (( -sizes[ cbn ].om_max ) - DPOFF1)
746*30039Smckusick 		, 0 , PCCT_INT ,(char *) 0 );
747*30039Smckusick 	putop( PCC_CM , PCCT_INT );
748*30039Smckusick 	putop( PCC_CALL , PCCT_INT );
749*30039Smckusick 	putdot( filename , line );
750*30039Smckusick     }
751*30039Smckusick 	/*
752*30039Smckusick 	 *  set up goto vector if non-local goto to this frame
753*30039Smckusick 	 */
754*30039Smckusick     if ( parts[ cbn ] & NONLOCALGOTO ) {
755*30039Smckusick 	putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
756*30039Smckusick 		, "_setjmp" );
757*30039Smckusick 	putLV( (char *) 0 , cbn , GOTOENVOFFSET , NLOCAL , PCCTM_PTR|PCCT_STRTY );
758*30039Smckusick 	putop( PCC_CALL , PCCT_INT );
759*30039Smckusick 	putleaf( PCC_ICON , 0 , 0 , PCCT_INT , (char *) 0 );
760*30039Smckusick 	putop( PCC_NE , PCCT_INT );
761*30039Smckusick 	putleaf( PCC_ICON , setjmp0 , 0 , PCCT_INT , (char *) 0 );
762*30039Smckusick 	putop( PCC_CBRANCH , PCCT_INT );
763*30039Smckusick 	putdot( filename , line );
764*30039Smckusick 	    /*
765*30039Smckusick 	     *	on non-local goto, setjmp returns with address to
766*30039Smckusick 	     *	be branched to.
767*30039Smckusick 	     */
768*30039Smckusick 	putprintf( "	jmp	(r0)" , 0 );
769*30039Smckusick 	(void) putlab((char *) setjmp0);
770*30039Smckusick     }
771*30039Smckusick }
772*30039Smckusick #endif tahoe
773*30039Smckusick 
774*30039Smckusick #if defined(vax) || defined(tahoe)
77510671Speter fp_exitcode(eecookiep)
77610671Speter     struct entry_exit_cookie	*eecookiep;
77710671Speter {
77810671Speter 	/*
77910671Speter 	 *	if there were file variables declared at this level
78010671Speter 	 *	call PCLOSE( ap ) to clean them up.
78110671Speter 	 */
78210671Speter     if ( dfiles[ cbn ] ) {
78318457Sralph 	putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
78410671Speter 		, "_PCLOSE" );
78518457Sralph 	putleaf( PCC_REG , 0 , P2AP , PCCM_ADDTYPE( PCCT_CHAR , PCCTM_PTR ) , (char *) 0 );
78618457Sralph 	putop( PCC_CALL , PCCT_INT );
78710671Speter 	putdot( filename , line );
78810671Speter     }
78910671Speter 	/*
79010671Speter 	 *	if this is a function,
79110671Speter 	 *	the function variable is the return value.
79210671Speter 	 *	if it's a scalar valued function, return scalar,
79310671Speter 	 *	else, return a pointer to the structure value.
79410671Speter 	 */
79510671Speter     if ( eecookiep-> nlp -> class == FUNC ) {
79610671Speter 	struct nl	*fvar = eecookiep-> nlp -> ptr[ NL_FVAR ];
79710671Speter 	long		fvartype = p2type( fvar -> type );
79810671Speter 	long		label;
79910671Speter 	char		labelname[ BUFSIZ ];
80010671Speter 
80110671Speter 	switch ( classify( fvar -> type ) ) {
80210671Speter 	    case TBOOL:
80310671Speter 	    case TCHAR:
80410671Speter 	    case TINT:
80510671Speter 	    case TSCAL:
80610671Speter 	    case TDOUBLE:
80710671Speter 	    case TPTR:
80810671Speter 		putRV( fvar -> symbol , ( fvar -> nl_block ) & 037 ,
80910671Speter 			fvar -> value[ NL_OFFS ] ,
81010671Speter 			fvar -> extra_flags ,
81118347Smckusick 			(int) fvartype );
81218457Sralph 		putop( PCC_FORCE , (int) fvartype );
81310671Speter 		break;
81410671Speter 	    default:
81518347Smckusick 		label = (int) getlab();
81610671Speter 		sprintf( labelname , PREFIXFORMAT , LABELPREFIX , label );
81710671Speter 		putprintf( "	.data" , 0 );
81810671Speter 		aligndot(A_STRUCT);
81910671Speter 		putprintf( "	.lcomm	%s,%d" , 0 ,
82018347Smckusick 			    (int) labelname , (int) lwidth( fvar -> type ) );
82110671Speter 		putprintf( "	.text" , 0 );
82218457Sralph 		putleaf( PCC_NAME , 0 , 0 , (int) fvartype , labelname );
82310671Speter 		putLV( fvar -> symbol , ( fvar -> nl_block ) & 037 ,
82410671Speter 			fvar -> value[ NL_OFFS ] ,
82510671Speter 			fvar -> extra_flags ,
82618347Smckusick 			(int) fvartype );
82718457Sralph 		putstrop( PCC_STASG , (int) PCCM_ADDTYPE(fvartype, PCCTM_PTR) ,
82818347Smckusick 			(int) lwidth( fvar -> type ) ,
82910671Speter 			align( fvar -> type ) );
83010671Speter 		putdot( filename , line );
83118457Sralph 		putleaf( PCC_ICON , 0 , 0 , (int) PCCM_ADDTYPE(fvartype, PCCTM_PTR), labelname );
83218457Sralph 		putop( PCC_FORCE , (int) PCCM_ADDTYPE(fvartype, PCCTM_PTR) );
83310671Speter 		break;
83410671Speter 	}
83510671Speter 	putdot( filename , line );
83610671Speter     }
83710671Speter 	/*
83810671Speter 	 *	if there are nested procedures we must save the display.
83910671Speter 	 */
84010671Speter     if ( parts[ cbn ] & NONLOCALVAR ) {
84110671Speter 	    /*
84210671Speter 	     *	restore old display entry from save area
84310671Speter 	     */
844*30039Smckusick #ifdef vax
84510671Speter 	putprintf( "	movq	%d(%s),%s+%d" , 0
84618347Smckusick 	    , DSAVEOFFSET , (int) P2FPNAME
84718347Smckusick 	    , (int) DISPLAYNAME , cbn * sizeof(struct dispsave) );
848*30039Smckusick #endif
849*30039Smckusick #ifdef tahoe
850*30039Smckusick 	putprintf( "	movl	%d(%s),%s+%d" , 0
851*30039Smckusick 	    , DSAVEOFFSET , (int) P2FPNAME
852*30039Smckusick 	    , (int) DISPLAYNAME , cbn * sizeof(struct dispsave) );
853*30039Smckusick #endif
85410671Speter     }
85510671Speter }
856*30039Smckusick #endif vax || tahoe
85710671Speter 
858*30039Smckusick #if defined(vax) || defined(tahoe)
85910671Speter fp_epilogue(eecookiep)
86010671Speter     struct entry_exit_cookie	*eecookiep;
86110671Speter {
86218346Smckusick     stabline(line);
86310671Speter     putprintf("	ret" , 0 );
86410671Speter 	/*
86510671Speter 	 *	set the register save mask.
86610671Speter 	 */
86710671Speter     putprintf("	.set	%s%d,0x%x", 0,
86818347Smckusick 		(int) SAVE_MASK_LABEL, eecookiep -> savlabel, savmask());
86910671Speter }
870*30039Smckusick #endif vax || tahoe
87110671Speter 
872*30039Smckusick #if defined(vax) || defined(tahoe)
87310671Speter fp_formalentry(eecookiep)
87410671Speter     struct entry_exit_cookie	*eecookiep;
87510671Speter {
87610671Speter 
87711857Speter     putprintf("	.align 1", 0);
87818347Smckusick     putprintf("%s%s:" , 0 , (int) FORMALPREFIX , (int) eecookiep -> extname );
87918347Smckusick     putprintf("	.word	%s%d", 0, (int) SAVE_MASK_LABEL, eecookiep -> savlabel );
88018457Sralph     putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) , "_FCALL" );
88118347Smckusick     putRV((char *) 0 , cbn ,
88210671Speter 	eecookiep -> nlp -> value[ NL_OFFS ] + sizeof( struct formalrtn * ) ,
88318457Sralph 	NPARAM , PCCTM_PTR | PCCT_STRTY );
88418457Sralph     putRV((char *) 0, cbn, eecookiep -> nlp -> value[NL_OFFS], NPARAM, PCCTM_PTR|PCCT_STRTY);
88518457Sralph     putop( PCC_CM , PCCT_INT );
88618457Sralph     putop( PCC_CALL , PCCT_INT );
88710671Speter     putdot( filename , line );
88818347Smckusick     putjbr( (long) eecookiep -> toplabel );
88910671Speter }
890*30039Smckusick #endif vax || tahoe
89110671Speter 
89210671Speter #ifdef mc68000
89310671Speter 
89410671Speter codeformain()
89510671Speter {
89610671Speter     putprintf("	.text", 0);
89710671Speter     putprintf("	.globl	_main", 0);
89810671Speter     putprintf("_main:", 0);
89910671Speter     putprintf("	link	%s,#0", 0, P2FPNAME);
90010671Speter     if (opt('t')) {
90110671Speter 	putprintf("	pea	1", 0);
90210671Speter     } else {
90310671Speter 	putprintf("	pea	0", 0);
90410671Speter     }
90510671Speter     putprintf("	jbsr	_PCSTART", 0);
90610671Speter     putprintf("	addql	#4,sp", 0);
90710671Speter     putprintf("	movl	%s@(8),__argc", 0, P2FPNAME);
90810671Speter     putprintf("	movl	%s@(12),__argv", 0, P2FPNAME);
90910671Speter     putprintf("	jbsr	_program", 0);
91010671Speter     putprintf("	pea	0", 0);
91110671Speter     putprintf("	jbsr	_PCEXIT", 0);
91210671Speter }
91310671Speter 
91410671Speter prog_prologue(eecookiep)
91510671Speter     struct entry_exit_cookie	*eecookiep;
91610671Speter {
91710671Speter     int	ftnno = eecookiep -> nlp -> value[NL_ENTLOC];
91810671Speter 
91910671Speter     putprintf("	.text", 0);
92010671Speter     putprintf("	.globl	_program", 0);
92110671Speter     putprintf("_program:", 0);
92210671Speter     putprintf("	link	%s,#0", 0, P2FPNAME);
92310671Speter     putprintf("	addl	#-%s%d,sp", 0, FRAME_SIZE_LABEL, ftnno);
92410671Speter 	/* touch new end of stack, to break more stack space */
92510671Speter     putprintf("	tstb	sp@(-%s%d)", 0, PAGE_BREAK_LABEL, ftnno);
92610671Speter     putprintf("	moveml	#%s%d,sp@", 0, SAVE_MASK_LABEL, ftnno);
92710671Speter }
92810671Speter 
92910671Speter fp_prologue(eecookiep)
93010671Speter     struct entry_exit_cookie	*eecookiep;
93110671Speter {
93210671Speter     int		ftnno = eecookiep -> nlp -> value[NL_ENTLOC];
93310671Speter 
93410671Speter     sextname(eecookiep -> extname, eecookiep -> nlp -> symbol, cbn - 1);
93510671Speter     putprintf("	.text", 0);
93610671Speter     putprintf("	.globl	%s%s", 0, FORMALPREFIX, eecookiep -> extname);
93710671Speter     putprintf("	.globl	%s", 0, eecookiep -> extname);
93810671Speter     putprintf("%s:", 0, eecookiep -> extname);
93910671Speter     putprintf("	link	%s,#0", 0, P2FPNAME);
94010671Speter     putprintf("	addl	#-%s%d,sp", 0, FRAME_SIZE_LABEL, ftnno);
94110671Speter 	/* touch new end of stack, to break more stack space */
94210671Speter     putprintf("	tstb	sp@(-%s%d)", 0, PAGE_BREAK_LABEL, ftnno);
94310671Speter     putprintf("	moveml	#%s%d,sp@", 0, SAVE_MASK_LABEL, ftnno);
94410671Speter }
94510671Speter 
94610671Speter fp_entrycode(eecookiep)
94710671Speter     struct entry_exit_cookie	*eecookiep;
94810671Speter {
94918347Smckusick     char *proflabel = getlab();
95018347Smckusick     char *setjmp0 = getlab();
95110671Speter 
95210671Speter 	/*
95310671Speter 	 *	fill in the label cookie
95410671Speter 	 */
95510671Speter     eecookiep -> toplabel = getlab();
95618347Smckusick     (void) putlab(eecookiep -> toplabel);
95710671Speter 	/*
95810671Speter 	 *	call mcount if we are profiling.
95910671Speter 	 */
96010671Speter     if ( profflag ) {
96110671Speter 	putprintf("	movl	#%s%d,a0", 0, LABELPREFIX,  proflabel);
96210671Speter 	putprintf("	jsr	mcount", 0);
96310671Speter 	putprintf("	.data", 0);
96410671Speter 	putprintf("	.even", 0);
96518347Smckusick 	(void) putlab(proflabel);
96610671Speter 	putprintf("	.long	0", 0);
96710671Speter 	putprintf("	.text", 0);
96810671Speter     }
96910671Speter 	/*
97010671Speter 	 *	if there are nested procedures that access our variables
97110671Speter 	 *	we must save the display
97210671Speter 	 */
97310671Speter     if (parts[cbn] & NONLOCALVAR) {
97410671Speter 	    /*
97510671Speter 	     *	save the old display
97610671Speter 	     */
97710671Speter 	putprintf("	movl	%s+%d,%s@(%d)", 0,
97810671Speter 		    DISPLAYNAME, cbn * sizeof(struct dispsave),
97910671Speter 		    P2FPNAME, DSAVEOFFSET);
98010671Speter 	    /*
98110671Speter 	     *	set up the new display by saving the framepointer
98210671Speter 	     *	in the display structure.
98310671Speter 	     */
98410671Speter 	putprintf("	movl	%s,%s+%d", 0,
98510671Speter 		    P2FPNAME, DISPLAYNAME, cbn * sizeof(struct dispsave));
98610671Speter     }
98710671Speter 	/*
98810671Speter 	 *	zero local variables if checking is on
98910671Speter 	 *	by calling blkclr( bytes of locals , starting local address );
99010671Speter 	 */
99110671Speter     if ( opt( 't' ) && ( -sizes[ cbn ].om_max ) > DPOFF1 ) {
99218457Sralph 	putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
99310671Speter 		, "_blkclr" );
99418457Sralph 	putLV( 0 , cbn , sizes[ cbn ].om_max , NLOCAL , PCCT_CHAR );
99518457Sralph 	putleaf( PCC_ICON ,  ( -sizes[ cbn ].om_max ) - DPOFF1
99618457Sralph 		, 0 , PCCT_INT , 0 );
99718457Sralph 	putop( PCC_CM , PCCT_INT );
99818457Sralph 	putop( PCC_CALL , PCCT_INT );
99910671Speter 	putdot( filename , line );
100010671Speter     }
100110671Speter 	/*
100210671Speter 	 *  set up goto vector if non-local goto to this frame
100310671Speter 	 */
100410671Speter     if ( parts[ cbn ] & NONLOCALGOTO ) {
100518457Sralph 	putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
100610671Speter 		, "_setjmp" );
100718457Sralph 	putLV( 0 , cbn , GOTOENVOFFSET , NLOCAL , PCCTM_PTR|PCCT_STRTY );
100818457Sralph 	putop( PCC_CALL , PCCT_INT );
100918457Sralph 	putleaf( PCC_ICON , 0 , 0 , PCCT_INT , 0 );
101018457Sralph 	putop( PCC_NE , PCCT_INT );
101118457Sralph 	putleaf( PCC_ICON , setjmp0 , 0 , PCCT_INT , 0 );
101218457Sralph 	putop( PCC_CBRANCH , PCCT_INT );
101310671Speter 	putdot( filename , line );
101410671Speter 	    /*
101510671Speter 	     *	on non-local goto, setjmp returns with address to
101610671Speter 	     *	be branched to.
101710671Speter 	     */
101810671Speter 	putprintf("	movl	d0,a0", 0);
101910671Speter 	putprintf("	jmp	a0@", 0);
102018347Smckusick 	(void) putlab(setjmp0);
102110671Speter     }
102210671Speter }
102310671Speter 
102410671Speter fp_exitcode(eecookiep)
102510671Speter     struct entry_exit_cookie	*eecookiep;
102610671Speter {
102710671Speter 	/*
102810671Speter 	 *	if there were file variables declared at this level
102910671Speter 	 *	call PCLOSE( ap ) to clean them up.
103010671Speter 	 */
103110671Speter     if ( dfiles[ cbn ] ) {
103218457Sralph 	putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
103310671Speter 		, "_PCLOSE" );
103418457Sralph 	putleaf( PCC_REG , 0 , P2AP , PCCM_ADDTYPE( PCCT_CHAR , PCCTM_PTR ) , 0 );
103518457Sralph 	putop( PCC_CALL , PCCT_INT );
103610671Speter 	putdot( filename , line );
103710671Speter     }
103810671Speter 	/*
103910671Speter 	 *	if this is a function,
104010671Speter 	 *	the function variable is the return value.
104110671Speter 	 *	if it's a scalar valued function, return scalar,
104210671Speter 	 *	else, return a pointer to the structure value.
104310671Speter 	 */
104410671Speter     if ( eecookiep -> nlp -> class == FUNC ) {
104510671Speter 	struct nl	*fvar = eecookiep -> nlp -> ptr[ NL_FVAR ];
104610671Speter 	long		fvartype = p2type( fvar -> type );
104718347Smckusick 	char		*label;
104810671Speter 	char		labelname[ BUFSIZ ];
104910671Speter 
105010671Speter 	switch ( classify( fvar -> type ) ) {
105110671Speter 	    case TBOOL:
105210671Speter 	    case TCHAR:
105310671Speter 	    case TINT:
105410671Speter 	    case TSCAL:
105510671Speter 	    case TDOUBLE:
105610671Speter 	    case TPTR:
105710671Speter 		putRV( fvar -> symbol , ( fvar -> nl_block ) & 037 ,
105810671Speter 			fvar -> value[ NL_OFFS ] ,
105910671Speter 			fvar -> extra_flags ,
106010671Speter 			fvartype );
106118457Sralph 		putop( PCC_FORCE , fvartype );
106210671Speter 		break;
106310671Speter 	    default:
106410671Speter 		label = getlab();
106510671Speter 		sprintf( labelname , PREFIXFORMAT , LABELPREFIX , label );
106610671Speter 		putprintf("	.lcomm	%s,%d", 0,
106710671Speter 			labelname, lwidth(fvar -> type));
106818457Sralph 		putleaf( PCC_NAME , 0 , 0 , fvartype , labelname );
106910671Speter 		putLV( fvar -> symbol , ( fvar -> nl_block ) & 037 ,
107010671Speter 			fvar -> value[ NL_OFFS ] ,
107110671Speter 			fvar -> extra_flags ,
107210671Speter 			fvartype );
107318457Sralph 		putstrop( PCC_STASG , PCCM_ADDTYPE(fvartype, PCCTM_PTR) ,
107411857Speter 			lwidth( fvar -> type ) ,
107510671Speter 			align( fvar -> type ) );
107610671Speter 		putdot( filename , line );
107718457Sralph 		putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE(fvartype, PCCTM_PTR), labelname );
107818457Sralph 		putop( PCC_FORCE , PCCM_ADDTYPE(fvartype, PCCTM_PTR) );
107910671Speter 		break;
108010671Speter 	}
108110671Speter 	putdot( filename , line );
108210671Speter     }
108310671Speter 	/*
108410671Speter 	 *	if we saved a display, we must restore it.
108510671Speter 	 */
108610671Speter     if ( parts[ cbn ] & NONLOCALVAR ) {
108710671Speter 	    /*
108810671Speter 	     *	restore old display entry from save area
108910671Speter 	     */
109010671Speter 	putprintf("	movl	%s@(%d),%s+%d", 0,
109110671Speter 		    P2FPNAME, DSAVEOFFSET,
109210671Speter 		    DISPLAYNAME, cbn * sizeof(struct dispsave));
109310671Speter     }
109410671Speter }
109510671Speter 
109610671Speter fp_epilogue(eecookiep)
109710671Speter     struct entry_exit_cookie	*eecookiep;
109810671Speter {
109910671Speter     /*
110010671Speter      *	all done by the second pass.
110110671Speter      */
110210671Speter }
110310671Speter 
110410671Speter fp_formalentry(eecookiep)
110510671Speter     struct entry_exit_cookie	*eecookiep;
110610671Speter {
110710671Speter     putprintf( "%s%s:" , 0 , FORMALPREFIX , eecookiep -> extname );
110810671Speter     putprintf("	link	%s,#0", 0, P2FPNAME);
110910671Speter     putprintf("	addl	#-%s%d,sp", 0, FRAME_SIZE_LABEL, ftnno);
111010671Speter 	/* touch new end of stack, to break more stack space */
111110671Speter     putprintf("	tstb	sp@(-%s%d)", 0, PAGE_BREAK_LABEL, ftnno);
111210671Speter     putprintf("	moveml	#%s%d,sp@", 0, SAVE_MASK_LABEL, ftnno);
111318457Sralph     putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) , "_FCALL" );
111410671Speter     putRV( 0 , cbn ,
111510671Speter 	eecookiep -> nlp -> value[ NL_OFFS ] + sizeof( struct formalrtn * ) ,
111618457Sralph 	NPARAM , PCCTM_PTR | PCCT_STRTY );
111718457Sralph     putRV(0, cbn, eecookiep -> nlp -> value[NL_OFFS], NPARAM, PCCTM_PTR|PCCT_STRTY);
111818457Sralph     putop( PCC_CM , PCCT_INT );
111918457Sralph     putop( PCC_CALL , PCCT_INT );
112010671Speter     putdot( filename , line );
112110671Speter     putjbr( eecookiep -> toplabel );
112210671Speter }
112310671Speter #endif mc68000
11243363Speter #endif PC
1125