Annotation of researchv9/cmd/sun/mip/match.c, revision 1.1.1.1

1.1       root        1: #ifndef lint
                      2: static char sccsid[] = "@(#)match.c 1.1 86/02/03 SMI";
                      3: #endif
                      4: 
                      5: # include "cpass2.h"
                      6: 
                      7: # ifdef WCARD1
                      8: # ifdef WCARD2
                      9: # define NOINDIRECT
                     10: # endif
                     11: # endif
                     12: 
                     13: extern vdebug;
                     14: 
                     15: int fldsz, fldshf;
                     16: 
                     17: int mamask[] = { /* masks for matching dope with shapes */
                     18:        SIMPFLG,        /* OPSIMP */
                     19:        SIMPFLG|ASGFLG, /* ASG OPSIMP */
                     20:        COMMFLG,        /* OPCOMM */
                     21:        COMMFLG|ASGFLG, /* ASG OPCOMM */
                     22:        MULFLG,         /* OPMUL */
                     23:        MULFLG|ASGFLG,  /* ASG OPMUL */
                     24:        DIVFLG,         /* OPDIV */
                     25:        DIVFLG|ASGFLG,  /* ASG OPDIV */
                     26:        UTYPE,          /* OPUNARY */
                     27:        TYFLG,          /* ASG OPUNARY is senseless */
                     28:        LTYPE,          /* OPLEAF */
                     29:        TYFLG,          /* ASG OPLEAF is senseless */
                     30:        0,              /* OPANY */
                     31:        ASGOPFLG|ASGFLG,/* ASG OPANY */
                     32:        LOGFLG,         /* OPLOG */
                     33:        TYFLG,          /* ASG OPLOG is senseless */
                     34:        FLOFLG,         /* OPFLOAT */
                     35:        FLOFLG|ASGFLG,  /* ASG OPFLOAT */
                     36:        SHFFLG,         /* OPSHFT */
                     37:        SHFFLG|ASGFLG,  /* ASG OPSHIFT */
                     38:        SPFLG,          /* OPLTYPE */
                     39:        TYFLG,          /* ASG OPLTYPE is senseless */
                     40:        INTRFLG,        /* OPINTR */
                     41:        TYFLG,          /* ASG OPINTR is senseless */
                     42: };
                     43: 
                     44: int sdebug = 0;
                     45: 
                     46: tshape( p, shape ) 
                     47:        register NODE *p;
                     48: {
                     49:        /*
                     50:         * return true if shape is appropriate for the node p
                     51:         * side effect for SFLD is to set up fldsz,etc
                     52:         */
                     53:        register o, mask;
                     54:        register lval;
                     55: 
                     56:        o = p->in.op;
                     57: 
                     58: # ifndef BUG3
                     59:        if ( sdebug ){
                     60:                printf( "tshape( %o, %o), op = %d\n", p, shape, o );
                     61:        }
                     62: # endif
                     63: 
                     64:        if ( shape & SPECIAL ){
                     65:                switch ( shape ){
                     66:                case SZERO:
                     67:                        if ( o != ICON || p->in.name[0] ) return(0);
                     68:                        return(p->tn.lval == 0);
                     69:                case SONE:
                     70:                        if ( o != ICON || p->in.name[0] ) return(0);
                     71:                        return(p->tn.lval == 1);
                     72:                case SMONE:
                     73:                        if ( o != ICON || p->in.name[0] ) return(0);
                     74:                        return(p->tn.lval == -1);
                     75:                case SSCON:
                     76:                        if ( o != ICON || p->in.name[0] ) return(0);
                     77:                        lval = p->tn.lval;
                     78:                        return(lval >= -32768 && lval <= 32767);
                     79:                case SCCON:
                     80:                        if ( o != ICON || p->in.name[0] ) return(0);
                     81:                        lval = p->tn.lval;
                     82:                        return(lval >= -128 && lval <= 127);
                     83:                case SSOREG:    /* non-indexed OREG */
                     84:                        return(o == OREG && !R2TEST(p->tn.rval));
                     85: 
                     86:                default:
                     87: # ifdef MULTILEVEL
                     88:                        if ( shape & MULTILEVEL )
                     89:                                return( mlmatch(p,shape,0) );
                     90:                        else
                     91: # endif
                     92:                        return (special( p, shape ));
                     93:                }
                     94:        }
                     95:        if ( shape & SANY ) return(1);
                     96:        if ( (shape&INTEMP) && shtemp(p) ) return(1);
                     97:        if ( (shape&SWADD) && (o==NAME||o==OREG) ){
                     98:                if ( BYTEOFF(p->tn.lval) ) return(0);
                     99:        }
                    100: 
                    101: # ifdef WCARD1
                    102:        if ( shape & WCARD1 )
                    103:                return( wcard1(p) & shape );
                    104: # endif
                    105: 
                    106: # ifdef WCARD2
                    107:        if ( shape & WCARD2 )
                    108:                return( wcard2(p) & shape );
                    109: # endif
                    110:        switch( o ){
                    111:        case NAME:
                    112:                return( shape&SNAME );
                    113:        case FCON:
                    114:        case ICON:
                    115:                mask = SCON;
                    116:                return( shape & mask );
                    117:        case FLD:
                    118:                if ( shape & SFLD ){
                    119:                        if ( !flshape( p->in.left ) ) return(0);
                    120:                        /* it is a FIELD shape; make side-effects */
                    121:                        o = p->tn.rval;
                    122:                        fldsz = UPKFSZ(o);
                    123: # ifdef RTOLBYTES
                    124:                        fldshf = UPKFOFF(o);
                    125: # else
                    126:                        fldshf = SZINT - fldsz - UPKFOFF(o);
                    127: # endif
                    128:                        return(1);
                    129:                }
                    130:                return(0);
                    131:        case FCCODES:
                    132:        case CCODES:
                    133:                return( shape&SCC );
                    134:        case REG:
                    135:                /* distinctions:
                    136:                 * SAREG        any scalar register
                    137:                 * STAREG       any temporary scalar register
                    138:                 * SBREG        any lvalue (index) register
                    139:                 * STBREG       any temporary lvalue register
                    140:                 * SCREG        any floating register
                    141:                 * STCREG       any temporary floating register
                    142:                 */
                    143:                if (isbreg( p->tn.rval ))
                    144:                        mask = SBREG; 
                    145:                else if (iscreg( p->tn.rval ))
                    146:                        mask = SCREG; 
                    147:                else 
                    148:                        mask = SAREG; 
                    149:                if ( istreg( p->tn.rval ) && busy[p->tn.rval]<=1 ) {
                    150:                        if (mask==SAREG)
                    151:                                mask |= STAREG;
                    152:                        else if (mask==SBREG)
                    153:                                mask |= STBREG;
                    154:                        else
                    155:                                mask |= STCREG;
                    156:                }
                    157:                return( shape & mask );
                    158:        case OREG:
                    159:                return( shape & SOREG );
                    160: 
                    161: # ifndef NOINDIRECT
                    162:        case UNARY MUL:
                    163:                /* return STARNM or STARREG or 0 */
                    164:                return( shumul(p->in.left) & shape );
                    165: # endif
                    166: 
                    167:        }
                    168: 
                    169:        return(0);
                    170: }
                    171: 
                    172: int tdebug = 0;
                    173: 
                    174: ttype( t, tword ) 
                    175:        register TWORD t;
                    176:        register tword;
                    177: {
                    178:        /* does the type t match tword */
                    179: 
                    180:        if ( tword & TANY ) return(1);
                    181:        if ( t == UNDEF ) t=INT; /* void functions eased thru tables */
                    182: # ifndef BUG3
                    183:        if ( tdebug ){
                    184:                printf( "ttype( %o, %o )\n", t, tword );
                    185:        }
                    186: # endif
                    187:        if ( ISPTR(t) && (tword&TPTRTO) ) {
                    188:                do {
                    189:                        t = DECREF(t);
                    190:                } while ( ISARY(t) );
                    191:                /* arrays that are left are usually only
                    192:                   in structure references... */
                    193:                return( ttype( t, tword&(~TPTRTO) ) );
                    194:        }
                    195:        if ( t != BTYPE(t) )
                    196:                return( tword & TPOINT );       /* TPOINT means not simple! */
                    197:        if ( tword & TPTRTO ) return(0);
                    198:        switch( t ){
                    199:        case CHAR:
                    200:                return( tword & TCHAR );
                    201:        case SHORT:
                    202:                return( tword & TSHORT );
                    203:        case STRTY:
                    204:        case UNIONTY:
                    205:                return( tword & TSTRUCT );
                    206:        case INT:
                    207:                return( tword & TINT );
                    208:        case UNSIGNED:
                    209:                return( tword & TUNSIGNED );
                    210:        case USHORT:
                    211:                return( tword & TUSHORT );
                    212:        case UCHAR:
                    213:                return( tword & TUCHAR );
                    214:        case ULONG:
                    215:                return( tword & TULONG );
                    216:        case LONG:
                    217:                return( tword & TLONG );
                    218:        case FLOAT:
                    219:                return( tword & TFLOAT );
                    220:        case DOUBLE:
                    221:                return( tword & TDOUBLE );
                    222:        }
                    223:        return(0);
                    224: }
                    225: 
                    226: #define MAXOPSET 2000
                    227: 
                    228: struct opvect {
                    229:        struct optab **first;
                    230:        struct optab **rewrite;
                    231: };
                    232: 
                    233: struct opvect opvect[DSIZE];
                    234: struct optab *opsets[MAXOPSET];
                    235: 
                    236: static struct optab **firstelement= opsets;
                    237: static struct optab **nextelement = opsets;
                    238: 
                    239: extern int opmatch(/* op, targetop */);        /* returns 1 if op matches targetop */
                    240: 
                    241: /*
                    242:  * setrew()
                    243:  *     Generates sets of templates to be examined by match(), one
                    244:  *     for each operator in 0..DSIZE.  The sets are represented as
                    245:  *     vectors of pointers into the code table.  The sets could be
                    246:  *     constructed by a separate program when the compiler is compiled,
                    247:  *     but doing it at startup enables us to deal more conveniently
                    248:  *     with user-selected processor options (e.g., -m68020 -m68881)
                    249:  */
                    250: 
                    251: setrew()
                    252: {
                    253:        register struct optab *q;
                    254:        register int op;
                    255:        register struct optab **nextel = nextelement;
                    256:        register struct optab **firstel = firstelement;
                    257: 
                    258:        for( op = 0; op < DSIZE; ++op ) {
                    259:                if (dope[op]) {
                    260:                        /*
                    261:                         * operator exists;
                    262:                         * scan table for matching templates
                    263:                         */
                    264:                        register struct optab **firstrew;
                    265:                        firstrew = (struct optab**)NULL;
                    266:                        for (q = table; q->op != FREE; q++) {
                    267:                                if (opmatch(op, q->op)) {
                    268:                                        if (q->needs == REWRITE) {
                    269:                                                if (!firstrew) {
                    270:                                                        firstrew = nextel;
                    271:                                                }
                    272:                                        }
                    273:                                        *nextel++ = q;
                    274:                                }
                    275:                        }
                    276:                        if (nextel-opsets >= MAXOPSET) {
                    277:                                cerror("too many opsets (%d)",
                    278:                                        nextel-opsets);
                    279:                        }
                    280:                        opvect[op].first = firstel;
                    281:                        opvect[op].rewrite = firstrew;
                    282:                        *nextel++ = (struct optab*)NULL;
                    283:                        firstel = nextel;
                    284:                } else {
                    285:                        /* no operator */
                    286:                        opvect[op].first = (struct optab**)NULL;
                    287:                        opvect[op].rewrite = (struct optab**)NULL;
                    288:                } /* else */
                    289:        } /* for each op */
                    290:        nextelement = nextel;
                    291:        firstelement = firstel;
                    292: } /* setrew */
                    293: 
                    294: match( p, cookie ) 
                    295:        NODE *p; 
                    296: {
                    297:        /*
                    298:         * called by: order, gencall
                    299:         * look for match in table and generate code if found unless
                    300:         * entry specified REWRITE.
                    301:         * returns MDONE, MNOPE, or rewrite specification from table 
                    302:         */
                    303: 
                    304:        register struct optab **opset;
                    305:        register struct optab *q;
                    306:        register op;
                    307:        register NODE *r;
                    308: 
                    309:        rcount();
                    310:        op = p->in.op;
                    311:        if (cookie == FORREW) {
                    312:                opset = opvect[op].rewrite;
                    313:        } else {
                    314:                opset = opvect[op].first;
                    315:                /*
                    316:                 * finish the special-case test for autoincrement trees
                    317:                 */
                    318:                if (op == UNARY MUL && !shumul(p->in.left)) {
                    319:                        return(MNOPE);
                    320:                }
                    321:        }
                    322:        if (opset == (struct optab**)NULL) {
                    323:                cerror("no template for op '%s'", opst[op]);
                    324:        }
                    325:        for (q = *opset++; q != (struct optab *)NULL; q = *opset++) {
                    326: 
                    327:                /* see if goal matches */
                    328:                if ( !(q->visit & cookie ) ) continue;
                    329: 
                    330:                /* see if left child matches */
                    331:                r = ( optype( op ) == LTYPE ? p : p->in.left );
                    332:                if ( !tshape( r, q->lshape ) )
                    333:                        continue;
                    334:                if ( !ttype( r->in.type, q->ltype ) ) 
                    335:                        continue;
                    336: 
                    337:                /* see if right child matches */
                    338:                r = ( optype( op ) != BITYPE ? p : p->in.right );
                    339:                if ( !tshape( r, q->rshape ) )
                    340:                        continue;
                    341:                if ( !ttype( r->in.type, q->rtype ) )
                    342:                        continue;
                    343: 
                    344:                /*
                    345:                 * REWRITE means no code from this match but go ahead
                    346:                 * and rewrite node to help future match.
                    347:                 */
                    348:                if ( q->needs & REWRITE )
                    349:                        return( q->rewrite );
                    350:                if ( !allo( p, q ) )
                    351:                        continue;       /* if can't generate code, skip entry */
                    352: 
                    353:                /* resources are available */
                    354: 
                    355:                /* generate code */
                    356:                expand( p, cookie, q->cstring );
                    357:                reclaim( p, q->rewrite, cookie );
                    358: 
                    359:                return(MDONE);
                    360: 
                    361:        }
                    362: 
                    363:        return(MNOPE);
                    364: }
                    365: 
                    366: int rtyflg = 0;
                    367: 
                    368: expand( p, cookie, cp )
                    369:        NODE *p; 
                    370:        register char *cp;
                    371: {
                    372:        /* generate code by interpreting table entry */
                    373: 
                    374:        register char c;
                    375:        CONSZ val;
                    376: 
                    377:        rtyflg = 0;
                    378: 
                    379:        for( ; *cp; ++cp ){
                    380:                switch( *cp ){
                    381: 
                    382:                case '\\':
                    383:                        cp++;
                    384:                        /* FALL THROUGH */
                    385:                default:
                    386:                        PUTCHAR( *cp );
                    387:                        continue;  /* this is the usual case... */
                    388:                case 'T':
                    389:                        /* rewrite register type is suppressed */
                    390:                        rtyflg = 1;
                    391:                        continue;
                    392: 
                    393:                case 'Z':  /* special machine dependent operations */
                    394: # ifdef NEWZZZ
                    395:                        switch( c = *++cp ) {
                    396: 
                    397:                        case '1':
                    398:                        case '2':
                    399:                        case '3':
                    400:                        case 'R':
                    401:                        case 'L':       /* get down first */
                    402:                                zzzcode( getlr( p, c ), *++cp );
                    403:                                break;
                    404:                        default:   /* normal zzzcode processing otherwise */
                    405:                                zzzcode( p, c );
                    406:                                break;
                    407:                        }
                    408: # else
                    409:                        zzzcode( p, *++cp, cookie );
                    410: # endif
                    411:                        continue;
                    412: 
                    413:                case 'F':  /* this line deleted if FOREFF is active */
                    414:                        if ( cookie & FOREFF )
                    415:                                while( *++cp != '\n' )
                    416:                                        ; /* VOID */
                    417:                        continue;
                    418: 
                    419: #ifdef undef
                    420:                case 'R': /* this line deleted if descendent is already in a temp register */
                    421:                        {
                    422:                        NODE * t;
                    423: 
                    424:                        t = getlr(p, *++cp );
                    425:                        if ( istnode(t) )
                    426:                                while( *++cp != '\n' )
                    427:                                        ; /* VOID */
                    428:                        continue;
                    429:                        }
                    430: #endif sun
                    431:                case 'S':  /* field size */
                    432:                        print_d(fldsz );
                    433:                        continue;
                    434: 
                    435:                case 'H':  /* field shift */
                    436:                        print_d( fldshf );
                    437:                        continue;
                    438: 
                    439:                case 'M':  /* field mask */
                    440:                case 'N':  /* complement of field mask */
                    441:                        val = 1;
                    442:                        val <<= fldsz;
                    443:                        --val;
                    444:                        val <<= fldshf;
                    445:                        adrcon( *cp=='M' ? val : ~val );
                    446:                        continue;
                    447: 
                    448:                case 'L':  /* output special label field */
                    449:                        print_d( p->bn.label );
                    450:                        continue;
                    451: 
                    452:                case 'O':  /* opcode string */
                    453:                        hopcode( *++cp, p->in.op );
                    454:                        continue;
                    455: 
                    456:                case 'B':  /* byte offset in word */
                    457:                        val = getlr(p,*++cp)->tn.lval;
                    458:                        val = BYTEOFF(val);
                    459:                        printf( CONFMT, val );
                    460:                        continue;
                    461: 
                    462:                case 'C': /* for constant value only */
                    463:                        conput( getlr( p, *++cp ) );
                    464:                        continue;
                    465: 
                    466:                case 'I': /* in instruction */
                    467:                        insput( getlr( p, *++cp ) );
                    468:                        continue;
                    469: 
                    470:                case 'A': /* address of */
                    471:                        adrput( getlr( p, *++cp ) );
                    472:                        continue;
                    473: 
                    474:                case 'U': /* for upper half of address, only */
                    475:                        upput( getlr( p, *++cp ) );
                    476:                        continue;
                    477: 
                    478:                }
                    479: 
                    480:        }
                    481: 
                    482: }
                    483: 
                    484: NODE *
                    485: getlr( p, c )
                    486:        NODE *p;
                    487: {
                    488: 
                    489:        /*
                    490:         * return the pointer to the left or right side of p, or p itself,
                    491:         * depending on the optype of p
                    492:         */
                    493: 
                    494:        switch ( c ) {
                    495: 
                    496:        case '1':
                    497:        case '2':
                    498:        case '3':
                    499:                return ( &resc[c-'1'] );
                    500: 
                    501:        case 'L':
                    502:                return ( optype( p->in.op ) == LTYPE ? p : p->in.left );
                    503: 
                    504:        case 'R':
                    505:                return ( optype( p->in.op ) != BITYPE ? p : p->in.right );
                    506: 
                    507:        case '.':
                    508:                return ( p );
                    509: 
                    510:        }
                    511:        cerror( "bad getlr: %c", c );
                    512:        /* NOTREACHED */
                    513: }
                    514: 
                    515: # ifdef MULTILEVEL
                    516: 
                    517: union mltemplate{
                    518:        struct ml_head{
                    519:                int tag; /* identifies class of tree */
                    520:                int subtag; /* subclass of tree */
                    521:                union mltemplate * nexthead; /* linked by mlinit() */
                    522:                } mlhead;
                    523:        struct ml_node{
                    524:                int op; /* either an operator or op description */
                    525:                int nshape; /* shape of node */
                    526:                /* both op and nshape must match the node.
                    527:                 * where the work is to be done entirely by
                    528:                 * op, nshape can be SANY, visa versa, op can
                    529:                 * be OPANY.
                    530:                 */
                    531:                int ntype; /* type descriptor from mfile2 */
                    532:                } mlnode;
                    533:        };
                    534: 
                    535: # define MLSZ 30
                    536: 
                    537: extern union mltemplate mltree[];
                    538: int mlstack[MLSZ];
                    539: int *mlsp; /* pointing into mlstack */
                    540: NODE * ststack[MLSZ];
                    541: NODE **stp; /* pointing into ststack */
                    542: 
                    543: mlinit(){
                    544:        union mltemplate **lastlink;
                    545:        register union mltemplate *n;
                    546:        register mlop;
                    547: 
                    548:        lastlink = &(mltree[0].nexthead);
                    549:        n = &mltree[0];
                    550:        for( ; (n++)->mlhead.tag != 0;
                    551:                *lastlink = ++n, lastlink = &(n->mlhead.nexthead) ){
                    552: # ifndef BUG3
                    553:                if ( vdebug )print_str_d_nl("mlinit: ",(n-1)->mlhead.tag);
                    554: # endif
                    555:        /* wander thru a tree with a stack finding
                    556:         * its structure so the next header can be located.
                    557:         */
                    558:                mlsp = mlstack;
                    559: 
                    560:                for( ;; ++n ){
                    561:                        if ( (mlop = n->mlnode.op) < OPSIMP ){
                    562:                                switch( optype(mlop) ){
                    563: 
                    564:                                        default:
                    565:                                                cerror("(1)unknown opcode: %o",mlop);
                    566:                                        case BITYPE:
                    567:                                                goto binary;
                    568:                                        case UTYPE:
                    569:                                                break;
                    570:                                        case LTYPE:
                    571:                                                goto leaf;
                    572:                                        }
                    573:                                }
                    574:                        else{
                    575:                                if ( mamask[mlop-OPSIMP] &
                    576:                                        (SIMPFLG|COMMFLG|MULFLG|DIVFLG|LOGFLG|FLOFLG|SHFFLG) ){
                    577:                                binary:
                    578:                                        *mlsp++ = BITYPE;
                    579:                                        }
                    580:                                else if ( ! (mamask[mlop-OPSIMP] & UTYPE) ){/* includes OPANY */
                    581: 
                    582:                                leaf:
                    583:                                        if ( mlsp == mlstack )
                    584:                                                goto tree_end;
                    585:                                        else if ( *--mlsp != BITYPE )
                    586:                                                cerror("(1)bad multi-level tree descriptor around mltree[%d]",
                    587:                                                n-mltree);
                    588:                                        }
                    589:                                }
                    590:                        }
                    591:                tree_end: /* n points to final leaf */
                    592:                ;
                    593:                }
                    594: # ifndef BUG3
                    595:                if ( vdebug > 3 ){
                    596:                        print_str("mltree={\n");
                    597:                        for( n= &(mltree[0]); n->mlhead.tag != 0; ++n)
                    598:                                printf("%o: %d, %d, %o,\n",n,
                    599:                                n->mlhead.tag,n->mlhead.subtag,n->mlhead.nexthead);
                    600:                        print_str("     }\n");
                    601:                        }
                    602: # endif
                    603:        }
                    604: 
                    605: mlmatch( subtree, target, subtarget ) NODE * subtree; int target,subtarget;{
                    606:        /*
                    607:         * does subtree match a multi-level tree with
                    608:         * tag "target"?  Return zero on failure,
                    609:         * non-zero subtag on success (or MDONE if
                    610:         * there is a zero subtag field).
                    611:         */
                    612:        union mltemplate *head; /* current template header */
                    613:        register union mltemplate *n; /* node being matched */
                    614:        NODE * st; /* subtree being matched */
                    615:        register int mlop;
                    616: 
                    617: # ifndef BUG3
                    618:        if ( vdebug ) printf("mlmatch(%o,%d)\n",subtree,target);
                    619: # endif
                    620:        for( head = &(mltree[0]); head->mlhead.tag != 0;
                    621:                head=head->mlhead.nexthead){
                    622: # ifndef BUG3
                    623:                if ( vdebug > 1 )printf("mlmatch head(%o) tag(%d)\n",
                    624:                        head->mlhead.tag);
                    625: # endif
                    626:                if ( head->mlhead.tag != target )continue;
                    627:                if ( subtarget && head->mlhead.subtag != subtarget)continue;
                    628: # ifndef BUG3
                    629:                if ( vdebug ) print_str_d_nl("mlmatch for ",target);
                    630: # endif
                    631: 
                    632:                /* potential for match */
                    633: 
                    634:                n = head + 1;
                    635:                st = subtree;
                    636:                stp = ststack;
                    637:                mlsp = mlstack;
                    638:                /* compare n->op, ->nshape, ->ntype to
                    639:                 * the subtree node st
                    640:                 */
                    641:                for( ;; ++n ){ /* for each node in multi-level template */
                    642:                        /* opmatch */
                    643:                        if ( n->op < OPSIMP ){
                    644:                                if ( st->op != n->op )break;
                    645:                                }
                    646:                        else {
                    647:                                register opmtemp;
                    648:                                if ((opmtemp=mamask[n->op-OPSIMP])&SPFLG){
                    649:                                        if (st->op!=NAME && st->op!=ICON && st->op!=OREG && 
                    650:                                                ! shltype(st->op,st)) break;
                    651:                                        }
                    652:                                else if ((dope[st->op]&(opmtemp|ASGFLG))!=opmtemp) break;
                    653:                                }
                    654:                        /* check shape and type */
                    655: 
                    656:                        if ( ! tshape( st, n->mlnode.nshape ) ) break;
                    657:                        if ( ! ttype( st->type, n->mlnode.ntype ) ) break;
                    658: 
                    659:                        /* that node matched, let's try another */
                    660:                        /* must advance both st and n and halt at right time */
                    661: 
                    662:                        if ( (mlop = n->mlnode.op) < OPSIMP ){
                    663:                                switch( optype(mlop) ){
                    664: 
                    665:                                        default:
                    666:                                                cerror("(2)unknown opcode: %o",mlop);
                    667:                                        case BITYPE:
                    668:                                                goto binary;
                    669:                                        case UTYPE:
                    670:                                                st = st->left;
                    671:                                                break;
                    672:                                        case LTYPE:
                    673:                                                goto leaf;
                    674:                                        }
                    675:                                }
                    676:                        else{
                    677:                                if ( mamask[mlop - OPSIMP] &
                    678:                                        (SIMPFLG|COMMFLG|MULFLG|DIVFLG|LOGFLG|FLOFLG|SHFFLG) ){
                    679:                                binary:
                    680:                                        *mlsp++ = BITYPE;
                    681:                                        *stp++ = st;
                    682:                                        st = st->left;
                    683:                                        }
                    684:                                else if ( ! (mamask[mlop-OPSIMP] & UTYPE) ){/* includes OPANY */
                    685: 
                    686:                                leaf:
                    687:                                        if ( mlsp == mlstack )
                    688:                                                goto matched;
                    689:                                        else if ( *--mlsp != BITYPE )
                    690:                                                cerror("(2)bad multi-level tree descriptor around mltree[%d]",
                    691:                                                n-mltree);
                    692:                                        st = (*--stp)->right;
                    693:                                        }
                    694:                                else /* UNARY */ st = st->left;
                    695:                                }
                    696:                        continue;
                    697: 
                    698:                        matched:
                    699:                        /* complete multi-level match successful */
                    700: # ifndef BUG3
                    701:                        if ( vdebug ) print_str("mlmatch() success\n");
                    702: # endif
                    703:                        if ( head->mlhead.subtag == 0 ) return( MDONE );
                    704:                        else {
                    705: # ifndef BUG3
                    706:                                if ( vdebug )print_str_d_nl("\treturns ",
                    707:                                        head->mlhead.subtag );
                    708: # endif
                    709:                                return( head->mlhead.subtag );
                    710:                                }
                    711:                        }
                    712:                }
                    713:        return( 0 );
                    714:        }
                    715: # endif

unix.superglobalmegacorp.com

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