13192Smckusick /* Copyright (c) 1979 Regents of the University of California */ 23192Smckusick 3*3279Smckusic static char sccsid[] = "@(#)fend.c 1.2 03/16/81"; 43192Smckusick 53192Smckusick #include "whoami.h" 63192Smckusick #include "0.h" 73192Smckusick #include "tree.h" 83192Smckusick #include "opcode.h" 93192Smckusick #include "objfmt.h" 103192Smckusick #include "align.h" 113192Smckusick 123192Smckusick /* 133192Smckusick * this array keeps the pxp counters associated with 143192Smckusick * functions and procedures, so that they can be output 153192Smckusick * when their bodies are encountered 163192Smckusick */ 173192Smckusick int bodycnts[ DSPLYSZ ]; 183192Smckusick 193192Smckusick #ifdef PC 203192Smckusick # include "pc.h" 213192Smckusick # include "pcops.h" 223192Smckusick #endif PC 233192Smckusick 243192Smckusick #ifdef OBJ 253192Smckusick int cntpatch; 263192Smckusick int nfppatch; 273192Smckusick #endif OBJ 283192Smckusick 293192Smckusick struct nl *Fp; 303192Smckusick int pnumcnt; 313192Smckusick /* 323192Smckusick * Funcend is called to 333192Smckusick * finish a block by generating 343192Smckusick * the code for the statements. 353192Smckusick * It then looks for unresolved declarations 363192Smckusick * of labels, procedures and functions, 373192Smckusick * and cleans up the name list. 383192Smckusick * For the program, it checks the 393192Smckusick * semantics of the program 403192Smckusick * statement (yuchh). 413192Smckusick */ 423192Smckusick funcend(fp, bundle, endline) 433192Smckusick struct nl *fp; 443192Smckusick int *bundle; 453192Smckusick int endline; 463192Smckusick { 473192Smckusick register struct nl *p; 483192Smckusick register int i, b; 493192Smckusick int var, inp, out, *blk; 503192Smckusick bool chkref; 513192Smckusick struct nl *iop; 523192Smckusick char *cp; 533192Smckusick extern int cntstat; 543192Smckusick # ifdef PC 55*3279Smckusic int savlabel = getlab(); 563192Smckusick int toplabel = getlab(); 573192Smckusick int botlabel = getlab(); 583192Smckusick # endif PC 593192Smckusick 603192Smckusick cntstat = 0; 613192Smckusick /* 623192Smckusick * yyoutline(); 633192Smckusick */ 643192Smckusick if (program != NIL) 653192Smckusick line = program->value[3]; 663192Smckusick blk = bundle[2]; 673192Smckusick if (fp == NIL) { 683192Smckusick cbn--; 693192Smckusick # ifdef PTREE 703192Smckusick nesting--; 713192Smckusick # endif PTREE 723192Smckusick return; 733192Smckusick } 743192Smckusick #ifdef OBJ 753192Smckusick /* 763192Smckusick * Patch the branch to the 773192Smckusick * entry point of the function 783192Smckusick */ 793192Smckusick patch4(fp->entloc); 803192Smckusick /* 813192Smckusick * Put out the block entrance code and the block name. 823192Smckusick * HDRSZE is the number of bytes of info in the static 833192Smckusick * BEG data area exclusive of the proc name. It is 843192Smckusick * currently defined as: 853192Smckusick /* struct hdr { 863192Smckusick /* long framesze; /* number of bytes of local vars */ 873192Smckusick /* long nargs; /* number of bytes of arguments */ 883192Smckusick /* bool tests; /* TRUE => perform runtime tests */ 893192Smckusick /* short offset; /* offset of procedure in source file */ 903192Smckusick /* char name[1]; /* name of active procedure */ 913192Smckusick /* }; 923192Smckusick */ 933192Smckusick # define HDRSZE (2 * sizeof(long) + sizeof(short) + sizeof(bool)) 943192Smckusick var = put(2, ((lenstr(fp->symbol,0) + HDRSZE) << 8) 953192Smckusick | (cbn == 1 && opt('p') == 0 ? O_NODUMP: O_BEG), (long)0); 963192Smckusick /* 973192Smckusick * output the number of bytes of arguments 983192Smckusick * this is only checked on formal calls. 993192Smckusick */ 1003192Smckusick put(2, O_CASE4, cbn == 1 ? (long)0 : (long)(fp->value[NL_OFFS]-DPOFF2)); 1013192Smckusick /* 1023192Smckusick * Output the runtime test mode for the routine 1033192Smckusick */ 1043192Smckusick put(2, sizeof(bool) == 2 ? O_CASE2 : O_CASE4, opt('t') ? TRUE : FALSE); 1053192Smckusick /* 1063192Smckusick * Output line number and routine name 1073192Smckusick */ 1083192Smckusick put(2, O_CASE2, bundle[1]); 1093192Smckusick putstr(fp->symbol, 0); 1103192Smckusick #endif OBJ 1113192Smckusick #ifdef PC 1123192Smckusick /* 1133192Smckusick * put out the procedure entry code 1143192Smckusick */ 1153192Smckusick if ( fp -> class == PROG ) { 1163192Smckusick putprintf( " .text" , 0 ); 1173192Smckusick putprintf( " .align 1" , 0 ); 1183192Smckusick putprintf( " .globl _main" , 0 ); 1193192Smckusick putprintf( "_main:" , 0 ); 1203192Smckusick putprintf( " .word 0" , 0 ); 1213192Smckusick putprintf( " calls $0,_PCSTART" , 0 ); 1223192Smckusick putprintf( " movl 4(ap),__argc" , 0 ); 1233192Smckusick putprintf( " movl 8(ap),__argv" , 0 ); 1243192Smckusick putprintf( " calls $0,_program" , 0 ); 1253192Smckusick putprintf( " calls $0,_PCEXIT" , 0 ); 1263192Smckusick ftnno = fp -> entloc; 1273192Smckusick putprintf( " .text" , 0 ); 1283192Smckusick putprintf( " .align 1" , 0 ); 1293192Smckusick putprintf( " .globl _program" , 0 ); 1303192Smckusick putprintf( "_program:" , 0 ); 1313192Smckusick stabfunc( "program" , fp -> class , bundle[1] , 0 ); 1323192Smckusick } else { 1333192Smckusick ftnno = fp -> entloc; 1343192Smckusick putprintf( " .text" , 0 ); 1353192Smckusick putprintf( " .align 1" , 0 ); 1363192Smckusick putprintf( " .globl " , 1 ); 1373192Smckusick for ( i = 1 ; i < cbn ; i++ ) { 1383192Smckusick putprintf( EXTFORMAT , 1 , enclosing[ i ] ); 1393192Smckusick } 1403192Smckusick putprintf( "" , 0 ); 1413192Smckusick for ( i = 1 ; i < cbn ; i++ ) { 1423192Smckusick putprintf( EXTFORMAT , 1 , enclosing[ i ] ); 1433192Smckusick } 1443192Smckusick putprintf( ":" , 0 ); 1453192Smckusick stabfunc( fp -> symbol , fp -> class , bundle[1] , cbn - 1 ); 1463192Smckusick for ( p = fp -> chain ; p != NIL ; p = p -> chain ) { 1473192Smckusick stabparam( p -> symbol , p2type( p -> type ) 1483192Smckusick , p -> value[ NL_OFFS ] , lwidth( p -> type ) ); 1493192Smckusick } 1503192Smckusick if ( fp -> class == FUNC ) { 1513192Smckusick /* 1523192Smckusick * stab the function variable 1533192Smckusick */ 1543192Smckusick p = fp -> ptr[ NL_FVAR ]; 1553192Smckusick stablvar( p -> symbol , p2type( p -> type ) , cbn 1563192Smckusick , p -> value[ NL_OFFS ] , lwidth( p -> type ) ); 1573192Smckusick } 1583192Smckusick /* 1593192Smckusick * stab local variables 1603192Smckusick * rummage down hash chain links. 1613192Smckusick */ 1623192Smckusick for ( i = 0 ; i <= 077 ; i++ ) { 1633192Smckusick for ( p = disptab[ i ] ; p != NIL ; p = p->nl_next) { 1643192Smckusick if ( ( p -> nl_block & 037 ) != cbn ) { 1653192Smckusick break; 1663192Smckusick } 1673192Smckusick /* 1683192Smckusick * stab local variables 1693192Smckusick * that's named variables, but not params 1703192Smckusick */ 1713192Smckusick if ( ( p -> symbol != NIL ) 1723192Smckusick && ( p -> class == VAR ) 1733192Smckusick && ( p -> value[ NL_OFFS ] < 0 ) ) { 1743192Smckusick stablvar( p -> symbol , p2type( p -> type ) , cbn 1753192Smckusick , p -> value[ NL_OFFS ] , lwidth( p -> type ) ); 1763192Smckusick } 1773192Smckusick } 1783192Smckusick } 1793192Smckusick } 1803192Smckusick stablbrac( cbn ); 1813192Smckusick /* 1823192Smckusick * register save mask 1833192Smckusick */ 184*3279Smckusic putprintf( " .word " , 1 ); 185*3279Smckusic putprintf( PREFIXFORMAT , 0 , LABELPREFIX , savlabel ); 1863192Smckusick putjbr( botlabel ); 1873192Smckusick putlab( toplabel ); 1883192Smckusick if ( profflag ) { 1893192Smckusick /* 1903192Smckusick * call mcount for profiling 1913192Smckusick */ 1923192Smckusick putprintf( " moval 1f,r0" , 0 ); 1933192Smckusick putprintf( " jsb mcount" , 0 ); 1943192Smckusick putprintf( " .data" , 0 ); 1953192Smckusick putprintf( " .align 2" , 0 ); 1963192Smckusick putprintf( "1:" , 0 ); 1973192Smckusick putprintf( " .long 0" , 0 ); 1983192Smckusick putprintf( " .text" , 0 ); 1993192Smckusick } 2003192Smckusick /* 2013192Smckusick * set up unwind exception vector. 2023192Smckusick */ 2033192Smckusick putprintf( " moval %s,%d(%s)" , 0 2043192Smckusick , UNWINDNAME , UNWINDOFFSET , P2FPNAME ); 2053192Smckusick /* 2063192Smckusick * save address of display entry, for unwind. 2073192Smckusick */ 2083192Smckusick putprintf( " moval %s+%d,%d(%s)" , 0 2093192Smckusick , DISPLAYNAME , cbn * sizeof(struct dispsave) 2103192Smckusick , DPTROFFSET , P2FPNAME ); 2113192Smckusick /* 2123192Smckusick * save old display 2133192Smckusick */ 2143192Smckusick putprintf( " movq %s+%d,%d(%s)" , 0 2153192Smckusick , DISPLAYNAME , cbn * sizeof(struct dispsave) 2163192Smckusick , DSAVEOFFSET , P2FPNAME ); 2173192Smckusick /* 2183192Smckusick * set up new display by saving AP and FP in appropriate 2193192Smckusick * slot in display structure. 2203192Smckusick */ 2213192Smckusick putprintf( " movq %s,%s+%d" , 0 2223192Smckusick , P2APNAME , DISPLAYNAME , cbn * sizeof(struct dispsave) ); 2233192Smckusick /* 2243192Smckusick * ask second pass to allocate known locals 2253192Smckusick */ 2263192Smckusick putlbracket( ftnno , -sizes[ cbn ].om_max ); 2273192Smckusick /* 2283192Smckusick * and zero them if checking is on 2293192Smckusick * by calling blkclr( bytes of locals , starting local address ); 2303192Smckusick */ 2313192Smckusick if ( opt( 't' ) ) { 2323192Smckusick if ( ( -sizes[ cbn ].om_max ) > DPOFF1 ) { 2333192Smckusick putleaf( P2ICON , 0 , 0 , ADDTYPE( P2FTN | P2INT , P2PTR ) 2343192Smckusick , "_blkclr" ); 2353192Smckusick putleaf( P2ICON , ( -sizes[ cbn ].om_max ) - DPOFF1 2363192Smckusick , 0 , P2INT , 0 ); 2373192Smckusick putLV( 0 , cbn , sizes[ cbn ].om_max , P2CHAR ); 2383192Smckusick putop( P2LISTOP , P2INT ); 2393192Smckusick putop( P2CALL , P2INT ); 2403192Smckusick putdot( filename , line ); 2413192Smckusick } 2423192Smckusick /* 2433192Smckusick * check number of longs of arguments 2443192Smckusick * this can only be wrong for formal calls. 2453192Smckusick */ 2463192Smckusick if ( fp -> class != PROG ) { 2473192Smckusick putleaf( P2ICON , 0 , 0 , ADDTYPE( P2PTR , P2FTN | P2INT ) , 2483192Smckusick "_NARGCHK" ); 2493192Smckusick putleaf( P2ICON , 2503192Smckusick (fp->value[NL_OFFS] - DPOFF2) / sizeof(long) , 2513192Smckusick 0 , P2INT , 0 ); 2523192Smckusick putop( P2CALL , P2INT ); 2533192Smckusick putdot( filename , line ); 2543192Smckusick } 2553192Smckusick } 2563192Smckusick #endif PC 2573192Smckusick if ( monflg ) { 2583192Smckusick if ( fp -> value[ NL_CNTR ] != 0 ) { 2593192Smckusick inccnt( fp -> value [ NL_CNTR ] ); 2603192Smckusick } 2613192Smckusick inccnt( bodycnts[ fp -> nl_block & 037 ] ); 2623192Smckusick } 2633192Smckusick if (fp->class == PROG) { 2643192Smckusick /* 2653192Smckusick * The glorious buffers option. 2663192Smckusick * 0 = don't buffer output 2673192Smckusick * 1 = line buffer output 2683192Smckusick * 2 = 512 byte buffer output 2693192Smckusick */ 2703192Smckusick # ifdef OBJ 2713192Smckusick if (opt('b') != 1) 2723192Smckusick put(1, O_BUFF | opt('b') << 8); 2733192Smckusick # endif OBJ 2743192Smckusick # ifdef PC 2753192Smckusick if ( opt( 'b' ) != 1 ) { 2763192Smckusick putleaf( P2ICON , 0 , 0 2773192Smckusick , ADDTYPE( P2FTN | P2INT , P2PTR ) , "_BUFF" ); 2783192Smckusick putleaf( P2ICON , opt( 'b' ) , 0 , P2INT , 0 ); 2793192Smckusick putop( P2CALL , P2INT ); 2803192Smckusick putdot( filename , line ); 2813192Smckusick } 2823192Smckusick # endif PC 2833192Smckusick out = 0; 2843192Smckusick for (p = fp->chain; p != NIL; p = p->chain) { 2853192Smckusick if (strcmp(p->symbol, "input") == 0) { 2863192Smckusick inp++; 2873192Smckusick continue; 2883192Smckusick } 2893192Smckusick if (strcmp(p->symbol, "output") == 0) { 2903192Smckusick out++; 2913192Smckusick continue; 2923192Smckusick } 2933192Smckusick iop = lookup1(p->symbol); 2943192Smckusick if (iop == NIL || bn != cbn) { 2953192Smckusick error("File %s listed in program statement but not declared", p->symbol); 2963192Smckusick continue; 2973192Smckusick } 2983192Smckusick if (iop->class != VAR) { 2993192Smckusick error("File %s listed in program statement but declared as a %s", p->symbol, classes[iop->class]); 3003192Smckusick continue; 3013192Smckusick } 3023192Smckusick if (iop->type == NIL) 3033192Smckusick continue; 3043192Smckusick if (iop->type->class != FILET) { 3053192Smckusick error("File %s listed in program statement but defined as %s", 3063192Smckusick p->symbol, nameof(iop->type)); 3073192Smckusick continue; 3083192Smckusick } 3093192Smckusick # ifdef OBJ 3103192Smckusick put(2, O_CON24, text(iop->type) ? 0 : width(iop->type->type)); 3113192Smckusick i = lenstr(p->symbol,0); 3123192Smckusick put(2, O_CON24, i); 3133192Smckusick put(2, O_LVCON, i); 3143192Smckusick putstr(p->symbol, 0); 3153192Smckusick put(2, O_LV | bn<<8+INDX, (int)iop->value[NL_OFFS]); 3163192Smckusick put(1, O_DEFNAME); 3173192Smckusick # endif OBJ 3183192Smckusick # ifdef PC 3193192Smckusick putleaf( P2ICON , 0 , 0 3203192Smckusick , ADDTYPE( P2FTN | P2INT , P2PTR ) 3213192Smckusick , "_DEFNAME" ); 3223192Smckusick putLV( p -> symbol , bn , iop -> value[NL_OFFS] 3233192Smckusick , p2type( iop ) ); 3243192Smckusick putCONG( p -> symbol , strlen( p -> symbol ) 3253192Smckusick , LREQ ); 3263192Smckusick putop( P2LISTOP , P2INT ); 3273192Smckusick putleaf( P2ICON , strlen( p -> symbol ) 3283192Smckusick , 0 , P2INT , 0 ); 3293192Smckusick putop( P2LISTOP , P2INT ); 3303192Smckusick putleaf( P2ICON 3313192Smckusick , text(iop->type) ? 0 : width(iop->type->type) 3323192Smckusick , 0 , P2INT , 0 ); 3333192Smckusick putop( P2LISTOP , P2INT ); 3343192Smckusick putop( P2CALL , P2INT ); 3353192Smckusick putdot( filename , line ); 3363192Smckusick # endif PC 3373192Smckusick } 3383192Smckusick if (out == 0 && fp->chain != NIL) { 3393192Smckusick recovered(); 3403192Smckusick error("The file output must appear in the program statement file list"); 3413192Smckusick } 3423192Smckusick } 3433192Smckusick /* 3443192Smckusick * Process the prog/proc/func body 3453192Smckusick */ 3463192Smckusick noreach = 0; 3473192Smckusick line = bundle[1]; 3483192Smckusick statlist(blk); 3493192Smckusick # ifdef PTREE 3503192Smckusick { 3513192Smckusick pPointer Body = tCopy( blk ); 3523192Smckusick 3533192Smckusick pDEF( PorFHeader[ nesting -- ] ).PorFBody = Body; 3543192Smckusick } 3553192Smckusick # endif PTREE 3563192Smckusick # ifdef OBJ 3573192Smckusick if (cbn== 1 && monflg != 0) { 3583192Smckusick patchfil(cntpatch - 2, (long)cnts, 2); 3593192Smckusick patchfil(nfppatch - 2, (long)pfcnt, 2); 3603192Smckusick } 3613192Smckusick # endif OBJ 3623192Smckusick # ifdef PC 3633192Smckusick if ( fp -> class == PROG && monflg ) { 3643192Smckusick putleaf( P2ICON , 0 , 0 , ADDTYPE( P2FTN | P2INT , P2PTR ) 3653192Smckusick , "_PMFLUSH" ); 3663192Smckusick putleaf( P2ICON , cnts , 0 , P2INT , 0 ); 3673192Smckusick putleaf( P2ICON , pfcnt , 0 , P2INT , 0 ); 3683192Smckusick putop( P2LISTOP , P2INT ); 3693192Smckusick putLV( PCPCOUNT , 0 , 0 , P2INT ); 3703192Smckusick putop( P2LISTOP , P2INT ); 3713192Smckusick putop( P2CALL , P2INT ); 3723192Smckusick putdot( filename , line ); 3733192Smckusick } 3743192Smckusick # endif PC 3753192Smckusick if (fp->class == PROG && inp == 0 && (input->nl_flags & (NUSED|NMOD)) != 0) { 3763192Smckusick recovered(); 3773192Smckusick error("Input is used but not defined in the program statement"); 3783192Smckusick } 3793192Smckusick /* 3803192Smckusick * Clean up the symbol table displays and check for unresolves 3813192Smckusick */ 3823192Smckusick line = endline; 3833192Smckusick b = cbn; 3843192Smckusick Fp = fp; 3853192Smckusick chkref = syneflg == errcnt[cbn] && opt('w') == 0; 3863192Smckusick for (i = 0; i <= 077; i++) { 3873192Smckusick for (p = disptab[i]; p != NIL && (p->nl_block & 037) == b; p = p->nl_next) { 3883192Smckusick /* 3893192Smckusick * Check for variables defined 3903192Smckusick * but not referenced 3913192Smckusick */ 3923192Smckusick if (chkref && p->symbol != NIL) 3933192Smckusick switch (p->class) { 3943192Smckusick case FIELD: 3953192Smckusick /* 3963192Smckusick * If the corresponding record is 3973192Smckusick * unused, we shouldn't complain about 3983192Smckusick * the fields. 3993192Smckusick */ 4003192Smckusick default: 4013192Smckusick if ((p->nl_flags & (NUSED|NMOD)) == 0) { 4023192Smckusick warning(); 4033192Smckusick nerror("%s %s is neither used nor set", classes[p->class], p->symbol); 4043192Smckusick break; 4053192Smckusick } 4063192Smckusick /* 4073192Smckusick * If a var parameter is either 4083192Smckusick * modified or used that is enough. 4093192Smckusick */ 4103192Smckusick if (p->class == REF) 4113192Smckusick continue; 4123192Smckusick # ifdef OBJ 4133192Smckusick if ((p->nl_flags & NUSED) == 0) { 4143192Smckusick warning(); 4153192Smckusick nerror("%s %s is never used", classes[p->class], p->symbol); 4163192Smckusick break; 4173192Smckusick } 4183192Smckusick # endif OBJ 4193192Smckusick # ifdef PC 4203192Smckusick if (((p->nl_flags & NUSED) == 0) && ((p->ext_flags & NEXTERN) == 0)) { 4213192Smckusick warning(); 4223192Smckusick nerror("%s %s is never used", classes[p->class], p->symbol); 4233192Smckusick break; 4243192Smckusick } 4253192Smckusick # endif PC 4263192Smckusick if ((p->nl_flags & NMOD) == 0) { 4273192Smckusick warning(); 4283192Smckusick nerror("%s %s is used but never set", classes[p->class], p->symbol); 4293192Smckusick break; 4303192Smckusick } 4313192Smckusick case LABEL: 4323192Smckusick case FVAR: 4333192Smckusick case BADUSE: 4343192Smckusick break; 4353192Smckusick } 4363192Smckusick switch (p->class) { 4373192Smckusick case BADUSE: 4383192Smckusick cp = "s"; 4393192Smckusick if (p->chain->ud_next == NIL) 4403192Smckusick cp++; 4413192Smckusick eholdnl(); 4423192Smckusick if (p->value[NL_KINDS] & ISUNDEF) 4433192Smckusick nerror("%s undefined on line%s", p->symbol, cp); 4443192Smckusick else 4453192Smckusick nerror("%s improperly used on line%s", p->symbol, cp); 4463192Smckusick pnumcnt = 10; 4473192Smckusick pnums(p->chain); 4483192Smckusick pchr('\n'); 4493192Smckusick break; 4503192Smckusick 4513192Smckusick case FUNC: 4523192Smckusick case PROC: 4533192Smckusick # ifdef OBJ 4543192Smckusick if ((p->nl_flags & NFORWD)) 4553192Smckusick nerror("Unresolved forward declaration of %s %s", classes[p->class], p->symbol); 4563192Smckusick # endif OBJ 4573192Smckusick # ifdef PC 4583192Smckusick if ((p->nl_flags & NFORWD) && ((p->ext_flags & NEXTERN) == 0)) 4593192Smckusick nerror("Unresolved forward declaration of %s %s", classes[p->class], p->symbol); 4603192Smckusick # endif PC 4613192Smckusick break; 4623192Smckusick 4633192Smckusick case LABEL: 4643192Smckusick if (p->nl_flags & NFORWD) 4653192Smckusick nerror("label %s was declared but not defined", p->symbol); 4663192Smckusick break; 4673192Smckusick case FVAR: 4683192Smckusick if ((p->nl_flags & NMOD) == 0) 4693192Smckusick nerror("No assignment to the function variable"); 4703192Smckusick break; 4713192Smckusick } 4723192Smckusick } 4733192Smckusick /* 4743192Smckusick * Pop this symbol 4753192Smckusick * table slot 4763192Smckusick */ 4773192Smckusick disptab[i] = p; 4783192Smckusick } 4793192Smckusick 4803192Smckusick # ifdef OBJ 4813192Smckusick put(1, O_END); 4823192Smckusick # endif OBJ 4833192Smckusick # ifdef PC 4843192Smckusick /* 4853192Smckusick * if there were file variables declared at this level 4863192Smckusick * call pclose( &__disply[ cbn ] ) to clean them up. 4873192Smckusick */ 4883192Smckusick if ( dfiles[ cbn ] ) { 4893192Smckusick putleaf( P2ICON , 0 , 0 , ADDTYPE( P2FTN | P2INT , P2PTR ) 4903192Smckusick , "_PCLOSE" ); 4913192Smckusick putRV( DISPLAYNAME , 0 , cbn * sizeof( struct dispsave ) 4923192Smckusick , P2PTR | P2CHAR ); 4933192Smckusick putop( P2CALL , P2INT ); 4943192Smckusick putdot( filename , line ); 4953192Smckusick } 4963192Smckusick /* 4973192Smckusick * if this is a function, 4983192Smckusick * the function variable is the return value. 4993192Smckusick * if it's a scalar valued function, return scalar, 5003192Smckusick * else, return a pointer to the structure value. 5013192Smckusick */ 5023192Smckusick if ( fp -> class == FUNC ) { 5033192Smckusick struct nl *fvar = fp -> ptr[ NL_FVAR ]; 5043192Smckusick long fvartype = p2type( fvar -> type ); 5053192Smckusick long label; 5063192Smckusick char labelname[ BUFSIZ ]; 5073192Smckusick 5083192Smckusick switch ( classify( fvar -> type ) ) { 5093192Smckusick case TBOOL: 5103192Smckusick case TCHAR: 5113192Smckusick case TINT: 5123192Smckusick case TSCAL: 5133192Smckusick case TDOUBLE: 5143192Smckusick case TPTR: 5153192Smckusick putRV( fvar -> symbol , ( fvar -> nl_block ) & 037 5163192Smckusick , fvar -> value[ NL_OFFS ] , fvartype ); 5173192Smckusick break; 5183192Smckusick default: 5193192Smckusick label = getlab(); 5203192Smckusick sprintf( labelname , PREFIXFORMAT , 5213192Smckusick LABELPREFIX , label ); 5223192Smckusick putprintf( " .data" , 0 ); 5233192Smckusick putprintf( " .lcomm %s,%d" , 0 , 5243192Smckusick labelname , lwidth( fvar -> type ) ); 5253192Smckusick putprintf( " .text" , 0 ); 5263192Smckusick putleaf( P2NAME , 0 , 0 , fvartype , labelname ); 5273192Smckusick putLV( fvar -> symbol , ( fvar -> nl_block ) & 037 5283192Smckusick , fvar -> value[ NL_OFFS ] , fvartype ); 5293192Smckusick putstrop( P2STASG , fvartype , lwidth( fvar -> type ) , 5303192Smckusick align( fvar -> type ) ); 5313192Smckusick putdot( filename , line ); 5323192Smckusick putleaf( P2ICON , 0 , 0 , fvartype , labelname ); 5333192Smckusick break; 5343192Smckusick } 5353192Smckusick putop( P2FORCE , fvartype ); 5363192Smckusick putdot( filename , line ); 5373192Smckusick } 5383192Smckusick /* 5393192Smckusick * restore old display entry from save area 5403192Smckusick */ 5413192Smckusick 5423192Smckusick putprintf( " movq %d(%s),%s+%d" , 0 5433192Smckusick , DSAVEOFFSET , P2FPNAME 5443192Smckusick , DISPLAYNAME , cbn * sizeof(struct dispsave) ); 5453192Smckusick stabrbrac( cbn ); 5463192Smckusick putprintf( " ret" , 0 ); 5473192Smckusick /* 5483192Smckusick * let the second pass allocate locals 549*3279Smckusic * and registers 5503192Smckusick */ 551*3279Smckusic putprintf( " .set " , 1 ); 552*3279Smckusic putprintf( PREFIXFORMAT , 1 , LABELPREFIX , savlabel ); 553*3279Smckusic putprintf( ", 0x%x" , 0 , savmask() ); 5543192Smckusick putlab( botlabel ); 5553192Smckusick putprintf( " subl2 $LF%d,sp" , 0 , ftnno ); 5563192Smckusick putrbracket( ftnno ); 5573192Smckusick putjbr( toplabel ); 5583192Smckusick /* 5593192Smckusick * declare pcp counters, if any 5603192Smckusick */ 5613192Smckusick if ( monflg && fp -> class == PROG ) { 5623192Smckusick putprintf( " .data" , 0 ); 5633192Smckusick putprintf( " .comm " , 1 ); 5643192Smckusick putprintf( PCPCOUNT , 1 ); 5653192Smckusick putprintf( ",%d" , 0 , ( cnts + 1 ) * sizeof (long) ); 5663192Smckusick putprintf( " .text" , 0 ); 5673192Smckusick } 5683192Smckusick # endif PC 5693192Smckusick #ifdef DEBUG 5703192Smckusick dumpnl(fp->ptr[2], fp->symbol); 5713192Smckusick #endif 5723192Smckusick /* 5733192Smckusick * Restore the 5743192Smckusick * (virtual) name list 5753192Smckusick * position 5763192Smckusick */ 5773192Smckusick nlfree(fp->ptr[2]); 5783192Smckusick /* 5793192Smckusick * Proc/func has been 5803192Smckusick * resolved 5813192Smckusick */ 5823192Smckusick fp->nl_flags &= ~NFORWD; 5833192Smckusick /* 5843192Smckusick * Patch the beg 5853192Smckusick * of the proc/func to 5863192Smckusick * the proper variable size 5873192Smckusick */ 5883192Smckusick if (Fp == NIL) 5893192Smckusick elineon(); 5903192Smckusick # ifdef OBJ 5913192Smckusick patchfil(var, (long)(-sizes[cbn].om_max), 2); 5923192Smckusick # endif OBJ 5933192Smckusick cbn--; 5943192Smckusick if (inpflist(fp->symbol)) { 5953192Smckusick opop('l'); 5963192Smckusick } 5973192Smckusick } 598