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