Annotation of researchv9/cmd/sun/pcc/bound.c, revision 1.1

1.1     ! root        1: #ifndef lint
        !             2: static char sccsid[] = "@(#)bound.c 1.1 86/02/03 Copyr 1985 Sun Micro";
        !             3: #endif
        !             4: 
        !             5: /*
        !             6:  * Copyright (c) 1985 by Sun Microsystems, Inc.
        !             7:  */
        !             8: 
        !             9: #include "cpass2.h"
        !            10: #include "ctype.h"
        !            11: 
        !            12: int failsafe; /* very disgusting: see offstar() for use */
        !            13: 
        !            14: # define SAFETY( a, reg,  b ) \
        !            15:        {if ((reg & MUSTDO) && find_mustdo( a , reg )) {rewrite_rall( b, 1 );} }
        !            16: # define isareg(r) (rstatus[r]&SAREG)
        !            17: # define iscnode(p) (p->in.op==REG && iscreg(p->tn.rval))
        !            18: 
        !            19: # define max(x,y) ((x)<(y)?(y):(x))
        !            20: # define min(x,y) ((x)<(y)?(x):(y))
        !            21: 
        !            22: 
        !            23: static char *unsigned_branches[2] = { "jcs", "jls"};
        !            24: static char   *signed_branches[2] = { "jlt", "jle"};
        !            25: 
        !            26: trapv(type)
        !            27: {
        !            28:     if (chk_ovfl){
        !            29:        if (!ISPTR(type) && !ISUNSIGNED(type)){
        !            30:            print_str( "        trapv\n" );
        !            31:        }
        !            32:     }
        !            33: }
        !            34: 
        !            35: 
        !            36: #ifdef NOTDEF
        !            37: chksize(p)
        !            38:     NODE *p;
        !            39: {
        !            40:     /* check size of result after a multiply instruction */
        !            41:     int chklab = getlab();
        !            42:     int oklab;
        !            43:     int type = p->in.type;
        !            44:     int lb, ub;
        !            45:     char *regname = rnames[p->in.left->tn.rval];
        !            46:     if (chk_ovfl){
        !            47:        if (use68020){
        !            48:            switch(type){
        !            49:            case CHAR:
        !            50:                printf("\t.data\nL%d:\t.long\t-0x80,0x7f\n\t.text\n", chklab);
        !            51:                break;
        !            52:            case UCHAR:
        !            53:                printf("\t.data\nL%d:\t.long\t0,0xff\n\t.text\n", chklab);
        !            54:                break;
        !            55:            case SHORT:
        !            56:                printf("\t.data\nL%d:\t.long\t-0x8000,0x7fff\n\t.text\n", chklab);
        !            57:                break;
        !            58:            case USHORT:
        !            59:                printf("\t.data\nL%d:\t.long\t0,0xffff\n\t.text\n", chklab);
        !            60:                break;
        !            61:            default: 
        !            62:                trapv( type );
        !            63:                return;
        !            64:            }
        !            65:            printf("    chk2l   L%d,%s\n", chklab, regname);
        !            66:            return;
        !            67:        }else {
        !            68:            oklab = getlab();
        !            69:            switch(type){
        !            70:            case CHAR:
        !            71:                        lb = -128; ub = 127;
        !            72:                        break;
        !            73:            case SHORT:
        !            74:                        lb = -32768; ub = 32767;
        !            75:            signed:
        !            76:                        printf("        cmpl    #%#x,%s\n", lb, regname);
        !            77:                        break;
        !            78:            case UCHAR:
        !            79:                        ub = 255;
        !            80:                        break;
        !            81:            case USHORT:
        !            82:                        ub = 0xffff;
        !            83:                        break;
        !            84:            default: 
        !            85:                        trapv( type );
        !            86:                        return;
        !            87:            }
        !            88:            printf("    jlt     L%d\n", chklab);
        !            89:            printf("    cmpl    #%#x,%s\n", ub, regname);
        !            90:            printf("    jle     L%d\n", oklab);
        !            91:            printf("L%d:        chk     #-1,%s\n", chklab, regname);
        !            92:            printf("L%d:\n", oklab);
        !            93:        }
        !            94:     }
        !            95: }
        !            96: #endif
        !            97: 
        !            98: /* generate a copy of p ; p should be simple */
        !            99: 
        !           100: static char *
        !           101: rcopy(p)
        !           102:     NODE *p;
        !           103: {
        !           104:     NODE *temp;
        !           105:     int r;
        !           106: 
        !           107:     if (busy[D0] && busy[D1])
        !           108:        return(NULL);
        !           109:     temp = tcopy(p);
        !           110:     order(temp, INTAREG);
        !           111:     r = temp->tn.rval;
        !           112:     reclaim(temp, RNULL, FOREFF);
        !           113:     return(rnames[r]);
        !           114: }
        !           115: 
        !           116: bound_test( p, cookie )
        !           117:     register NODE *p;
        !           118: {
        !           119:     register NODE *expr, *lb, *ub;
        !           120:     register t = p->in.type;
        !           121:     NODE *bounds = p->in.right;
        !           122:     int chklab, oklab;
        !           123:     char *size;
        !           124:     char  **branch;
        !           125:     NODE *copy;
        !           126:     char *regname;
        !           127: 
        !           128:     expr = p->in.left;
        !           129:     lb = bounds->in.left;
        !           130:     ub = bounds->in.right;
        !           131:     if (!chk_ovfl){
        !           132:        order( expr, cookie );
        !           133:        return;
        !           134:     }
        !           135:     regname = rnames[expr->tn.rval];
        !           136:     /*
        !           137:      * see if we can use the chk or chkl instructions.
        !           138:      * For nonzero lower bounds, try to generate a copy and
        !           139:      * subtract the lower bound.  In array subscripting the
        !           140:      * lower bound must be subtracted anyway; c2 may be able
        !           141:      * to identify this as a cse.
        !           142:      */
        !           143:     if (lb->in.op == ICON && lb->in.name[0] == '\0' &&
        !           144:        ub->in.op == ICON && ub->in.name[0] == '\0' ){
        !           145:        /* constant bounds */
        !           146:        switch(t){
        !           147:        case CHAR:
        !           148:            printf("    extw    %s\n", regname );
        !           149:            p->in.type = expr->in.type = SHORT;
        !           150:            goto use_chkw;
        !           151:        case UCHAR: 
        !           152:            printf("    andw    #0xff,%s\n", regname );
        !           153:            p->in.type = expr->in.type = SHORT;
        !           154:            /* FALL THROUGH */
        !           155:        case SHORT:
        !           156:        use_chkw:
        !           157:            if (lb->tn.lval) {
        !           158:                char *regcopy = rcopy(expr);
        !           159:                if (regcopy == NULL) goto long_case;
        !           160:                regname = regcopy;
        !           161:                printf("        subw    #0x%x,%s\n", lb->tn.lval, regname);
        !           162:            }
        !           163:            if (ub->tn.lval - lb->tn.lval < 0x8000) {
        !           164:                printf("        chk     #0x%x,%s\n", ub->tn.lval-lb->tn.lval,
        !           165:                    regname);
        !           166:            } else {
        !           167:                printf("        cmpw    #0x%x,%s\n", ub->tn.lval-lb->tn.lval,
        !           168:                    regname);
        !           169:                oklab = getlab();
        !           170:                printf("        jls     L%d\n", oklab);
        !           171:                printf("        chk     #-1,%s\n", regname);
        !           172:                printf("L%d:\n", oklab);
        !           173:            }
        !           174:            break;
        !           175:        case USHORT:
        !           176:            if (ub->tn.lval <= 0x7fff) goto use_chkw;
        !           177:            printf("    andl    #0xffff,%s\n", regname);
        !           178:            p->in.type = expr->in.type = INT;
        !           179:            /* FALL THROUGH */
        !           180:        default:
        !           181:            if (lb->tn.lval == -32768 && ub->tn.lval == 32767) {
        !           182:                /* common case, can be done without long literals */
        !           183:                char *regcopy = rcopy(expr);
        !           184:                if (regcopy == NULL) goto long_case;
        !           185:                regname = regcopy;
        !           186:                printf("        extl    %s\n", regname);
        !           187:                expand(p, cookie, "     cmpl    AL,");
        !           188:                printf("%s\n", regname);
        !           189:                oklab = getlab();
        !           190:                printf("        jeq     L%d\n", oklab);
        !           191:                printf("        chk     #-1,%s\n", regname);
        !           192:                printf("L%d:\n", oklab);
        !           193:                break;
        !           194:            }
        !           195:            if (lb->tn.lval) {
        !           196:                char *regcopy = rcopy(expr);
        !           197:                if (regcopy == NULL) goto long_case;
        !           198:                regname = regcopy;
        !           199:                printf("        subl    #0x%x,%s\n", lb->tn.lval, regname);
        !           200:            }
        !           201:            if (use68020 && (unsigned)(ub->tn.lval-lb->tn.lval) < 0x80000000) {
        !           202:                printf("        chkl    #0x%x,%s\n", ub->tn.lval-lb->tn.lval,
        !           203:                    regname);
        !           204:            } else {
        !           205:                printf("        cmpl    #0x%x,%s\n", ub->tn.lval-lb->tn.lval,
        !           206:                    regname);
        !           207:                oklab = getlab();
        !           208:                printf("        jls     L%d\n", oklab);
        !           209:                printf("        chk     #-1,%s\n", regname);
        !           210:                printf("L%d:\n", oklab);
        !           211:            }
        !           212:            break;
        !           213:        }
        !           214:        return;
        !           215: long_case:
        !           216:        if (use68020) {
        !           217:            /* use chk2l */
        !           218:            switch(t){
        !           219:            case CHAR:
        !           220:            case UCHAR:
        !           221:                size = "byte"; break;
        !           222:            case SHORT:
        !           223:            case USHORT:
        !           224:                size = "word"; break;
        !           225:            default:
        !           226:                size = "long"; break;
        !           227:            }
        !           228:            chklab = getlab();
        !           229:            printf("    .data\nL%d: .%s %d,%d\n .text\n",
        !           230:                chklab, size, lb->tn.lval, ub->tn.lval);
        !           231:            printf("    chk2%c  L%d,%s\n", size[0], chklab, regname);
        !           232:            return;
        !           233:        }
        !           234:     }
        !           235:     /* can't use any chk instructions -- do cmp & branch */
        !           236:     branch = unsigned_branches;
        !           237:     if (ISUNSIGNED(t) || ISPTR(t))
        !           238:        branch = unsigned_branches;
        !           239:     else
        !           240:        branch =   signed_branches;
        !           241:     chklab = getlab();
        !           242:     oklab  = getlab();
        !           243:     if (adjacent(lb, ub)) {
        !           244:        /*
        !           245:         * bounds are in adjacent memory operands
        !           246:         */
        !           247:        if (SUTEST(lb->in.su))
        !           248:            order(lb, SOREG);
        !           249:        p->in.right = lb;
        !           250:        if (use68020) {
        !           251:            expand( p, FORCC, " chk2ZB  AR,AL\n");
        !           252:            p->in.right = bounds;
        !           253:            reclaim( lb, RNULL, FOREFF );
        !           254:            reclaim( ub, RNULL, FOREFF );
        !           255:            return;
        !           256:        } else {
        !           257:            expand( p, FORCC, " cmpZB   AR,AL\n");
        !           258:            printf("    %s      L%d\n", branch[0], chklab);
        !           259:            expand( p, FORCC, " cmpZB   UR,AL\n");
        !           260:            printf("    %s      L%d\n", branch[1], oklab);
        !           261:            reclaim( lb, RNULL, FOREFF );
        !           262:            reclaim( ub, RNULL, FOREFF );
        !           263:            /* finish up below */
        !           264:        }
        !           265:     } else {
        !           266:        /* 
        !           267:         * lower bound
        !           268:         */
        !           269:        if (SUTEST(lb->in.su)) {
        !           270:            order( lb, INTAREG|INTEMP|SOREG );
        !           271:        }
        !           272:        p->in.right = lb;
        !           273:        expand( p, FORCC, "     cmpZB   AR,AL\n");
        !           274:        printf("        %s      L%d\n", branch[0], chklab);
        !           275:        reclaim( lb, RNULL, FOREFF );
        !           276:        /* 
        !           277:         * upper bound
        !           278:         */
        !           279:        if (SUTEST(ub->in.su)) {
        !           280:            order( ub, INTAREG|INTEMP|SOREG );
        !           281:        }
        !           282:        p->in.right = ub;
        !           283:        expand( p, FORCC, "     cmpZB   AR,AL\n");
        !           284:        printf("        %s      L%d\n", branch[1], oklab);
        !           285:        reclaim( ub, RNULL, FOREFF );
        !           286:     }
        !           287: 
        !           288:     printf("L%d:       chk     #-1,%s\n", chklab, regname);
        !           289:     printf("L%d:\n", oklab);
        !           290:     p->in.right = bounds;
        !           291: 
        !           292: }
        !           293: 
        !           294: 
        !           295: #define true 1
        !           296: #define false 0
        !           297: 
        !           298: /*
        !           299:  * are operands p and q adjacent
        !           300:  * (in the sense assumed by upput() and adrput())?
        !           301:  */
        !           302: int
        !           303: adjacent(p,q)
        !           304:     register NODE *p,*q;
        !           305: {
        !           306:     register NODE *lp, *lq;
        !           307:     register o;
        !           308:     int result;
        !           309:     CONSZ temp;
        !           310: 
        !           311:     o = p->in.op;
        !           312:     if (o != q->in.op)
        !           313:        return false;
        !           314:     switch(o) {
        !           315:     case NAME:
        !           316:     case OREG:
        !           317:        p->tn.lval+= SZINT/SZCHAR;
        !           318:        result = equal(p,q);
        !           319:        p->tn.lval-= SZINT/SZCHAR;
        !           320:        return result;
        !           321:     case UNARY MUL:
        !           322:        lp = p->in.left;
        !           323:        lq = q->in.left;
        !           324:        if (lp->in.op == PLUS && lq->in.op == PLUS) {
        !           325:            lp = lp->in.right;
        !           326:            lq = lq->in.right;
        !           327:            if (lp->in.op == ICON && lq->in.op == ICON) {
        !           328:                if (lp->tn.lval+SZINT/SZCHAR == lq->tn.lval) {
        !           329:                    lp->tn.lval += SZINT/SZCHAR;
        !           330:                    result = equal(p,q);
        !           331:                    lp->tn.lval -= SZINT/SZCHAR;
        !           332:                    return result;
        !           333:                }
        !           334:            }
        !           335:        }
        !           336:        break;
        !           337:     }
        !           338:     return false;
        !           339: }
        !           340: 
        !           341: /*
        !           342:  * equal(p,q) : returns 1 if expressions p and q are equivalent,
        !           343:  *     in the sense that they always return the same value given
        !           344:  *     the same initial values of their operands.  Note that if
        !           345:  *     either p or q contains operators producing side-effects,
        !           346:  *     equal(p,q) = 0.
        !           347:  */
        !           348: 
        !           349: int
        !           350: equal(p,q)
        !           351:     register NODE *p,*q;
        !           352: {
        !           353:     register char *pn,*qn;
        !           354:     register o;
        !           355: 
        !           356:     if (p == q)
        !           357:        return true;
        !           358:     if (p == NIL || q == NIL)
        !           359:        return false;
        !           360:     o = p->in.op;
        !           361:     if (o != q->in.op)
        !           362:        return false;
        !           363:     if (p->in.type != q->in.type)
        !           364:        return false;
        !           365:     switch(optype(o)) {
        !           366:     case UTYPE:
        !           367:        if (callop(o))
        !           368:            return false;
        !           369:        return equal(p->in.left, q->in.left);
        !           370:     case BITYPE:
        !           371:        if (callop(o) || asgop(o))
        !           372:            return false;
        !           373:        if (equal(p->in.left, q->in.left))
        !           374:            return equal(p->in.right, q->in.right);
        !           375:        return false;
        !           376:     default:
        !           377:        /* leaf nodes */
        !           378:        switch (o) {
        !           379:        case ICON:
        !           380:        case OREG:
        !           381:        case NAME:
        !           382:            pn = p->tn.name;
        !           383:            qn = q->tn.name;
        !           384:            if (pn != NULL && qn != NULL) {
        !           385:                if ( *pn == *qn 
        !           386:                  && (*pn == '\0' || strcmp(pn,qn) == 0) ) {
        !           387:                    return (p->tn.lval == q->tn.lval);
        !           388:                }
        !           389: 
        !           390:            } else if (pn == qn) {      /* == NULL */
        !           391:                return ( p->tn.lval == q->tn.lval );
        !           392:            }
        !           393:            return false;
        !           394:        case REG:
        !           395:            return(p->tn.rval == q->tn.rval);
        !           396:        case FCON:
        !           397:            return(p->fpn.dval == q->fpn.dval);
        !           398:        }
        !           399:     }
        !           400:     return false;
        !           401: }

unix.superglobalmegacorp.com

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