|
|
1.1 ! root 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
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.