122164Sdist /* 222164Sdist * Copyright (c) 1980 Regents of the University of California. 322164Sdist * All rights reserved. The Berkeley software License Agreement 422164Sdist * specifies the terms and conditions for redistribution. 522164Sdist */ 63192Smckusick 718347Smckusick #ifndef lint 8*30039Smckusick static char sccsid[] = "@(#)fend.c 5.3 (Berkeley) 11/12/86"; 922164Sdist #endif not lint 103192Smckusick 113192Smckusick #include "whoami.h" 123192Smckusick #include "0.h" 133192Smckusick #include "tree.h" 143192Smckusick #include "opcode.h" 153192Smckusick #include "objfmt.h" 163192Smckusick #include "align.h" 1711337Speter #include "tmps.h" 183192Smckusick 193192Smckusick /* 203192Smckusick * this array keeps the pxp counters associated with 213192Smckusick * functions and procedures, so that they can be output 223192Smckusick * when their bodies are encountered 233192Smckusick */ 243192Smckusick int bodycnts[ DSPLYSZ ]; 253192Smckusick 263192Smckusick #ifdef PC 273192Smckusick # include "pc.h" 2818457Sralph # include <pcc.h> 293192Smckusick #endif PC 303192Smckusick 313192Smckusick #ifdef OBJ 323192Smckusick int cntpatch; 333192Smckusick int nfppatch; 343192Smckusick #endif OBJ 353192Smckusick 3618347Smckusick #include "tree_ty.h" 3718347Smckusick 383192Smckusick struct nl *Fp; 393192Smckusick int pnumcnt; 403192Smckusick /* 413192Smckusick * Funcend is called to 423192Smckusick * finish a block by generating 433192Smckusick * the code for the statements. 443192Smckusick * It then looks for unresolved declarations 453192Smckusick * of labels, procedures and functions, 463192Smckusick * and cleans up the name list. 473192Smckusick * For the program, it checks the 483192Smckusick * semantics of the program 493192Smckusick * statement (yuchh). 503192Smckusick */ 513192Smckusick funcend(fp, bundle, endline) 523192Smckusick struct nl *fp; 5318347Smckusick struct tnode *bundle; 543192Smckusick int endline; 553192Smckusick { 563192Smckusick register struct nl *p; 573192Smckusick register int i, b; 5818347Smckusick int inp, out; 5918347Smckusick struct tnode *blk; 603192Smckusick bool chkref; 613192Smckusick struct nl *iop; 623192Smckusick char *cp; 633192Smckusick extern int cntstat; 643192Smckusick # ifdef PC 6510671Speter struct entry_exit_cookie eecookie; 663192Smckusick # endif PC 6718347Smckusick # ifndef PC 6818347Smckusick int var; 6918347Smckusick # endif PC 703192Smckusick 713192Smckusick cntstat = 0; 723192Smckusick /* 733192Smckusick * yyoutline(); 743192Smckusick */ 753192Smckusick if (program != NIL) 763192Smckusick line = program->value[3]; 7718347Smckusick blk = bundle->stmnt_blck.stmnt_list; 783192Smckusick if (fp == NIL) { 793192Smckusick cbn--; 803192Smckusick # ifdef PTREE 813192Smckusick nesting--; 823192Smckusick # endif PTREE 833192Smckusick return; 843192Smckusick } 853192Smckusick #ifdef OBJ 863192Smckusick /* 87*30039Smckusick * Patch the branch to the entry point of the function. 88*30039Smckusick * Assure alignment of O_BEG structure. 893192Smckusick */ 90*30039Smckusick if (((int)lc & 02) == 0) 91*30039Smckusick word(0); 9218347Smckusick patch4((PTR_DCL) fp->value[NL_ENTLOC]); 933192Smckusick /* 943192Smckusick * Put out the block entrance code and the block name. 953192Smckusick * HDRSZE is the number of bytes of info in the static 963192Smckusick * BEG data area exclusive of the proc name. It is 973192Smckusick * currently defined as: 983192Smckusick /* struct hdr { 993192Smckusick /* long framesze; /* number of bytes of local vars */ 1003192Smckusick /* long nargs; /* number of bytes of arguments */ 1013192Smckusick /* bool tests; /* TRUE => perform runtime tests */ 1023192Smckusick /* short offset; /* offset of procedure in source file */ 1033192Smckusick /* char name[1]; /* name of active procedure */ 1043192Smckusick /* }; 1053192Smckusick */ 1063192Smckusick # define HDRSZE (2 * sizeof(long) + sizeof(short) + sizeof(bool)) 1073192Smckusick var = put(2, ((lenstr(fp->symbol,0) + HDRSZE) << 8) 1083192Smckusick | (cbn == 1 && opt('p') == 0 ? O_NODUMP: O_BEG), (long)0); 1093192Smckusick /* 1103192Smckusick * output the number of bytes of arguments 1113192Smckusick * this is only checked on formal calls. 1123192Smckusick */ 11318347Smckusick (void) put(2, O_CASE4, cbn == 1 ? (long)0 : (long)(fp->value[NL_OFFS]-DPOFF2)); 1143192Smckusick /* 1153192Smckusick * Output the runtime test mode for the routine 1163192Smckusick */ 11718347Smckusick (void) put(2, sizeof(bool) == 2 ? O_CASE2 : O_CASE4, opt('t') ? TRUE : FALSE); 1183192Smckusick /* 1193192Smckusick * Output line number and routine name 1203192Smckusick */ 12118347Smckusick (void) put(2, O_CASE2, bundle->stmnt_blck.line_no); 1223192Smckusick putstr(fp->symbol, 0); 1233192Smckusick #endif OBJ 1243192Smckusick #ifdef PC 1253192Smckusick /* 1263192Smckusick * put out the procedure entry code 1273192Smckusick */ 12810671Speter eecookie.nlp = fp; 1293192Smckusick if ( fp -> class == PROG ) { 1309129Smckusick /* 1319129Smckusick * If there is a label declaration in the main routine 1329129Smckusick * then there may be a non-local goto to it that does 1339129Smckusick * not appear in this module. We have to assume that 1349129Smckusick * such a reference may occur and generate code to 1359129Smckusick * prepare for it. 1369129Smckusick */ 1379129Smckusick if ( parts[ cbn ] & LPRT ) { 1389129Smckusick parts[ cbn ] |= ( NONLOCALVAR | NONLOCALGOTO ); 1399129Smckusick } 14010671Speter codeformain(); 1417917Smckusick ftnno = fp -> value[NL_ENTLOC]; 14210671Speter prog_prologue(&eecookie); 14318347Smckusick stabline(bundle->stmnt_blck.line_no); 14418347Smckusick stabfunc(fp, "program", bundle->stmnt_blck.line_no , (long) 0 ); 1453192Smckusick } else { 1467917Smckusick ftnno = fp -> value[NL_ENTLOC]; 14710671Speter fp_prologue(&eecookie); 14818347Smckusick stabline(bundle->stmnt_blck.line_no); 14918347Smckusick stabfunc(fp, fp->symbol, bundle->stmnt_blck.line_no, 15018347Smckusick (long)(cbn - 1)); 1513192Smckusick for ( p = fp -> chain ; p != NIL ; p = p -> chain ) { 15218347Smckusick stabparam( p , p -> value[ NL_OFFS ] , (int) lwidth(p->type)); 1533192Smckusick } 1543192Smckusick if ( fp -> class == FUNC ) { 1553192Smckusick /* 1563192Smckusick * stab the function variable 1573192Smckusick */ 1583192Smckusick p = fp -> ptr[ NL_FVAR ]; 15918347Smckusick stablvar( p , p -> value[ NL_OFFS ] , (int) lwidth( p -> type)); 1603192Smckusick } 1613192Smckusick /* 1623192Smckusick * stab local variables 1633192Smckusick * rummage down hash chain links. 1643192Smckusick */ 1653192Smckusick for ( i = 0 ; i <= 077 ; i++ ) { 1663192Smckusick for ( p = disptab[ i ] ; p != NIL ; p = p->nl_next) { 1673192Smckusick if ( ( p -> nl_block & 037 ) != cbn ) { 1683192Smckusick break; 1693192Smckusick } 1703192Smckusick /* 17118346Smckusick * stab locals (not parameters) 1723192Smckusick */ 17318347Smckusick if ( p -> symbol != NIL ) { 17418347Smckusick if ( p -> class == VAR && p -> value[ NL_OFFS ] < 0 ) { 17518347Smckusick stablvar( p , p -> value[ NL_OFFS ] , 17618347Smckusick (int) lwidth( p -> type ) ); 17718347Smckusick } else if ( p -> class == CONST ) { 17818347Smckusick stabconst( p ); 17918346Smckusick } 1803192Smckusick } 1813192Smckusick } 1823192Smckusick } 1833192Smckusick } 1843192Smckusick stablbrac( cbn ); 1853192Smckusick /* 1863192Smckusick * ask second pass to allocate known locals 1873192Smckusick */ 18811337Speter putlbracket(ftnno, &sizes[cbn]); 18910671Speter fp_entrycode(&eecookie); 1903192Smckusick #endif PC 1913192Smckusick if ( monflg ) { 1923192Smckusick if ( fp -> value[ NL_CNTR ] != 0 ) { 1933192Smckusick inccnt( fp -> value [ NL_CNTR ] ); 1943192Smckusick } 1953192Smckusick inccnt( bodycnts[ fp -> nl_block & 037 ] ); 1963192Smckusick } 1973192Smckusick if (fp->class == PROG) { 1983192Smckusick /* 1993192Smckusick * The glorious buffers option. 2003192Smckusick * 0 = don't buffer output 2013192Smckusick * 1 = line buffer output 2023192Smckusick * 2 = 512 byte buffer output 2033192Smckusick */ 2043192Smckusick # ifdef OBJ 2053192Smckusick if (opt('b') != 1) 20618347Smckusick (void) put(1, O_BUFF | opt('b') << 8); 2073192Smckusick # endif OBJ 2083192Smckusick # ifdef PC 2093192Smckusick if ( opt( 'b' ) != 1 ) { 21018457Sralph putleaf( PCC_ICON , 0 , 0 21118457Sralph , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) , "_BUFF" ); 21218457Sralph putleaf( PCC_ICON , opt( 'b' ) , 0 , PCCT_INT , (char *) 0 ); 21318457Sralph putop( PCC_CALL , PCCT_INT ); 2143192Smckusick putdot( filename , line ); 2153192Smckusick } 2163192Smckusick # endif PC 2177953Speter inp = 0; 2183192Smckusick out = 0; 2193192Smckusick for (p = fp->chain; p != NIL; p = p->chain) { 22018347Smckusick if (pstrcmp(p->symbol, input->symbol) == 0) { 2213192Smckusick inp++; 2223192Smckusick continue; 2233192Smckusick } 22418347Smckusick if (pstrcmp(p->symbol, output->symbol) == 0) { 2253192Smckusick out++; 2263192Smckusick continue; 2273192Smckusick } 2283192Smckusick iop = lookup1(p->symbol); 2293192Smckusick if (iop == NIL || bn != cbn) { 2303192Smckusick error("File %s listed in program statement but not declared", p->symbol); 2313192Smckusick continue; 2323192Smckusick } 2333192Smckusick if (iop->class != VAR) { 2343192Smckusick error("File %s listed in program statement but declared as a %s", p->symbol, classes[iop->class]); 2353192Smckusick continue; 2363192Smckusick } 2373192Smckusick if (iop->type == NIL) 2383192Smckusick continue; 2393192Smckusick if (iop->type->class != FILET) { 2403192Smckusick error("File %s listed in program statement but defined as %s", 2413192Smckusick p->symbol, nameof(iop->type)); 2423192Smckusick continue; 2433192Smckusick } 2443192Smckusick # ifdef OBJ 24518347Smckusick (void) put(2, O_CON24, text(iop->type) ? 0 : width(iop->type->type)); 2463192Smckusick i = lenstr(p->symbol,0); 24718347Smckusick (void) put(2, O_CON24, i); 24818347Smckusick (void) put(2, O_LVCON, i); 2493192Smckusick putstr(p->symbol, 0); 25018347Smckusick (void) put(2, O_LV | bn<<8+INDX, (int)iop->value[NL_OFFS]); 25118347Smckusick (void) put(1, O_DEFNAME); 2523192Smckusick # endif OBJ 2533192Smckusick # ifdef PC 25418457Sralph putleaf( PCC_ICON , 0 , 0 25518457Sralph , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 2563192Smckusick , "_DEFNAME" ); 2573837Speter putLV( p -> symbol , bn , iop -> value[NL_OFFS] , 2583837Speter iop -> extra_flags , p2type( iop ) ); 2593192Smckusick putCONG( p -> symbol , strlen( p -> symbol ) 2603192Smckusick , LREQ ); 26118457Sralph putop( PCC_CM , PCCT_INT ); 26218457Sralph putleaf( PCC_ICON , strlen( p -> symbol ) 26318457Sralph , 0 , PCCT_INT , (char *) 0 ); 26418457Sralph putop( PCC_CM , PCCT_INT ); 26518457Sralph putleaf( PCC_ICON 2663192Smckusick , text(iop->type) ? 0 : width(iop->type->type) 26718457Sralph , 0 , PCCT_INT , (char *) 0 ); 26818457Sralph putop( PCC_CM , PCCT_INT ); 26918457Sralph putop( PCC_CALL , PCCT_INT ); 2703192Smckusick putdot( filename , line ); 2713192Smckusick # endif PC 2723192Smckusick } 2733192Smckusick } 2743192Smckusick /* 2753192Smckusick * Process the prog/proc/func body 2763192Smckusick */ 27718347Smckusick noreach = FALSE; 27818347Smckusick line = bundle->stmnt_blck.line_no; 2793192Smckusick statlist(blk); 2803192Smckusick # ifdef PTREE 2813192Smckusick { 2823192Smckusick pPointer Body = tCopy( blk ); 2833192Smckusick 2843192Smckusick pDEF( PorFHeader[ nesting -- ] ).PorFBody = Body; 2853192Smckusick } 2863192Smckusick # endif PTREE 2873192Smckusick # ifdef OBJ 28818347Smckusick if (cbn== 1 && monflg != FALSE) { 28918347Smckusick patchfil((PTR_DCL) (cntpatch - 2), (long)cnts, 2); 29018347Smckusick patchfil((PTR_DCL) (nfppatch - 2), (long)pfcnt, 2); 2913192Smckusick } 2923192Smckusick # endif OBJ 2933192Smckusick # ifdef PC 2943192Smckusick if ( fp -> class == PROG && monflg ) { 29518457Sralph putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 2963192Smckusick , "_PMFLUSH" ); 29718457Sralph putleaf( PCC_ICON , cnts , 0 , PCCT_INT , (char *) 0 ); 29818457Sralph putleaf( PCC_ICON , pfcnt , 0 , PCCT_INT , (char *) 0 ); 29918457Sralph putop( PCC_CM , PCCT_INT ); 30018457Sralph putLV( PCPCOUNT , 0 , 0 , NGLOBAL , PCCT_INT ); 30118457Sralph putop( PCC_CM , PCCT_INT ); 30218457Sralph putop( PCC_CALL , PCCT_INT ); 3033192Smckusick putdot( filename , line ); 3043192Smckusick } 3053192Smckusick # endif PC 3067953Speter /* 3077953Speter * Clean up the symbol table displays and check for unresolves 3087953Speter */ 3097953Speter line = endline; 3103192Smckusick if (fp->class == PROG && inp == 0 && (input->nl_flags & (NUSED|NMOD)) != 0) { 3113192Smckusick recovered(); 3123192Smckusick error("Input is used but not defined in the program statement"); 3133192Smckusick } 3147953Speter if (fp->class == PROG && out == 0 && (output->nl_flags & (NUSED|NMOD)) != 0) { 3157953Speter recovered(); 3167953Speter error("Output is used but not defined in the program statement"); 3177953Speter } 3183192Smckusick b = cbn; 3193192Smckusick Fp = fp; 32018347Smckusick chkref = (syneflg == errcnt[cbn] && opt('w') == 0)?TRUE:FALSE; 3213192Smckusick for (i = 0; i <= 077; i++) { 3223192Smckusick for (p = disptab[i]; p != NIL && (p->nl_block & 037) == b; p = p->nl_next) { 3233192Smckusick /* 3243192Smckusick * Check for variables defined 3253192Smckusick * but not referenced 3263192Smckusick */ 3273192Smckusick if (chkref && p->symbol != NIL) 3283192Smckusick switch (p->class) { 3293192Smckusick case FIELD: 3303192Smckusick /* 3313192Smckusick * If the corresponding record is 3323192Smckusick * unused, we shouldn't complain about 3333192Smckusick * the fields. 3343192Smckusick */ 3353192Smckusick default: 3363192Smckusick if ((p->nl_flags & (NUSED|NMOD)) == 0) { 3373192Smckusick warning(); 3383192Smckusick nerror("%s %s is neither used nor set", classes[p->class], p->symbol); 3393192Smckusick break; 3403192Smckusick } 3413192Smckusick /* 3423192Smckusick * If a var parameter is either 3433192Smckusick * modified or used that is enough. 3443192Smckusick */ 3453192Smckusick if (p->class == REF) 3463192Smckusick continue; 3473192Smckusick # ifdef OBJ 3483192Smckusick if ((p->nl_flags & NUSED) == 0) { 3493192Smckusick warning(); 3503192Smckusick nerror("%s %s is never used", classes[p->class], p->symbol); 3513192Smckusick break; 3523192Smckusick } 3533192Smckusick # endif OBJ 3543192Smckusick # ifdef PC 3553837Speter if (((p->nl_flags & NUSED) == 0) && ((p->extra_flags & NEXTERN) == 0)) { 3563192Smckusick warning(); 3573192Smckusick nerror("%s %s is never used", classes[p->class], p->symbol); 3583192Smckusick break; 3593192Smckusick } 3603192Smckusick # endif PC 3613192Smckusick if ((p->nl_flags & NMOD) == 0) { 3623192Smckusick warning(); 3633192Smckusick nerror("%s %s is used but never set", classes[p->class], p->symbol); 3643192Smckusick break; 3653192Smckusick } 3663192Smckusick case LABEL: 3673192Smckusick case FVAR: 3683192Smckusick case BADUSE: 3693192Smckusick break; 3703192Smckusick } 3713192Smckusick switch (p->class) { 3723192Smckusick case BADUSE: 3733192Smckusick cp = "s"; 37418347Smckusick /* This used to say ud_next 37518347Smckusick that is not a member of nl so 37618347Smckusick i changed it to nl_next, 37718347Smckusick which may be wrong */ 37818347Smckusick if (p->chain->nl_next == NIL) 3793192Smckusick cp++; 3803192Smckusick eholdnl(); 3813192Smckusick if (p->value[NL_KINDS] & ISUNDEF) 3823192Smckusick nerror("%s undefined on line%s", p->symbol, cp); 3833192Smckusick else 3843192Smckusick nerror("%s improperly used on line%s", p->symbol, cp); 3853192Smckusick pnumcnt = 10; 38618347Smckusick pnums((struct udinfo *) p->chain); 3873192Smckusick pchr('\n'); 3883192Smckusick break; 3893192Smckusick 3903192Smckusick case FUNC: 3913192Smckusick case PROC: 3923192Smckusick # ifdef OBJ 3933192Smckusick if ((p->nl_flags & NFORWD)) 3943192Smckusick nerror("Unresolved forward declaration of %s %s", classes[p->class], p->symbol); 3953192Smckusick # endif OBJ 3963192Smckusick # ifdef PC 3973837Speter if ((p->nl_flags & NFORWD) && ((p->extra_flags & NEXTERN) == 0)) 3983192Smckusick nerror("Unresolved forward declaration of %s %s", classes[p->class], p->symbol); 3993192Smckusick # endif PC 4003192Smckusick break; 4013192Smckusick 4023192Smckusick case LABEL: 4033192Smckusick if (p->nl_flags & NFORWD) 4043192Smckusick nerror("label %s was declared but not defined", p->symbol); 4053192Smckusick break; 4063192Smckusick case FVAR: 4073192Smckusick if ((p->nl_flags & NMOD) == 0) 4083192Smckusick nerror("No assignment to the function variable"); 4093192Smckusick break; 4103192Smckusick } 4113192Smckusick } 4123192Smckusick /* 4133192Smckusick * Pop this symbol 4143192Smckusick * table slot 4153192Smckusick */ 4163192Smckusick disptab[i] = p; 4173192Smckusick } 4183192Smckusick 4193192Smckusick # ifdef OBJ 42018347Smckusick (void) put(1, O_END); 4213192Smckusick # endif OBJ 4223192Smckusick # ifdef PC 42310671Speter fp_exitcode(&eecookie); 42410671Speter stabrbrac(cbn); 42510671Speter putrbracket(ftnno); 42610671Speter fp_epilogue(&eecookie); 42710671Speter if (fp -> class != PROG) { 42810671Speter fp_formalentry(&eecookie); 4293192Smckusick } 4303192Smckusick /* 4313192Smckusick * declare pcp counters, if any 4323192Smckusick */ 4333192Smckusick if ( monflg && fp -> class == PROG ) { 4343192Smckusick putprintf( " .data" , 0 ); 43518457Sralph aligndot(PCCT_INT); 4363192Smckusick putprintf( " .comm " , 1 ); 4373192Smckusick putprintf( PCPCOUNT , 1 ); 4383192Smckusick putprintf( ",%d" , 0 , ( cnts + 1 ) * sizeof (long) ); 4393192Smckusick putprintf( " .text" , 0 ); 4403192Smckusick } 4413192Smckusick # endif PC 4423192Smckusick #ifdef DEBUG 44318347Smckusick dumpnl(fp->ptr[2], (int) fp->symbol); 4443192Smckusick #endif 4455654Slinton 4465654Slinton #ifdef OBJ 4473192Smckusick /* 4485654Slinton * save the namelist for the debugger pdx 4495654Slinton */ 4505654Slinton 45118347Smckusick savenl(fp->ptr[2], (int) fp->symbol); 4525654Slinton #endif 4535654Slinton 4545654Slinton /* 4553192Smckusick * Restore the 4563192Smckusick * (virtual) name list 4573192Smckusick * position 4583192Smckusick */ 4593192Smckusick nlfree(fp->ptr[2]); 4603192Smckusick /* 4613192Smckusick * Proc/func has been 4623192Smckusick * resolved 4633192Smckusick */ 4643192Smckusick fp->nl_flags &= ~NFORWD; 4653192Smckusick /* 4663192Smckusick * Patch the beg 4673192Smckusick * of the proc/func to 4683192Smckusick * the proper variable size 4693192Smckusick */ 4703192Smckusick if (Fp == NIL) 4713192Smckusick elineon(); 4723192Smckusick # ifdef OBJ 47330037Smckusick patchfil((PTR_DCL) var, 47430037Smckusick roundup(-sizes[cbn].om_max, (long) A_STACK), 2); 4753192Smckusick # endif OBJ 4763192Smckusick cbn--; 4773192Smckusick if (inpflist(fp->symbol)) { 4783192Smckusick opop('l'); 4793192Smckusick } 4803192Smckusick } 4813363Speter 4823363Speter #ifdef PC 4833363Speter /* 4843363Speter * construct the long name of a function based on it's static nesting. 4853363Speter * into a caller-supplied buffer (that should be about BUFSIZ big). 4863363Speter */ 4873363Speter sextname( buffer , name , level ) 4883363Speter char buffer[]; 4893363Speter char *name; 4903363Speter int level; 4913363Speter { 4923363Speter char *starthere; 4933363Speter int i; 4943363Speter 4953363Speter starthere = &buffer[0]; 4963363Speter for ( i = 1 ; i < level ; i++ ) { 4973363Speter sprintf( starthere , EXTFORMAT , enclosing[ i ] ); 4983363Speter starthere += strlen( enclosing[ i ] ) + 1; 4993363Speter } 5003367Speter sprintf( starthere , EXTFORMAT , name ); 5013367Speter starthere += strlen( name ) + 1; 5023363Speter if ( starthere >= &buffer[ BUFSIZ ] ) { 5033363Speter panic( "sextname" ); 5043363Speter } 5053363Speter } 50610671Speter 50710671Speter /* 50810671Speter * code for main() 50910671Speter */ 51010671Speter #ifdef vax 51110671Speter 51210671Speter codeformain() 51310671Speter { 51410671Speter putprintf(" .text" , 0 ); 51510671Speter putprintf(" .align 1" , 0 ); 51610671Speter putprintf(" .globl _main" , 0 ); 51710671Speter putprintf("_main:" , 0 ); 51810671Speter putprintf(" .word 0" , 0 ); 51910671Speter if ( opt ( 't' ) ) { 52010671Speter putprintf(" pushl $1" , 0 ); 52110671Speter } else { 52210671Speter putprintf(" pushl $0" , 0 ); 52310671Speter } 52410671Speter putprintf(" calls $1,_PCSTART" , 0 ); 52510671Speter putprintf(" movl 4(ap),__argc" , 0 ); 52610671Speter putprintf(" movl 8(ap),__argv" , 0 ); 52710671Speter putprintf(" calls $0,_program" , 0 ); 52810671Speter putprintf(" pushl $0" , 0 ); 52910671Speter putprintf(" calls $1,_PCEXIT" , 0 ); 53010671Speter } 531*30039Smckusick #endif vax 53210671Speter 533*30039Smckusick #ifdef tahoe 534*30039Smckusick codeformain() 535*30039Smckusick { 536*30039Smckusick putprintf(" .text" , 0 ); 537*30039Smckusick putprintf(" .align 1" , 0 ); 538*30039Smckusick putprintf(" .globl _main" , 0 ); 539*30039Smckusick putprintf("_main:" , 0 ); 540*30039Smckusick putprintf(" .word 0" , 0 ); 541*30039Smckusick if ( opt ( 't' ) ) { 542*30039Smckusick putprintf(" pushl $1" , 0 ); 543*30039Smckusick } else { 544*30039Smckusick putprintf(" pushl $0" , 0 ); 545*30039Smckusick } 546*30039Smckusick putprintf(" callf $8,_PCSTART" , 0 ); 547*30039Smckusick putprintf(" movl 4(fp),__argc" , 0 ); 548*30039Smckusick putprintf(" movl 8(fp),__argv" , 0 ); 549*30039Smckusick putprintf(" callf $4,_program" , 0 ); 550*30039Smckusick putprintf(" pushl $0" , 0 ); 551*30039Smckusick putprintf(" callf $8,_PCEXIT" , 0 ); 552*30039Smckusick } 553*30039Smckusick #endif tahoe 554*30039Smckusick 55510671Speter /* 55610671Speter * prologue for the program. 55710671Speter * different because it 55810671Speter * doesn't have formal entry point 55910671Speter */ 560*30039Smckusick #if defined(vax) || defined(tahoe) 56110671Speter prog_prologue(eecookiep) 56210671Speter struct entry_exit_cookie *eecookiep; 56310671Speter { 56410671Speter putprintf(" .text" , 0 ); 56510671Speter putprintf(" .align 1" , 0 ); 56610671Speter putprintf(" .globl _program" , 0 ); 56710671Speter putprintf("_program:" , 0 ); 56810716Speter /* 56910716Speter * register save mask 57010716Speter */ 57118347Smckusick eecookiep -> savlabel = (int) getlab(); 57218347Smckusick putprintf(" .word %s%d", 0, (int) SAVE_MASK_LABEL , eecookiep -> savlabel ); 57310671Speter } 57410671Speter 57510671Speter fp_prologue(eecookiep) 57610671Speter struct entry_exit_cookie *eecookiep; 57710671Speter { 57810671Speter 57910671Speter sextname( eecookiep -> extname, eecookiep -> nlp -> symbol , cbn - 1 ); 58010671Speter putprintf( " .text" , 0 ); 58110671Speter putprintf( " .align 1" , 0 ); 58218347Smckusick putprintf( " .globl %s%s", 0, (int) FORMALPREFIX, (int) eecookiep -> extname ); 58318347Smckusick putprintf( " .globl %s" , 0 , (int) eecookiep -> extname ); 58418347Smckusick putprintf( "%s:" , 0 , (int) eecookiep -> extname ); 58510671Speter /* 58610671Speter * register save mask 58710671Speter */ 58818347Smckusick eecookiep -> savlabel = (int) getlab(); 58918347Smckusick putprintf(" .word %s%d", 0, (int) SAVE_MASK_LABEL , eecookiep -> savlabel ); 59010671Speter } 591*30039Smckusick #endif vax || tahoe 59210671Speter 59310671Speter /* 59410671Speter * code before any user code. 59510671Speter * or code that is machine dependent. 59610671Speter */ 597*30039Smckusick #ifdef vax 59810671Speter fp_entrycode(eecookiep) 59910671Speter struct entry_exit_cookie *eecookiep; 60010671Speter { 60110714Speter int ftnno = eecookiep -> nlp -> value[NL_ENTLOC]; 60218347Smckusick int proflabel = (int) getlab(); 60318347Smckusick int setjmp0 = (int) getlab(); 60410671Speter 60510671Speter /* 60610671Speter * top of code; destination of jump from formal entry code. 60710671Speter */ 60818347Smckusick eecookiep -> toplabel = (int) getlab(); 60918347Smckusick (void) putlab( (char *) eecookiep -> toplabel ); 61018347Smckusick putprintf(" subl2 $%s%d,sp" , 0 , (int) FRAME_SIZE_LABEL, ftnno ); 61110671Speter if ( profflag ) { 61210671Speter /* 61310671Speter * call mcount for profiling 61410671Speter */ 61510671Speter putprintf( " moval " , 1 ); 61618347Smckusick putprintf( PREFIXFORMAT , 1 , (int) LABELPREFIX , proflabel ); 61710671Speter putprintf( ",r0" , 0 ); 61810671Speter putprintf( " jsb mcount" , 0 ); 61910671Speter putprintf( " .data" , 0 ); 62010671Speter putprintf( " .align 2" , 0 ); 62118347Smckusick (void) putlab( (char *) proflabel ); 62210671Speter putprintf( " .long 0" , 0 ); 62310671Speter putprintf( " .text" , 0 ); 62410671Speter } 62510671Speter /* 62610671Speter * if there are nested procedures that access our variables 62710671Speter * we must save the display. 62810671Speter */ 62910671Speter if ( parts[ cbn ] & NONLOCALVAR ) { 63010671Speter /* 63110671Speter * save old display 63210671Speter */ 63310671Speter putprintf( " movq %s+%d,%d(%s)" , 0 63418347Smckusick , (int) DISPLAYNAME , cbn * sizeof(struct dispsave) 63518347Smckusick , DSAVEOFFSET , (int) P2FPNAME ); 63610671Speter /* 63710671Speter * set up new display by saving AP and FP in appropriate 63810671Speter * slot in display structure. 63910671Speter */ 64010671Speter putprintf( " movq %s,%s+%d" , 0 64118347Smckusick , (int) P2APNAME , (int) DISPLAYNAME , cbn * sizeof(struct dispsave) ); 64210671Speter } 64310671Speter /* 64410671Speter * set underflow checking if runtime tests 64510671Speter */ 64610671Speter if ( opt( 't' ) ) { 64710671Speter putprintf( " bispsw $0xe0" , 0 ); 64810671Speter } 64910671Speter /* 65010671Speter * zero local variables if checking is on 65110671Speter * by calling blkclr( bytes of locals , starting local address ); 65210671Speter */ 65310671Speter if ( opt( 't' ) && ( -sizes[ cbn ].om_max ) > DPOFF1 ) { 65418457Sralph putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 65510671Speter , "_blkclr" ); 65618457Sralph putLV((char *) 0 , cbn , (int) sizes[ cbn ].om_max , NLOCAL , PCCT_CHAR ); 65718457Sralph putleaf( PCC_ICON , (int) (( -sizes[ cbn ].om_max ) - DPOFF1) 65818457Sralph , 0 , PCCT_INT ,(char *) 0 ); 65918457Sralph putop( PCC_CM , PCCT_INT ); 66018457Sralph putop( PCC_CALL , PCCT_INT ); 66110671Speter putdot( filename , line ); 66210671Speter } 66310671Speter /* 66410671Speter * set up goto vector if non-local goto to this frame 66510671Speter */ 66610671Speter if ( parts[ cbn ] & NONLOCALGOTO ) { 66718457Sralph putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 66810671Speter , "_setjmp" ); 66918457Sralph putLV( (char *) 0 , cbn , GOTOENVOFFSET , NLOCAL , PCCTM_PTR|PCCT_STRTY ); 67018457Sralph putop( PCC_CALL , PCCT_INT ); 67118457Sralph putleaf( PCC_ICON , 0 , 0 , PCCT_INT , (char *) 0 ); 67218457Sralph putop( PCC_NE , PCCT_INT ); 67318457Sralph putleaf( PCC_ICON , setjmp0 , 0 , PCCT_INT , (char *) 0 ); 67418457Sralph putop( PCC_CBRANCH , PCCT_INT ); 67510671Speter putdot( filename , line ); 67610671Speter /* 67710671Speter * on non-local goto, setjmp returns with address to 67810671Speter * be branched to. 67910671Speter */ 68010671Speter putprintf( " jmp (r0)" , 0 ); 68118347Smckusick (void) putlab((char *) setjmp0); 68210671Speter } 68310671Speter } 684*30039Smckusick #endif vax 68510671Speter 686*30039Smckusick #ifdef tahoe 687*30039Smckusick fp_entrycode(eecookiep) 688*30039Smckusick struct entry_exit_cookie *eecookiep; 689*30039Smckusick { 690*30039Smckusick int ftnno = eecookiep -> nlp -> value[NL_ENTLOC]; 691*30039Smckusick int proflabel = (int) getlab(); 692*30039Smckusick int setjmp0 = (int) getlab(); 693*30039Smckusick 694*30039Smckusick /* 695*30039Smckusick * top of code; destination of jump from formal entry code. 696*30039Smckusick */ 697*30039Smckusick eecookiep -> toplabel = (int) getlab(); 698*30039Smckusick (void) putlab( (char *) eecookiep -> toplabel ); 699*30039Smckusick putprintf(" subl3 $%s%d,fp,sp" , 0 , (int) FRAME_SIZE_LABEL, ftnno ); 700*30039Smckusick if ( profflag ) { 701*30039Smckusick /* 702*30039Smckusick * call mcount for profiling 703*30039Smckusick */ 704*30039Smckusick putprintf( " pushal " , 1 ); 705*30039Smckusick putprintf( PREFIXFORMAT , 1 , (int) LABELPREFIX , proflabel, 0 ); 706*30039Smckusick putprintf( " callf $8,mcount" , 0 ); 707*30039Smckusick putprintf( " .data" , 0 ); 708*30039Smckusick putprintf( " .align 2" , 0 ); 709*30039Smckusick (void) putlab( (char *) proflabel ); 710*30039Smckusick putprintf( " .long 0" , 0 ); 711*30039Smckusick putprintf( " .text" , 0 ); 712*30039Smckusick } 713*30039Smckusick /* 714*30039Smckusick * if there are nested procedures that access our variables 715*30039Smckusick * we must save the display. 716*30039Smckusick */ 717*30039Smckusick if ( parts[ cbn ] & NONLOCALVAR ) { 718*30039Smckusick /* 719*30039Smckusick * save old display 720*30039Smckusick */ 721*30039Smckusick putprintf( " movl %s+%d,%d(%s)" , 0 722*30039Smckusick , (int) DISPLAYNAME , cbn * sizeof(struct dispsave) 723*30039Smckusick , DSAVEOFFSET , (int) P2FPNAME ); 724*30039Smckusick /* 725*30039Smckusick * set up new display by saving FP in appropriate 726*30039Smckusick * slot in display structure. 727*30039Smckusick */ 728*30039Smckusick putprintf( " movl %s,%s+%d" , 0 729*30039Smckusick , (int) P2FPNAME , (int) DISPLAYNAME , cbn * sizeof(struct dispsave) ); 730*30039Smckusick } 731*30039Smckusick /* 732*30039Smckusick * set underflow checking if runtime tests 733*30039Smckusick */ 734*30039Smckusick if ( opt( 't' ) ) { 735*30039Smckusick putprintf( " bicpsw $0x20" , 0 ); 736*30039Smckusick } 737*30039Smckusick /* 738*30039Smckusick * zero local variables if checking is on 739*30039Smckusick * by calling blkclr( bytes of locals , starting local address ); 740*30039Smckusick */ 741*30039Smckusick if ( opt( 't' ) && ( -sizes[ cbn ].om_max ) > DPOFF1 ) { 742*30039Smckusick putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 743*30039Smckusick , "_blkclr" ); 744*30039Smckusick putLV((char *) 0 , cbn , (int) sizes[ cbn ].om_max , NLOCAL , PCCT_CHAR ); 745*30039Smckusick putleaf( PCC_ICON , (int) (( -sizes[ cbn ].om_max ) - DPOFF1) 746*30039Smckusick , 0 , PCCT_INT ,(char *) 0 ); 747*30039Smckusick putop( PCC_CM , PCCT_INT ); 748*30039Smckusick putop( PCC_CALL , PCCT_INT ); 749*30039Smckusick putdot( filename , line ); 750*30039Smckusick } 751*30039Smckusick /* 752*30039Smckusick * set up goto vector if non-local goto to this frame 753*30039Smckusick */ 754*30039Smckusick if ( parts[ cbn ] & NONLOCALGOTO ) { 755*30039Smckusick putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 756*30039Smckusick , "_setjmp" ); 757*30039Smckusick putLV( (char *) 0 , cbn , GOTOENVOFFSET , NLOCAL , PCCTM_PTR|PCCT_STRTY ); 758*30039Smckusick putop( PCC_CALL , PCCT_INT ); 759*30039Smckusick putleaf( PCC_ICON , 0 , 0 , PCCT_INT , (char *) 0 ); 760*30039Smckusick putop( PCC_NE , PCCT_INT ); 761*30039Smckusick putleaf( PCC_ICON , setjmp0 , 0 , PCCT_INT , (char *) 0 ); 762*30039Smckusick putop( PCC_CBRANCH , PCCT_INT ); 763*30039Smckusick putdot( filename , line ); 764*30039Smckusick /* 765*30039Smckusick * on non-local goto, setjmp returns with address to 766*30039Smckusick * be branched to. 767*30039Smckusick */ 768*30039Smckusick putprintf( " jmp (r0)" , 0 ); 769*30039Smckusick (void) putlab((char *) setjmp0); 770*30039Smckusick } 771*30039Smckusick } 772*30039Smckusick #endif tahoe 773*30039Smckusick 774*30039Smckusick #if defined(vax) || defined(tahoe) 77510671Speter fp_exitcode(eecookiep) 77610671Speter struct entry_exit_cookie *eecookiep; 77710671Speter { 77810671Speter /* 77910671Speter * if there were file variables declared at this level 78010671Speter * call PCLOSE( ap ) to clean them up. 78110671Speter */ 78210671Speter if ( dfiles[ cbn ] ) { 78318457Sralph putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 78410671Speter , "_PCLOSE" ); 78518457Sralph putleaf( PCC_REG , 0 , P2AP , PCCM_ADDTYPE( PCCT_CHAR , PCCTM_PTR ) , (char *) 0 ); 78618457Sralph putop( PCC_CALL , PCCT_INT ); 78710671Speter putdot( filename , line ); 78810671Speter } 78910671Speter /* 79010671Speter * if this is a function, 79110671Speter * the function variable is the return value. 79210671Speter * if it's a scalar valued function, return scalar, 79310671Speter * else, return a pointer to the structure value. 79410671Speter */ 79510671Speter if ( eecookiep-> nlp -> class == FUNC ) { 79610671Speter struct nl *fvar = eecookiep-> nlp -> ptr[ NL_FVAR ]; 79710671Speter long fvartype = p2type( fvar -> type ); 79810671Speter long label; 79910671Speter char labelname[ BUFSIZ ]; 80010671Speter 80110671Speter switch ( classify( fvar -> type ) ) { 80210671Speter case TBOOL: 80310671Speter case TCHAR: 80410671Speter case TINT: 80510671Speter case TSCAL: 80610671Speter case TDOUBLE: 80710671Speter case TPTR: 80810671Speter putRV( fvar -> symbol , ( fvar -> nl_block ) & 037 , 80910671Speter fvar -> value[ NL_OFFS ] , 81010671Speter fvar -> extra_flags , 81118347Smckusick (int) fvartype ); 81218457Sralph putop( PCC_FORCE , (int) fvartype ); 81310671Speter break; 81410671Speter default: 81518347Smckusick label = (int) getlab(); 81610671Speter sprintf( labelname , PREFIXFORMAT , LABELPREFIX , label ); 81710671Speter putprintf( " .data" , 0 ); 81810671Speter aligndot(A_STRUCT); 81910671Speter putprintf( " .lcomm %s,%d" , 0 , 82018347Smckusick (int) labelname , (int) lwidth( fvar -> type ) ); 82110671Speter putprintf( " .text" , 0 ); 82218457Sralph putleaf( PCC_NAME , 0 , 0 , (int) fvartype , labelname ); 82310671Speter putLV( fvar -> symbol , ( fvar -> nl_block ) & 037 , 82410671Speter fvar -> value[ NL_OFFS ] , 82510671Speter fvar -> extra_flags , 82618347Smckusick (int) fvartype ); 82718457Sralph putstrop( PCC_STASG , (int) PCCM_ADDTYPE(fvartype, PCCTM_PTR) , 82818347Smckusick (int) lwidth( fvar -> type ) , 82910671Speter align( fvar -> type ) ); 83010671Speter putdot( filename , line ); 83118457Sralph putleaf( PCC_ICON , 0 , 0 , (int) PCCM_ADDTYPE(fvartype, PCCTM_PTR), labelname ); 83218457Sralph putop( PCC_FORCE , (int) PCCM_ADDTYPE(fvartype, PCCTM_PTR) ); 83310671Speter break; 83410671Speter } 83510671Speter putdot( filename , line ); 83610671Speter } 83710671Speter /* 83810671Speter * if there are nested procedures we must save the display. 83910671Speter */ 84010671Speter if ( parts[ cbn ] & NONLOCALVAR ) { 84110671Speter /* 84210671Speter * restore old display entry from save area 84310671Speter */ 844*30039Smckusick #ifdef vax 84510671Speter putprintf( " movq %d(%s),%s+%d" , 0 84618347Smckusick , DSAVEOFFSET , (int) P2FPNAME 84718347Smckusick , (int) DISPLAYNAME , cbn * sizeof(struct dispsave) ); 848*30039Smckusick #endif 849*30039Smckusick #ifdef tahoe 850*30039Smckusick putprintf( " movl %d(%s),%s+%d" , 0 851*30039Smckusick , DSAVEOFFSET , (int) P2FPNAME 852*30039Smckusick , (int) DISPLAYNAME , cbn * sizeof(struct dispsave) ); 853*30039Smckusick #endif 85410671Speter } 85510671Speter } 856*30039Smckusick #endif vax || tahoe 85710671Speter 858*30039Smckusick #if defined(vax) || defined(tahoe) 85910671Speter fp_epilogue(eecookiep) 86010671Speter struct entry_exit_cookie *eecookiep; 86110671Speter { 86218346Smckusick stabline(line); 86310671Speter putprintf(" ret" , 0 ); 86410671Speter /* 86510671Speter * set the register save mask. 86610671Speter */ 86710671Speter putprintf(" .set %s%d,0x%x", 0, 86818347Smckusick (int) SAVE_MASK_LABEL, eecookiep -> savlabel, savmask()); 86910671Speter } 870*30039Smckusick #endif vax || tahoe 87110671Speter 872*30039Smckusick #if defined(vax) || defined(tahoe) 87310671Speter fp_formalentry(eecookiep) 87410671Speter struct entry_exit_cookie *eecookiep; 87510671Speter { 87610671Speter 87711857Speter putprintf(" .align 1", 0); 87818347Smckusick putprintf("%s%s:" , 0 , (int) FORMALPREFIX , (int) eecookiep -> extname ); 87918347Smckusick putprintf(" .word %s%d", 0, (int) SAVE_MASK_LABEL, eecookiep -> savlabel ); 88018457Sralph putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) , "_FCALL" ); 88118347Smckusick putRV((char *) 0 , cbn , 88210671Speter eecookiep -> nlp -> value[ NL_OFFS ] + sizeof( struct formalrtn * ) , 88318457Sralph NPARAM , PCCTM_PTR | PCCT_STRTY ); 88418457Sralph putRV((char *) 0, cbn, eecookiep -> nlp -> value[NL_OFFS], NPARAM, PCCTM_PTR|PCCT_STRTY); 88518457Sralph putop( PCC_CM , PCCT_INT ); 88618457Sralph putop( PCC_CALL , PCCT_INT ); 88710671Speter putdot( filename , line ); 88818347Smckusick putjbr( (long) eecookiep -> toplabel ); 88910671Speter } 890*30039Smckusick #endif vax || tahoe 89110671Speter 89210671Speter #ifdef mc68000 89310671Speter 89410671Speter codeformain() 89510671Speter { 89610671Speter putprintf(" .text", 0); 89710671Speter putprintf(" .globl _main", 0); 89810671Speter putprintf("_main:", 0); 89910671Speter putprintf(" link %s,#0", 0, P2FPNAME); 90010671Speter if (opt('t')) { 90110671Speter putprintf(" pea 1", 0); 90210671Speter } else { 90310671Speter putprintf(" pea 0", 0); 90410671Speter } 90510671Speter putprintf(" jbsr _PCSTART", 0); 90610671Speter putprintf(" addql #4,sp", 0); 90710671Speter putprintf(" movl %s@(8),__argc", 0, P2FPNAME); 90810671Speter putprintf(" movl %s@(12),__argv", 0, P2FPNAME); 90910671Speter putprintf(" jbsr _program", 0); 91010671Speter putprintf(" pea 0", 0); 91110671Speter putprintf(" jbsr _PCEXIT", 0); 91210671Speter } 91310671Speter 91410671Speter prog_prologue(eecookiep) 91510671Speter struct entry_exit_cookie *eecookiep; 91610671Speter { 91710671Speter int ftnno = eecookiep -> nlp -> value[NL_ENTLOC]; 91810671Speter 91910671Speter putprintf(" .text", 0); 92010671Speter putprintf(" .globl _program", 0); 92110671Speter putprintf("_program:", 0); 92210671Speter putprintf(" link %s,#0", 0, P2FPNAME); 92310671Speter putprintf(" addl #-%s%d,sp", 0, FRAME_SIZE_LABEL, ftnno); 92410671Speter /* touch new end of stack, to break more stack space */ 92510671Speter putprintf(" tstb sp@(-%s%d)", 0, PAGE_BREAK_LABEL, ftnno); 92610671Speter putprintf(" moveml #%s%d,sp@", 0, SAVE_MASK_LABEL, ftnno); 92710671Speter } 92810671Speter 92910671Speter fp_prologue(eecookiep) 93010671Speter struct entry_exit_cookie *eecookiep; 93110671Speter { 93210671Speter int ftnno = eecookiep -> nlp -> value[NL_ENTLOC]; 93310671Speter 93410671Speter sextname(eecookiep -> extname, eecookiep -> nlp -> symbol, cbn - 1); 93510671Speter putprintf(" .text", 0); 93610671Speter putprintf(" .globl %s%s", 0, FORMALPREFIX, eecookiep -> extname); 93710671Speter putprintf(" .globl %s", 0, eecookiep -> extname); 93810671Speter putprintf("%s:", 0, eecookiep -> extname); 93910671Speter putprintf(" link %s,#0", 0, P2FPNAME); 94010671Speter putprintf(" addl #-%s%d,sp", 0, FRAME_SIZE_LABEL, ftnno); 94110671Speter /* touch new end of stack, to break more stack space */ 94210671Speter putprintf(" tstb sp@(-%s%d)", 0, PAGE_BREAK_LABEL, ftnno); 94310671Speter putprintf(" moveml #%s%d,sp@", 0, SAVE_MASK_LABEL, ftnno); 94410671Speter } 94510671Speter 94610671Speter fp_entrycode(eecookiep) 94710671Speter struct entry_exit_cookie *eecookiep; 94810671Speter { 94918347Smckusick char *proflabel = getlab(); 95018347Smckusick char *setjmp0 = getlab(); 95110671Speter 95210671Speter /* 95310671Speter * fill in the label cookie 95410671Speter */ 95510671Speter eecookiep -> toplabel = getlab(); 95618347Smckusick (void) putlab(eecookiep -> toplabel); 95710671Speter /* 95810671Speter * call mcount if we are profiling. 95910671Speter */ 96010671Speter if ( profflag ) { 96110671Speter putprintf(" movl #%s%d,a0", 0, LABELPREFIX, proflabel); 96210671Speter putprintf(" jsr mcount", 0); 96310671Speter putprintf(" .data", 0); 96410671Speter putprintf(" .even", 0); 96518347Smckusick (void) putlab(proflabel); 96610671Speter putprintf(" .long 0", 0); 96710671Speter putprintf(" .text", 0); 96810671Speter } 96910671Speter /* 97010671Speter * if there are nested procedures that access our variables 97110671Speter * we must save the display 97210671Speter */ 97310671Speter if (parts[cbn] & NONLOCALVAR) { 97410671Speter /* 97510671Speter * save the old display 97610671Speter */ 97710671Speter putprintf(" movl %s+%d,%s@(%d)", 0, 97810671Speter DISPLAYNAME, cbn * sizeof(struct dispsave), 97910671Speter P2FPNAME, DSAVEOFFSET); 98010671Speter /* 98110671Speter * set up the new display by saving the framepointer 98210671Speter * in the display structure. 98310671Speter */ 98410671Speter putprintf(" movl %s,%s+%d", 0, 98510671Speter P2FPNAME, DISPLAYNAME, cbn * sizeof(struct dispsave)); 98610671Speter } 98710671Speter /* 98810671Speter * zero local variables if checking is on 98910671Speter * by calling blkclr( bytes of locals , starting local address ); 99010671Speter */ 99110671Speter if ( opt( 't' ) && ( -sizes[ cbn ].om_max ) > DPOFF1 ) { 99218457Sralph putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 99310671Speter , "_blkclr" ); 99418457Sralph putLV( 0 , cbn , sizes[ cbn ].om_max , NLOCAL , PCCT_CHAR ); 99518457Sralph putleaf( PCC_ICON , ( -sizes[ cbn ].om_max ) - DPOFF1 99618457Sralph , 0 , PCCT_INT , 0 ); 99718457Sralph putop( PCC_CM , PCCT_INT ); 99818457Sralph putop( PCC_CALL , PCCT_INT ); 99910671Speter putdot( filename , line ); 100010671Speter } 100110671Speter /* 100210671Speter * set up goto vector if non-local goto to this frame 100310671Speter */ 100410671Speter if ( parts[ cbn ] & NONLOCALGOTO ) { 100518457Sralph putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 100610671Speter , "_setjmp" ); 100718457Sralph putLV( 0 , cbn , GOTOENVOFFSET , NLOCAL , PCCTM_PTR|PCCT_STRTY ); 100818457Sralph putop( PCC_CALL , PCCT_INT ); 100918457Sralph putleaf( PCC_ICON , 0 , 0 , PCCT_INT , 0 ); 101018457Sralph putop( PCC_NE , PCCT_INT ); 101118457Sralph putleaf( PCC_ICON , setjmp0 , 0 , PCCT_INT , 0 ); 101218457Sralph putop( PCC_CBRANCH , PCCT_INT ); 101310671Speter putdot( filename , line ); 101410671Speter /* 101510671Speter * on non-local goto, setjmp returns with address to 101610671Speter * be branched to. 101710671Speter */ 101810671Speter putprintf(" movl d0,a0", 0); 101910671Speter putprintf(" jmp a0@", 0); 102018347Smckusick (void) putlab(setjmp0); 102110671Speter } 102210671Speter } 102310671Speter 102410671Speter fp_exitcode(eecookiep) 102510671Speter struct entry_exit_cookie *eecookiep; 102610671Speter { 102710671Speter /* 102810671Speter * if there were file variables declared at this level 102910671Speter * call PCLOSE( ap ) to clean them up. 103010671Speter */ 103110671Speter if ( dfiles[ cbn ] ) { 103218457Sralph putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) 103310671Speter , "_PCLOSE" ); 103418457Sralph putleaf( PCC_REG , 0 , P2AP , PCCM_ADDTYPE( PCCT_CHAR , PCCTM_PTR ) , 0 ); 103518457Sralph putop( PCC_CALL , PCCT_INT ); 103610671Speter putdot( filename , line ); 103710671Speter } 103810671Speter /* 103910671Speter * if this is a function, 104010671Speter * the function variable is the return value. 104110671Speter * if it's a scalar valued function, return scalar, 104210671Speter * else, return a pointer to the structure value. 104310671Speter */ 104410671Speter if ( eecookiep -> nlp -> class == FUNC ) { 104510671Speter struct nl *fvar = eecookiep -> nlp -> ptr[ NL_FVAR ]; 104610671Speter long fvartype = p2type( fvar -> type ); 104718347Smckusick char *label; 104810671Speter char labelname[ BUFSIZ ]; 104910671Speter 105010671Speter switch ( classify( fvar -> type ) ) { 105110671Speter case TBOOL: 105210671Speter case TCHAR: 105310671Speter case TINT: 105410671Speter case TSCAL: 105510671Speter case TDOUBLE: 105610671Speter case TPTR: 105710671Speter putRV( fvar -> symbol , ( fvar -> nl_block ) & 037 , 105810671Speter fvar -> value[ NL_OFFS ] , 105910671Speter fvar -> extra_flags , 106010671Speter fvartype ); 106118457Sralph putop( PCC_FORCE , fvartype ); 106210671Speter break; 106310671Speter default: 106410671Speter label = getlab(); 106510671Speter sprintf( labelname , PREFIXFORMAT , LABELPREFIX , label ); 106610671Speter putprintf(" .lcomm %s,%d", 0, 106710671Speter labelname, lwidth(fvar -> type)); 106818457Sralph putleaf( PCC_NAME , 0 , 0 , fvartype , labelname ); 106910671Speter putLV( fvar -> symbol , ( fvar -> nl_block ) & 037 , 107010671Speter fvar -> value[ NL_OFFS ] , 107110671Speter fvar -> extra_flags , 107210671Speter fvartype ); 107318457Sralph putstrop( PCC_STASG , PCCM_ADDTYPE(fvartype, PCCTM_PTR) , 107411857Speter lwidth( fvar -> type ) , 107510671Speter align( fvar -> type ) ); 107610671Speter putdot( filename , line ); 107718457Sralph putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE(fvartype, PCCTM_PTR), labelname ); 107818457Sralph putop( PCC_FORCE , PCCM_ADDTYPE(fvartype, PCCTM_PTR) ); 107910671Speter break; 108010671Speter } 108110671Speter putdot( filename , line ); 108210671Speter } 108310671Speter /* 108410671Speter * if we saved a display, we must restore it. 108510671Speter */ 108610671Speter if ( parts[ cbn ] & NONLOCALVAR ) { 108710671Speter /* 108810671Speter * restore old display entry from save area 108910671Speter */ 109010671Speter putprintf(" movl %s@(%d),%s+%d", 0, 109110671Speter P2FPNAME, DSAVEOFFSET, 109210671Speter DISPLAYNAME, cbn * sizeof(struct dispsave)); 109310671Speter } 109410671Speter } 109510671Speter 109610671Speter fp_epilogue(eecookiep) 109710671Speter struct entry_exit_cookie *eecookiep; 109810671Speter { 109910671Speter /* 110010671Speter * all done by the second pass. 110110671Speter */ 110210671Speter } 110310671Speter 110410671Speter fp_formalentry(eecookiep) 110510671Speter struct entry_exit_cookie *eecookiep; 110610671Speter { 110710671Speter putprintf( "%s%s:" , 0 , FORMALPREFIX , eecookiep -> extname ); 110810671Speter putprintf(" link %s,#0", 0, P2FPNAME); 110910671Speter putprintf(" addl #-%s%d,sp", 0, FRAME_SIZE_LABEL, ftnno); 111010671Speter /* touch new end of stack, to break more stack space */ 111110671Speter putprintf(" tstb sp@(-%s%d)", 0, PAGE_BREAK_LABEL, ftnno); 111210671Speter putprintf(" moveml #%s%d,sp@", 0, SAVE_MASK_LABEL, ftnno); 111318457Sralph putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) , "_FCALL" ); 111410671Speter putRV( 0 , cbn , 111510671Speter eecookiep -> nlp -> value[ NL_OFFS ] + sizeof( struct formalrtn * ) , 111618457Sralph NPARAM , PCCTM_PTR | PCCT_STRTY ); 111718457Sralph putRV(0, cbn, eecookiep -> nlp -> value[NL_OFFS], NPARAM, PCCTM_PTR|PCCT_STRTY); 111818457Sralph putop( PCC_CM , PCCT_INT ); 111918457Sralph putop( PCC_CALL , PCCT_INT ); 112010671Speter putdot( filename , line ); 112110671Speter putjbr( eecookiep -> toplabel ); 112210671Speter } 112310671Speter #endif mc68000 11243363Speter #endif PC 1125