# 2.11BSD#431 - /usr/src/ucb/PORT/pascal/src/fend.c

##### Functions

    codeformain       X
    fp_entrycode      X
    fp_epilogue       X
    fp_exitcode       X
    fp_formalentry    X
    fp_prologue       X
    funcend           X
    prog_prologue     X
    sextname          X

##### Variables

    Fp                X
    bodycnts          X
    cntpatch          X
    nfppatch          X
    pnumcnt           X

##### Macros

    HDRSZE            X

       1: /*
       2:  * Copyright (c) 1980 Regents of the University of California.
       3:  * All rights reserved.  The Berkeley software License Agreement
       4:  * specifies the terms and conditions for redistribution.
       5:  */
       6:
       7: #ifndef lint
       8: static char sccsid[] = "@(#)fend.c	5.1 (Berkeley) 6/5/85";
       9: #endif not lint
      10:
      11: #include "whoami.h"
      12: #include "0.h"
      13: #include "tree.h"
      14: #include "opcode.h"
      15: #include "objfmt.h"
      16: #include "align.h"
      17: #include "tmps.h"
      18:
      19: /*
      20:  * this array keeps the pxp counters associated with
      21:  * functions and procedures, so that they can be output
      22:  * when their bodies are encountered
      23:  */
      24: int bodycnts[ DSPLYSZ ];
      25:
      26: #ifdef PC
      27: #   include "pc.h"
      28: #   include <pcc.h>
      29: #endif PC
      30:
      31: #ifdef OBJ
      32: int cntpatch;
      33: int nfppatch;
      34: #endif OBJ
      35:
      36: #include "tree_ty.h"
      37:
      38: struct  nl *Fp;
      39: int pnumcnt;
      40: /*
      41:  * Funcend is called to
      42:  * finish a block by generating
      43:  * the code for the statements.
      44:  * It then looks for unresolved declarations
      45:  * of labels, procedures and functions,
      46:  * and cleans up the name list.
      47:  * For the program, it checks the
      48:  * semantics of the program
      49:  * statement (yuchh).
      50:  */
      51: funcend(fp, bundle, endline)
      52:     struct nl *fp;
      53:     struct tnode *bundle;
      54:     int endline;
      55: {
      56:     register struct nl *p;
      57:     register int i, b;
      58:     int inp, out;
      59:     struct tnode *blk;
      60:     bool chkref;
      61:     struct nl *iop;
      62:     char *cp;
      63:     extern int cntstat;
      64: #	ifdef PC
      65:         struct entry_exit_cookie    eecookie;
      66: #	endif PC
      67: #	ifndef PC
      68:     int var;
      69: #	endif PC
      70:
      71:     cntstat = 0;
      72: /*
      73:  *	yyoutline();
      74:  */
      75:     if (program != NIL)
      76:         line = program->value[3];
      77:     blk = bundle->stmnt_blck.stmnt_list;
      78:     if (fp == NIL) {
      79:         cbn--;
      80: #		ifdef PTREE
      81:             nesting--;
      82: #		endif PTREE
      83:         return;
      84:     }
      85: #ifdef OBJ
      86:     /*
      87: 	 * Patch the branch to the
      88: 	 * entry point of the function
      89: 	 */
      90:     patch4((PTR_DCL) fp->value[NL_ENTLOC]);
      91:     /*
      92: 	 * Put out the block entrance code and the block name.
      93: 	 * HDRSZE is the number of bytes of info in the static
      94: 	 * BEG data area exclusive of the proc name. It is
      95: 	 * currently defined as:
      96: 	/*	struct hdr {
      97: 	/*		long framesze;	/* number of bytes of local vars */
      98:     /*		long nargs;	/* number of bytes of arguments */
      99:     /*		bool tests;	/* TRUE => perform runtime tests */
     100:     /*		short offset;	/* offset of procedure in source file */
     101:     /*		char name[1];	/* name of active procedure */
     102:     /*	};
     103: 	 */
     104: #	define HDRSZE (2 * sizeof(long) + sizeof(short) + sizeof(bool))
     105:     var = put(2, ((lenstr(fp->symbol,0) + HDRSZE) << 8)
     106:         | (cbn == 1 && opt('p') == 0 ? O_NODUMP: O_BEG), (long)0);
     107:         /*
     108: 	     *  output the number of bytes of arguments
     109: 	     *  this is only checked on formal calls.
     110: 	     */
     111:     (void) put(2, O_CASE4, cbn == 1 ? (long)0 : (long)(fp->value[NL_OFFS]-DPOFF2));
     112:         /*
     113: 	     *	Output the runtime test mode for the routine
     114: 	     */
     115:     (void) put(2, sizeof(bool) == 2 ? O_CASE2 : O_CASE4, opt('t') ? TRUE : FALSE);
     116:         /*
     117: 	     *	Output line number and routine name
     118: 	     */
     119:     (void) put(2, O_CASE2, bundle->stmnt_blck.line_no);
     120:     putstr(fp->symbol, 0);
     121: #endif OBJ
     122: #ifdef PC
     123:     /*
     124: 	 * put out the procedure entry code
     125: 	 */
     126:     eecookie.nlp = fp;
     127:     if ( fp -> class == PROG ) {
     128:         /*
     129: 		 *	If there is a label declaration in the main routine
     130: 		 *	then there may be a non-local goto to it that does
     131: 		 *	not appear in this module. We have to assume that
     132: 		 *	such a reference may occur and generate code to
     133: 		 *	prepare for it.
     134: 		 */
     135:         if ( parts[ cbn ] & LPRT ) {
     136:         parts[ cbn ] |= ( NONLOCALVAR | NONLOCALGOTO );
     137:         }
     138:         codeformain();
     139:         ftnno = fp -> value[NL_ENTLOC];
     140:         prog_prologue(&eecookie);
     141:         stabline(bundle->stmnt_blck.line_no);
     142:         stabfunc(fp, "program", bundle->stmnt_blck.line_no , (long) 0 );
     143:     } else {
     144:         ftnno = fp -> value[NL_ENTLOC];
     145:         fp_prologue(&eecookie);
     146:         stabline(bundle->stmnt_blck.line_no);
     147:         stabfunc(fp, fp->symbol, bundle->stmnt_blck.line_no,
     148:         (long)(cbn - 1));
     149:         for ( p = fp -> chain ; p != NIL ; p = p -> chain ) {
     150:         stabparam( p , p -> value[ NL_OFFS ] , (int) lwidth(p->type));
     151:         }
     152:         if ( fp -> class == FUNC ) {
     153:             /*
     154: 		     *	stab the function variable
     155: 		     */
     156:         p = fp -> ptr[ NL_FVAR ];
     157:         stablvar( p , p -> value[ NL_OFFS ] , (int) lwidth( p -> type));
     158:         }
     159:         /*
     160: 		 *	stab local variables
     161: 		 *	rummage down hash chain links.
     162: 		 */
     163:         for ( i = 0 ; i <= 077 ; i++ ) {
     164:         for ( p = disptab[ i ] ; p != NIL ; p = p->nl_next) {
     165:             if ( ( p -> nl_block & 037 ) != cbn ) {
     166:             break;
     167:             }
     168:             /*
     169: 		     *	stab locals (not parameters)
     170: 		     */
     171:             if ( p -> symbol != NIL ) {
     172:             if ( p -> class == VAR && p -> value[ NL_OFFS ] < 0 ) {
     173:                 stablvar( p , p -> value[ NL_OFFS ] ,
     174:                 (int) lwidth( p -> type ) );
     175:             } else if ( p -> class == CONST ) {
     176:                 stabconst( p );
     177:             }
     178:             }
     179:         }
     180:         }
     181:     }
     182:     stablbrac( cbn );
     183:         /*
     184: 	     *	ask second pass to allocate known locals
     185: 	     */
     186:     putlbracket(ftnno, &sizes[cbn]);
     187:     fp_entrycode(&eecookie);
     188: #endif PC
     189:     if ( monflg ) {
     190:         if ( fp -> value[ NL_CNTR ] != 0 ) {
     191:             inccnt( fp -> value [ NL_CNTR ] );
     192:         }
     193:         inccnt( bodycnts[ fp -> nl_block & 037 ] );
     194:     }
     195:     if (fp->class == PROG) {
     196:         /*
     197: 		 * The glorious buffers option.
     198: 		 *          0 = don't buffer output
     199: 		 *          1 = line buffer output
     200: 		 *          2 = 512 byte buffer output
     201: 		 */
     202: #		ifdef OBJ
     203:             if (opt('b') != 1)
     204:                 (void) put(1, O_BUFF | opt('b') << 8);
     205: #		endif OBJ
     206: #		ifdef PC
     207:             if ( opt( 'b' ) != 1 ) {
     208:             putleaf( PCC_ICON , 0 , 0
     209:                 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) , "_BUFF" );
     210:             putleaf( PCC_ICON , opt( 'b' ) , 0 , PCCT_INT , (char *) 0 );
     211:             putop( PCC_CALL , PCCT_INT );
     212:             putdot( filename , line );
     213:             }
     214: #		endif PC
     215:         inp = 0;
     216:         out = 0;
     217:         for (p = fp->chain; p != NIL; p = p->chain) {
     218:             if (pstrcmp(p->symbol, input->symbol) == 0) {
     219:                 inp++;
     220:                 continue;
     221:             }
     222:             if (pstrcmp(p->symbol, output->symbol) == 0) {
     223:                 out++;
     224:                 continue;
     225:             }
     226:             iop = lookup1(p->symbol);
     227:             if (iop == NIL || bn != cbn) {
     228:                 error("File %s listed in program statement but not declared", p->symbol);
     229:                 continue;
     230:             }
     231:             if (iop->class != VAR) {
     232:                 error("File %s listed in program statement but declared as a %s", p->symbol, classes[iop->class]);
     233:                 continue;
     234:             }
     235:             if (iop->type == NIL)
     236:                 continue;
     237:             if (iop->type->class != FILET) {
     238:                 error("File %s listed in program statement but defined as %s",
     239:                     p->symbol, nameof(iop->type));
     240:                 continue;
     241:             }
     242: #			ifdef OBJ
     243:                 (void) put(2, O_CON24, text(iop->type) ? 0 : width(iop->type->type));
     244:                 i = lenstr(p->symbol,0);
     245:                 (void) put(2, O_CON24, i);
     246:                 (void) put(2, O_LVCON, i);
     247:                 putstr(p->symbol, 0);
     248:                 (void) put(2, O_LV | bn<<8+INDX, (int)iop->value[NL_OFFS]);
     249:                 (void) put(1, O_DEFNAME);
     250: #			endif OBJ
     251: #			ifdef PC
     252:                 putleaf( PCC_ICON , 0 , 0
     253:                     , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
     254:                     , "_DEFNAME" );
     255:                 putLV( p -> symbol , bn , iop -> value[NL_OFFS] ,
     256:                     iop -> extra_flags , p2type( iop ) );
     257:                 putCONG( p -> symbol , strlen( p -> symbol )
     258:                     , LREQ );
     259:                 putop( PCC_CM , PCCT_INT );
     260:                 putleaf( PCC_ICON , strlen( p -> symbol )
     261:                     , 0 , PCCT_INT , (char *) 0 );
     262:                 putop( PCC_CM , PCCT_INT );
     263:                 putleaf( PCC_ICON
     264:                 , text(iop->type) ? 0 : width(iop->type->type)
     265:                 , 0 , PCCT_INT , (char *) 0 );
     266:                 putop( PCC_CM , PCCT_INT );
     267:                 putop( PCC_CALL , PCCT_INT );
     268:                 putdot( filename , line );
     269: #			endif PC
     270:         }
     271:     }
     272:     /*
     273: 	 * Process the prog/proc/func body
     274: 	 */
     275:     noreach = FALSE;
     276:     line = bundle->stmnt_blck.line_no;
     277:     statlist(blk);
     278: #	ifdef PTREE
     279:         {
     280:         pPointer Body = tCopy( blk );
     281:
     282:         pDEF( PorFHeader[ nesting -- ] ).PorFBody = Body;
     283:         }
     284: #	endif PTREE
     285: #	ifdef OBJ
     286:         if (cbn== 1 && monflg != FALSE) {
     287:             patchfil((PTR_DCL) (cntpatch - 2), (long)cnts, 2);
     288:             patchfil((PTR_DCL) (nfppatch - 2), (long)pfcnt, 2);
     289:         }
     290: #	endif OBJ
     291: #	ifdef PC
     292:         if ( fp -> class == PROG && monflg ) {
     293:         putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
     294:             , "_PMFLUSH" );
     295:         putleaf( PCC_ICON , cnts , 0 , PCCT_INT , (char *) 0 );
     296:         putleaf( PCC_ICON , pfcnt , 0 , PCCT_INT , (char *) 0 );
     297:         putop( PCC_CM , PCCT_INT );
     298:         putLV( PCPCOUNT , 0 , 0 , NGLOBAL , PCCT_INT );
     299:         putop( PCC_CM , PCCT_INT );
     300:         putop( PCC_CALL , PCCT_INT );
     301:         putdot( filename , line );
     302:         }
     303: #	endif PC
     304:     /*
     305: 	 * Clean up the symbol table displays and check for unresolves
     306: 	 */
     307:     line = endline;
     308:     if (fp->class == PROG && inp == 0 && (input->nl_flags & (NUSED|NMOD)) != 0) {
     309:         recovered();
     310:         error("Input is used but not defined in the program statement");
     311:     }
     312:     if (fp->class == PROG && out == 0 && (output->nl_flags & (NUSED|NMOD)) != 0) {
     313:         recovered();
     314:         error("Output is used but not defined in the program statement");
     315:     }
     316:     b = cbn;
     317:     Fp = fp;
     318:     chkref = (syneflg == errcnt[cbn] && opt('w') == 0)?TRUE:FALSE;
     319:     for (i = 0; i <= 077; i++) {
     320:         for (p = disptab[i]; p != NIL && (p->nl_block & 037) == b; p = p->nl_next) {
     321:             /*
     322: 			 * Check for variables defined
     323: 			 * but not referenced
     324: 			 */
     325:             if (chkref && p->symbol != NIL)
     326:             switch (p->class) {
     327:                 case FIELD:
     328:                     /*
     329: 					 * If the corresponding record is
     330: 					 * unused, we shouldn't complain about
     331: 					 * the fields.
     332: 					 */
     333:                 default:
     334:                     if ((p->nl_flags & (NUSED|NMOD)) == 0) {
     335:                         warning();
     336:                         nerror("%s %s is neither used nor set", classes[p->class], p->symbol);
     337:                         break;
     338:                     }
     339:                     /*
     340: 					 * If a var parameter is either
     341: 					 * modified or used that is enough.
     342: 					 */
     343:                     if (p->class == REF)
     344:                         continue;
     345: #					ifdef OBJ
     346:                         if ((p->nl_flags & NUSED) == 0) {
     347:                         warning();
     348:                         nerror("%s %s is never used", classes[p->class], p->symbol);
     349:                         break;
     350:                         }
     351: #					endif OBJ
     352: #					ifdef PC
     353:                         if (((p->nl_flags & NUSED) == 0) && ((p->extra_flags & NEXTERN) == 0)) {
     354:                         warning();
     355:                         nerror("%s %s is never used", classes[p->class], p->symbol);
     356:                         break;
     357:                         }
     358: #					endif PC
     359:                     if ((p->nl_flags & NMOD) == 0) {
     360:                         warning();
     361:                         nerror("%s %s is used but never set", classes[p->class], p->symbol);
     362:                         break;
     363:                     }
     364:                 case LABEL:
     365:                 case FVAR:
     366:                 case BADUSE:
     367:                     break;
     368:             }
     369:             switch (p->class) {
     370:                 case BADUSE:
     371:                     cp = "s";
     372:                     /* This used to say ud_next
     373: 					   that is not a member of nl so
     374: 					   i changed it to nl_next,
     375: 					   which may be wrong */
     376:                     if (p->chain->nl_next == NIL)
     377:                         cp++;
     378:                     eholdnl();
     379:                     if (p->value[NL_KINDS] & ISUNDEF)
     380:                         nerror("%s undefined on line%s", p->symbol, cp);
     381:                     else
     382:                         nerror("%s improperly used on line%s", p->symbol, cp);
     383:                     pnumcnt = 10;
     384:                     pnums((struct udinfo *) p->chain);
     385:                     pchr('\n');
     386:                     break;
     387:
     388:                 case FUNC:
     389:                 case PROC:
     390: #					ifdef OBJ
     391:                         if ((p->nl_flags & NFORWD))
     392:                         nerror("Unresolved forward declaration of %s %s", classes[p->class], p->symbol);
     393: #					endif OBJ
     394: #					ifdef PC
     395:                         if ((p->nl_flags & NFORWD) && ((p->extra_flags & NEXTERN) == 0))
     396:                         nerror("Unresolved forward declaration of %s %s", classes[p->class], p->symbol);
     397: #					endif PC
     398:                     break;
     399:
     400:                 case LABEL:
     401:                     if (p->nl_flags & NFORWD)
     402:                         nerror("label %s was declared but not defined", p->symbol);
     403:                     break;
     404:                 case FVAR:
     405:                     if ((p->nl_flags & NMOD) == 0)
     406:                         nerror("No assignment to the function variable");
     407:                     break;
     408:             }
     409:         }
     410:         /*
     411: 		 * Pop this symbol
     412: 		 * table slot
     413: 		 */
     414:         disptab[i] = p;
     415:     }
     416:
     417: #	ifdef OBJ
     418:         (void) put(1, O_END);
     419: #	endif OBJ
     420: #	ifdef PC
     421:         fp_exitcode(&eecookie);
     422:         stabrbrac(cbn);
     423:         putrbracket(ftnno);
     424:         fp_epilogue(&eecookie);
     425:         if (fp -> class != PROG) {
     426:         fp_formalentry(&eecookie);
     427:         }
     428:         /*
     429: 		 *	declare pcp counters, if any
     430: 		 */
     431:         if ( monflg && fp -> class == PROG ) {
     432:         putprintf( "	.data" , 0 );
     433:         aligndot(PCCT_INT);
     434:         putprintf( "	.comm	" , 1 );
     435:         putprintf( PCPCOUNT , 1 );
     436:         putprintf( ",%d" , 0 , ( cnts + 1 ) * sizeof (long) );
     437:         putprintf( "	.text" , 0 );
     438:         }
     439: #	endif PC
     440: #ifdef DEBUG
     441:     dumpnl(fp->ptr[2], (int) fp->symbol);
     442: #endif
     443:
     444: #ifdef OBJ
     445:     /*
     446: 	 * save the namelist for the debugger pdx
     447: 	 */
     448:
     449:     savenl(fp->ptr[2], (int) fp->symbol);
     450: #endif
     451:
     452:     /*
     453: 	 * Restore the
     454: 	 * (virtual) name list
     455: 	 * position
     456: 	 */
     457:     nlfree(fp->ptr[2]);
     458:     /*
     459: 	 * Proc/func has been
     460: 	 * resolved
     461: 	 */
     462:     fp->nl_flags &= ~NFORWD;
     463:     /*
     464: 	 * Patch the beg
     465: 	 * of the proc/func to
     466: 	 * the proper variable size
     467: 	 */
     468:     if (Fp == NIL)
     469:         elineon();
     470: #	ifdef OBJ
     471:         patchfil((PTR_DCL) var, leven(-sizes[cbn].om_max), 2);
     472: #	endif OBJ
     473:     cbn--;
     474:     if (inpflist(fp->symbol)) {
     475:         opop('l');
     476:     }
     477: }
     478:
     479: #ifdef PC
     480:     /*
     481:      *	construct the long name of a function based on it's static nesting.
     482:      *	into a caller-supplied buffer (that should be about BUFSIZ big).
     483:      */
     484: sextname( buffer , name , level )
     485:     char    buffer[];
     486:     char    *name;
     487:     int     level;
     488: {
     489:     char    *starthere;
     490:     int i;
     491:
     492:     starthere = &buffer[0];
     493:     for ( i = 1 ; i < level ; i++ ) {
     494:     sprintf( starthere , EXTFORMAT , enclosing[ i ] );
     495:     starthere += strlen( enclosing[ i ] ) + 1;
     496:     }
     497:     sprintf( starthere , EXTFORMAT , name );
     498:     starthere += strlen( name ) + 1;
     499:     if ( starthere >= &buffer[ BUFSIZ ] ) {
     500:     panic( "sextname" );
     501:     }
     502: }
     503:
     504:     /*
     505:      *	code for main()
     506:      */
     507: #ifdef vax
     508:
     509: codeformain()
     510: {
     511:     putprintf("	.text" , 0 );
     512:     putprintf("	.align	1" , 0 );
     513:     putprintf("	.globl	_main" , 0 );
     514:     putprintf("_main:" , 0 );
     515:     putprintf("	.word	0" , 0 );
     516:     if ( opt ( 't' ) ) {
     517:     putprintf("	pushl	$1" , 0 );
     518:     } else {
     519:     putprintf("	pushl	$0" , 0 );
     520:     }
     521:     putprintf("	calls	$1,_PCSTART" , 0 );
     522:     putprintf("	movl	4(ap),__argc" , 0 );
     523:     putprintf("	movl	8(ap),__argv" , 0 );
     524:     putprintf("	calls	$0,_program" , 0 );
     525:     putprintf("	pushl	$0" , 0 );
     526:     putprintf("	calls	$1,_PCEXIT" , 0 );
     527: }
     528:
     529:     /*
     530:      *	prologue for the program.
     531:      *	different because it
     532:      *		doesn't have formal entry point
     533:      */
     534: prog_prologue(eecookiep)
     535:     struct entry_exit_cookie    *eecookiep;
     536: {
     537:     putprintf("	.text" , 0 );
     538:     putprintf("	.align	1" , 0 );
     539:     putprintf("	.globl	_program" , 0 );
     540:     putprintf("_program:" , 0 );
     541:     /*
     542: 	 *	register save mask
     543: 	 */
     544:     eecookiep -> savlabel = (int) getlab();
     545:     putprintf("	.word	%s%d", 0, (int) SAVE_MASK_LABEL , eecookiep -> savlabel );
     546: }
     547:
     548: fp_prologue(eecookiep)
     549:     struct entry_exit_cookie    *eecookiep;
     550: {
     551:
     552:     sextname( eecookiep -> extname, eecookiep -> nlp -> symbol , cbn - 1 );
     553:     putprintf( "	.text" , 0 );
     554:     putprintf( "	.align	1" , 0 );
     555:     putprintf( "	.globl	%s%s", 0, (int) FORMALPREFIX, (int) eecookiep -> extname );
     556:     putprintf( "	.globl	%s" , 0 , (int) eecookiep -> extname );
     557:     putprintf( "%s:" , 0 , (int) eecookiep -> extname );
     558:     /*
     559: 	 *	register save mask
     560: 	 */
     561:     eecookiep -> savlabel = (int) getlab();
     562:     putprintf("	.word	%s%d", 0, (int) SAVE_MASK_LABEL , eecookiep -> savlabel );
     563: }
     564:
     565:     /*
     566:      *	code before any user code.
     567:      *	or code that is machine dependent.
     568:      */
     569: fp_entrycode(eecookiep)
     570:     struct entry_exit_cookie    *eecookiep;
     571: {
     572:     int ftnno = eecookiep -> nlp -> value[NL_ENTLOC];
     573:     int proflabel = (int) getlab();
     574:     int setjmp0 = (int) getlab();
     575:
     576:     /*
     577: 	 *	top of code;  destination of jump from formal entry code.
     578: 	 */
     579:     eecookiep -> toplabel = (int) getlab();
     580:     (void) putlab( (char *) eecookiep -> toplabel );
     581:     putprintf("	subl2	$%s%d,sp" , 0 , (int) FRAME_SIZE_LABEL, ftnno );
     582:     if ( profflag ) {
     583:         /*
     584: 	     *	call mcount for profiling
     585: 	     */
     586:     putprintf( "	moval	" , 1 );
     587:     putprintf( PREFIXFORMAT , 1 , (int) LABELPREFIX , proflabel );
     588:     putprintf( ",r0" , 0 );
     589:     putprintf( "	jsb	mcount" , 0 );
     590:     putprintf( "	.data" , 0 );
     591:     putprintf( "	.align	2" , 0 );
     592:     (void) putlab( (char *) proflabel );
     593:     putprintf( "	.long	0" , 0 );
     594:     putprintf( "	.text" , 0 );
     595:     }
     596:     /*
     597: 	 *	if there are nested procedures that access our variables
     598: 	 *	we must save the display.
     599: 	 */
     600:     if ( parts[ cbn ] & NONLOCALVAR ) {
     601:         /*
     602: 	     *	save old display
     603: 	     */
     604:     putprintf( "	movq	%s+%d,%d(%s)" , 0
     605:         , (int) DISPLAYNAME , cbn * sizeof(struct dispsave)
     606:         , DSAVEOFFSET , (int) P2FPNAME );
     607:         /*
     608: 	     *	set up new display by saving AP and FP in appropriate
     609: 	     *	slot in display structure.
     610: 	     */
     611:     putprintf( "	movq	%s,%s+%d" , 0
     612:         , (int) P2APNAME , (int) DISPLAYNAME , cbn * sizeof(struct dispsave) );
     613:     }
     614:     /*
     615: 	 *	set underflow checking if runtime tests
     616: 	 */
     617:     if ( opt( 't' ) ) {
     618:     putprintf( "	bispsw	$0xe0" , 0 );
     619:     }
     620:     /*
     621: 	 *	zero local variables if checking is on
     622: 	 *	by calling blkclr( bytes of locals , starting local address );
     623: 	 */
     624:     if ( opt( 't' ) && ( -sizes[ cbn ].om_max ) > DPOFF1 ) {
     625:     putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
     626:         , "_blkclr" );
     627:     putLV((char *) 0 , cbn , (int) sizes[ cbn ].om_max , NLOCAL , PCCT_CHAR );
     628:     putleaf( PCC_ICON ,  (int) (( -sizes[ cbn ].om_max ) - DPOFF1)
     629:         , 0 , PCCT_INT ,(char *) 0 );
     630:     putop( PCC_CM , PCCT_INT );
     631:     putop( PCC_CALL , PCCT_INT );
     632:     putdot( filename , line );
     633:     }
     634:     /*
     635: 	 *  set up goto vector if non-local goto to this frame
     636: 	 */
     637:     if ( parts[ cbn ] & NONLOCALGOTO ) {
     638:     putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
     639:         , "_setjmp" );
     640:     putLV( (char *) 0 , cbn , GOTOENVOFFSET , NLOCAL , PCCTM_PTR|PCCT_STRTY );
     641:     putop( PCC_CALL , PCCT_INT );
     642:     putleaf( PCC_ICON , 0 , 0 , PCCT_INT , (char *) 0 );
     643:     putop( PCC_NE , PCCT_INT );
     644:     putleaf( PCC_ICON , setjmp0 , 0 , PCCT_INT , (char *) 0 );
     645:     putop( PCC_CBRANCH , PCCT_INT );
     646:     putdot( filename , line );
     647:         /*
     648: 	     *	on non-local goto, setjmp returns with address to
     649: 	     *	be branched to.
     650: 	     */
     651:     putprintf( "	jmp	(r0)" , 0 );
     652:     (void) putlab((char *) setjmp0);
     653:     }
     654: }
     655:
     656: fp_exitcode(eecookiep)
     657:     struct entry_exit_cookie    *eecookiep;
     658: {
     659:     /*
     660: 	 *	if there were file variables declared at this level
     661: 	 *	call PCLOSE( ap ) to clean them up.
     662: 	 */
     663:     if ( dfiles[ cbn ] ) {
     664:     putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
     665:         , "_PCLOSE" );
     666:     putleaf( PCC_REG , 0 , P2AP , PCCM_ADDTYPE( PCCT_CHAR , PCCTM_PTR ) , (char *) 0 );
     667:     putop( PCC_CALL , PCCT_INT );
     668:     putdot( filename , line );
     669:     }
     670:     /*
     671: 	 *	if this is a function,
     672: 	 *	the function variable is the return value.
     673: 	 *	if it's a scalar valued function, return scalar,
     674: 	 *	else, return a pointer to the structure value.
     675: 	 */
     676:     if ( eecookiep-> nlp -> class == FUNC ) {
     677:     struct nl   *fvar = eecookiep-> nlp -> ptr[ NL_FVAR ];
     678:     long        fvartype = p2type( fvar -> type );
     679:     long        label;
     680:     char        labelname[ BUFSIZ ];
     681:
     682:     switch ( classify( fvar -> type ) ) {
     683:         case TBOOL:
     684:         case TCHAR:
     685:         case TINT:
     686:         case TSCAL:
     687:         case TDOUBLE:
     688:         case TPTR:
     689:         putRV( fvar -> symbol , ( fvar -> nl_block ) & 037 ,
     690:             fvar -> value[ NL_OFFS ] ,
     691:             fvar -> extra_flags ,
     692:             (int) fvartype );
     693:         putop( PCC_FORCE , (int) fvartype );
     694:         break;
     695:         default:
     696:         label = (int) getlab();
     697:         sprintf( labelname , PREFIXFORMAT , LABELPREFIX , label );
     698:         putprintf( "	.data" , 0 );
     699:         aligndot(A_STRUCT);
     700:         putprintf( "	.lcomm	%s,%d" , 0 ,
     701:                 (int) labelname , (int) lwidth( fvar -> type ) );
     702:         putprintf( "	.text" , 0 );
     703:         putleaf( PCC_NAME , 0 , 0 , (int) fvartype , labelname );
     704:         putLV( fvar -> symbol , ( fvar -> nl_block ) & 037 ,
     705:             fvar -> value[ NL_OFFS ] ,
     706:             fvar -> extra_flags ,
     707:             (int) fvartype );
     708:         putstrop( PCC_STASG , (int) PCCM_ADDTYPE(fvartype, PCCTM_PTR) ,
     709:             (int) lwidth( fvar -> type ) ,
     710:             align( fvar -> type ) );
     711:         putdot( filename , line );
     712:         putleaf( PCC_ICON , 0 , 0 , (int) PCCM_ADDTYPE(fvartype, PCCTM_PTR), labelname );
     713:         putop( PCC_FORCE , (int) PCCM_ADDTYPE(fvartype, PCCTM_PTR) );
     714:         break;
     715:     }
     716:     putdot( filename , line );
     717:     }
     718:     /*
     719: 	 *	if there are nested procedures we must save the display.
     720: 	 */
     721:     if ( parts[ cbn ] & NONLOCALVAR ) {
     722:         /*
     723: 	     *	restore old display entry from save area
     724: 	     */
     725:     putprintf( "	movq	%d(%s),%s+%d" , 0
     726:         , DSAVEOFFSET , (int) P2FPNAME
     727:         , (int) DISPLAYNAME , cbn * sizeof(struct dispsave) );
     728:     }
     729: }
     730:
     731: fp_epilogue(eecookiep)
     732:     struct entry_exit_cookie    *eecookiep;
     733: {
     734:     stabline(line);
     735:     putprintf("	ret" , 0 );
     736:     /*
     737: 	 *	set the register save mask.
     738: 	 */
     739:     putprintf("	.set	%s%d,0x%x", 0,
     740:         (int) SAVE_MASK_LABEL, eecookiep -> savlabel, savmask());
     741: }
     742:
     743: fp_formalentry(eecookiep)
     744:     struct entry_exit_cookie    *eecookiep;
     745: {
     746:
     747:     putprintf("	.align 1", 0);
     748:     putprintf("%s%s:" , 0 , (int) FORMALPREFIX , (int) eecookiep -> extname );
     749:     putprintf("	.word	%s%d", 0, (int) SAVE_MASK_LABEL, eecookiep -> savlabel );
     750:     putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) , "_FCALL" );
     751:     putRV((char *) 0 , cbn ,
     752:     eecookiep -> nlp -> value[ NL_OFFS ] + sizeof( struct formalrtn * ) ,
     753:     NPARAM , PCCTM_PTR | PCCT_STRTY );
     754:     putRV((char *) 0, cbn, eecookiep -> nlp -> value[NL_OFFS], NPARAM, PCCTM_PTR|PCCT_STRTY);
     755:     putop( PCC_CM , PCCT_INT );
     756:     putop( PCC_CALL , PCCT_INT );
     757:     putdot( filename , line );
     758:     putjbr( (long) eecookiep -> toplabel );
     759: }
     760: #endif vax
     761:
     762: #ifdef mc68000
     763:
     764: codeformain()
     765: {
     766:     putprintf("	.text", 0);
     767:     putprintf("	.globl	_main", 0);
     768:     putprintf("_main:", 0);
     769:     putprintf("	link	%s,#0", 0, P2FPNAME);
     770:     if (opt('t')) {
     771:     putprintf("	pea	1", 0);
     772:     } else {
     773:     putprintf("	pea	0", 0);
     774:     }
     775:     putprintf("	jbsr	_PCSTART", 0);
     776:     putprintf("	addql	#4,sp", 0);
     777:     putprintf("	movl	%s@(8),__argc", 0, P2FPNAME);
     778:     putprintf("	movl	%s@(12),__argv", 0, P2FPNAME);
     779:     putprintf("	jbsr	_program", 0);
     780:     putprintf("	pea	0", 0);
     781:     putprintf("	jbsr	_PCEXIT", 0);
     782: }
     783:
     784: prog_prologue(eecookiep)
     785:     struct entry_exit_cookie    *eecookiep;
     786: {
     787:     int ftnno = eecookiep -> nlp -> value[NL_ENTLOC];
     788:
     789:     putprintf("	.text", 0);
     790:     putprintf("	.globl	_program", 0);
     791:     putprintf("_program:", 0);
     792:     putprintf("	link	%s,#0", 0, P2FPNAME);
     793:     putprintf("	addl	#-%s%d,sp", 0, FRAME_SIZE_LABEL, ftnno);
     794:     /* touch new end of stack, to break more stack space */
     795:     putprintf("	tstb	sp@(-%s%d)", 0, PAGE_BREAK_LABEL, ftnno);
     796:     putprintf("	moveml	#%s%d,sp@", 0, SAVE_MASK_LABEL, ftnno);
     797: }
     798:
     799: fp_prologue(eecookiep)
     800:     struct entry_exit_cookie    *eecookiep;
     801: {
     802:     int     ftnno = eecookiep -> nlp -> value[NL_ENTLOC];
     803:
     804:     sextname(eecookiep -> extname, eecookiep -> nlp -> symbol, cbn - 1);
     805:     putprintf("	.text", 0);
     806:     putprintf("	.globl	%s%s", 0, FORMALPREFIX, eecookiep -> extname);
     807:     putprintf("	.globl	%s", 0, eecookiep -> extname);
     808:     putprintf("%s:", 0, eecookiep -> extname);
     809:     putprintf("	link	%s,#0", 0, P2FPNAME);
     810:     putprintf("	addl	#-%s%d,sp", 0, FRAME_SIZE_LABEL, ftnno);
     811:     /* touch new end of stack, to break more stack space */
     812:     putprintf("	tstb	sp@(-%s%d)", 0, PAGE_BREAK_LABEL, ftnno);
     813:     putprintf("	moveml	#%s%d,sp@", 0, SAVE_MASK_LABEL, ftnno);
     814: }
     815:
     816: fp_entrycode(eecookiep)
     817:     struct entry_exit_cookie    *eecookiep;
     818: {
     819:     char *proflabel = getlab();
     820:     char *setjmp0 = getlab();
     821:
     822:     /*
     823: 	 *	fill in the label cookie
     824: 	 */
     825:     eecookiep -> toplabel = getlab();
     826:     (void) putlab(eecookiep -> toplabel);
     827:     /*
     828: 	 *	call mcount if we are profiling.
     829: 	 */
     830:     if ( profflag ) {
     831:     putprintf("	movl	#%s%d,a0", 0, LABELPREFIX,  proflabel);
     832:     putprintf("	jsr	mcount", 0);
     833:     putprintf("	.data", 0);
     834:     putprintf("	.even", 0);
     835:     (void) putlab(proflabel);
     836:     putprintf("	.long	0", 0);
     837:     putprintf("	.text", 0);
     838:     }
     839:     /*
     840: 	 *	if there are nested procedures that access our variables
     841: 	 *	we must save the display
     842: 	 */
     843:     if (parts[cbn] & NONLOCALVAR) {
     844:         /*
     845: 	     *	save the old display
     846: 	     */
     847:     putprintf("	movl	%s+%d,%s@(%d)", 0,
     848:             DISPLAYNAME, cbn * sizeof(struct dispsave),
     849:             P2FPNAME, DSAVEOFFSET);
     850:         /*
     851: 	     *	set up the new display by saving the framepointer
     852: 	     *	in the display structure.
     853: 	     */
     854:     putprintf("	movl	%s,%s+%d", 0,
     855:             P2FPNAME, DISPLAYNAME, cbn * sizeof(struct dispsave));
     856:     }
     857:     /*
     858: 	 *	zero local variables if checking is on
     859: 	 *	by calling blkclr( bytes of locals , starting local address );
     860: 	 */
     861:     if ( opt( 't' ) && ( -sizes[ cbn ].om_max ) > DPOFF1 ) {
     862:     putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
     863:         , "_blkclr" );
     864:     putLV( 0 , cbn , sizes[ cbn ].om_max , NLOCAL , PCCT_CHAR );
     865:     putleaf( PCC_ICON ,  ( -sizes[ cbn ].om_max ) - DPOFF1
     866:         , 0 , PCCT_INT , 0 );
     867:     putop( PCC_CM , PCCT_INT );
     868:     putop( PCC_CALL , PCCT_INT );
     869:     putdot( filename , line );
     870:     }
     871:     /*
     872: 	 *  set up goto vector if non-local goto to this frame
     873: 	 */
     874:     if ( parts[ cbn ] & NONLOCALGOTO ) {
     875:     putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
     876:         , "_setjmp" );
     877:     putLV( 0 , cbn , GOTOENVOFFSET , NLOCAL , PCCTM_PTR|PCCT_STRTY );
     878:     putop( PCC_CALL , PCCT_INT );
     879:     putleaf( PCC_ICON , 0 , 0 , PCCT_INT , 0 );
     880:     putop( PCC_NE , PCCT_INT );
     881:     putleaf( PCC_ICON , setjmp0 , 0 , PCCT_INT , 0 );
     882:     putop( PCC_CBRANCH , PCCT_INT );
     883:     putdot( filename , line );
     884:         /*
     885: 	     *	on non-local goto, setjmp returns with address to
     886: 	     *	be branched to.
     887: 	     */
     888:     putprintf("	movl	d0,a0", 0);
     889:     putprintf("	jmp	a0@", 0);
     890:     (void) putlab(setjmp0);
     891:     }
     892: }
     893:
     894: fp_exitcode(eecookiep)
     895:     struct entry_exit_cookie    *eecookiep;
     896: {
     897:     /*
     898: 	 *	if there were file variables declared at this level
     899: 	 *	call PCLOSE( ap ) to clean them up.
     900: 	 */
     901:     if ( dfiles[ cbn ] ) {
     902:     putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
     903:         , "_PCLOSE" );
     904:     putleaf( PCC_REG , 0 , P2AP , PCCM_ADDTYPE( PCCT_CHAR , PCCTM_PTR ) , 0 );
     905:     putop( PCC_CALL , PCCT_INT );
     906:     putdot( filename , line );
     907:     }
     908:     /*
     909: 	 *	if this is a function,
     910: 	 *	the function variable is the return value.
     911: 	 *	if it's a scalar valued function, return scalar,
     912: 	 *	else, return a pointer to the structure value.
     913: 	 */
     914:     if ( eecookiep -> nlp -> class == FUNC ) {
     915:     struct nl   *fvar = eecookiep -> nlp -> ptr[ NL_FVAR ];
     916:     long        fvartype = p2type( fvar -> type );
     917:     char        *label;
     918:     char        labelname[ BUFSIZ ];
     919:
     920:     switch ( classify( fvar -> type ) ) {
     921:         case TBOOL:
     922:         case TCHAR:
     923:         case TINT:
     924:         case TSCAL:
     925:         case TDOUBLE:
     926:         case TPTR:
     927:         putRV( fvar -> symbol , ( fvar -> nl_block ) & 037 ,
     928:             fvar -> value[ NL_OFFS ] ,
     929:             fvar -> extra_flags ,
     930:             fvartype );
     931:         putop( PCC_FORCE , fvartype );
     932:         break;
     933:         default:
     934:         label = getlab();
     935:         sprintf( labelname , PREFIXFORMAT , LABELPREFIX , label );
     936:         putprintf("	.lcomm	%s,%d", 0,
     937:             labelname, lwidth(fvar -> type));
     938:         putleaf( PCC_NAME , 0 , 0 , fvartype , labelname );
     939:         putLV( fvar -> symbol , ( fvar -> nl_block ) & 037 ,
     940:             fvar -> value[ NL_OFFS ] ,
     941:             fvar -> extra_flags ,
     942:             fvartype );
     943:         putstrop( PCC_STASG , PCCM_ADDTYPE(fvartype, PCCTM_PTR) ,
     944:             lwidth( fvar -> type ) ,
     945:             align( fvar -> type ) );
     946:         putdot( filename , line );
     947:         putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE(fvartype, PCCTM_PTR), labelname );
     948:         putop( PCC_FORCE , PCCM_ADDTYPE(fvartype, PCCTM_PTR) );
     949:         break;
     950:     }
     951:     putdot( filename , line );
     952:     }
     953:     /*
     954: 	 *	if we saved a display, we must restore it.
     955: 	 */
     956:     if ( parts[ cbn ] & NONLOCALVAR ) {
     957:         /*
     958: 	     *	restore old display entry from save area
     959: 	     */
     960:     putprintf("	movl	%s@(%d),%s+%d", 0,
     961:             P2FPNAME, DSAVEOFFSET,
     962:             DISPLAYNAME, cbn * sizeof(struct dispsave));
     963:     }
     964: }
     965:
     966: fp_epilogue(eecookiep)
     967:     struct entry_exit_cookie    *eecookiep;
     968: {
     969:     /*
     970:      *	all done by the second pass.
     971:      */
     972: }
     973:
     974: fp_formalentry(eecookiep)
     975:     struct entry_exit_cookie    *eecookiep;
     976: {
     977:     putprintf( "%s%s:" , 0 , FORMALPREFIX , eecookiep -> extname );
     978:     putprintf("	link	%s,#0", 0, P2FPNAME);
     979:     putprintf("	addl	#-%s%d,sp", 0, FRAME_SIZE_LABEL, ftnno);
     980:     /* touch new end of stack, to break more stack space */
     981:     putprintf("	tstb	sp@(-%s%d)", 0, PAGE_BREAK_LABEL, ftnno);
     982:     putprintf("	moveml	#%s%d,sp@", 0, SAVE_MASK_LABEL, ftnno);
     983:     putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) , "_FCALL" );
     984:     putRV( 0 , cbn ,
     985:     eecookiep -> nlp -> value[ NL_OFFS ] + sizeof( struct formalrtn * ) ,
     986:     NPARAM , PCCTM_PTR | PCCT_STRTY );
     987:     putRV(0, cbn, eecookiep -> nlp -> value[NL_OFFS], NPARAM, PCCTM_PTR|PCCT_STRTY);
     988:     putop( PCC_CM , PCCT_INT );
     989:     putop( PCC_CALL , PCCT_INT );
     990:     putdot( filename , line );
     991:     putjbr( eecookiep -> toplabel );
     992: }
     993: #endif mc68000
     994: #endif PC

