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
fp_entrycode defined in line 816; used 1 times
fp_epilogue defined in line 966; used 1 times
fp_exitcode defined in line 894; used 1 times
fp_formalentry defined in line 974; used 1 times
fp_prologue defined in line 799; used 1 times
funcend defined in line 51; used 2 times
prog_prologue defined in line 784; used 1 times

Defined variables

Fp defined in line 38; used 8 times
bodycnts defined in line 24; used 1 times
cntpatch defined in line 32; used 1 times
nfppatch defined in line 33; used 1 times
pnumcnt defined in line 39; used 6 times
sccsid defined in line 8; never used

Defined macros

HDRSZE defined in line 104; used 1 times
Last modified: 1985-06-05
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 5507
Valid CSS Valid XHTML 1.0 Strict