148116Sbostic /*-
2*62209Sbostic * Copyright (c) 1980, 1993
3*62209Sbostic * The Regents of the University of California. All rights reserved.
448116Sbostic *
548116Sbostic * %sccs.include.redist.c%
622164Sdist */
73192Smckusick
818347Smckusick #ifndef lint
9*62209Sbostic static char sccsid[] = "@(#)fend.c 8.1 (Berkeley) 06/06/93";
1048116Sbostic #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 */
sextname(buffer,name,level)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
codeformain()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
codeformain()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
codeformain()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