xref: /csrg-svn/usr.bin/pascal/src/fhdr.c (revision 15969)
13191Smckusick /* Copyright (c) 1979 Regents of the University of California */
23191Smckusick 
314731Sthien #ifndef lint
4*15969Smckusick static char sccsid[] = "@(#)fhdr.c 1.9 02/08/84";
514731Sthien #endif
63191Smckusick 
73191Smckusick #include "whoami.h"
83191Smckusick #include "0.h"
93191Smckusick #include "tree.h"
103191Smckusick #include "opcode.h"
113191Smckusick #include "objfmt.h"
123191Smckusick #include "align.h"
1314731Sthien #include "tree_ty.h"
143191Smckusick 
153191Smckusick /*
163191Smckusick  * this array keeps the pxp counters associated with
173191Smckusick  * functions and procedures, so that they can be output
183191Smckusick  * when their bodies are encountered
193191Smckusick  */
203191Smckusick int	bodycnts[ DSPLYSZ ];
213191Smckusick 
223191Smckusick #ifdef PC
233191Smckusick #   include "pc.h"
243191Smckusick #   include "pcops.h"
253191Smckusick #endif PC
263191Smckusick 
273191Smckusick #ifdef OBJ
283191Smckusick int	cntpatch;
293191Smckusick int	nfppatch;
303191Smckusick #endif OBJ
313191Smckusick 
323191Smckusick /*
333191Smckusick  * Funchdr inserts
343191Smckusick  * declaration of a the
353191Smckusick  * prog/proc/func into the
363191Smckusick  * namelist. It also handles
373191Smckusick  * the arguments and puts out
383191Smckusick  * a transfer which defines
393191Smckusick  * the entry point of a procedure.
403191Smckusick  */
413191Smckusick 
423191Smckusick struct nl *
433191Smckusick funchdr(r)
4414731Sthien 	struct tnode *r;
453191Smckusick {
463191Smckusick 	register struct nl *p;
4714731Sthien 	register struct tnode *rl;
4814731Sthien 	struct nl *cp, *dp, *temp;
4914731Sthien 	int o;
503191Smckusick 
5114731Sthien 	if (inpflist(r->p_dec.id_ptr)) {
523191Smckusick 		opush('l');
533191Smckusick 		yyretrieve();	/* kludge */
543191Smckusick 	}
553191Smckusick 	pfcnt++;
563191Smckusick 	parts[ cbn ] |= RPRT;
5714731Sthien 	line = r->p_dec.line_no;
5814731Sthien 	if (r->p_dec.param_list == TR_NIL &&
5914731Sthien 		(p=lookup1(r->p_dec.id_ptr)) != NIL && bn == cbn) {
603191Smckusick 		/*
613191Smckusick 		 * Symbol already defined
623191Smckusick 		 * in this block. it is either
633191Smckusick 		 * a redeclared symbol (error)
643191Smckusick 		 * a forward declaration,
653191Smckusick 		 * or an external declaration.
667589Speter 		 * check that forwards are of the right kind:
677589Speter 		 *     if this fails, we are trying to redefine it
687589Speter 		 *     and enter() will complain.
693191Smckusick 		 */
707589Speter 		if (  ( ( p->nl_flags & NFORWD ) != 0 )
7114731Sthien 		   && (  ( p->class == FUNC && r->tag == T_FDEC )
7214731Sthien 		      || ( p->class == PROC && r->tag == T_PDEC ) ) ) {
733191Smckusick 			/*
743191Smckusick 			 * Grammar doesnt forbid
753191Smckusick 			 * types on a resolution
763191Smckusick 			 * of a forward function
773191Smckusick 			 * declaration.
783191Smckusick 			 */
7914731Sthien 			if (p->class == FUNC && r->p_dec.type)
803191Smckusick 				error("Function type should be given only in forward declaration");
813191Smckusick 			/*
823191Smckusick 			 * get another counter for the actual
833191Smckusick 			 */
843191Smckusick 			if ( monflg ) {
853191Smckusick 			    bodycnts[ cbn ] = getcnt();
863191Smckusick 			}
873191Smckusick #			ifdef PC
883191Smckusick 			    enclosing[ cbn ] = p -> symbol;
893191Smckusick #			endif PC
903191Smckusick #			ifdef PTREE
913191Smckusick 				/*
923191Smckusick 				 *	mark this proc/func as forward
933191Smckusick 				 *	in the pTree.
943191Smckusick 				 */
953191Smckusick 			    pDEF( p -> inTree ).PorFForward = TRUE;
963191Smckusick #			endif PTREE
973191Smckusick 			return (p);
983191Smckusick 		}
993191Smckusick 	}
1003191Smckusick 
1013191Smckusick 	/* if a routine segment is being compiled,
1023191Smckusick 	 * do level one processing.
1033191Smckusick 	 */
1043191Smckusick 
10514731Sthien 	 if ((r->tag != T_PROG) && (!progseen))
1063191Smckusick 		level1();
1073191Smckusick 
1083191Smckusick 
1093191Smckusick 	/*
1103191Smckusick 	 * Declare the prog/proc/func
1113191Smckusick 	 */
11214731Sthien 	switch (r->tag) {
1133191Smckusick 	    case T_PROG:
1143191Smckusick 		    progseen = TRUE;
1153191Smckusick 		    if (opt('z'))
1163191Smckusick 			    monflg = TRUE;
11714731Sthien 		    program = p = defnl(r->p_dec.id_ptr, PROG, NLNIL, 0);
11814731Sthien 		    p->value[3] = r->p_dec.line_no;
1193191Smckusick 		    break;
1203191Smckusick 	    case T_PDEC:
12114731Sthien 		    if (r->p_dec.type != TR_NIL)
1223191Smckusick 			    error("Procedures do not have types, only functions do");
12314731Sthien 		    p = enter(defnl(r->p_dec.id_ptr, PROC, NLNIL, 0));
1243191Smckusick 		    p->nl_flags |= NMOD;
1253191Smckusick #		    ifdef PC
12614731Sthien 			enclosing[ cbn ] = r->p_dec.id_ptr;
1273838Speter 			p -> extra_flags |= NGLOBAL;
1283191Smckusick #		    endif PC
1293191Smckusick 		    break;
1303191Smckusick 	    case T_FDEC:
13114731Sthien 		    {
13214731Sthien 			register struct tnode *il;
13314731Sthien 		    il = r->p_dec.type;
13414731Sthien 		    if (il == TR_NIL)
1353191Smckusick 			    error("Function type must be specified");
13614731Sthien 		    else if (il->tag != T_TYID) {
13714731Sthien 			    temp = NLNIL;
1383191Smckusick 			    error("Function type can be specified only by using a type identifier");
1393191Smckusick 		    } else
14014731Sthien 			    temp = gtype(il);
14114731Sthien 		    }
14214731Sthien 		    {
14314731Sthien 			register struct nl *il;
14414731Sthien 
14514731Sthien 		    il = temp;
14614731Sthien 		    p = enter(defnl(r->p_dec.id_ptr, FUNC, il, NIL));
14714731Sthien 
14814731Sthien 		    }
14914731Sthien 
1503191Smckusick 		    p->nl_flags |= NMOD;
1513191Smckusick 		    /*
1523191Smckusick 		     * An arbitrary restriction
1533191Smckusick 		     */
1543191Smckusick 		    switch (o = classify(p->type)) {
1553191Smckusick 			    case TFILE:
1563191Smckusick 			    case TARY:
1573191Smckusick 			    case TREC:
1583191Smckusick 			    case TSET:
1593191Smckusick 			    case TSTR:
1603191Smckusick 				    warning();
1613191Smckusick 				    if (opt('s')) {
1623191Smckusick 					    standard();
1633191Smckusick 				    }
1643191Smckusick 				    error("Functions should not return %ss", clnames[o]);
1653191Smckusick 		    }
1663191Smckusick #		    ifdef PC
16714731Sthien 			enclosing[ cbn ] = r->p_dec.id_ptr;
1683838Speter 			p -> extra_flags |= NGLOBAL;
1693191Smckusick #		    endif PC
1703191Smckusick 		    break;
1713191Smckusick 	    default:
1723191Smckusick 		    panic("funchdr");
1733191Smckusick 	}
17414731Sthien 	if (r->tag != T_PROG) {
1753191Smckusick 		/*
1763191Smckusick 		 * Mark this proc/func as
1773191Smckusick 		 * being forward declared
1783191Smckusick 		 */
1793191Smckusick 		p->nl_flags |= NFORWD;
1803191Smckusick 		/*
1813191Smckusick 		 * Enter the parameters
1823191Smckusick 		 * in the next block for
1833191Smckusick 		 * the time being
1843191Smckusick 		 */
1853191Smckusick 		if (++cbn >= DSPLYSZ) {
1863191Smckusick 			error("Procedure/function nesting too deep");
1873191Smckusick 			pexit(ERRS);
1883191Smckusick 		}
1893191Smckusick 		/*
1903191Smckusick 		 * For functions, the function variable
1913191Smckusick 		 */
1923191Smckusick 		if (p->class == FUNC) {
1933191Smckusick #			ifdef OBJ
19414731Sthien 			    cp = defnl(r->p_dec.id_ptr, FVAR, p->type, 0);
1953191Smckusick #			endif OBJ
1963191Smckusick #			ifdef PC
1973191Smckusick 				/*
1983191Smckusick 				 * fvars used to be allocated and deallocated
1993191Smckusick 				 * by the caller right before the arguments.
2003191Smckusick 				 * the offset of the fvar was kept in
2013191Smckusick 				 * value[NL_OFFS] of function (very wierd,
2023191Smckusick 				 * but see asgnop).
2033191Smckusick 				 * now, they are locals to the function
2043191Smckusick 				 * with the offset kept in the fvar.
2053191Smckusick 				 */
2063191Smckusick 
20714731Sthien 			    cp = defnl(r->p_dec.id_ptr, FVAR, p->type,
2083302Smckusic 				(int)-leven(roundup(
2093302Smckusic 			            (int)(DPOFF1+lwidth(p->type)),
2103302Smckusic 				    (long)align(p->type))));
2113838Speter 			    cp -> extra_flags |= NLOCAL;
2123191Smckusick #			endif PC
2133191Smckusick 			cp->chain = p;
2143191Smckusick 			p->ptr[NL_FVAR] = cp;
2153191Smckusick 		}
2163191Smckusick 		/*
2173191Smckusick 		 * Enter the parameters
2183191Smckusick 		 * and compute total size
2193191Smckusick 		 */
22014731Sthien 	        p->value[NL_OFFS] = params(p, r->p_dec.param_list);
2213302Smckusic 		/*
2223302Smckusic 		 * because NL_LINENO field in the function
2233302Smckusic 		 * namelist entry has been used (as have all
2243302Smckusic 		 * the other fields), the line number is
2253302Smckusic 		 * stored in the NL_LINENO field of its fvar.
2263302Smckusic 		 */
2273302Smckusic 		if (p->class == FUNC)
22814731Sthien 		    p->ptr[NL_FVAR]->value[NL_LINENO] = r->p_dec.line_no;
2293302Smckusic 		else
23014731Sthien 		    p->value[NL_LINENO] = r->p_dec.line_no;
2313191Smckusick 		cbn--;
2323191Smckusick 	} else {
2333191Smckusick 		/*
2343191Smckusick 		 * The wonderful
2353191Smckusick 		 * program statement!
2363191Smckusick 		 */
2373191Smckusick #		ifdef OBJ
2383191Smckusick 		    if (monflg) {
23914731Sthien 			    (void) put(1, O_PXPBUF);
2403191Smckusick 			    cntpatch = put(2, O_CASE4, (long)0);
2413191Smckusick 			    nfppatch = put(2, O_CASE4, (long)0);
2423191Smckusick 		    }
2433191Smckusick #		endif OBJ
2443191Smckusick 		cp = p;
24514731Sthien 		for (rl = r->p_dec.param_list; rl; rl = rl->list_node.next) {
24614731Sthien 			if (rl->list_node.list == TR_NIL)
2473191Smckusick 				continue;
24814731Sthien 			dp = defnl((char *) rl->list_node.list, VAR, NLNIL, 0);
2493191Smckusick 			cp->chain = dp;
2503191Smckusick 			cp = dp;
2513191Smckusick 		}
2523191Smckusick 	}
2533191Smckusick 	/*
2543191Smckusick 	 * Define a branch at
2553191Smckusick 	 * the "entry point" of
2563191Smckusick 	 * the prog/proc/func.
2573191Smckusick 	 */
25814731Sthien 	p->value[NL_ENTLOC] = (int) getlab();
2593191Smckusick 	if (monflg) {
2603191Smckusick 		bodycnts[ cbn ] = getcnt();
2613191Smckusick 		p->value[ NL_CNTR ] = 0;
2623191Smckusick 	}
2633191Smckusick #	ifdef OBJ
26414731Sthien 	    (void) put(2, O_TRA4, (long)p->value[NL_ENTLOC]);
2653191Smckusick #	endif OBJ
2663191Smckusick #	ifdef PTREE
2673191Smckusick 	    {
2683191Smckusick 		pPointer	PF = tCopy( r );
2693191Smckusick 
2703191Smckusick 		pSeize( PorFHeader[ nesting ] );
27114731Sthien 		if ( r->tag != T_PROG ) {
2723191Smckusick 			pPointer	*PFs;
2733191Smckusick 
2743191Smckusick 			PFs = &( pDEF( PorFHeader[ nesting ] ).PorFPFs );
2753191Smckusick 			*PFs = ListAppend( *PFs , PF );
2763191Smckusick 		} else {
2773191Smckusick 			pDEF( PorFHeader[ nesting ] ).GlobProg = PF;
2783191Smckusick 		}
2793191Smckusick 		pRelease( PorFHeader[ nesting ] );
2803191Smckusick 	    }
2813191Smckusick #	endif PTREE
2823191Smckusick 	return (p);
2833191Smckusick }
2843302Smckusic 
2853302Smckusic 	/*
2863302Smckusic 	 * deal with the parameter declaration for a routine.
2873302Smckusic 	 * p is the namelist entry of the routine.
2883302Smckusic 	 * formalist is the parse tree for the parameter declaration.
2893302Smckusic 	 * formalist	[0]	T_LISTPP
2903302Smckusic 	 *		[1]	pointer to a formal
2913302Smckusic 	 *		[2]	pointer to next formal
2923302Smckusic 	 * for by-value or by-reference formals, the formal is
2933302Smckusic 	 * formal	[0]	T_PVAL or T_PVAR
2943302Smckusic 	 *		[1]	pointer to id_list
2953302Smckusic 	 *		[2]	pointer to type (error if not typeid)
2963302Smckusic 	 * for function and procedure formals, the formal is
2973302Smckusic 	 * formal	[0]	T_PFUNC or T_PPROC
2983302Smckusic 	 *		[1]	pointer to id_list (error if more than one)
2993302Smckusic 	 *		[2]	pointer to type (error if not typeid, or proc)
3003302Smckusic 	 *		[3]	pointer to formalist for this routine.
3013302Smckusic 	 */
3023302Smckusic fparams(p, formal)
3033302Smckusic 	register struct nl *p;
30414731Sthien 	struct tnode *formal;		/* T_PFUNC or T_PPROC */
3053302Smckusic {
30614731Sthien 	(void) params(p, formal->pfunc_node.param_list);
30714731Sthien 	p -> value[ NL_LINENO ] = formal->pfunc_node.line_no;
3083302Smckusic 	p -> ptr[ NL_FCHAIN ] = p -> chain;
3093302Smckusic 	p -> chain = NIL;
3103302Smckusic }
3113302Smckusic 
3123302Smckusic params(p, formalist)
3133302Smckusic 	register struct nl *p;
31414731Sthien 	struct tnode *formalist;	/* T_LISTPP */
3153302Smckusic {
3163302Smckusic 	struct nl *chainp, *savedp;
3173302Smckusic 	struct nl *dp;
31814731Sthien 	register struct tnode *formalp;	/* an element of the formal list */
31914731Sthien 	register struct tnode *formal;	/* a formal */
320*15969Smckusick 	struct tnode *r, *s, *t, *typ, *idlist;
3213302Smckusic 	int w, o;
3223302Smckusic 
3233302Smckusic 	/*
3243302Smckusic 	 * Enter the parameters
3253302Smckusic 	 * and compute total size
3263302Smckusic 	 */
3273302Smckusic 	chainp = savedp = p;
3283302Smckusic 
3293302Smckusic #	ifdef OBJ
3303302Smckusic 	    o = 0;
3313302Smckusic #	endif OBJ
3323302Smckusic #	ifdef PC
3333302Smckusic 		/*
3343302Smckusic 		 * parameters used to be allocated backwards,
3353302Smckusic 		 * then fixed.  for pc, they are allocated correctly.
3363302Smckusic 		 * also, they are aligned.
3373302Smckusic 		 */
3383302Smckusic 	    o = DPOFF2;
3393302Smckusic #	endif PC
34014731Sthien 	for (formalp = formalist; formalp != TR_NIL;
34114731Sthien 			formalp = formalp->list_node.next) {
34214731Sthien 		p = NLNIL;
34314731Sthien 		formal = formalp->list_node.list;
34414731Sthien 		if (formal == TR_NIL)
3453302Smckusic 			continue;
3463302Smckusic 		/*
3473302Smckusic 		 * Parametric procedures
3483302Smckusic 		 * don't have types !?!
3493302Smckusic 		 */
35014731Sthien 		typ = formal->pfunc_node.type;
35114731Sthien 		if ( typ == TR_NIL ) {
35214731Sthien 		    if ( formal->tag != T_PPROC ) {
3533302Smckusic 			error("Types must be specified for arguments");
35414731Sthien 			p = NLNIL;
3553302Smckusic 		    }
3563302Smckusic 		} else {
35714731Sthien 		    if ( formal->tag == T_PPROC ) {
3583302Smckusic 			error("Procedures cannot have types");
35914731Sthien 			p = NLNIL;
3603302Smckusic 		    } else {
361*15969Smckusick 			p = gtype(typ);
3623302Smckusic 		    }
3633302Smckusic 		}
36414731Sthien 		for (idlist = formal->param.id_list; idlist != TR_NIL;
36514731Sthien 				idlist = idlist->list_node.next) {
36614731Sthien 			switch (formal->tag) {
3673302Smckusic 			    default:
3683302Smckusic 				    panic("funchdr2");
3693302Smckusic 			    case T_PVAL:
37014731Sthien 				    if (p != NLNIL) {
3713302Smckusic 					    if (p->class == FILET)
3723302Smckusic 						    error("Files cannot be passed by value");
3733302Smckusic 					    else if (p->nl_flags & NFILES)
3743302Smckusic 						    error("Files cannot be a component of %ss passed by value",
3753302Smckusic 							    nameof(p));
3763302Smckusic 				    }
3773302Smckusic #				    ifdef OBJ
3783302Smckusic 					w = lwidth(p);
3793302Smckusic 					o -= even(w);
3803302Smckusic #					ifdef DEC11
38114731Sthien 					    dp = defnl((char *) idlist->list_node.list,
38214731Sthien 								VAR, p, o);
3833302Smckusic #					else
38414731Sthien 					    dp = defnl((char *) idlist->list_node.list,
38514731Sthien 						    VAR,p, (w < 2) ? o + 1 : o);
3863302Smckusic #					endif DEC11
3873302Smckusic #				    endif OBJ
3883302Smckusic #				    ifdef PC
38914731Sthien 					o = roundup(o, (long) A_STACK);
39010654Speter 					w = lwidth(p);
39110654Speter #					ifndef DEC11
39210654Speter 					    if (w <= sizeof(int)) {
39310654Speter 						o += sizeof(int) - w;
39410654Speter 					    }
39510654Speter #					endif not DEC11
39614731Sthien 					dp = defnl((char *) idlist->list_node.list,VAR,
39714731Sthien 							p, o);
39810654Speter 					o += w;
3993302Smckusic #				    endif PC
4003302Smckusic 				    dp->nl_flags |= NMOD;
4013302Smckusic 				    break;
4023302Smckusic 			    case T_PVAR:
4033302Smckusic #				    ifdef OBJ
40414731Sthien 					dp = defnl((char *) idlist->list_node.list, REF,
40514731Sthien 						    p, o -= sizeof ( int * ) );
4063302Smckusic #				    endif OBJ
4073302Smckusic #				    ifdef PC
40814731Sthien 					dp = defnl( (char *) idlist->list_node.list, REF,
40914731Sthien 						    p ,
41014731Sthien 					    o = roundup( o , (long)A_STACK ) );
4113302Smckusic 					o += sizeof(char *);
4123302Smckusic #				    endif PC
4133302Smckusic 				    break;
4143302Smckusic 			    case T_PFUNC:
41514731Sthien 				    if (idlist->list_node.next != TR_NIL) {
4163302Smckusic 					error("Each function argument must be declared separately");
41714731Sthien 					idlist->list_node.next = TR_NIL;
4183302Smckusic 				    }
4193302Smckusic #				    ifdef OBJ
42014731Sthien 					dp = defnl((char *) idlist->list_node.list,FFUNC,
42114731Sthien 						p, o -= sizeof ( int * ) );
4223302Smckusic #				    endif OBJ
4233302Smckusic #				    ifdef PC
42414731Sthien 					dp = defnl( (char *) idlist->list_node.list ,
42514731Sthien 						FFUNC , p ,
42614731Sthien 						o = roundup( o , (long)A_STACK ) );
4273302Smckusic 					o += sizeof(char *);
4283302Smckusic #				    endif PC
4293302Smckusic 				    dp -> nl_flags |= NMOD;
4303302Smckusic 				    fparams(dp, formal);
4313302Smckusic 				    break;
4323302Smckusic 			    case T_PPROC:
43314731Sthien 				    if (idlist->list_node.next != TR_NIL) {
4343302Smckusic 					error("Each procedure argument must be declared separately");
43514731Sthien 					idlist->list_node.next = TR_NIL;
4363302Smckusic 				    }
4373302Smckusic #				    ifdef OBJ
43814731Sthien 					dp = defnl((char *) idlist->list_node.list,
43914731Sthien 					    FPROC, p, o -= sizeof ( int * ) );
4403302Smckusic #				    endif OBJ
4413302Smckusic #				    ifdef PC
44214731Sthien 					dp = defnl( (char *) idlist->list_node.list ,
44314731Sthien 						FPROC , p,
44414731Sthien 						o = roundup( o , (long)A_STACK ) );
4453302Smckusic 					o += sizeof(char *);
4463302Smckusic #				    endif PC
4473302Smckusic 				    dp -> nl_flags |= NMOD;
4483302Smckusic 				    fparams(dp, formal);
4493302Smckusic 				    break;
4503302Smckusic 			    }
45114731Sthien 			if (dp != NLNIL) {
4523838Speter #				ifdef PC
4533838Speter 				    dp -> extra_flags |= NPARAM;
4543838Speter #				endif PC
4553302Smckusic 				chainp->chain = dp;
4563302Smckusic 				chainp = dp;
4573302Smckusic 			}
4583302Smckusic 		}
459*15969Smckusick 		if (typ->tag == T_TYCARY) {
460*15969Smckusick #		    ifdef OBJ
461*15969Smckusick 			w = -even(lwidth(p->chain));
462*15969Smckusick #			ifndef DEC11
463*15969Smckusick 			    w = (w > -2)? w + 1 : w;
464*15969Smckusick #			endif
465*15969Smckusick #		    endif OBJ
466*15969Smckusick #		    ifdef PC
467*15969Smckusick 			w = lwidth(p->chain);
468*15969Smckusick 			o = roundup(o, (long)A_STACK);
469*15969Smckusick #		    endif PC
470*15969Smckusick 		    /*
471*15969Smckusick 		     * Allocate space for upper and
472*15969Smckusick 		     * lower bounds and width.
473*15969Smckusick 		     */
474*15969Smckusick 		    for (s=typ; s->tag == T_TYCARY; s = s->ary_ty.type) {
475*15969Smckusick 			for (r=s->ary_ty.type_list; r != TR_NIL;
476*15969Smckusick 						r = r->list_node.next) {
477*15969Smckusick 			    t = r->list_node.list;
478*15969Smckusick 			    p = p->chain;
479*15969Smckusick #			    ifdef OBJ
480*15969Smckusick 				o += w;
481*15969Smckusick #			    endif OBJ
482*15969Smckusick 			    chainp->chain = defnl(t->crang_ty.lwb_var,
483*15969Smckusick 								VAR, p, o);
484*15969Smckusick 			    chainp = chainp->chain;
485*15969Smckusick 			    chainp->nl_flags |= (NMOD | NUSED);
486*15969Smckusick 			    p->nptr[0] = chainp;
487*15969Smckusick 			    o += w;
488*15969Smckusick 			    chainp->chain = defnl(t->crang_ty.upb_var,
489*15969Smckusick 								VAR, p, o);
490*15969Smckusick 			    chainp = chainp->chain;
491*15969Smckusick 			    chainp->nl_flags |= (NMOD | NUSED);
492*15969Smckusick 			    p->nptr[1] = chainp;
493*15969Smckusick 			    o += w;
494*15969Smckusick 			    chainp->chain  = defnl(0, VAR, p, o);
495*15969Smckusick 			    chainp = chainp->chain;
496*15969Smckusick 			    chainp->nl_flags |= (NMOD | NUSED);
497*15969Smckusick 			    p->nptr[2] = chainp;
498*15969Smckusick #			    ifdef PC
499*15969Smckusick 				o += w;
500*15969Smckusick #			    endif PC
501*15969Smckusick 			}
502*15969Smckusick 		    }
503*15969Smckusick 		}
5043302Smckusic 	}
5053302Smckusic 	p = savedp;
5063302Smckusic #	ifdef OBJ
5073302Smckusic 		/*
5083302Smckusic 		 * Correct the naivete (naivety)
5093302Smckusic 		 * of our above code to
5103302Smckusic 		 * calculate offsets
5113302Smckusic 		 */
51214731Sthien 	    for (dp = p->chain; dp != NLNIL; dp = dp->chain)
5133302Smckusic 		    dp->value[NL_OFFS] += -o + DPOFF2;
5143302Smckusic 	    return (-o + DPOFF2);
5153302Smckusic #	endif OBJ
5163302Smckusic #	ifdef PC
5173302Smckusic 	    return roundup( o , (long)A_STACK );
5183302Smckusic #	endif PC
5193302Smckusic }
520