1*48116Sbostic /*- 2*48116Sbostic * Copyright (c) 1980 The Regents of the University of California. 3*48116Sbostic * All rights reserved. 4*48116Sbostic * 5*48116Sbostic * %sccs.include.redist.c% 622164Sdist */ 73192Smckusick 818347Smckusick #ifndef lint 9*48116Sbostic static char sccsid[] = "@(#)fend.c 5.5 (Berkeley) 04/16/91"; 10*48116Sbostic #endif /* not lint */ 113192Smckusick 123192Smckusick #include "whoami.h" 133192Smckusick #include "0.h" 143192Smckusick #include "tree.h" 153192Smckusick #include "opcode.h" 163192Smckusick #include "objfmt.h" 173192Smckusick #include "align.h" 1811337Speter #include "tmps.h" 193192Smckusick 203192Smckusick /* 213192Smckusick * this array keeps the pxp counters associated with 223192Smckusick * functions and procedures, so that they can be output 233192Smckusick * when their bodies are encountered 243192Smckusick */ 253192Smckusick int bodycnts[ DSPLYSZ ]; 263192Smckusick 273192Smckusick #ifdef PC 283192Smckusick # include "pc.h" 2918457Sralph # include <pcc.h> 303192Smckusick #endif PC 313192Smckusick 323192Smckusick #ifdef OBJ 333192Smckusick int cntpatch; 343192Smckusick int nfppatch; 353192Smckusick #endif OBJ 363192Smckusick 3718347Smckusick #include "tree_ty.h" 3818347Smckusick 393192Smckusick struct nl *Fp; 403192Smckusick int pnumcnt; 413192Smckusick /* 423192Smckusick * Funcend is called to 433192Smckusick * finish a block by generating 443192Smckusick * the code for the statements. 453192Smckusick * It then looks for unresolved declarations 463192Smckusick * of labels, procedures and functions, 473192Smckusick * and cleans up the name list. 483192Smckusick * For the program, it checks the 493192Smckusick * semantics of the program 503192Smckusick * statement (yuchh). 513192Smckusick */ 523192Smckusick funcend(fp, bundle, endline) 533192Smckusick struct nl *fp; 5418347Smckusick struct tnode *bundle; 553192Smckusick int endline; 563192Smckusick { 573192Smckusick register struct nl *p; 583192Smckusick register int i, b; 5918347Smckusick int inp, out; 6018347Smckusick struct tnode *blk; 613192Smckusick bool chkref; 623192Smckusick struct nl *iop; 633192Smckusick char *cp; 643192Smckusick extern int cntstat; 653192Smckusick # ifdef PC 6610671Speter struct entry_exit_cookie eecookie; 673192Smckusick # endif PC 6818347Smckusick # ifndef PC 6918347Smckusick int var; 7018347Smckusick # endif PC 713192Smckusick 723192Smckusick cntstat = 0; 733192Smckusick /* 743192Smckusick * yyoutline(); 753192Smckusick */ 763192Smckusick if (program != NIL) 773192Smckusick line = program->value[3]; 7818347Smckusick blk = bundle->stmnt_blck.stmnt_list; 793192Smckusick if (fp == NIL) { 803192Smckusick cbn--; 813192Smckusick # ifdef PTREE 823192Smckusick nesting--; 833192Smckusick # endif PTREE 843192Smckusick return; 853192Smckusick } 863192Smckusick #ifdef OBJ 873192Smckusick /* 8830039Smckusick * Patch the branch to the entry point of the function. 8930039Smckusick * Assure alignment of O_BEG structure. 903192Smckusick */ 9130039Smckusick if (((int)lc & 02) == 0) 9230039Smckusick word(0); 9318347Smckusick patch4((PTR_DCL) fp->value[NL_ENTLOC]); 943192Smckusick /* 953192Smckusick * Put out the block entrance code and the block name. 963192Smckusick * HDRSZE is the number of bytes of info in the static 973192Smckusick * BEG data area exclusive of the proc name. It is 983192Smckusick * currently defined as: 993192Smckusick /* struct hdr { 1003192Smckusick /* long framesze; /* number of bytes of local vars */ 1013192Smckusick /* long nargs; /* number of bytes of arguments */ 1023192Smckusick /* bool tests; /* TRUE => perform runtime tests */ 1033192Smckusick /* short offset; /* offset of procedure in source file */ 1043192Smckusick /* char name[1]; /* name of active procedure */ 1053192Smckusick /* }; 1063192Smckusick */ 1073192Smckusick # define HDRSZE (2 * sizeof(long) + sizeof(short) + sizeof(bool)) 1083192Smckusick var = put(2, ((lenstr(fp->symbol,0) + HDRSZE) << 8) 1093192Smckusick | (cbn == 1 && opt('p') == 0 ? O_NODUMP: O_BEG), (long)0); 1103192Smckusick /* 1113192Smckusick * output the number of bytes of arguments 1123192Smckusick * this is only checked on formal calls. 1133192Smckusick */ 11418347Smckusick (void) put(2, O_CASE4, cbn == 1 ? (long)0 : (long)(fp->value[NL_OFFS]-DPOFF2)); 1153192Smckusick /* 1163192Smckusick * Output the runtime test mode for the routine 1173192Smckusick */ 11818347Smckusick (void) put(2, sizeof(bool) == 2 ? O_CASE2 : O_CASE4, opt('t') ? TRUE : FALSE); 1193192Smckusick /* 1203192Smckusick * Output line number and routine name 1213192Smckusick */ 12218347Smckusick (void) put(2, O_CASE2, bundle->stmnt_blck.line_no); 1233192Smckusick putstr(fp->symbol, 0); 1243192Smckusick #endif OBJ 1253192Smckusick #ifdef PC 1263192Smckusick /* 1273192Smckusick * put out the procedure entry code 1283192Smckusick */ 12910671Speter eecookie.nlp = fp; 1303192Smckusick if ( fp -> class == PROG ) { 1319129Smckusick /* 1329129Smckusick * If there is a label declaration in the main routine 1339129Smckusick * then there may be a non-local goto to it that does 1349129Smckusick * not appear in this module. We have to assume that 1359129Smckusick * such a reference may occur and generate code to 1369129Smckusick * prepare for it. 1379129Smckusick */ 1389129Smckusick if ( parts[ cbn ] & LPRT ) { 1399129Smckusick parts[ cbn ] |= ( NONLOCALVAR | NONLOCALGOTO ); 1409129Smckusick } 14110671Speter codeformain(); 1427917Smckusick ftnno = fp -> value[NL_ENTLOC]; 14310671Speter prog_prologue(&eecookie); 14418347Smckusick stabline(bundle->stmnt_blck.line_no); 14518347Smckusick stabfunc(fp, "program", bundle->stmnt_blck.line_no , (long) 0 ); 1463192Smckusick } else { 1477917Smckusick ftnno = fp -> value[NL_ENTLOC]; 14810671Speter fp_prologue(&eecookie); 14918347Smckusick stabline(bundle->stmnt_blck.line_no); 15018347Smckusick stabfunc(fp, fp->symbol, bundle->stmnt_blck.line_no, 15118347Smckusick (long)(cbn - 1)); 1523192Smckusick for ( p = fp -> chain ; p != NIL ; p = p -> chain ) { 15318347Smckusick stabparam( p , p -> value[ NL_OFFS ] , (int) lwidth(p->type)); 1543192Smckusick } 1553192Smckusick if ( fp -> class == FUNC ) { 1563192Smckusick /* 1573192Smckusick * stab the function variable 1583192Smckusick */ 1593192Smckusick p = fp -> ptr[ NL_FVAR ]; 16018347Smckusick stablvar( p , p -> value[ NL_OFFS ] , (int) lwidth( p -> type)); 1613192Smckusick } 1623192Smckusick /* 1633192Smckusick * stab local variables 1643192Smckusick * rummage down hash chain links. 1653192Smckusick */ 1663192Smckusick for ( i = 0 ; i <= 077 ; i++ ) { 1673192Smckusick for ( p = disptab[ i ] ; p != NIL ; p = p->nl_next) { 1683192Smckusick if ( ( p -> nl_block & 037 ) != cbn ) { 1693192Smckusick break; 1703192Smckusick } 1713192Smckusick /* 17218346Smckusick * stab locals (not parameters) 1733192Smckusick */ 17418347Smckusick if ( p -> symbol != NIL ) { 17518347Smckusick if ( p -> class == VAR && p -> value[ NL_OFFS ] < 0 ) { 17618347Smckusick stablvar( p , p -> value[ NL_OFFS ] , 17718347Smckusick (int) lwidth( p -> type ) ); 17818347Smckusick } else if ( p -> class == CONST ) { 17918347Smckusick stabconst( p ); 18018346Smckusick } 1813192Smckusick } 1823192Smckusick } 1833192Smckusick } 1843192Smckusick } 1853192Smckusick stablbrac( cbn ); 1863192Smckusick /* 1873192Smckusick * ask second pass to allocate known locals 1883192Smckusick */ 18911337Speter putlbracket(ftnno, &sizes[cbn]); 19010671Speter fp_entrycode(&eecookie); 1913192Smckusick #endif PC 1923192Smckusick if ( monflg ) { 1933192Smckusick if ( fp -> value[ NL_CNTR ] != 0 ) { 1943192Smckusick inccnt( fp -> value [ NL_CNTR ] ); 1953192Smckusick } 1963192Smckusick inccnt( bodycnts[ fp -> nl_block & 037 ] ); 1973192Smckusick } 1983192Smckusick if (fp->class == PROG) { 1993192Smckusick /* 2003192Smckusick * The glorious buffers option. 2013192Smckusick * 0 = don't buffer output 2023192Smckusick * 1 = line buffer output 2033192Smckusick * 2 = 512 byte buffer output 2043192Smckusick */ 2053192Smckusick # ifdef OBJ 2063192Smckusick if (opt('b') != 1) 20718347Smckusick (void) put(1, O_BUFF | opt('b') << 8); 2083192Smckusick # endif OBJ 2093192Smckusick # ifdef PC 2103192Smckusick if ( opt( 'b' ) != 1 ) { 21118457Sralph putleaf( PCC_ICON , 0 , 0 21218457Sralph , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) , "_BUFF" ); 21318457Sralph putleaf( PCC_ICON , opt( 'b' ) , 0 , PCCT_INT , (char *) 0 ); 21418457Sralph putop( PCC_CALL , PCCT_INT ); 2153192Smckusick putdot( filename , line ); 2163192Smckusick } 2173192Smckusick # endif PC 2187953Speter inp = 0; 2193192Smckusick out = 0; 2203192Smckusick for (p = fp->chain; p != NIL; p = p->chain) { 22118347Smckusick if (pstrcmp(p->symbol, input->symbol) == 0) { 2223192Smckusick inp++; 2233192Smckusick continue; 2243192Smckusick } 22518347Smckusick if (pstrcmp(p->symbol, output->symbol) == 0) { 2263192Smckusick out++; 2273192Smckusick continue; 2283192Smckusick } 2293192Smckusick iop = lookup1(p->symbol); 2303192Smckusick if (iop == NIL || bn != cbn) { 2313192Smckusick error("File %s listed in program statement but not declared", p->symbol); 2323192Smckusick continue; 2333192Smckusick } 2343192Smckusick if (iop->class != VAR) { 2353192Smckusick error("File %s listed in program statement but declared as a %s", p->symbol, classes[iop->class]); 2363192Smckusick continue; 2373192Smckusick } 2383192Smckusick if (iop->type == NIL) 2393192Smckusick continue; 2403192Smckusick if (iop->type->class != FILET) { 2413192Smckusick error("File %s listed in program statement but defined as %s", 2423192Smckusick p->symbol, nameof(iop->type)); 2433192Smckusick continue; 2443192Smckusick } 2453192Smckusick # ifdef OBJ 24618347Smckusick (void) put(2, O_CON24, text(iop->type) ? 0 : width(iop->type->type)); 2473192Smckusick i = lenstr(p->symbol,0); 24818347Smckusick (void) put(2, O_CON24, i); 24918347Smckusick (void) put(2, O_LVCON, i); 2503192Smckusick putstr(p->symbol, 0); 25118347Smckusick (void) put(2, O_LV | bn<<8+INDX, (int)iop->value[NL_OFFS]); 25218347Smckusick (void) put(1, O_DEFNAME); 2533192Smckusick # endif OBJ 2543192Smckusick # ifdef PC 25518457Sralph putleaf( PCC_ICON , 0 , 0 25618457Sralph , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 2573192Smckusick , "_DEFNAME" ); 2583837Speter putLV( p -> symbol , bn , iop -> value[NL_OFFS] , 2593837Speter iop -> extra_flags , p2type( iop ) ); 2603192Smckusick putCONG( p -> symbol , strlen( p -> symbol ) 2613192Smckusick , LREQ ); 26218457Sralph putop( PCC_CM , PCCT_INT ); 26318457Sralph putleaf( PCC_ICON , strlen( p -> symbol ) 26418457Sralph , 0 , PCCT_INT , (char *) 0 ); 26518457Sralph putop( PCC_CM , PCCT_INT ); 26618457Sralph putleaf( PCC_ICON 2673192Smckusick , text(iop->type) ? 0 : width(iop->type->type) 26818457Sralph , 0 , PCCT_INT , (char *) 0 ); 26918457Sralph putop( PCC_CM , PCCT_INT ); 27018457Sralph putop( PCC_CALL , PCCT_INT ); 2713192Smckusick putdot( filename , line ); 2723192Smckusick # endif PC 2733192Smckusick } 2743192Smckusick } 2753192Smckusick /* 2763192Smckusick * Process the prog/proc/func body 2773192Smckusick */ 27818347Smckusick noreach = FALSE; 27918347Smckusick line = bundle->stmnt_blck.line_no; 2803192Smckusick statlist(blk); 2813192Smckusick # ifdef PTREE 2823192Smckusick { 2833192Smckusick pPointer Body = tCopy( blk ); 2843192Smckusick 2853192Smckusick pDEF( PorFHeader[ nesting -- ] ).PorFBody = Body; 2863192Smckusick } 2873192Smckusick # endif PTREE 2883192Smckusick # ifdef OBJ 28918347Smckusick if (cbn== 1 && monflg != FALSE) { 29018347Smckusick patchfil((PTR_DCL) (cntpatch - 2), (long)cnts, 2); 29118347Smckusick patchfil((PTR_DCL) (nfppatch - 2), (long)pfcnt, 2); 2923192Smckusick } 2933192Smckusick # endif OBJ 2943192Smckusick # ifdef PC 2953192Smckusick if ( fp -> class == PROG && monflg ) { 29618457Sralph putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 2973192Smckusick , "_PMFLUSH" ); 29818457Sralph putleaf( PCC_ICON , cnts , 0 , PCCT_INT , (char *) 0 ); 29918457Sralph putleaf( PCC_ICON , pfcnt , 0 , PCCT_INT , (char *) 0 ); 30018457Sralph putop( PCC_CM , PCCT_INT ); 30118457Sralph putLV( PCPCOUNT , 0 , 0 , NGLOBAL , PCCT_INT ); 30218457Sralph putop( PCC_CM , PCCT_INT ); 30318457Sralph putop( PCC_CALL , PCCT_INT ); 3043192Smckusick putdot( filename , line ); 3053192Smckusick } 3063192Smckusick # endif PC 3077953Speter /* 3087953Speter * Clean up the symbol table displays and check for unresolves 3097953Speter */ 3107953Speter line = endline; 3113192Smckusick if (fp->class == PROG && inp == 0 && (input->nl_flags & (NUSED|NMOD)) != 0) { 3123192Smckusick recovered(); 3133192Smckusick error("Input is used but not defined in the program statement"); 3143192Smckusick } 3157953Speter if (fp->class == PROG && out == 0 && (output->nl_flags & (NUSED|NMOD)) != 0) { 3167953Speter recovered(); 3177953Speter error("Output is used but not defined in the program statement"); 3187953Speter } 3193192Smckusick b = cbn; 3203192Smckusick Fp = fp; 32118347Smckusick chkref = (syneflg == errcnt[cbn] && opt('w') == 0)?TRUE:FALSE; 3223192Smckusick for (i = 0; i <= 077; i++) { 3233192Smckusick for (p = disptab[i]; p != NIL && (p->nl_block & 037) == b; p = p->nl_next) { 3243192Smckusick /* 3253192Smckusick * Check for variables defined 3263192Smckusick * but not referenced 3273192Smckusick */ 3283192Smckusick if (chkref && p->symbol != NIL) 3293192Smckusick switch (p->class) { 3303192Smckusick case FIELD: 3313192Smckusick /* 3323192Smckusick * If the corresponding record is 3333192Smckusick * unused, we shouldn't complain about 3343192Smckusick * the fields. 3353192Smckusick */ 3363192Smckusick default: 3373192Smckusick if ((p->nl_flags & (NUSED|NMOD)) == 0) { 3383192Smckusick warning(); 3393192Smckusick nerror("%s %s is neither used nor set", classes[p->class], p->symbol); 3403192Smckusick break; 3413192Smckusick } 3423192Smckusick /* 3433192Smckusick * If a var parameter is either 3443192Smckusick * modified or used that is enough. 3453192Smckusick */ 3463192Smckusick if (p->class == REF) 3473192Smckusick continue; 3483192Smckusick # ifdef OBJ 3493192Smckusick if ((p->nl_flags & NUSED) == 0) { 3503192Smckusick warning(); 3513192Smckusick nerror("%s %s is never used", classes[p->class], p->symbol); 3523192Smckusick break; 3533192Smckusick } 3543192Smckusick # endif OBJ 3553192Smckusick # ifdef PC 3563837Speter if (((p->nl_flags & NUSED) == 0) && ((p->extra_flags & NEXTERN) == 0)) { 3573192Smckusick warning(); 3583192Smckusick nerror("%s %s is never used", classes[p->class], p->symbol); 3593192Smckusick break; 3603192Smckusick } 3613192Smckusick # endif PC 3623192Smckusick if ((p->nl_flags & NMOD) == 0) { 3633192Smckusick warning(); 3643192Smckusick nerror("%s %s is used but never set", classes[p->class], p->symbol); 3653192Smckusick break; 3663192Smckusick } 3673192Smckusick case LABEL: 3683192Smckusick case FVAR: 3693192Smckusick case BADUSE: 3703192Smckusick break; 3713192Smckusick } 3723192Smckusick switch (p->class) { 3733192Smckusick case BADUSE: 3743192Smckusick cp = "s"; 37518347Smckusick /* This used to say ud_next 37618347Smckusick that is not a member of nl so 37718347Smckusick i changed it to nl_next, 37818347Smckusick which may be wrong */ 37918347Smckusick if (p->chain->nl_next == NIL) 3803192Smckusick cp++; 3813192Smckusick eholdnl(); 3823192Smckusick if (p->value[NL_KINDS] & ISUNDEF) 3833192Smckusick nerror("%s undefined on line%s", p->symbol, cp); 3843192Smckusick else 3853192Smckusick nerror("%s improperly used on line%s", p->symbol, cp); 3863192Smckusick pnumcnt = 10; 38718347Smckusick pnums((struct udinfo *) p->chain); 3883192Smckusick pchr('\n'); 3893192Smckusick break; 3903192Smckusick 3913192Smckusick case FUNC: 3923192Smckusick case PROC: 3933192Smckusick # ifdef OBJ 3943192Smckusick if ((p->nl_flags & NFORWD)) 3953192Smckusick nerror("Unresolved forward declaration of %s %s", classes[p->class], p->symbol); 3963192Smckusick # endif OBJ 3973192Smckusick # ifdef PC 3983837Speter if ((p->nl_flags & NFORWD) && ((p->extra_flags & NEXTERN) == 0)) 3993192Smckusick nerror("Unresolved forward declaration of %s %s", classes[p->class], p->symbol); 4003192Smckusick # endif PC 4013192Smckusick break; 4023192Smckusick 4033192Smckusick case LABEL: 4043192Smckusick if (p->nl_flags & NFORWD) 4053192Smckusick nerror("label %s was declared but not defined", p->symbol); 4063192Smckusick break; 4073192Smckusick case FVAR: 4083192Smckusick if ((p->nl_flags & NMOD) == 0) 4093192Smckusick nerror("No assignment to the function variable"); 4103192Smckusick break; 4113192Smckusick } 4123192Smckusick } 4133192Smckusick /* 4143192Smckusick * Pop this symbol 4153192Smckusick * table slot 4163192Smckusick */ 4173192Smckusick disptab[i] = p; 4183192Smckusick } 4193192Smckusick 4203192Smckusick # ifdef OBJ 42118347Smckusick (void) put(1, O_END); 4223192Smckusick # endif OBJ 4233192Smckusick # ifdef PC 42410671Speter fp_exitcode(&eecookie); 42510671Speter stabrbrac(cbn); 42610671Speter putrbracket(ftnno); 42710671Speter fp_epilogue(&eecookie); 42810671Speter if (fp -> class != PROG) { 42910671Speter fp_formalentry(&eecookie); 4303192Smckusick } 4313192Smckusick /* 4323192Smckusick * declare pcp counters, if any 4333192Smckusick */ 4343192Smckusick if ( monflg && fp -> class == PROG ) { 4353192Smckusick putprintf( " .data" , 0 ); 43618457Sralph aligndot(PCCT_INT); 4373192Smckusick putprintf( " .comm " , 1 ); 4383192Smckusick putprintf( PCPCOUNT , 1 ); 4393192Smckusick putprintf( ",%d" , 0 , ( cnts + 1 ) * sizeof (long) ); 4403192Smckusick putprintf( " .text" , 0 ); 4413192Smckusick } 4423192Smckusick # endif PC 4433192Smckusick #ifdef DEBUG 44418347Smckusick dumpnl(fp->ptr[2], (int) fp->symbol); 4453192Smckusick #endif 4465654Slinton 4475654Slinton #ifdef OBJ 4483192Smckusick /* 4495654Slinton * save the namelist for the debugger pdx 4505654Slinton */ 4515654Slinton 45218347Smckusick savenl(fp->ptr[2], (int) fp->symbol); 4535654Slinton #endif 4545654Slinton 4555654Slinton /* 4563192Smckusick * Restore the 4573192Smckusick * (virtual) name list 4583192Smckusick * position 4593192Smckusick */ 4603192Smckusick nlfree(fp->ptr[2]); 4613192Smckusick /* 4623192Smckusick * Proc/func has been 4633192Smckusick * resolved 4643192Smckusick */ 4653192Smckusick fp->nl_flags &= ~NFORWD; 4663192Smckusick /* 4673192Smckusick * Patch the beg 4683192Smckusick * of the proc/func to 4693192Smckusick * the proper variable size 4703192Smckusick */ 4713192Smckusick if (Fp == NIL) 4723192Smckusick elineon(); 4733192Smckusick # ifdef OBJ 47430037Smckusick patchfil((PTR_DCL) var, 47530037Smckusick roundup(-sizes[cbn].om_max, (long) A_STACK), 2); 4763192Smckusick # endif OBJ 4773192Smckusick cbn--; 4783192Smckusick if (inpflist(fp->symbol)) { 4793192Smckusick opop('l'); 4803192Smckusick } 4813192Smckusick } 4823363Speter 4833363Speter #ifdef PC 4843363Speter /* 4853363Speter * construct the long name of a function based on it's static nesting. 4863363Speter * into a caller-supplied buffer (that should be about BUFSIZ big). 4873363Speter */ 4883363Speter sextname( buffer , name , level ) 4893363Speter char buffer[]; 4903363Speter char *name; 4913363Speter int level; 4923363Speter { 4933363Speter char *starthere; 4943363Speter int i; 4953363Speter 4963363Speter starthere = &buffer[0]; 4973363Speter for ( i = 1 ; i < level ; i++ ) { 4983363Speter sprintf( starthere , EXTFORMAT , enclosing[ i ] ); 4993363Speter starthere += strlen( enclosing[ i ] ) + 1; 5003363Speter } 5013367Speter sprintf( starthere , EXTFORMAT , name ); 5023367Speter starthere += strlen( name ) + 1; 5033363Speter if ( starthere >= &buffer[ BUFSIZ ] ) { 5043363Speter panic( "sextname" ); 5053363Speter } 5063363Speter } 50710671Speter 50810671Speter /* 50910671Speter * code for main() 51010671Speter */ 51110671Speter #ifdef vax 51210671Speter 51310671Speter codeformain() 51410671Speter { 51510671Speter putprintf(" .text" , 0 ); 51610671Speter putprintf(" .align 1" , 0 ); 51710671Speter putprintf(" .globl _main" , 0 ); 51810671Speter putprintf("_main:" , 0 ); 51910671Speter putprintf(" .word 0" , 0 ); 52010671Speter if ( opt ( 't' ) ) { 52110671Speter putprintf(" pushl $1" , 0 ); 52210671Speter } else { 52310671Speter putprintf(" pushl $0" , 0 ); 52410671Speter } 52510671Speter putprintf(" calls $1,_PCSTART" , 0 ); 52610671Speter putprintf(" movl 4(ap),__argc" , 0 ); 52710671Speter putprintf(" movl 8(ap),__argv" , 0 ); 52810671Speter putprintf(" calls $0,_program" , 0 ); 52910671Speter putprintf(" pushl $0" , 0 ); 53010671Speter putprintf(" calls $1,_PCEXIT" , 0 ); 53110671Speter } 53230039Smckusick #endif vax 53310671Speter 53430039Smckusick #ifdef tahoe 53530039Smckusick codeformain() 53630039Smckusick { 53730039Smckusick putprintf(" .text" , 0 ); 53830039Smckusick putprintf(" .align 1" , 0 ); 53930039Smckusick putprintf(" .globl _main" , 0 ); 54030039Smckusick putprintf("_main:" , 0 ); 54130039Smckusick putprintf(" .word 0" , 0 ); 54230039Smckusick if ( opt ( 't' ) ) { 54330039Smckusick putprintf(" pushl $1" , 0 ); 54430039Smckusick } else { 54530039Smckusick putprintf(" pushl $0" , 0 ); 54630039Smckusick } 54730039Smckusick putprintf(" callf $8,_PCSTART" , 0 ); 54830039Smckusick putprintf(" movl 4(fp),__argc" , 0 ); 54930039Smckusick putprintf(" movl 8(fp),__argv" , 0 ); 55030039Smckusick putprintf(" callf $4,_program" , 0 ); 55130039Smckusick putprintf(" pushl $0" , 0 ); 55230039Smckusick putprintf(" callf $8,_PCEXIT" , 0 ); 55330039Smckusick } 55430039Smckusick #endif tahoe 55530039Smckusick 55610671Speter /* 55710671Speter * prologue for the program. 55810671Speter * different because it 55910671Speter * doesn't have formal entry point 56010671Speter */ 56130039Smckusick #if defined(vax) || defined(tahoe) 56210671Speter prog_prologue(eecookiep) 56310671Speter struct entry_exit_cookie *eecookiep; 56410671Speter { 56510671Speter putprintf(" .text" , 0 ); 56610671Speter putprintf(" .align 1" , 0 ); 56710671Speter putprintf(" .globl _program" , 0 ); 56810671Speter putprintf("_program:" , 0 ); 56910716Speter /* 57010716Speter * register save mask 57110716Speter */ 57218347Smckusick eecookiep -> savlabel = (int) getlab(); 57318347Smckusick putprintf(" .word %s%d", 0, (int) SAVE_MASK_LABEL , eecookiep -> savlabel ); 57410671Speter } 57510671Speter 57610671Speter fp_prologue(eecookiep) 57710671Speter struct entry_exit_cookie *eecookiep; 57810671Speter { 57910671Speter 58010671Speter sextname( eecookiep -> extname, eecookiep -> nlp -> symbol , cbn - 1 ); 58110671Speter putprintf( " .text" , 0 ); 58210671Speter putprintf( " .align 1" , 0 ); 58318347Smckusick putprintf( " .globl %s%s", 0, (int) FORMALPREFIX, (int) eecookiep -> extname ); 58418347Smckusick putprintf( " .globl %s" , 0 , (int) eecookiep -> extname ); 58518347Smckusick putprintf( "%s:" , 0 , (int) eecookiep -> extname ); 58610671Speter /* 58710671Speter * register save mask 58810671Speter */ 58918347Smckusick eecookiep -> savlabel = (int) getlab(); 59018347Smckusick putprintf(" .word %s%d", 0, (int) SAVE_MASK_LABEL , eecookiep -> savlabel ); 59110671Speter } 59230039Smckusick #endif vax || tahoe 59310671Speter 59410671Speter /* 59510671Speter * code before any user code. 59610671Speter * or code that is machine dependent. 59710671Speter */ 59830039Smckusick #ifdef vax 59910671Speter fp_entrycode(eecookiep) 60010671Speter struct entry_exit_cookie *eecookiep; 60110671Speter { 60210714Speter int ftnno = eecookiep -> nlp -> value[NL_ENTLOC]; 60318347Smckusick int proflabel = (int) getlab(); 60418347Smckusick int setjmp0 = (int) getlab(); 60510671Speter 60610671Speter /* 60710671Speter * top of code; destination of jump from formal entry code. 60810671Speter */ 60918347Smckusick eecookiep -> toplabel = (int) getlab(); 61018347Smckusick (void) putlab( (char *) eecookiep -> toplabel ); 61118347Smckusick putprintf(" subl2 $%s%d,sp" , 0 , (int) FRAME_SIZE_LABEL, ftnno ); 61210671Speter if ( profflag ) { 61310671Speter /* 61410671Speter * call mcount for profiling 61510671Speter */ 61610671Speter putprintf( " moval " , 1 ); 61718347Smckusick putprintf( PREFIXFORMAT , 1 , (int) LABELPREFIX , proflabel ); 61810671Speter putprintf( ",r0" , 0 ); 61910671Speter putprintf( " jsb mcount" , 0 ); 62010671Speter putprintf( " .data" , 0 ); 62110671Speter putprintf( " .align 2" , 0 ); 62218347Smckusick (void) putlab( (char *) proflabel ); 62310671Speter putprintf( " .long 0" , 0 ); 62410671Speter putprintf( " .text" , 0 ); 62510671Speter } 62610671Speter /* 62710671Speter * if there are nested procedures that access our variables 62810671Speter * we must save the display. 62910671Speter */ 63010671Speter if ( parts[ cbn ] & NONLOCALVAR ) { 63110671Speter /* 63210671Speter * save old display 63310671Speter */ 63410671Speter putprintf( " movq %s+%d,%d(%s)" , 0 63518347Smckusick , (int) DISPLAYNAME , cbn * sizeof(struct dispsave) 63618347Smckusick , DSAVEOFFSET , (int) P2FPNAME ); 63710671Speter /* 63810671Speter * set up new display by saving AP and FP in appropriate 63910671Speter * slot in display structure. 64010671Speter */ 64110671Speter putprintf( " movq %s,%s+%d" , 0 64218347Smckusick , (int) P2APNAME , (int) DISPLAYNAME , cbn * sizeof(struct dispsave) ); 64310671Speter } 64410671Speter /* 64510671Speter * set underflow checking if runtime tests 64610671Speter */ 64710671Speter if ( opt( 't' ) ) { 64810671Speter putprintf( " bispsw $0xe0" , 0 ); 64910671Speter } 65010671Speter /* 65110671Speter * zero local variables if checking is on 65210671Speter * by calling blkclr( bytes of locals , starting local address ); 65310671Speter */ 65410671Speter if ( opt( 't' ) && ( -sizes[ cbn ].om_max ) > DPOFF1 ) { 65518457Sralph putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 65610671Speter , "_blkclr" ); 65718457Sralph putLV((char *) 0 , cbn , (int) sizes[ cbn ].om_max , NLOCAL , PCCT_CHAR ); 65818457Sralph putleaf( PCC_ICON , (int) (( -sizes[ cbn ].om_max ) - DPOFF1) 65918457Sralph , 0 , PCCT_INT ,(char *) 0 ); 66018457Sralph putop( PCC_CM , PCCT_INT ); 66118457Sralph putop( PCC_CALL , PCCT_INT ); 66210671Speter putdot( filename , line ); 66310671Speter } 66410671Speter /* 66510671Speter * set up goto vector if non-local goto to this frame 66610671Speter */ 66710671Speter if ( parts[ cbn ] & NONLOCALGOTO ) { 66818457Sralph putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 66910671Speter , "_setjmp" ); 67018457Sralph putLV( (char *) 0 , cbn , GOTOENVOFFSET , NLOCAL , PCCTM_PTR|PCCT_STRTY ); 67118457Sralph putop( PCC_CALL , PCCT_INT ); 67218457Sralph putleaf( PCC_ICON , 0 , 0 , PCCT_INT , (char *) 0 ); 67318457Sralph putop( PCC_NE , PCCT_INT ); 67418457Sralph putleaf( PCC_ICON , setjmp0 , 0 , PCCT_INT , (char *) 0 ); 67518457Sralph putop( PCC_CBRANCH , PCCT_INT ); 67610671Speter putdot( filename , line ); 67710671Speter /* 67810671Speter * on non-local goto, setjmp returns with address to 67910671Speter * be branched to. 68010671Speter */ 68110671Speter putprintf( " jmp (r0)" , 0 ); 68218347Smckusick (void) putlab((char *) setjmp0); 68310671Speter } 68410671Speter } 68530039Smckusick #endif vax 68610671Speter 68730039Smckusick #ifdef tahoe 68830039Smckusick fp_entrycode(eecookiep) 68930039Smckusick struct entry_exit_cookie *eecookiep; 69030039Smckusick { 69130039Smckusick int ftnno = eecookiep -> nlp -> value[NL_ENTLOC]; 69230039Smckusick int proflabel = (int) getlab(); 69330039Smckusick int setjmp0 = (int) getlab(); 69430039Smckusick 69530039Smckusick /* 69630039Smckusick * top of code; destination of jump from formal entry code. 69730039Smckusick */ 69830039Smckusick eecookiep -> toplabel = (int) getlab(); 69930039Smckusick (void) putlab( (char *) eecookiep -> toplabel ); 70030039Smckusick putprintf(" subl3 $%s%d,fp,sp" , 0 , (int) FRAME_SIZE_LABEL, ftnno ); 70130039Smckusick if ( profflag ) { 70230039Smckusick /* 70330039Smckusick * call mcount for profiling 70430039Smckusick */ 70530039Smckusick putprintf( " pushal " , 1 ); 70630375Smckusick putprintf( PREFIXFORMAT , 0 , (int) LABELPREFIX , proflabel ); 70730039Smckusick putprintf( " callf $8,mcount" , 0 ); 70830039Smckusick putprintf( " .data" , 0 ); 70930039Smckusick putprintf( " .align 2" , 0 ); 71030039Smckusick (void) putlab( (char *) proflabel ); 71130039Smckusick putprintf( " .long 0" , 0 ); 71230039Smckusick putprintf( " .text" , 0 ); 71330039Smckusick } 71430039Smckusick /* 71530039Smckusick * if there are nested procedures that access our variables 71630039Smckusick * we must save the display. 71730039Smckusick */ 71830039Smckusick if ( parts[ cbn ] & NONLOCALVAR ) { 71930039Smckusick /* 72030039Smckusick * save old display 72130039Smckusick */ 72230039Smckusick putprintf( " movl %s+%d,%d(%s)" , 0 72330039Smckusick , (int) DISPLAYNAME , cbn * sizeof(struct dispsave) 72430039Smckusick , DSAVEOFFSET , (int) P2FPNAME ); 72530039Smckusick /* 72630039Smckusick * set up new display by saving FP in appropriate 72730039Smckusick * slot in display structure. 72830039Smckusick */ 72930039Smckusick putprintf( " movl %s,%s+%d" , 0 73030039Smckusick , (int) P2FPNAME , (int) DISPLAYNAME , cbn * sizeof(struct dispsave) ); 73130039Smckusick } 73230039Smckusick /* 73330039Smckusick * set underflow checking if runtime tests 73430039Smckusick */ 73530039Smckusick if ( opt( 't' ) ) { 73630039Smckusick putprintf( " bicpsw $0x20" , 0 ); 73730039Smckusick } 73830039Smckusick /* 73930039Smckusick * zero local variables if checking is on 74030039Smckusick * by calling blkclr( bytes of locals , starting local address ); 74130039Smckusick */ 74230039Smckusick if ( opt( 't' ) && ( -sizes[ cbn ].om_max ) > DPOFF1 ) { 74330039Smckusick putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 74430039Smckusick , "_blkclr" ); 74530039Smckusick putLV((char *) 0 , cbn , (int) sizes[ cbn ].om_max , NLOCAL , PCCT_CHAR ); 74630039Smckusick putleaf( PCC_ICON , (int) (( -sizes[ cbn ].om_max ) - DPOFF1) 74730039Smckusick , 0 , PCCT_INT ,(char *) 0 ); 74830039Smckusick putop( PCC_CM , PCCT_INT ); 74930039Smckusick putop( PCC_CALL , PCCT_INT ); 75030039Smckusick putdot( filename , line ); 75130039Smckusick } 75230039Smckusick /* 75330039Smckusick * set up goto vector if non-local goto to this frame 75430039Smckusick */ 75530039Smckusick if ( parts[ cbn ] & NONLOCALGOTO ) { 75630039Smckusick putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 75730039Smckusick , "_setjmp" ); 75830039Smckusick putLV( (char *) 0 , cbn , GOTOENVOFFSET , NLOCAL , PCCTM_PTR|PCCT_STRTY ); 75930039Smckusick putop( PCC_CALL , PCCT_INT ); 76030039Smckusick putleaf( PCC_ICON , 0 , 0 , PCCT_INT , (char *) 0 ); 76130039Smckusick putop( PCC_NE , PCCT_INT ); 76230039Smckusick putleaf( PCC_ICON , setjmp0 , 0 , PCCT_INT , (char *) 0 ); 76330039Smckusick putop( PCC_CBRANCH , PCCT_INT ); 76430039Smckusick putdot( filename , line ); 76530039Smckusick /* 76630039Smckusick * on non-local goto, setjmp returns with address to 76730039Smckusick * be branched to. 76830039Smckusick */ 76930039Smckusick putprintf( " jmp (r0)" , 0 ); 77030039Smckusick (void) putlab((char *) setjmp0); 77130039Smckusick } 77230039Smckusick } 77330039Smckusick #endif tahoe 77430039Smckusick 77530039Smckusick #if defined(vax) || defined(tahoe) 77610671Speter fp_exitcode(eecookiep) 77710671Speter struct entry_exit_cookie *eecookiep; 77810671Speter { 77910671Speter /* 78010671Speter * if there were file variables declared at this level 78110671Speter * call PCLOSE( ap ) to clean them up. 78210671Speter */ 78310671Speter if ( dfiles[ cbn ] ) { 78418457Sralph putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 78510671Speter , "_PCLOSE" ); 78618457Sralph putleaf( PCC_REG , 0 , P2AP , PCCM_ADDTYPE( PCCT_CHAR , PCCTM_PTR ) , (char *) 0 ); 78718457Sralph putop( PCC_CALL , PCCT_INT ); 78810671Speter putdot( filename , line ); 78910671Speter } 79010671Speter /* 79110671Speter * if this is a function, 79210671Speter * the function variable is the return value. 79310671Speter * if it's a scalar valued function, return scalar, 79410671Speter * else, return a pointer to the structure value. 79510671Speter */ 79610671Speter if ( eecookiep-> nlp -> class == FUNC ) { 79710671Speter struct nl *fvar = eecookiep-> nlp -> ptr[ NL_FVAR ]; 79810671Speter long fvartype = p2type( fvar -> type ); 79910671Speter long label; 80010671Speter char labelname[ BUFSIZ ]; 80110671Speter 80210671Speter switch ( classify( fvar -> type ) ) { 80310671Speter case TBOOL: 80410671Speter case TCHAR: 80510671Speter case TINT: 80610671Speter case TSCAL: 80710671Speter case TDOUBLE: 80810671Speter case TPTR: 80910671Speter putRV( fvar -> symbol , ( fvar -> nl_block ) & 037 , 81010671Speter fvar -> value[ NL_OFFS ] , 81110671Speter fvar -> extra_flags , 81218347Smckusick (int) fvartype ); 81318457Sralph putop( PCC_FORCE , (int) fvartype ); 81410671Speter break; 81510671Speter default: 81618347Smckusick label = (int) getlab(); 81710671Speter sprintf( labelname , PREFIXFORMAT , LABELPREFIX , label ); 81810671Speter putprintf( " .data" , 0 ); 81910671Speter aligndot(A_STRUCT); 82010671Speter putprintf( " .lcomm %s,%d" , 0 , 82118347Smckusick (int) labelname , (int) lwidth( fvar -> type ) ); 82210671Speter putprintf( " .text" , 0 ); 82318457Sralph putleaf( PCC_NAME , 0 , 0 , (int) fvartype , labelname ); 82410671Speter putLV( fvar -> symbol , ( fvar -> nl_block ) & 037 , 82510671Speter fvar -> value[ NL_OFFS ] , 82610671Speter fvar -> extra_flags , 82718347Smckusick (int) fvartype ); 82818457Sralph putstrop( PCC_STASG , (int) PCCM_ADDTYPE(fvartype, PCCTM_PTR) , 82918347Smckusick (int) lwidth( fvar -> type ) , 83010671Speter align( fvar -> type ) ); 83110671Speter putdot( filename , line ); 83218457Sralph putleaf( PCC_ICON , 0 , 0 , (int) PCCM_ADDTYPE(fvartype, PCCTM_PTR), labelname ); 83318457Sralph putop( PCC_FORCE , (int) PCCM_ADDTYPE(fvartype, PCCTM_PTR) ); 83410671Speter break; 83510671Speter } 83610671Speter putdot( filename , line ); 83710671Speter } 83810671Speter /* 83910671Speter * if there are nested procedures we must save the display. 84010671Speter */ 84110671Speter if ( parts[ cbn ] & NONLOCALVAR ) { 84210671Speter /* 84310671Speter * restore old display entry from save area 84410671Speter */ 84530039Smckusick #ifdef vax 84610671Speter putprintf( " movq %d(%s),%s+%d" , 0 84718347Smckusick , DSAVEOFFSET , (int) P2FPNAME 84818347Smckusick , (int) DISPLAYNAME , cbn * sizeof(struct dispsave) ); 84930039Smckusick #endif 85030039Smckusick #ifdef tahoe 85130039Smckusick putprintf( " movl %d(%s),%s+%d" , 0 85230039Smckusick , DSAVEOFFSET , (int) P2FPNAME 85330039Smckusick , (int) DISPLAYNAME , cbn * sizeof(struct dispsave) ); 85430039Smckusick #endif 85510671Speter } 85610671Speter } 85730039Smckusick #endif vax || tahoe 85810671Speter 85930039Smckusick #if defined(vax) || defined(tahoe) 86010671Speter fp_epilogue(eecookiep) 86110671Speter struct entry_exit_cookie *eecookiep; 86210671Speter { 86318346Smckusick stabline(line); 86410671Speter putprintf(" ret" , 0 ); 86510671Speter /* 86610671Speter * set the register save mask. 86710671Speter */ 86810671Speter putprintf(" .set %s%d,0x%x", 0, 86918347Smckusick (int) SAVE_MASK_LABEL, eecookiep -> savlabel, savmask()); 87010671Speter } 87130039Smckusick #endif vax || tahoe 87210671Speter 87330039Smckusick #if defined(vax) || defined(tahoe) 87410671Speter fp_formalentry(eecookiep) 87510671Speter struct entry_exit_cookie *eecookiep; 87610671Speter { 87710671Speter 87811857Speter putprintf(" .align 1", 0); 87918347Smckusick putprintf("%s%s:" , 0 , (int) FORMALPREFIX , (int) eecookiep -> extname ); 88018347Smckusick putprintf(" .word %s%d", 0, (int) SAVE_MASK_LABEL, eecookiep -> savlabel ); 88118457Sralph putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) , "_FCALL" ); 88218347Smckusick putRV((char *) 0 , cbn , 88310671Speter eecookiep -> nlp -> value[ NL_OFFS ] + sizeof( struct formalrtn * ) , 88418457Sralph NPARAM , PCCTM_PTR | PCCT_STRTY ); 88518457Sralph putRV((char *) 0, cbn, eecookiep -> nlp -> value[NL_OFFS], NPARAM, PCCTM_PTR|PCCT_STRTY); 88618457Sralph putop( PCC_CM , PCCT_INT ); 88718457Sralph putop( PCC_CALL , PCCT_INT ); 88810671Speter putdot( filename , line ); 88918347Smckusick putjbr( (long) eecookiep -> toplabel ); 89010671Speter } 89130039Smckusick #endif vax || tahoe 89210671Speter 89310671Speter #ifdef mc68000 89410671Speter 89510671Speter codeformain() 89610671Speter { 89710671Speter putprintf(" .text", 0); 89810671Speter putprintf(" .globl _main", 0); 89910671Speter putprintf("_main:", 0); 90010671Speter putprintf(" link %s,#0", 0, P2FPNAME); 90110671Speter if (opt('t')) { 90210671Speter putprintf(" pea 1", 0); 90310671Speter } else { 90410671Speter putprintf(" pea 0", 0); 90510671Speter } 90610671Speter putprintf(" jbsr _PCSTART", 0); 90710671Speter putprintf(" addql #4,sp", 0); 90810671Speter putprintf(" movl %s@(8),__argc", 0, P2FPNAME); 90910671Speter putprintf(" movl %s@(12),__argv", 0, P2FPNAME); 91010671Speter putprintf(" jbsr _program", 0); 91110671Speter putprintf(" pea 0", 0); 91210671Speter putprintf(" jbsr _PCEXIT", 0); 91310671Speter } 91410671Speter 91510671Speter prog_prologue(eecookiep) 91610671Speter struct entry_exit_cookie *eecookiep; 91710671Speter { 91810671Speter int ftnno = eecookiep -> nlp -> value[NL_ENTLOC]; 91910671Speter 92010671Speter putprintf(" .text", 0); 92110671Speter putprintf(" .globl _program", 0); 92210671Speter putprintf("_program:", 0); 92310671Speter putprintf(" link %s,#0", 0, P2FPNAME); 92410671Speter putprintf(" addl #-%s%d,sp", 0, FRAME_SIZE_LABEL, ftnno); 92510671Speter /* touch new end of stack, to break more stack space */ 92610671Speter putprintf(" tstb sp@(-%s%d)", 0, PAGE_BREAK_LABEL, ftnno); 92710671Speter putprintf(" moveml #%s%d,sp@", 0, SAVE_MASK_LABEL, ftnno); 92810671Speter } 92910671Speter 93010671Speter fp_prologue(eecookiep) 93110671Speter struct entry_exit_cookie *eecookiep; 93210671Speter { 93310671Speter int ftnno = eecookiep -> nlp -> value[NL_ENTLOC]; 93410671Speter 93510671Speter sextname(eecookiep -> extname, eecookiep -> nlp -> symbol, cbn - 1); 93610671Speter putprintf(" .text", 0); 93710671Speter putprintf(" .globl %s%s", 0, FORMALPREFIX, eecookiep -> extname); 93810671Speter putprintf(" .globl %s", 0, eecookiep -> extname); 93910671Speter putprintf("%s:", 0, eecookiep -> extname); 94010671Speter putprintf(" link %s,#0", 0, P2FPNAME); 94110671Speter putprintf(" addl #-%s%d,sp", 0, FRAME_SIZE_LABEL, ftnno); 94210671Speter /* touch new end of stack, to break more stack space */ 94310671Speter putprintf(" tstb sp@(-%s%d)", 0, PAGE_BREAK_LABEL, ftnno); 94410671Speter putprintf(" moveml #%s%d,sp@", 0, SAVE_MASK_LABEL, ftnno); 94510671Speter } 94610671Speter 94710671Speter fp_entrycode(eecookiep) 94810671Speter struct entry_exit_cookie *eecookiep; 94910671Speter { 95018347Smckusick char *proflabel = getlab(); 95118347Smckusick char *setjmp0 = getlab(); 95210671Speter 95310671Speter /* 95410671Speter * fill in the label cookie 95510671Speter */ 95610671Speter eecookiep -> toplabel = getlab(); 95718347Smckusick (void) putlab(eecookiep -> toplabel); 95810671Speter /* 95910671Speter * call mcount if we are profiling. 96010671Speter */ 96110671Speter if ( profflag ) { 96210671Speter putprintf(" movl #%s%d,a0", 0, LABELPREFIX, proflabel); 96310671Speter putprintf(" jsr mcount", 0); 96410671Speter putprintf(" .data", 0); 96510671Speter putprintf(" .even", 0); 96618347Smckusick (void) putlab(proflabel); 96710671Speter putprintf(" .long 0", 0); 96810671Speter putprintf(" .text", 0); 96910671Speter } 97010671Speter /* 97110671Speter * if there are nested procedures that access our variables 97210671Speter * we must save the display 97310671Speter */ 97410671Speter if (parts[cbn] & NONLOCALVAR) { 97510671Speter /* 97610671Speter * save the old display 97710671Speter */ 97810671Speter putprintf(" movl %s+%d,%s@(%d)", 0, 97910671Speter DISPLAYNAME, cbn * sizeof(struct dispsave), 98010671Speter P2FPNAME, DSAVEOFFSET); 98110671Speter /* 98210671Speter * set up the new display by saving the framepointer 98310671Speter * in the display structure. 98410671Speter */ 98510671Speter putprintf(" movl %s,%s+%d", 0, 98610671Speter P2FPNAME, DISPLAYNAME, cbn * sizeof(struct dispsave)); 98710671Speter } 98810671Speter /* 98910671Speter * zero local variables if checking is on 99010671Speter * by calling blkclr( bytes of locals , starting local address ); 99110671Speter */ 99210671Speter if ( opt( 't' ) && ( -sizes[ cbn ].om_max ) > DPOFF1 ) { 99318457Sralph putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 99410671Speter , "_blkclr" ); 99518457Sralph putLV( 0 , cbn , sizes[ cbn ].om_max , NLOCAL , PCCT_CHAR ); 99618457Sralph putleaf( PCC_ICON , ( -sizes[ cbn ].om_max ) - DPOFF1 99718457Sralph , 0 , PCCT_INT , 0 ); 99818457Sralph putop( PCC_CM , PCCT_INT ); 99918457Sralph putop( PCC_CALL , PCCT_INT ); 100010671Speter putdot( filename , line ); 100110671Speter } 100210671Speter /* 100310671Speter * set up goto vector if non-local goto to this frame 100410671Speter */ 100510671Speter if ( parts[ cbn ] & NONLOCALGOTO ) { 100618457Sralph putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 100710671Speter , "_setjmp" ); 100818457Sralph putLV( 0 , cbn , GOTOENVOFFSET , NLOCAL , PCCTM_PTR|PCCT_STRTY ); 100918457Sralph putop( PCC_CALL , PCCT_INT ); 101018457Sralph putleaf( PCC_ICON , 0 , 0 , PCCT_INT , 0 ); 101118457Sralph putop( PCC_NE , PCCT_INT ); 101218457Sralph putleaf( PCC_ICON , setjmp0 , 0 , PCCT_INT , 0 ); 101318457Sralph putop( PCC_CBRANCH , PCCT_INT ); 101410671Speter putdot( filename , line ); 101510671Speter /* 101610671Speter * on non-local goto, setjmp returns with address to 101710671Speter * be branched to. 101810671Speter */ 101910671Speter putprintf(" movl d0,a0", 0); 102010671Speter putprintf(" jmp a0@", 0); 102118347Smckusick (void) putlab(setjmp0); 102210671Speter } 102310671Speter } 102410671Speter 102510671Speter fp_exitcode(eecookiep) 102610671Speter struct entry_exit_cookie *eecookiep; 102710671Speter { 102810671Speter /* 102910671Speter * if there were file variables declared at this level 103010671Speter * call PCLOSE( ap ) to clean them up. 103110671Speter */ 103210671Speter if ( dfiles[ cbn ] ) { 103318457Sralph putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 103410671Speter , "_PCLOSE" ); 103518457Sralph putleaf( PCC_REG , 0 , P2AP , PCCM_ADDTYPE( PCCT_CHAR , PCCTM_PTR ) , 0 ); 103618457Sralph putop( PCC_CALL , PCCT_INT ); 103710671Speter putdot( filename , line ); 103810671Speter } 103910671Speter /* 104010671Speter * if this is a function, 104110671Speter * the function variable is the return value. 104210671Speter * if it's a scalar valued function, return scalar, 104310671Speter * else, return a pointer to the structure value. 104410671Speter */ 104510671Speter if ( eecookiep -> nlp -> class == FUNC ) { 104610671Speter struct nl *fvar = eecookiep -> nlp -> ptr[ NL_FVAR ]; 104710671Speter long fvartype = p2type( fvar -> type ); 104818347Smckusick char *label; 104910671Speter char labelname[ BUFSIZ ]; 105010671Speter 105110671Speter switch ( classify( fvar -> type ) ) { 105210671Speter case TBOOL: 105310671Speter case TCHAR: 105410671Speter case TINT: 105510671Speter case TSCAL: 105610671Speter case TDOUBLE: 105710671Speter case TPTR: 105810671Speter putRV( fvar -> symbol , ( fvar -> nl_block ) & 037 , 105910671Speter fvar -> value[ NL_OFFS ] , 106010671Speter fvar -> extra_flags , 106110671Speter fvartype ); 106218457Sralph putop( PCC_FORCE , fvartype ); 106310671Speter break; 106410671Speter default: 106510671Speter label = getlab(); 106610671Speter sprintf( labelname , PREFIXFORMAT , LABELPREFIX , label ); 106710671Speter putprintf(" .lcomm %s,%d", 0, 106810671Speter labelname, lwidth(fvar -> type)); 106918457Sralph putleaf( PCC_NAME , 0 , 0 , fvartype , labelname ); 107010671Speter putLV( fvar -> symbol , ( fvar -> nl_block ) & 037 , 107110671Speter fvar -> value[ NL_OFFS ] , 107210671Speter fvar -> extra_flags , 107310671Speter fvartype ); 107418457Sralph putstrop( PCC_STASG , PCCM_ADDTYPE(fvartype, PCCTM_PTR) , 107511857Speter lwidth( fvar -> type ) , 107610671Speter align( fvar -> type ) ); 107710671Speter putdot( filename , line ); 107818457Sralph putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE(fvartype, PCCTM_PTR), labelname ); 107918457Sralph putop( PCC_FORCE , PCCM_ADDTYPE(fvartype, PCCTM_PTR) ); 108010671Speter break; 108110671Speter } 108210671Speter putdot( filename , line ); 108310671Speter } 108410671Speter /* 108510671Speter * if we saved a display, we must restore it. 108610671Speter */ 108710671Speter if ( parts[ cbn ] & NONLOCALVAR ) { 108810671Speter /* 108910671Speter * restore old display entry from save area 109010671Speter */ 109110671Speter putprintf(" movl %s@(%d),%s+%d", 0, 109210671Speter P2FPNAME, DSAVEOFFSET, 109310671Speter DISPLAYNAME, cbn * sizeof(struct dispsave)); 109410671Speter } 109510671Speter } 109610671Speter 109710671Speter fp_epilogue(eecookiep) 109810671Speter struct entry_exit_cookie *eecookiep; 109910671Speter { 110010671Speter /* 110110671Speter * all done by the second pass. 110210671Speter */ 110310671Speter } 110410671Speter 110510671Speter fp_formalentry(eecookiep) 110610671Speter struct entry_exit_cookie *eecookiep; 110710671Speter { 110810671Speter putprintf( "%s%s:" , 0 , FORMALPREFIX , eecookiep -> extname ); 110910671Speter putprintf(" link %s,#0", 0, P2FPNAME); 111010671Speter putprintf(" addl #-%s%d,sp", 0, FRAME_SIZE_LABEL, ftnno); 111110671Speter /* touch new end of stack, to break more stack space */ 111210671Speter putprintf(" tstb sp@(-%s%d)", 0, PAGE_BREAK_LABEL, ftnno); 111310671Speter putprintf(" moveml #%s%d,sp@", 0, SAVE_MASK_LABEL, ftnno); 111418457Sralph putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) , "_FCALL" ); 111510671Speter putRV( 0 , cbn , 111610671Speter eecookiep -> nlp -> value[ NL_OFFS ] + sizeof( struct formalrtn * ) , 111718457Sralph NPARAM , PCCTM_PTR | PCCT_STRTY ); 111818457Sralph putRV(0, cbn, eecookiep -> nlp -> value[NL_OFFS], NPARAM, PCCTM_PTR|PCCT_STRTY); 111918457Sralph putop( PCC_CM , PCCT_INT ); 112018457Sralph putop( PCC_CALL , PCCT_INT ); 112110671Speter putdot( filename , line ); 112210671Speter putjbr( eecookiep -> toplabel ); 112310671Speter } 112410671Speter #endif mc68000 11253363Speter #endif PC 1126