Annotation of researchv9/cmd/sun/pcc/bound.c, revision 1.1.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.