#### Defined functions

codeformain defined in line 764; used 1 times

- in line 138

fp_entrycode defined in line 816; used 1 times

- in line 187

fp_epilogue defined in line 966; used 1 times

- in line 424

fp_exitcode defined in line 894; used 1 times

- in line 421

fp_formalentry defined in line 974; used 1 times

- in line 426

fp_prologue defined in line 799; used 1 times

- in line 145

funcend defined in line 51; used 2 times

- in /usr/src/ucb/PORT/pascal/src/pas.y line 130, 293

prog_prologue defined in line 784; used 1 times

- in line 140

sextname defined in line 484; used 6 times

- in line 552, 804
- in /usr/src/ucb/PORT/pascal/src/call.c line 160
- in /usr/src/ucb/PORT/pascal/src/flvalue.c line 96
- in /usr/src/ucb/PORT/pascal/src/stab.c line 226, 278

#### Defined variables

Fp defined in line 38; used 8 times

- in line 317, 468
- in /usr/src/ucb/PORT/pascal/src/fdec.c line 268, 275-276(3)
- in /usr/src/ucb/PORT/pascal/src/fend.c line 317, 468

bodycnts defined in line 24; used 1 times

- in line 193

cntpatch defined in line 32; used 1 times

- in line 287

nfppatch defined in line 33; used 1 times

- in line 288

pnumcnt defined in line 39; used 6 times

- in line 383
- in /usr/src/ucb/PORT/pascal/src/fdec.c line 191, 255-259(3)
- in /usr/src/ucb/PORT/pascal/src/fend.c line 383

sccsid defined in line 8; never used

#### Defined macros

HDRSZE defined in line 104; used 1 times

- in line 105

Last modified: 1985-06-05 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 2838 |