Annotation of 42BSD/ucb/pascal/src/fend.c, revision 1.1

1.1     ! root        1: /* Copyright (c) 1979 Regents of the University of California */
        !             2: 
        !             3: static char sccsid[] = "@(#)fend.c 1.22 4/6/83";
        !             4: 
        !             5: #include "whoami.h"
        !             6: #include "0.h"
        !             7: #include "tree.h"
        !             8: #include "opcode.h"
        !             9: #include "objfmt.h"
        !            10: #include "align.h"
        !            11: #include "tmps.h"
        !            12: 
        !            13: /*
        !            14:  * this array keeps the pxp counters associated with
        !            15:  * functions and procedures, so that they can be output
        !            16:  * when their bodies are encountered
        !            17:  */
        !            18: int    bodycnts[ DSPLYSZ ];
        !            19: 
        !            20: #ifdef PC
        !            21: #   include "pc.h"
        !            22: #   include "pcops.h"
        !            23: #endif PC
        !            24: 
        !            25: #ifdef OBJ
        !            26: int    cntpatch;
        !            27: int    nfppatch;
        !            28: #endif OBJ
        !            29: 
        !            30: struct nl *Fp;
        !            31: int    pnumcnt;
        !            32: /*
        !            33:  * Funcend is called to
        !            34:  * finish a block by generating
        !            35:  * the code for the statements.
        !            36:  * It then looks for unresolved declarations
        !            37:  * of labels, procedures and functions,
        !            38:  * and cleans up the name list.
        !            39:  * For the program, it checks the
        !            40:  * semantics of the program
        !            41:  * statement (yuchh).
        !            42:  */
        !            43: funcend(fp, bundle, endline)
        !            44:        struct nl *fp;
        !            45:        int *bundle;
        !            46:        int endline;
        !            47: {
        !            48:        register struct nl *p;
        !            49:        register int i, b;
        !            50:        int var, inp, out, *blk;
        !            51:        bool chkref;
        !            52:        struct nl *iop;
        !            53:        char *cp;
        !            54:        extern int cntstat;
        !            55: #      ifdef PC
        !            56:            struct entry_exit_cookie    eecookie;
        !            57: #      endif PC
        !            58: 
        !            59:        cntstat = 0;
        !            60: /*
        !            61:  *     yyoutline();
        !            62:  */
        !            63:        if (program != NIL)
        !            64:                line = program->value[3];
        !            65:        blk = bundle[2];
        !            66:        if (fp == NIL) {
        !            67:                cbn--;
        !            68: #              ifdef PTREE
        !            69:                    nesting--;
        !            70: #              endif PTREE
        !            71:                return;
        !            72:        }
        !            73: #ifdef OBJ
        !            74:        /*
        !            75:         * Patch the branch to the
        !            76:         * entry point of the function
        !            77:         */
        !            78:        patch4(fp->value[NL_ENTLOC]);
        !            79:        /*
        !            80:         * Put out the block entrance code and the block name.
        !            81:         * HDRSZE is the number of bytes of info in the static
        !            82:         * BEG data area exclusive of the proc name. It is
        !            83:         * currently defined as:
        !            84:        /*      struct hdr {
        !            85:        /*              long framesze;  /* number of bytes of local vars */
        !            86:        /*              long nargs;     /* number of bytes of arguments */
        !            87:        /*              bool tests;     /* TRUE => perform runtime tests */
        !            88:        /*              short offset;   /* offset of procedure in source file */
        !            89:        /*              char name[1];   /* name of active procedure */
        !            90:        /*      };
        !            91:         */
        !            92: #      define HDRSZE (2 * sizeof(long) + sizeof(short) + sizeof(bool))
        !            93:        var = put(2, ((lenstr(fp->symbol,0) + HDRSZE) << 8)
        !            94:                | (cbn == 1 && opt('p') == 0 ? O_NODUMP: O_BEG), (long)0);
        !            95:            /*
        !            96:             *  output the number of bytes of arguments
        !            97:             *  this is only checked on formal calls.
        !            98:             */
        !            99:        put(2, O_CASE4, cbn == 1 ? (long)0 : (long)(fp->value[NL_OFFS]-DPOFF2));
        !           100:            /*
        !           101:             *  Output the runtime test mode for the routine
        !           102:             */
        !           103:        put(2, sizeof(bool) == 2 ? O_CASE2 : O_CASE4, opt('t') ? TRUE : FALSE);
        !           104:            /*
        !           105:             *  Output line number and routine name
        !           106:             */
        !           107:        put(2, O_CASE2, bundle[1]);
        !           108:        putstr(fp->symbol, 0);
        !           109: #endif OBJ
        !           110: #ifdef PC
        !           111:        /*
        !           112:         * put out the procedure entry code
        !           113:         */
        !           114:        eecookie.nlp = fp;
        !           115:        if ( fp -> class == PROG ) {
        !           116:                /*
        !           117:                 *      If there is a label declaration in the main routine
        !           118:                 *      then there may be a non-local goto to it that does
        !           119:                 *      not appear in this module. We have to assume that
        !           120:                 *      such a reference may occur and generate code to
        !           121:                 *      prepare for it.
        !           122:                 */
        !           123:            if ( parts[ cbn ] & LPRT ) {
        !           124:                parts[ cbn ] |= ( NONLOCALVAR | NONLOCALGOTO );
        !           125:            }
        !           126:            codeformain();
        !           127:            ftnno = fp -> value[NL_ENTLOC];
        !           128:            prog_prologue(&eecookie);
        !           129:            stabfunc( "program" , fp -> class , bundle[1] , 0 );
        !           130:        } else {
        !           131:            ftnno = fp -> value[NL_ENTLOC];
        !           132:            fp_prologue(&eecookie);
        !           133:            stabfunc( fp -> symbol , fp -> class , bundle[1] , cbn - 1 );
        !           134:            for ( p = fp -> chain ; p != NIL ; p = p -> chain ) {
        !           135:                stabparam( p -> symbol , p2type( p -> type )
        !           136:                            , p -> value[ NL_OFFS ] , lwidth( p -> type ) );
        !           137:            }
        !           138:            if ( fp -> class == FUNC ) {
        !           139:                    /*
        !           140:                     *  stab the function variable
        !           141:                     */
        !           142:                p = fp -> ptr[ NL_FVAR ];
        !           143:                stablvar( p -> symbol , p2type( p -> type ) , cbn 
        !           144:                        , p -> value[ NL_OFFS ] , lwidth( p -> type ) );
        !           145:            }
        !           146:                /*
        !           147:                 *      stab local variables
        !           148:                 *      rummage down hash chain links.
        !           149:                 */
        !           150:            for ( i = 0 ; i <= 077 ; i++ ) {
        !           151:                for ( p = disptab[ i ] ; p != NIL ; p = p->nl_next) {
        !           152:                    if ( ( p -> nl_block & 037 ) != cbn ) {
        !           153:                        break;
        !           154:                    }
        !           155:                    /*
        !           156:                     *  stab local variables
        !           157:                     *  that's named variables, but not params
        !           158:                     */
        !           159:                    if (   ( p -> symbol != NIL ) 
        !           160:                        && ( p -> class == VAR )
        !           161:                        && ( p -> value[ NL_OFFS ] < 0 ) ) {
        !           162:                        stablvar( p -> symbol , p2type( p -> type ) , cbn 
        !           163:                            , p -> value[ NL_OFFS ] , lwidth( p -> type ) );
        !           164:                    }
        !           165:                }
        !           166:            }
        !           167:        }
        !           168:        stablbrac( cbn );
        !           169:            /*
        !           170:             *  ask second pass to allocate known locals
        !           171:             */
        !           172:        putlbracket(ftnno, &sizes[cbn]);
        !           173:        fp_entrycode(&eecookie);
        !           174: #endif PC
        !           175:        if ( monflg ) {
        !           176:                if ( fp -> value[ NL_CNTR ] != 0 ) {
        !           177:                        inccnt( fp -> value [ NL_CNTR ] );
        !           178:                }
        !           179:                inccnt( bodycnts[ fp -> nl_block & 037 ] );
        !           180:        }
        !           181:        if (fp->class == PROG) {
        !           182:                /*
        !           183:                 * The glorious buffers option.
        !           184:                 *          0 = don't buffer output
        !           185:                 *          1 = line buffer output
        !           186:                 *          2 = 512 byte buffer output
        !           187:                 */
        !           188: #              ifdef OBJ
        !           189:                    if (opt('b') != 1)
        !           190:                            put(1, O_BUFF | opt('b') << 8);
        !           191: #              endif OBJ
        !           192: #              ifdef PC
        !           193:                    if ( opt( 'b' ) != 1 ) {
        !           194:                        putleaf( P2ICON , 0 , 0
        !           195:                                , ADDTYPE( P2FTN | P2INT , P2PTR ) , "_BUFF" );
        !           196:                        putleaf( P2ICON , opt( 'b' ) , 0 , P2INT , 0 );
        !           197:                        putop( P2CALL , P2INT );
        !           198:                        putdot( filename , line );
        !           199:                    }
        !           200: #              endif PC
        !           201:                inp = 0;
        !           202:                out = 0;
        !           203:                for (p = fp->chain; p != NIL; p = p->chain) {
        !           204:                        if (strcmp(p->symbol, input->symbol) == 0) {
        !           205:                                inp++;
        !           206:                                continue;
        !           207:                        }
        !           208:                        if (strcmp(p->symbol, output->symbol) == 0) {
        !           209:                                out++;
        !           210:                                continue;
        !           211:                        }
        !           212:                        iop = lookup1(p->symbol);
        !           213:                        if (iop == NIL || bn != cbn) {
        !           214:                                error("File %s listed in program statement but not declared", p->symbol);
        !           215:                                continue;
        !           216:                        }
        !           217:                        if (iop->class != VAR) {
        !           218:                                error("File %s listed in program statement but declared as a %s", p->symbol, classes[iop->class]);
        !           219:                                continue;
        !           220:                        }
        !           221:                        if (iop->type == NIL)
        !           222:                                continue;
        !           223:                        if (iop->type->class != FILET) {
        !           224:                                error("File %s listed in program statement but defined as %s",
        !           225:                                        p->symbol, nameof(iop->type));
        !           226:                                continue;
        !           227:                        }
        !           228: #                      ifdef OBJ
        !           229:                            put(2, O_CON24, text(iop->type) ? 0 : width(iop->type->type));
        !           230:                            i = lenstr(p->symbol,0);
        !           231:                            put(2, O_CON24, i);
        !           232:                            put(2, O_LVCON, i);
        !           233:                            putstr(p->symbol, 0);
        !           234:                            put(2, O_LV | bn<<8+INDX, (int)iop->value[NL_OFFS]);
        !           235:                            put(1, O_DEFNAME);
        !           236: #                      endif OBJ
        !           237: #                      ifdef PC
        !           238:                            putleaf( P2ICON , 0 , 0
        !           239:                                    , ADDTYPE( P2FTN | P2INT , P2PTR )
        !           240:                                    , "_DEFNAME" );
        !           241:                            putLV( p -> symbol , bn , iop -> value[NL_OFFS] ,
        !           242:                                    iop -> extra_flags , p2type( iop ) );
        !           243:                            putCONG( p -> symbol , strlen( p -> symbol )
        !           244:                                    , LREQ );
        !           245:                            putop( P2LISTOP , P2INT );
        !           246:                            putleaf( P2ICON , strlen( p -> symbol )
        !           247:                                    , 0 , P2INT , 0 );
        !           248:                            putop( P2LISTOP , P2INT );
        !           249:                            putleaf( P2ICON
        !           250:                                , text(iop->type) ? 0 : width(iop->type->type)
        !           251:                                , 0 , P2INT , 0 );
        !           252:                            putop( P2LISTOP , P2INT );
        !           253:                            putop( P2CALL , P2INT );
        !           254:                            putdot( filename , line );
        !           255: #                      endif PC
        !           256:                }
        !           257:        }
        !           258:        /*
        !           259:         * Process the prog/proc/func body
        !           260:         */
        !           261:        noreach = 0;
        !           262:        line = bundle[1];
        !           263:        statlist(blk);
        !           264: #      ifdef PTREE
        !           265:            {
        !           266:                pPointer Body = tCopy( blk );
        !           267: 
        !           268:                pDEF( PorFHeader[ nesting -- ] ).PorFBody = Body;
        !           269:            }
        !           270: #      endif PTREE
        !           271: #      ifdef OBJ
        !           272:            if (cbn== 1 && monflg != 0) {
        !           273:                    patchfil(cntpatch - 2, (long)cnts, 2);
        !           274:                    patchfil(nfppatch - 2, (long)pfcnt, 2);
        !           275:            }
        !           276: #      endif OBJ
        !           277: #      ifdef PC
        !           278:            if ( fp -> class == PROG && monflg ) {
        !           279:                putleaf( P2ICON , 0 , 0 , ADDTYPE( P2FTN | P2INT , P2PTR )
        !           280:                        , "_PMFLUSH" );
        !           281:                putleaf( P2ICON , cnts , 0 , P2INT , 0 );
        !           282:                putleaf( P2ICON , pfcnt , 0 , P2INT , 0 );
        !           283:                putop( P2LISTOP , P2INT );
        !           284:                putLV( PCPCOUNT , 0 , 0 , NGLOBAL , P2INT );
        !           285:                putop( P2LISTOP , P2INT );
        !           286:                putop( P2CALL , P2INT );
        !           287:                putdot( filename , line );
        !           288:            }
        !           289: #      endif PC
        !           290:        /*
        !           291:         * Clean up the symbol table displays and check for unresolves
        !           292:         */
        !           293:        line = endline;
        !           294:        if (fp->class == PROG && inp == 0 && (input->nl_flags & (NUSED|NMOD)) != 0) {
        !           295:                recovered();
        !           296:                error("Input is used but not defined in the program statement");
        !           297:        }
        !           298:        if (fp->class == PROG && out == 0 && (output->nl_flags & (NUSED|NMOD)) != 0) {
        !           299:                recovered();
        !           300:                error("Output is used but not defined in the program statement");
        !           301:        }
        !           302:        b = cbn;
        !           303:        Fp = fp;
        !           304:        chkref = syneflg == errcnt[cbn] && opt('w') == 0;
        !           305:        for (i = 0; i <= 077; i++) {
        !           306:                for (p = disptab[i]; p != NIL && (p->nl_block & 037) == b; p = p->nl_next) {
        !           307:                        /*
        !           308:                         * Check for variables defined
        !           309:                         * but not referenced 
        !           310:                         */
        !           311:                        if (chkref && p->symbol != NIL)
        !           312:                        switch (p->class) {
        !           313:                                case FIELD:
        !           314:                                        /*
        !           315:                                         * If the corresponding record is
        !           316:                                         * unused, we shouldn't complain about
        !           317:                                         * the fields.
        !           318:                                         */
        !           319:                                default:
        !           320:                                        if ((p->nl_flags & (NUSED|NMOD)) == 0) {
        !           321:                                                warning();
        !           322:                                                nerror("%s %s is neither used nor set", classes[p->class], p->symbol);
        !           323:                                                break;
        !           324:                                        }
        !           325:                                        /*
        !           326:                                         * If a var parameter is either
        !           327:                                         * modified or used that is enough.
        !           328:                                         */
        !           329:                                        if (p->class == REF)
        !           330:                                                continue;
        !           331: #                                      ifdef OBJ
        !           332:                                            if ((p->nl_flags & NUSED) == 0) {
        !           333:                                                warning();
        !           334:                                                nerror("%s %s is never used", classes[p->class], p->symbol);
        !           335:                                                break;
        !           336:                                            }
        !           337: #                                      endif OBJ
        !           338: #                                      ifdef PC
        !           339:                                            if (((p->nl_flags & NUSED) == 0) && ((p->extra_flags & NEXTERN) == 0)) {
        !           340:                                                warning();
        !           341:                                                nerror("%s %s is never used", classes[p->class], p->symbol);
        !           342:                                                break;
        !           343:                                            }
        !           344: #                                      endif PC
        !           345:                                        if ((p->nl_flags & NMOD) == 0) {
        !           346:                                                warning();
        !           347:                                                nerror("%s %s is used but never set", classes[p->class], p->symbol);
        !           348:                                                break;
        !           349:                                        }
        !           350:                                case LABEL:
        !           351:                                case FVAR:
        !           352:                                case BADUSE:
        !           353:                                        break;
        !           354:                        }
        !           355:                        switch (p->class) {
        !           356:                                case BADUSE:
        !           357:                                        cp = "s";
        !           358:                                        if (p->chain->ud_next == NIL)
        !           359:                                                cp++;
        !           360:                                        eholdnl();
        !           361:                                        if (p->value[NL_KINDS] & ISUNDEF)
        !           362:                                                nerror("%s undefined on line%s", p->symbol, cp);
        !           363:                                        else
        !           364:                                                nerror("%s improperly used on line%s", p->symbol, cp);
        !           365:                                        pnumcnt = 10;
        !           366:                                        pnums(p->chain);
        !           367:                                        pchr('\n');
        !           368:                                        break;
        !           369: 
        !           370:                                case FUNC:
        !           371:                                case PROC:
        !           372: #                                      ifdef OBJ
        !           373:                                            if ((p->nl_flags & NFORWD))
        !           374:                                                nerror("Unresolved forward declaration of %s %s", classes[p->class], p->symbol);
        !           375: #                                      endif OBJ
        !           376: #                                      ifdef PC
        !           377:                                            if ((p->nl_flags & NFORWD) && ((p->extra_flags & NEXTERN) == 0))
        !           378:                                                nerror("Unresolved forward declaration of %s %s", classes[p->class], p->symbol);
        !           379: #                                      endif PC
        !           380:                                        break;
        !           381: 
        !           382:                                case LABEL:
        !           383:                                        if (p->nl_flags & NFORWD)
        !           384:                                                nerror("label %s was declared but not defined", p->symbol);
        !           385:                                        break;
        !           386:                                case FVAR:
        !           387:                                        if ((p->nl_flags & NMOD) == 0)
        !           388:                                                nerror("No assignment to the function variable");
        !           389:                                        break;
        !           390:                        }
        !           391:                }
        !           392:                /*
        !           393:                 * Pop this symbol
        !           394:                 * table slot
        !           395:                 */
        !           396:                disptab[i] = p;
        !           397:        }
        !           398: 
        !           399: #      ifdef OBJ
        !           400:            put(1, O_END);
        !           401: #      endif OBJ
        !           402: #      ifdef PC
        !           403:            fp_exitcode(&eecookie);
        !           404:            stabrbrac(cbn);
        !           405:            putrbracket(ftnno);
        !           406:            fp_epilogue(&eecookie);
        !           407:            if (fp -> class != PROG) {
        !           408:                fp_formalentry(&eecookie);
        !           409:            }
        !           410:                /*
        !           411:                 *      declare pcp counters, if any
        !           412:                 */
        !           413:            if ( monflg && fp -> class == PROG ) {
        !           414:                putprintf( "    .data" , 0 );
        !           415:                aligndot(P2INT);
        !           416:                putprintf( "    .comm   " , 1 );
        !           417:                putprintf( PCPCOUNT , 1 );
        !           418:                putprintf( ",%d" , 0 , ( cnts + 1 ) * sizeof (long) );
        !           419:                putprintf( "    .text" , 0 );
        !           420:            }
        !           421: #      endif PC
        !           422: #ifdef DEBUG
        !           423:        dumpnl(fp->ptr[2], fp->symbol);
        !           424: #endif
        !           425: 
        !           426: #ifdef OBJ
        !           427:        /*
        !           428:         * save the namelist for the debugger pdx
        !           429:         */
        !           430: 
        !           431:        savenl(fp->ptr[2], fp->symbol);
        !           432: #endif
        !           433: 
        !           434:        /*
        !           435:         * Restore the
        !           436:         * (virtual) name list
        !           437:         * position
        !           438:         */
        !           439:        nlfree(fp->ptr[2]);
        !           440:        /*
        !           441:         * Proc/func has been
        !           442:         * resolved
        !           443:         */
        !           444:        fp->nl_flags &= ~NFORWD;
        !           445:        /*
        !           446:         * Patch the beg
        !           447:         * of the proc/func to
        !           448:         * the proper variable size
        !           449:         */
        !           450:        if (Fp == NIL)
        !           451:                elineon();
        !           452: #      ifdef OBJ
        !           453:            patchfil(var, leven(-sizes[cbn].om_max), 2);
        !           454: #      endif OBJ
        !           455:        cbn--;
        !           456:        if (inpflist(fp->symbol)) {
        !           457:                opop('l');
        !           458:        }
        !           459: }
        !           460: 
        !           461: #ifdef PC
        !           462:     /*
        !           463:      * construct the long name of a function based on it's static nesting.
        !           464:      * into a caller-supplied buffer (that should be about BUFSIZ big).
        !           465:      */
        !           466: sextname( buffer , name , level )
        !           467:     char       buffer[];
        !           468:     char       *name;
        !           469:     int                level;
        !           470: {
        !           471:     char       *starthere;
        !           472:     int        i;
        !           473: 
        !           474:     starthere = &buffer[0];
        !           475:     for ( i = 1 ; i < level ; i++ ) {
        !           476:        sprintf( starthere , EXTFORMAT , enclosing[ i ] );
        !           477:        starthere += strlen( enclosing[ i ] ) + 1;
        !           478:     }
        !           479:     sprintf( starthere , EXTFORMAT , name );
        !           480:     starthere += strlen( name ) + 1;
        !           481:     if ( starthere >= &buffer[ BUFSIZ ] ) {
        !           482:        panic( "sextname" );
        !           483:     }
        !           484: }
        !           485: 
        !           486:     /*
        !           487:      * code for main()
        !           488:      */
        !           489: #ifdef vax
        !           490: 
        !           491: codeformain()
        !           492: {
        !           493:     putprintf("        .text" , 0 );
        !           494:     putprintf("        .align  1" , 0 );
        !           495:     putprintf("        .globl  _main" , 0 );
        !           496:     putprintf("_main:" , 0 );
        !           497:     putprintf("        .word   0" , 0 );
        !           498:     if ( opt ( 't' ) ) {
        !           499:        putprintf("     pushl   $1" , 0 );
        !           500:     } else {
        !           501:        putprintf("     pushl   $0" , 0 );
        !           502:     }
        !           503:     putprintf("        calls   $1,_PCSTART" , 0 );
        !           504:     putprintf("        movl    4(ap),__argc" , 0 );
        !           505:     putprintf("        movl    8(ap),__argv" , 0 );
        !           506:     putprintf("        calls   $0,_program" , 0 );
        !           507:     putprintf("        pushl   $0" , 0 );
        !           508:     putprintf("        calls   $1,_PCEXIT" , 0 );
        !           509: }
        !           510: 
        !           511:     /*
        !           512:      * prologue for the program.
        !           513:      * different because it
        !           514:      *         doesn't have formal entry point
        !           515:      */
        !           516: prog_prologue(eecookiep)
        !           517:     struct entry_exit_cookie   *eecookiep;
        !           518: {
        !           519:     putprintf("        .text" , 0 );
        !           520:     putprintf("        .align  1" , 0 );
        !           521:     putprintf("        .globl  _program" , 0 );
        !           522:     putprintf("_program:" , 0 );
        !           523:        /*
        !           524:         *      register save mask
        !           525:         */
        !           526:     eecookiep -> savlabel = getlab();
        !           527:     putprintf("        .word   %s%d", 0, SAVE_MASK_LABEL , eecookiep -> savlabel );
        !           528: }
        !           529: 
        !           530: fp_prologue(eecookiep)
        !           531:     struct entry_exit_cookie   *eecookiep;
        !           532: {
        !           533:     int                ftnno = eecookiep -> nlp -> value[NL_ENTLOC];
        !           534: 
        !           535:     sextname( eecookiep -> extname, eecookiep -> nlp -> symbol , cbn - 1 );
        !           536:     putprintf( "       .text" , 0 );
        !           537:     putprintf( "       .align  1" , 0 );
        !           538:     putprintf( "       .globl  %s%s", 0, FORMALPREFIX, eecookiep -> extname );
        !           539:     putprintf( "       .globl  %s" , 0 , eecookiep -> extname );
        !           540:     putprintf( "%s:" , 0 , eecookiep -> extname );
        !           541:        /*
        !           542:         *      register save mask
        !           543:         */
        !           544:     eecookiep -> savlabel = getlab();
        !           545:     putprintf("        .word   %s%d", 0, SAVE_MASK_LABEL , eecookiep -> savlabel );
        !           546: }
        !           547: 
        !           548:     /*
        !           549:      * code before any user code.
        !           550:      * or code that is machine dependent.
        !           551:      */
        !           552: fp_entrycode(eecookiep)
        !           553:     struct entry_exit_cookie   *eecookiep;
        !           554: {
        !           555:     int        ftnno = eecookiep -> nlp -> value[NL_ENTLOC];
        !           556:     int        proflabel = getlab();
        !           557:     int        setjmp0 = getlab();
        !           558: 
        !           559:        /*
        !           560:         *      top of code;  destination of jump from formal entry code.
        !           561:         */
        !           562:     eecookiep -> toplabel = getlab();
        !           563:     putlab( eecookiep -> toplabel );
        !           564:     putprintf("        subl2   $%s%d,sp" , 0 , FRAME_SIZE_LABEL, ftnno );
        !           565:     if ( profflag ) {
        !           566:            /*
        !           567:             *  call mcount for profiling
        !           568:             */
        !           569:        putprintf( "    moval   " , 1 );
        !           570:        putprintf( PREFIXFORMAT , 1 , LABELPREFIX , proflabel );
        !           571:        putprintf( ",r0" , 0 );
        !           572:        putprintf( "    jsb     mcount" , 0 );
        !           573:        putprintf( "    .data" , 0 );
        !           574:        putprintf( "    .align  2" , 0 );
        !           575:        putlab( proflabel );
        !           576:        putprintf( "    .long   0" , 0 );
        !           577:        putprintf( "    .text" , 0 );
        !           578:     }
        !           579:        /*
        !           580:         *      if there are nested procedures that access our variables
        !           581:         *      we must save the display.
        !           582:         */
        !           583:     if ( parts[ cbn ] & NONLOCALVAR ) {
        !           584:            /*
        !           585:             *  save old display 
        !           586:             */
        !           587:        putprintf( "    movq    %s+%d,%d(%s)" , 0
        !           588:                , DISPLAYNAME , cbn * sizeof(struct dispsave)
        !           589:                , DSAVEOFFSET , P2FPNAME );
        !           590:            /*
        !           591:             *  set up new display by saving AP and FP in appropriate
        !           592:             *  slot in display structure.
        !           593:             */
        !           594:        putprintf( "    movq    %s,%s+%d" , 0
        !           595:                , P2APNAME , DISPLAYNAME , cbn * sizeof(struct dispsave) );
        !           596:     }
        !           597:        /*
        !           598:         *      set underflow checking if runtime tests
        !           599:         */
        !           600:     if ( opt( 't' ) ) {
        !           601:        putprintf( "    bispsw  $0xe0" , 0 );
        !           602:     }
        !           603:        /*
        !           604:         *      zero local variables if checking is on
        !           605:         *      by calling blkclr( bytes of locals , starting local address );
        !           606:         */
        !           607:     if ( opt( 't' ) && ( -sizes[ cbn ].om_max ) > DPOFF1 ) {
        !           608:        putleaf( P2ICON , 0 , 0 , ADDTYPE( P2FTN | P2INT , P2PTR )
        !           609:                , "_blkclr" );
        !           610:        putLV( 0 , cbn , sizes[ cbn ].om_max , NLOCAL , P2CHAR );
        !           611:        putleaf( P2ICON ,  ( -sizes[ cbn ].om_max ) - DPOFF1
        !           612:                , 0 , P2INT , 0 );
        !           613:        putop( P2LISTOP , P2INT );
        !           614:        putop( P2CALL , P2INT );
        !           615:        putdot( filename , line );
        !           616:     }
        !           617:        /*
        !           618:         *  set up goto vector if non-local goto to this frame
        !           619:         */
        !           620:     if ( parts[ cbn ] & NONLOCALGOTO ) {
        !           621:        putleaf( P2ICON , 0 , 0 , ADDTYPE( P2FTN | P2INT , P2PTR )
        !           622:                , "_setjmp" );
        !           623:        putLV( 0 , cbn , GOTOENVOFFSET , NLOCAL , P2PTR|P2STRTY );
        !           624:        putop( P2CALL , P2INT );
        !           625:        putleaf( P2ICON , 0 , 0 , P2INT , 0 );
        !           626:        putop( P2NE , P2INT );
        !           627:        putleaf( P2ICON , setjmp0 , 0 , P2INT , 0 );
        !           628:        putop( P2CBRANCH , P2INT );
        !           629:        putdot( filename , line );
        !           630:            /*
        !           631:             *  on non-local goto, setjmp returns with address to
        !           632:             *  be branched to.
        !           633:             */
        !           634:        putprintf( "    jmp     (r0)" , 0 );
        !           635:        putlab(setjmp0);
        !           636:     }
        !           637: }
        !           638: 
        !           639: fp_exitcode(eecookiep)
        !           640:     struct entry_exit_cookie   *eecookiep;
        !           641: {
        !           642:        /*
        !           643:         *      if there were file variables declared at this level
        !           644:         *      call PCLOSE( ap ) to clean them up.
        !           645:         */
        !           646:     if ( dfiles[ cbn ] ) {
        !           647:        putleaf( P2ICON , 0 , 0 , ADDTYPE( P2FTN | P2INT , P2PTR )
        !           648:                , "_PCLOSE" );
        !           649:        putleaf( P2REG , 0 , P2AP , ADDTYPE( P2CHAR , P2PTR ) , 0 );
        !           650:        putop( P2CALL , P2INT );
        !           651:        putdot( filename , line );
        !           652:     }
        !           653:        /*
        !           654:         *      if this is a function,
        !           655:         *      the function variable is the return value.
        !           656:         *      if it's a scalar valued function, return scalar,
        !           657:         *      else, return a pointer to the structure value.
        !           658:         */
        !           659:     if ( eecookiep-> nlp -> class == FUNC ) {
        !           660:        struct nl       *fvar = eecookiep-> nlp -> ptr[ NL_FVAR ];
        !           661:        long            fvartype = p2type( fvar -> type );
        !           662:        long            label;
        !           663:        char            labelname[ BUFSIZ ];
        !           664: 
        !           665:        switch ( classify( fvar -> type ) ) {
        !           666:            case TBOOL:
        !           667:            case TCHAR:
        !           668:            case TINT:
        !           669:            case TSCAL:
        !           670:            case TDOUBLE:
        !           671:            case TPTR:
        !           672:                putRV( fvar -> symbol , ( fvar -> nl_block ) & 037 ,
        !           673:                        fvar -> value[ NL_OFFS ] ,
        !           674:                        fvar -> extra_flags ,
        !           675:                        fvartype );
        !           676:                putop( P2FORCE , fvartype );
        !           677:                break;
        !           678:            default:
        !           679:                label = getlab();
        !           680:                sprintf( labelname , PREFIXFORMAT , LABELPREFIX , label );
        !           681:                putprintf( "    .data" , 0 );
        !           682:                aligndot(A_STRUCT);
        !           683:                putprintf( "    .lcomm  %s,%d" , 0 ,
        !           684:                            labelname , lwidth( fvar -> type ) );
        !           685:                putprintf( "    .text" , 0 );
        !           686:                putleaf( P2NAME , 0 , 0 , fvartype , labelname );
        !           687:                putLV( fvar -> symbol , ( fvar -> nl_block ) & 037 ,
        !           688:                        fvar -> value[ NL_OFFS ] ,
        !           689:                        fvar -> extra_flags ,
        !           690:                        fvartype );
        !           691:                putstrop( P2STASG , ADDTYPE(fvartype, P2PTR) ,
        !           692:                        lwidth( fvar -> type ) ,
        !           693:                        align( fvar -> type ) );
        !           694:                putdot( filename , line );
        !           695:                putleaf( P2ICON , 0 , 0 , ADDTYPE(fvartype, P2PTR), labelname );
        !           696:                putop( P2FORCE , ADDTYPE(fvartype, P2PTR) );
        !           697:                break;
        !           698:        }
        !           699:        putdot( filename , line );
        !           700:     }
        !           701:        /*
        !           702:         *      if there are nested procedures we must save the display.
        !           703:         */
        !           704:     if ( parts[ cbn ] & NONLOCALVAR ) {
        !           705:            /*
        !           706:             *  restore old display entry from save area
        !           707:             */
        !           708:        putprintf( "    movq    %d(%s),%s+%d" , 0
        !           709:            , DSAVEOFFSET , P2FPNAME
        !           710:            , DISPLAYNAME , cbn * sizeof(struct dispsave) );
        !           711:     }
        !           712: }
        !           713: 
        !           714: fp_epilogue(eecookiep)
        !           715:     struct entry_exit_cookie   *eecookiep;
        !           716: {
        !           717:     putprintf("        ret" , 0 );
        !           718:        /*
        !           719:         *      set the register save mask.
        !           720:         */
        !           721:     putprintf("        .set    %s%d,0x%x", 0,
        !           722:                SAVE_MASK_LABEL, eecookiep -> savlabel, savmask());
        !           723: }
        !           724: 
        !           725: fp_formalentry(eecookiep)
        !           726:     struct entry_exit_cookie   *eecookiep;
        !           727: {
        !           728: 
        !           729:     putprintf("        .align 1", 0);
        !           730:     putprintf("%s%s:" , 0 , FORMALPREFIX , eecookiep -> extname );
        !           731:     putprintf("        .word   %s%d", 0, SAVE_MASK_LABEL, eecookiep -> savlabel );
        !           732:     putleaf( P2ICON , 0 , 0 , ADDTYPE( P2FTN | P2INT , P2PTR ) , "_FCALL" );
        !           733:     putRV( 0 , cbn ,
        !           734:        eecookiep -> nlp -> value[ NL_OFFS ] + sizeof( struct formalrtn * ) ,
        !           735:        NPARAM , P2PTR | P2STRTY );
        !           736:     putRV(0, cbn, eecookiep -> nlp -> value[NL_OFFS], NPARAM, P2PTR|P2STRTY);
        !           737:     putop( P2LISTOP , P2INT );
        !           738:     putop( P2CALL , P2INT );
        !           739:     putdot( filename , line );
        !           740:     putjbr( eecookiep -> toplabel );
        !           741: }
        !           742: #endif vax
        !           743: 
        !           744: #ifdef mc68000
        !           745: 
        !           746: codeformain()
        !           747: {
        !           748:     putprintf("        .text", 0);
        !           749:     putprintf("        .globl  _main", 0);
        !           750:     putprintf("_main:", 0);
        !           751:     putprintf("        link    %s,#0", 0, P2FPNAME);
        !           752:     if (opt('t')) {
        !           753:        putprintf("     pea     1", 0);
        !           754:     } else {
        !           755:        putprintf("     pea     0", 0);
        !           756:     }
        !           757:     putprintf("        jbsr    _PCSTART", 0);
        !           758:     putprintf("        addql   #4,sp", 0);
        !           759:     putprintf("        movl    %s@(8),__argc", 0, P2FPNAME);
        !           760:     putprintf("        movl    %s@(12),__argv", 0, P2FPNAME);
        !           761:     putprintf("        jbsr    _program", 0);
        !           762:     putprintf("        pea     0", 0);
        !           763:     putprintf("        jbsr    _PCEXIT", 0);
        !           764: }
        !           765: 
        !           766: prog_prologue(eecookiep)
        !           767:     struct entry_exit_cookie   *eecookiep;
        !           768: {
        !           769:     int        ftnno = eecookiep -> nlp -> value[NL_ENTLOC];
        !           770: 
        !           771:     putprintf("        .text", 0);
        !           772:     putprintf("        .globl  _program", 0);
        !           773:     putprintf("_program:", 0);
        !           774:     putprintf("        link    %s,#0", 0, P2FPNAME);
        !           775:     putprintf("        addl    #-%s%d,sp", 0, FRAME_SIZE_LABEL, ftnno);
        !           776:        /* touch new end of stack, to break more stack space */
        !           777:     putprintf("        tstb    sp@(-%s%d)", 0, PAGE_BREAK_LABEL, ftnno);
        !           778:     putprintf("        moveml  #%s%d,sp@", 0, SAVE_MASK_LABEL, ftnno);
        !           779: }
        !           780: 
        !           781: fp_prologue(eecookiep)
        !           782:     struct entry_exit_cookie   *eecookiep;
        !           783: {
        !           784:     int                ftnno = eecookiep -> nlp -> value[NL_ENTLOC];
        !           785: 
        !           786:     sextname(eecookiep -> extname, eecookiep -> nlp -> symbol, cbn - 1);
        !           787:     putprintf("        .text", 0);
        !           788:     putprintf("        .globl  %s%s", 0, FORMALPREFIX, eecookiep -> extname);
        !           789:     putprintf("        .globl  %s", 0, eecookiep -> extname);
        !           790:     putprintf("%s:", 0, eecookiep -> extname);
        !           791:     putprintf("        link    %s,#0", 0, P2FPNAME);
        !           792:     putprintf("        addl    #-%s%d,sp", 0, FRAME_SIZE_LABEL, ftnno);
        !           793:        /* touch new end of stack, to break more stack space */
        !           794:     putprintf("        tstb    sp@(-%s%d)", 0, PAGE_BREAK_LABEL, ftnno);
        !           795:     putprintf("        moveml  #%s%d,sp@", 0, SAVE_MASK_LABEL, ftnno);
        !           796: }
        !           797: 
        !           798: fp_entrycode(eecookiep)
        !           799:     struct entry_exit_cookie   *eecookiep;
        !           800: {
        !           801:     int        proflabel = getlab();
        !           802:     int        setjmp0 = getlab();
        !           803: 
        !           804:        /*
        !           805:         *      fill in the label cookie
        !           806:         */
        !           807:     eecookiep -> toplabel = getlab();
        !           808:     putlab(eecookiep -> toplabel);
        !           809:        /*
        !           810:         *      call mcount if we are profiling.
        !           811:         */
        !           812:     if ( profflag ) {
        !           813:        putprintf("     movl    #%s%d,a0", 0, LABELPREFIX,  proflabel);
        !           814:        putprintf("     jsr     mcount", 0);
        !           815:        putprintf("     .data", 0);
        !           816:        putprintf("     .even", 0);
        !           817:        putlab(proflabel);
        !           818:        putprintf("     .long   0", 0);
        !           819:        putprintf("     .text", 0);
        !           820:     }
        !           821:        /*
        !           822:         *      if there are nested procedures that access our variables
        !           823:         *      we must save the display
        !           824:         */
        !           825:     if (parts[cbn] & NONLOCALVAR) {
        !           826:            /*
        !           827:             *  save the old display
        !           828:             */
        !           829:        putprintf("     movl    %s+%d,%s@(%d)", 0,
        !           830:                    DISPLAYNAME, cbn * sizeof(struct dispsave),
        !           831:                    P2FPNAME, DSAVEOFFSET);
        !           832:            /*
        !           833:             *  set up the new display by saving the framepointer
        !           834:             *  in the display structure.
        !           835:             */
        !           836:        putprintf("     movl    %s,%s+%d", 0,
        !           837:                    P2FPNAME, DISPLAYNAME, cbn * sizeof(struct dispsave));
        !           838:     }
        !           839:        /*
        !           840:         *      zero local variables if checking is on
        !           841:         *      by calling blkclr( bytes of locals , starting local address );
        !           842:         */
        !           843:     if ( opt( 't' ) && ( -sizes[ cbn ].om_max ) > DPOFF1 ) {
        !           844:        putleaf( P2ICON , 0 , 0 , ADDTYPE( P2FTN | P2INT , P2PTR )
        !           845:                , "_blkclr" );
        !           846:        putLV( 0 , cbn , sizes[ cbn ].om_max , NLOCAL , P2CHAR );
        !           847:        putleaf( P2ICON ,  ( -sizes[ cbn ].om_max ) - DPOFF1
        !           848:                , 0 , P2INT , 0 );
        !           849:        putop( P2LISTOP , P2INT );
        !           850:        putop( P2CALL , P2INT );
        !           851:        putdot( filename , line );
        !           852:     }
        !           853:        /*
        !           854:         *  set up goto vector if non-local goto to this frame
        !           855:         */
        !           856:     if ( parts[ cbn ] & NONLOCALGOTO ) {
        !           857:        putleaf( P2ICON , 0 , 0 , ADDTYPE( P2FTN | P2INT , P2PTR )
        !           858:                , "_setjmp" );
        !           859:        putLV( 0 , cbn , GOTOENVOFFSET , NLOCAL , P2PTR|P2STRTY );
        !           860:        putop( P2CALL , P2INT );
        !           861:        putleaf( P2ICON , 0 , 0 , P2INT , 0 );
        !           862:        putop( P2NE , P2INT );
        !           863:        putleaf( P2ICON , setjmp0 , 0 , P2INT , 0 );
        !           864:        putop( P2CBRANCH , P2INT );
        !           865:        putdot( filename , line );
        !           866:            /*
        !           867:             *  on non-local goto, setjmp returns with address to
        !           868:             *  be branched to.
        !           869:             */
        !           870:        putprintf("     movl    d0,a0", 0);
        !           871:        putprintf("     jmp     a0@", 0);
        !           872:        putlab(setjmp0);
        !           873:     }
        !           874: }
        !           875: 
        !           876: fp_exitcode(eecookiep)
        !           877:     struct entry_exit_cookie   *eecookiep;
        !           878: {
        !           879:        /*
        !           880:         *      if there were file variables declared at this level
        !           881:         *      call PCLOSE( ap ) to clean them up.
        !           882:         */
        !           883:     if ( dfiles[ cbn ] ) {
        !           884:        putleaf( P2ICON , 0 , 0 , ADDTYPE( P2FTN | P2INT , P2PTR )
        !           885:                , "_PCLOSE" );
        !           886:        putleaf( P2REG , 0 , P2AP , ADDTYPE( P2CHAR , P2PTR ) , 0 );
        !           887:        putop( P2CALL , P2INT );
        !           888:        putdot( filename , line );
        !           889:     }
        !           890:        /*
        !           891:         *      if this is a function,
        !           892:         *      the function variable is the return value.
        !           893:         *      if it's a scalar valued function, return scalar,
        !           894:         *      else, return a pointer to the structure value.
        !           895:         */
        !           896:     if ( eecookiep -> nlp -> class == FUNC ) {
        !           897:        struct nl       *fvar = eecookiep -> nlp -> ptr[ NL_FVAR ];
        !           898:        long            fvartype = p2type( fvar -> type );
        !           899:        long            label;
        !           900:        char            labelname[ BUFSIZ ];
        !           901: 
        !           902:        switch ( classify( fvar -> type ) ) {
        !           903:            case TBOOL:
        !           904:            case TCHAR:
        !           905:            case TINT:
        !           906:            case TSCAL:
        !           907:            case TDOUBLE:
        !           908:            case TPTR:
        !           909:                putRV( fvar -> symbol , ( fvar -> nl_block ) & 037 ,
        !           910:                        fvar -> value[ NL_OFFS ] ,
        !           911:                        fvar -> extra_flags ,
        !           912:                        fvartype );
        !           913:                putop( P2FORCE , fvartype );
        !           914:                break;
        !           915:            default:
        !           916:                label = getlab();
        !           917:                sprintf( labelname , PREFIXFORMAT , LABELPREFIX , label );
        !           918:                putprintf("     .lcomm  %s,%d", 0,
        !           919:                        labelname, lwidth(fvar -> type));
        !           920:                putleaf( P2NAME , 0 , 0 , fvartype , labelname );
        !           921:                putLV( fvar -> symbol , ( fvar -> nl_block ) & 037 ,
        !           922:                        fvar -> value[ NL_OFFS ] ,
        !           923:                        fvar -> extra_flags ,
        !           924:                        fvartype );
        !           925:                putstrop( P2STASG , ADDTYPE(fvartype, P2PTR) ,
        !           926:                        lwidth( fvar -> type ) ,
        !           927:                        align( fvar -> type ) );
        !           928:                putdot( filename , line );
        !           929:                putleaf( P2ICON , 0 , 0 , ADDTYPE(fvartype, P2PTR), labelname );
        !           930:                putop( P2FORCE , ADDTYPE(fvartype, P2PTR) );
        !           931:                break;
        !           932:        }
        !           933:        putdot( filename , line );
        !           934:     }
        !           935:        /*
        !           936:         *      if we saved a display, we must restore it.
        !           937:         */
        !           938:     if ( parts[ cbn ] & NONLOCALVAR ) {
        !           939:            /*
        !           940:             *  restore old display entry from save area
        !           941:             */
        !           942:        putprintf("     movl    %s@(%d),%s+%d", 0,
        !           943:                    P2FPNAME, DSAVEOFFSET,
        !           944:                    DISPLAYNAME, cbn * sizeof(struct dispsave));
        !           945:     }
        !           946: }
        !           947: 
        !           948: fp_epilogue(eecookiep)
        !           949:     struct entry_exit_cookie   *eecookiep;
        !           950: {
        !           951:     /*
        !           952:      * all done by the second pass.
        !           953:      */
        !           954: }
        !           955: 
        !           956: fp_formalentry(eecookiep)
        !           957:     struct entry_exit_cookie   *eecookiep;
        !           958: {
        !           959:     putprintf( "%s%s:" , 0 , FORMALPREFIX , eecookiep -> extname );
        !           960:     putprintf("        link    %s,#0", 0, P2FPNAME);
        !           961:     putprintf("        addl    #-%s%d,sp", 0, FRAME_SIZE_LABEL, ftnno);
        !           962:        /* touch new end of stack, to break more stack space */
        !           963:     putprintf("        tstb    sp@(-%s%d)", 0, PAGE_BREAK_LABEL, ftnno);
        !           964:     putprintf("        moveml  #%s%d,sp@", 0, SAVE_MASK_LABEL, ftnno);
        !           965:     putleaf( P2ICON , 0 , 0 , ADDTYPE( P2FTN | P2INT , P2PTR ) , "_FCALL" );
        !           966:     putRV( 0 , cbn ,
        !           967:        eecookiep -> nlp -> value[ NL_OFFS ] + sizeof( struct formalrtn * ) ,
        !           968:        NPARAM , P2PTR | P2STRTY );
        !           969:     putRV(0, cbn, eecookiep -> nlp -> value[NL_OFFS], NPARAM, P2PTR|P2STRTY);
        !           970:     putop( P2LISTOP , P2INT );
        !           971:     putop( P2CALL , P2INT );
        !           972:     putdot( filename , line );
        !           973:     putjbr( eecookiep -> toplabel );
        !           974: }
        !           975: #endif mc68000
        !           976: #endif PC

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.