Annotation of researchv8dc/cmd/ccom/common/match.c, revision 1.1

1.1     ! root        1: /* @(#) match.c: 1.1 12/22/83                          */
        !             2: 
        !             3: # include "mfile2.h"
        !             4: 
        !             5: int fldsz, fldshf;
        !             6: 
        !             7: extern int zflag;              /* non-zero to output stin line and cost for
        !             8:                                ** each assembly instruction
        !             9:                                */
        !            10: # define VALUE (RESC1|RESC2|RESC3|RLEFT|RRIGHT)
        !            11: 
        !            12: OPTAB *
        !            13: match( p, q )
        !            14: register NODE *p; 
        !            15: register OPTAB *q; 
        !            16: {
        !            17:        /* look for match in table */
        !            18:        /* given a tree, p, and a template q, returns the next template that
        !            19:        /* matches p */
        !            20:        /* q == NULL starts the process off */
        !            21:        /* match is not called recursively, so much of the setup can be done
        !            22:        /* into static variables */
        !            23: 
        !            24:        static NODE *r, *l;
        !            25:        static tl, tr, goal, tyop;
        !            26:        static pop, lflg;
        !            27:        int rr;
        !            28: 
        !            29:        if( !q ) {
        !            30:                /* startup code */
        !            31: 
        !            32:                q = ophead[pop=p->tn.op];
        !            33:                l = getlo( p, pop );            /* left child */
        !            34:                r = getro( p, pop );            /* right child */
        !            35:                tl = l->in.type;
        !            36:                tr = r->in.type;
        !            37:                lflg = asgop(pop);  /* forces a match on lvalues */
        !            38:                if( p->tn.goal == CCC ) goal = (VALUE|RESCC);
        !            39:                else if( p->tn.goal == NRGS ) goal = VALUE;
        !            40:                else goal = ~0;
        !            41:                tyop = p->in.type;
        !            42:        }
        !            43: 
        !            44:        else {
        !            45:                if( fast ) return( (OPTAB *)0 );  /* only first match */
        !            46:                else q = q->nextop;
        !            47:        }
        !            48:        if( !q ) return( (OPTAB *)0 );
        !            49: 
        !            50: # ifndef NODBG
        !            51:        if( sdebug ) {
        !            52:                printf( "match tree %d, op %s\n", p-node, opst[pop] );
        !            53:        }
        !            54: # endif
        !            55:        for( ; q ; q = q->nextop ){
        !            56: 
        !            57:                /* some templates are no good for computing values */
        !            58: 
        !            59:                if( !( tl & q->ltype ) ) continue;
        !            60:                if( !( tr & q->rtype ) ) continue;
        !            61: 
        !            62:                if( !( goal & q->rewrite ) ) continue;
        !            63: 
        !            64: # ifndef NODBG
        !            65:                if( sdebug ) {
        !            66:                        printf( "       try table entry, line %d, op %s\n",
        !            67:                                q->stinline, opst[q->op] );
        !            68:                }
        !            69: # endif
        !            70:                if( !( tyop & q->tyop ) ) {
        !            71: # ifndef NODBG
        !            72:                        if( sdebug ) {
        !            73:                                printf(
        !            74:                                "\tentry line %d fails tyop, %o vs %o\n",
        !            75:                                q->stinline, tyop, q->tyop );
        !            76:                        }
        !            77: # endif
        !            78:                        continue;
        !            79:                }
        !            80: 
        !            81:                if( q->rshape ){
        !            82:                        if( rr=mspine( q->rshape, (q->lshape)?r:p, 0, sha[1] )){
        !            83:                                sha[1][rr] = 0;
        !            84:                                if( !q->lshape ) ustrip(pop);
        !            85:                        }
        !            86:                        else continue;
        !            87:                }
        !            88:                else {
        !            89:                        sha[1][1] = sha[1][0] = (SHAPE *)0;
        !            90:                }
        !            91: 
        !            92:                if( q->lshape ){
        !            93:                        if( !lflg && asgop(q->op) ){
        !            94:                                /* q->op is an assignment op, pop isn't */
        !            95:                                /* thus, the lhs => a register or temp */
        !            96:                                rr = rtspine( q->lshape, p );
        !            97:                        }
        !            98:                        else rr = mspine( q->lshape, l, lflg, sha[0] );
        !            99:                        if( rr ) sha[0][rr] = 0;
        !           100:                        else continue;
        !           101:                }
        !           102:                else {
        !           103:                        sha[0][1] = sha[0][0] = (SHAPE *)0;
        !           104:                }
        !           105: 
        !           106:                /* at this point, we have a match */
        !           107: 
        !           108: # ifndef NODBG
        !           109:                if( sdebug ) {
        !           110:                        printf( "table line %d matches tree %d\n",
        !           111:                                q->stinline, p-node );
        !           112:                }
        !           113: # endif
        !           114: 
        !           115:                return( q );  /* found match */
        !           116:        }
        !           117:        return( (OPTAB *)0 );
        !           118: }
        !           119: 
        !           120: ustrip( o )
        !           121: {
        !           122:        /* strip out of sha[1] all shapes with op != o */
        !           123:        /* sty should do this someday, but for now, it's done here */
        !           124:        register i, j;
        !           125: 
        !           126:        for( j=i=0; sha[1][j]; ++j ) {
        !           127:                if( sha[1][j]->op == o ) sha[1][i++] = sha[1][j];
        !           128:        }
        !           129:        sha[1][i] = (SHAPE *)0;
        !           130: }
        !           131: 
        !           132: rtspine( ps, p )
        !           133: SHAPE **ps;
        !           134: NODE *p; {
        !           135:        /* special routine to put the lhs into a reg or a temp */
        !           136:        /* looks for reg and/or temp in s */
        !           137:        /* makes a list in sha[0] */
        !           138:        register rr;
        !           139:        register SHAPE *s;
        !           140: 
        !           141:        for( rr = 0; s = *ps; ++ps ) {
        !           142:                /* works because FREE, CCODES, REG, and TEMP are first */
        !           143:                switch( s->op ) {
        !           144: 
        !           145:                case FREE:
        !           146:                case CCODES:
        !           147:                        continue;
        !           148: 
        !           149:                case REG:
        !           150:                case TEMP:
        !           151:                        if( s->sh ) if( !spshape( s->sh, p ) ) continue;
        !           152:                        if( rr >= NSHP-1 ) cerror( "too many shapes" );
        !           153:                        sha[0][rr] = s;
        !           154:                        ++rr;
        !           155:                        continue;
        !           156: 
        !           157:                default:
        !           158:                        break;
        !           159:                }
        !           160: 
        !           161:                break;
        !           162:        }
        !           163: 
        !           164:        return( rr );
        !           165: }
        !           166: 
        !           167: restrip( pls )
        !           168: register SHAPE **pls; 
        !           169: {
        !           170:        /* throw away those shapes that can't be results */
        !           171:        register SHAPE **p;
        !           172: 
        !           173:        for( p=pls; *p = *pls; ++p, ++pls ) 
        !           174:        {
        !           175:                if( noresult( *p ) ) --p;  /* overwrite if result is illegal */
        !           176:        }
        !           177: }
        !           178: 
        !           179: noresult( s )
        !           180: register SHAPE *s; 
        !           181: {
        !           182:        if( !s ) return( 0 );
        !           183:        if( s->op == INCR || s->op == DECR ) return( 1 );
        !           184:        return( (s->sr && noresult(s->sr)) ||
        !           185:            (s->sl && noresult( s->sl )) );
        !           186: }
        !           187: 
        !           188: smspine( s, p, flag )
        !           189: register NODE  *p; 
        !           190: register SHAPE *s; 
        !           191: {
        !           192:        /* match the spine of s, including special shapes */
        !           193:        /* this is a submatch, called only by mspine */
        !           194:        /* flag is nonzero if STAR's must be skipped */
        !           195: 
        !           196:        register sop, pop;
        !           197: 
        !           198: again:
        !           199: 
        !           200:        sop = s->op;
        !           201:        pop = p->tn.op;
        !           202: 
        !           203: # ifndef NODBG
        !           204:        if( sdebug>1 )
        !           205:        {
        !           206:                printf( "                       smspine(%d[%s], %d[%s])\n",
        !           207:                s-shapes, opst[sop], p-node, opst[pop] );
        !           208:        }
        !           209: # endif
        !           210: 
        !           211:        if( ( s->sh ) && !spshape( s->sh,p) ) return( 0 );
        !           212:        if( sop != pop ) 
        !           213:        {
        !           214:                if( sop == CCODES || sop == FREE ) return(1);
        !           215:                return( !flag && (sop==REG || sop==TEMP) );
        !           216:        }
        !           217:        if( sop == STAR ) 
        !           218:        {
        !           219:                flag = 0;
        !           220:                goto recurse;
        !           221:        }
        !           222:        switch( optype( sop ) ) 
        !           223:        {
        !           224: 
        !           225:        case BITYPE:
        !           226:                if( !smspine( s->sr, p->in.right, 0 ) ) return(0);
        !           227:                flag = asgop(sop);
        !           228:                /* FALLTHRU */
        !           229: 
        !           230:        case UTYPE:
        !           231: recurse:
        !           232:                s = s->sl;
        !           233:                p = p->in.left;
        !           234:                goto again;
        !           235: 
        !           236:        default:
        !           237:                return( 1 );
        !           238:        }
        !           239: }
        !           240: 
        !           241: mspine( ps, p, flag, ppls )
        !           242: register NODE  *p;
        !           243: register SHAPE **ps;
        !           244: register SHAPE **ppls; 
        !           245: {
        !           246:        /* match the spine of s, including special shapes */
        !           247:        /* s points to a list of shapes */
        !           248:        /* those shapes that match are copied into **ppls, with a null at end */
        !           249:        /* flag = 1 forces regs and temps to match exactly */
        !           250:        /* rr, the number of matches, is returned */
        !           251: 
        !           252:        register SHAPE *s;
        !           253:        int pop, rr;
        !           254: 
        !           255: # ifndef NODBG
        !           256:        if( sdebug ) 
        !           257:        {
        !           258:                printf( "\tmspine( %d, %d, %d )\n", ps-pshape, p-node, flag );
        !           259:        }
        !           260: # endif
        !           261:        pop = p->tn.op;
        !           262: 
        !           263:        /* copy the wild-cards, and those where the op matches */
        !           264:        for( rr=0; s = *ps; ++ps ) 
        !           265:        {
        !           266:                switch( s->op ) 
        !           267:                {
        !           268: 
        !           269:                case REG:
        !           270:                case TEMP:
        !           271:                        if( flag ) break;
        !           272:                        if( s->sh ) if( !spshape(s->sh,p) ) continue;
        !           273:                        /* FALLTHRU */
        !           274: 
        !           275:                case FREE:
        !           276:                case CCODES:
        !           277:                        if( rr >= NSHP-1 ) cerror( "too many shapes" );
        !           278: 
        !           279: # ifndef NODBG
        !           280:                        if( sdebug )
        !           281:                        {
        !           282:                                printf(
        !           283:                                "\t\tmspine( %d[%s], %d[%s] ), becomes %d\n",
        !           284:                                s-shapes, opst[s->op], p-node,
        !           285:                                opst[pop], rr );
        !           286:                        }
        !           287: # endif
        !           288: 
        !           289:                        ppls[rr++] = s;
        !           290:                        continue;
        !           291: 
        !           292:                default:
        !           293:                        break;
        !           294:                }
        !           295:                break;
        !           296:        }
        !           297: 
        !           298:        /* now, either s is 0 or s has a "real" op */
        !           299:        /* the first condition survives the next two loops */
        !           300: 
        !           301:        /* we have matched the wild cards: find others where the op matches */
        !           302: 
        !           303:        for( ; (s= *ps) && s->op != pop; ++ps ) 
        !           304:        {
        !           305:                 ; 
        !           306:        }
        !           307: 
        !           308:        /* now, s is null or matches the op of p */
        !           309:        for( ; (s = *ps) && s->op == pop; ++ps ) 
        !           310:        {
        !           311: 
        !           312:                if( pop == STAR ) 
        !           313:                {
        !           314:                        if( !smspine( s->sl, p->in.left, 0 ) ) continue;
        !           315:                }
        !           316: 
        !           317:                /* general case: check the subtrees also */
        !           318:                else if( s->sl ) 
        !           319:                {
        !           320:                        if( s->sr ) 
        !           321:                        {
        !           322:                                if( !smspine( s->sr, p->in.right, 0 ) )
        !           323:                                        continue;
        !           324:                                if( !smspine( s->sl, p->in.left, asgop(s->op)) )
        !           325:                                        continue;
        !           326:                        }
        !           327:                        else 
        !           328:                        {
        !           329:                                if( !smspine( s->sl, p->in.left, flag ))
        !           330:                                        continue;
        !           331:                        }
        !           332:                }
        !           333:                else if( s->sr && !smspine( s->sr, p->in.right, 0 ) )
        !           334:                        continue;
        !           335: 
        !           336:                /* if we get this far, we are in good shape */
        !           337: 
        !           338:                if( s->sh ) if( !spshape( s->sh, p ) ) continue;
        !           339:                if( rr >= NSHP-1 ) cerror( "too many shapes" );
        !           340: 
        !           341: # ifndef NODBG
        !           342:                if( sdebug )
        !           343:                {
        !           344:                        printf( "\t\tmspine( %d[%s], %d[%s] ), becomes %d\n",
        !           345:                        s-shapes, opst[s->op], p-node,
        !           346:                        opst[pop], rr );
        !           347:                }
        !           348: # endif
        !           349: 
        !           350:                ppls[rr++] = s;
        !           351:        }
        !           352: 
        !           353:        /* fall out and we are done */
        !           354:        return( rr );
        !           355: }
        !           356: 
        !           357: 
        !           358: tempok( p )
        !           359: NODE *p; 
        !           360: 
        !           361: {
        !           362:        /* decide if the result of p is OK as a temp */
        !           363:        int o;
        !           364:        if( (o = p->tn.op) == TEMP ) return( 1 );
        !           365:        if( asgop(o) && o!=INCR && o!=DECR ) 
        !           366:        {
        !           367:                return( p->in.left->tn.op == TEMP );
        !           368:        }
        !           369:        return( 0 );
        !           370: }
        !           371: 
        !           372: int sideff;
        !           373: 
        !           374: rmside( p )
        !           375: NODE *p; 
        !           376: 
        !           377: {
        !           378:        /* p is a tree with side effects: remove them */
        !           379:        /* this is done in place */
        !           380:        int o;
        !           381:        NODE *q;
        !           382: 
        !           383:        o = p->tn.op;
        !           384:        switch( o ) 
        !           385:        {
        !           386: 
        !           387:        case INCR:
        !           388:        case DECR:
        !           389:        case ASG PLUS:
        !           390:        case ASG MINUS:
        !           391:                if( p->in.right->tn.op == ICON ) p->in.right->tn.op = FREE;
        !           392:                else 
        !           393:                {
        !           394:                        regrcl( p->in.right );
        !           395:                        tfree( p->in.right );
        !           396:                }
        !           397:                q = p->in.left;
        !           398:                *p = *q;
        !           399:                q->tn.op = FREE;
        !           400:                rmside( p );
        !           401:                return;
        !           402:        }
        !           403: 
        !           404:        switch( optype( o ) )
        !           405:        {
        !           406: 
        !           407:        case BITYPE:
        !           408:                rmside( p->in.right );
        !           409:        case UTYPE:
        !           410:                rmside( p->in.left );
        !           411:        }
        !           412: }
        !           413: 
        !           414: expand( p, goal, cp, q )
        !           415: NODE *p;  
        !           416: char *cp; 
        !           417: OPTAB *q;
        !           418: {
        !           419:        /* generate code by interpreting table entry */
        !           420: 
        !           421:        CONSZ val;
        !           422:        NODE *q1, *q2;
        !           423:        int c;
        !           424:        TWORD t;
        !           425: 
        !           426: #ifdef GDEBUG
        !           427:        if ((c = p->stn.op) == CALL || c == UNARY CALL)
        !           428:                dbnargs(p->stn.argsize);
        !           429: #endif
        !           430:        for( ; *cp; ++cp )
        !           431:        {
        !           432:                switch( *cp )
        !           433:                {
        !           434: 
        !           435:                case '\\':
        !           436:                        ++cp;
        !           437:                        /* FALLTHRU */
        !           438:                default:
        !           439:                        PUTCHAR( *cp );
        !           440:                        continue;  /* this is the usual case... */
        !           441: 
        !           442:                case '\n':
        !           443:                        if( zflag )
        !           444:                        {  /* add stin line number of production as a comment */
        !           445:                                printf( "\t\t%s %d", COMMENTSTR, q->stinline );
        !           446:                                if( p->in.cst[CEFF] < INFINITY )
        !           447:                                        printf( " = %d", p->in.cst[CEFF] );
        !           448:                        }
        !           449:                        PUTCHAR( *cp );
        !           450:                        continue;
        !           451: 
        !           452:                case 'Y':
        !           453:                        /* don't check this string: deleted by match */
        !           454:                        continue;
        !           455: 
        !           456:                case 'Z':  /* special machine dependent operations */
        !           457:                        zzzcode( p, &cp, q );
        !           458:                        continue;
        !           459: 
        !           460:                case 'E':       /* exit */
        !           461:                        if( zflag )
        !           462:                        {  /* add stin line number of production as a comment */
        !           463:                                printf( "\t%s\t%d = %d",
        !           464:                                COMMENTSTR, q->stinline, p->in.cst[CEFF] );
        !           465:                        }
        !           466:                        PUTCHAR( '\n' );
        !           467:                        return;
        !           468: 
        !           469: # ifndef STACK
        !           470:                case 'D':       /* test for dependency */
        !           471:                        q1 = getadr( p, &cp );
        !           472:                        if( cp[1] == '!' )
        !           473:                        {
        !           474:                                c=0;
        !           475:                                ++cp;
        !           476:                        }
        !           477:                        else c=1;
        !           478:                        q2 = getadr( p, &cp );
        !           479:                        if( q1->tn.op != REG ) cerror( "bad D" );
        !           480:                        if( ushare( q2, q1->tn.rval ) == c ) continue;
        !           481:                        goto cream;
        !           482: # endif
        !           483: 
        !           484:                case 'R':  /* put an operand into a particular register */
        !           485:                        /* if the operand is in the register, delete the line */
        !           486:                        q1 = getadr( p, &cp );
        !           487:                        c = (*++cp == '=');
        !           488:                        q2 = getadr( p, &cp );
        !           489:                        if( q1->tn.op != REG )
        !           490:                        {
        !           491:                                if( c ) goto cream;
        !           492:                                continue;
        !           493:                        }
        !           494:                        if( q2->tn.op != REG )
        !           495:                        {
        !           496:                                if( c ) goto cream;
        !           497:                                continue;
        !           498:                        }
        !           499:                        if( q1->tn.rval != q2->tn.rval )
        !           500:                        {
        !           501:                                if( c ) goto cream;
        !           502:                                continue;
        !           503:                        }
        !           504:                        if( c ) continue;
        !           505: cream:
        !           506:                        /* clobber a line to newline, or up to an E */
        !           507:                        while( *++cp != '\n' && *cp != 'E' ) 
        !           508:                        {
        !           509:                                if( *cp == '\\' ) ++cp; /* hide next char */
        !           510:                                if( !*cp ) return;
        !           511:                        }
        !           512:                        continue;
        !           513: 
        !           514:                case 'F':  /* this line deleted if FOREFF is active */
        !           515:                        if( goal & FOREFF ) goto cream;
        !           516:                        continue;
        !           517: 
        !           518:                case 'S':  /* field size */
        !           519:                case 'H':  /* field shift */
        !           520:                case 'M':  /* field mask, in place */
        !           521:                case 'N':  /* field mask, right shifted */
        !           522:                        c = *cp;
        !           523:                        if( cp[1] == '~' ) 
        !           524:                        {
        !           525:                                if( c == 'M' ) c = 'm';
        !           526:                                else if( c == 'N' ) c = 'n';
        !           527:                                else cerror( "bad ~ after S or H" );
        !           528:                                ++cp;
        !           529:                        }
        !           530:                        else if( cp[1] == '?' ) 
        !           531:                        {
        !           532:                                if( c == 'H' ) c = 'h';
        !           533:                                else cerror( "bad ? after S, M, or N" );
        !           534:                                ++cp;
        !           535:                        }
        !           536:                        q1 = getadr(p,&cp);
        !           537:                        if( q1->tn.op != FLD ) cerror( "bad FLD for %c", c );
        !           538:                        fldsz = UPKFSZ(q1->tn.rval);
        !           539: # ifdef RTOLBYTES
        !           540:                        fldshf = UPKFOFF(q1->tn.rval);
        !           541: # else
        !           542:                        t = q1->tn.type;
        !           543:                        if( t & (TLONG|TULONG) )
        !           544:                        {
        !           545:                                fldshf = SZLONG - fldsz - UPKFOFF(q1->tn.rval);
        !           546:                        }
        !           547:                        else if( t & (TSHORT|TUSHORT) )
        !           548:                        {
        !           549:                                fldshf = SZSHORT - fldsz - UPKFOFF(q1->tn.rval);
        !           550:                        }
        !           551:                        else if( t & (TCHAR|TUCHAR) )
        !           552:                        {
        !           553:                                fldshf = SZCHAR - fldsz - UPKFOFF(q1->tn.rval);
        !           554:                        }
        !           555:                        else fldshf = SZINT - fldsz - UPKFOFF(q1->tn.rval);
        !           556: # endif
        !           557:                        if( c == 'h' ) 
        !           558:                        {
        !           559:                                if( fldshf == 0 ) goto cream;
        !           560:                                continue;
        !           561:                        }
        !           562:                        if( c=='S' || c=='H' )
        !           563:                        {
        !           564:                                printf( "%d", c=='S' ? fldsz : fldshf );
        !           565:                                continue;
        !           566:                        }
        !           567:                        val = 1;
        !           568:                        val <<= fldsz;
        !           569:                        --val;
        !           570:                        if( c=='M' || c == 'm' ) val <<= fldshf;
        !           571:                        if( c=='m' || c == 'n' ) val = ~val;
        !           572: # ifdef MYMASK
        !           573:                        MYMASK(val);
        !           574: # else
        !           575:                        printf( "%ld" , val );
        !           576: # endif
        !           577:                        continue;
        !           578: 
        !           579:                case 'L':  /* output special label field */
        !           580:                        printf( "%d", p->bn.label );
        !           581:                        continue;
        !           582: 
        !           583:                case 'C': /* for constant value only */
        !           584:                        conput( q1 = getadr( p, &cp ) );
        !           585:                        if( !sideff ) cerror( "constant with side effects?" );
        !           586:                        continue;
        !           587: 
        !           588:                case 'I': /* in instruction */
        !           589:                        insput( q1 = getadr( p, &cp ) );
        !           590:                        if( sideff ) rmside( q1 );
        !           591:                        continue;
        !           592: 
        !           593:                case 'A': /* address of */
        !           594:                        adrput( q1 = getadr( p, &cp ) );
        !           595:                        if( sideff ) rmside( q1 );
        !           596:                        continue;
        !           597: 
        !           598:                case 'U': /* for upper half of address, only */
        !           599:                        upput( q1 = getadr( p, &cp ) );
        !           600:                        if( sideff ) rmside( q1 );
        !           601:                        continue;
        !           602: #ifdef TMPSRET
        !           603:                case 'T': /* grab a temp for structure return and give it */
        !           604:                          /* to adrput */
        !           605:                        q1 = talloc();
        !           606:                        q1->tn.op = TEMP;
        !           607:                        q1->tn.type = TSTRUCT;
        !           608:                        q1->tn.lval = freetemp(p->stn.stsize / SZINT);
        !           609:                        q1->tn.lval = BITOOR(q1->tn.lval);
        !           610:                        adrput(q1);
        !           611:                        tfree(q1);
        !           612:                        continue;
        !           613: #endif
        !           614: 
        !           615:                }
        !           616:        }
        !           617: }
        !           618: 
        !           619: NODE *
        !           620: getlr( p, c )
        !           621: NODE *p; 
        !           622: 
        !           623: {
        !           624: 
        !           625:        /* return the pointer to the left or right side of p, or p itself,
        !           626:        ** depending on the optype of p 
        !           627:        */
        !           628: 
        !           629:        switch( c ) 
        !           630:        {
        !           631: 
        !           632:        case '1':
        !           633:        case '2':
        !           634:        case '3':
        !           635:                return( &resc[c-'1'] );
        !           636: 
        !           637:        case 'L':
        !           638:                return( optype( p->in.op ) == LTYPE ? p : p->in.left );
        !           639: 
        !           640:        case 'R':
        !           641:                return( optype( p->in.op ) != BITYPE ? p : p->in.right );
        !           642: 
        !           643:        }
        !           644:        cerror( "bad getlr: %c", c );
        !           645:        /* NOTREACHED */
        !           646: }
        !           647: 
        !           648: NODE *
        !           649: getadr( p, pc )
        !           650: NODE *p; 
        !           651: char **pc; 
        !           652: 
        !           653: {
        !           654:        /* like getlr, but allows (LL), (LR), etc. */
        !           655:        int c;
        !           656:        sideff = 1;
        !           657:        c = *++(*pc);
        !           658:        if( c == '-' )
        !           659:        {
        !           660:                c = *++(*pc);
        !           661:                sideff = 0;
        !           662:        }
        !           663:        if( c == '.' ) return( p );
        !           664:        else if( c != '(' ) return( getlr( p, c ) );
        !           665: 
        !           666:        for(;;) 
        !           667:        {
        !           668:                switch( c = *++(*pc) ) 
        !           669:                {
        !           670: 
        !           671:                case ')':
        !           672:                        return( p );
        !           673: 
        !           674:                case 'L':
        !           675:                        p = getl( p );
        !           676:                        continue;
        !           677: 
        !           678:                case 'R':
        !           679:                        p = getr( p );
        !           680:                        continue;
        !           681: 
        !           682:                default:
        !           683:                        cerror( "bad table char in (): %c", c );
        !           684:                }
        !           685:        }
        !           686:        /* NOTREACHED */
        !           687: }
        !           688: 
        !           689: long pow2[] = 
        !           690: {
        !           691:        01L,    02L,    04L,
        !           692:        010L,   020L,   040L,
        !           693:        0100L,  0200L,  0400L,
        !           694:        01000L, 02000L, 04000L,
        !           695:        010000L,        020000L,        040000L,
        !           696:        0100000L,       0200000L,       0400000L,
        !           697:        01000000L,      02000000L,      04000000L,
        !           698:        010000000L,     020000000L,     040000000L,
        !           699:        0100000000L,    0200000000L,    0400000000L,
        !           700:        01000000000L,   02000000000L,   04000000000L,
        !           701:        010000000000L,  020000000000L,  040000000000L,
        !           702: };
        !           703: 
        !           704: spshape( sh, p )
        !           705: NODE *p; 
        !           706: 
        !           707: {
        !           708:        long val;
        !           709:        int t, i;
        !           710: 
        !           711:        if( !(sh&SPECIAL) ) cerror( "spshape" );
        !           712:        if( sh&SPTYPE )
        !           713:        {
        !           714: # ifndef NODBG
        !           715:                if( sdebug )
        !           716:                        printf( "SPTYPE(%d, %o), ttype=%o\n", p-node,
        !           717:                                sh, p->tn.type );
        !           718: # endif
        !           719: 
        !           720:                if( sh & p->tn.type ) return( 1 );
        !           721:                else return( 0 );
        !           722:        }
        !           723:        t = (sh&STMASK);
        !           724:        i = (sh&SVMASK);
        !           725: 
        !           726:        switch( t ) 
        !           727:        {
        !           728: 
        !           729:        case SRANGE0:
        !           730:        case SSRANGE:
        !           731:                if( i<0 || i>31 ) cerror( "bad shape range" );
        !           732:        case SVAL:
        !           733:        case SNVAL:
        !           734:        case NACON:
        !           735: 
        !           736:                if( p->tn.op != ICON || p->tn.name != (char *) 0 ) return( 0 );
        !           737:                if( t == NACON ) return(1);
        !           738:                val = p->tn.lval;
        !           739:                if( t==SVAL && val == i ) return( 1 );
        !           740:                else if( t==SNVAL && val == -i ) return( 1 );
        !           741:                else if( t==SRANGE0 && val>=0 && val<pow2[i] ) return( 1 );
        !           742:                else if( t==SSRANGE && val>= -pow2[i] && val<pow2[i] )return(1);
        !           743:                return( 0 );
        !           744: 
        !           745:        case SUSER:
        !           746:                return( special( sh, p ) );
        !           747: 
        !           748:        default:
        !           749:                cerror( "bad special call" );
        !           750:                /* NOTREACHED */
        !           751:        }
        !           752: }

unix.superglobalmegacorp.com

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