Annotation of 43BSDTahoe/lib/old_compiler/c2/c2.tahoe/save2/c22.c, revision 1.1

1.1     ! root        1: #ifndef lint
        !             2: static char sccsid[] = "%W% (Berkeley/CCI) %G%";
        !             3: #endif
        !             4: 
        !             5: /*
        !             6:  * C object code improver-- third part
        !             7:  */
        !             8: 
        !             9: #include "c2.h"
        !            10: #include <stdio.h>
        !            11: #include <ctype.h>
        !            12: 
        !            13: rmove()
        !            14: {
        !            15:        register struct node *p;
        !            16:        register int r, r1;
        !            17: 
        !            18:        clearreg();
        !            19:        for (p=first.forw; p!=0; p = p->forw) {
        !            20:        if (debug) {
        !            21:                printf("Regs: ");
        !            22:                for (r=0; r<=NREG; r++)
        !            23:                        if (regs[r][0]) {
        !            24:                                r1=regs[r][0];
        !            25:                                printf("%d: %d%d %s\n", r, r1&0xF, r1>>4, regs[r]+1);
        !            26:                        }
        !            27:                printf("-\n");
        !            28:        }
        !            29:        switch (p->op) {
        !            30: 
        !            31:        case CVT:
        !            32:        case MOVZ:
        !            33:                splitrand(p);
        !            34:                repladdr(p);
        !            35:                r = isreg(regs[RT1]);
        !            36:                r1 = isreg(regs[RT2]);
        !            37:                dest(regs[RT2],p->subop, 1);
        !            38:                if (r>=0 && r1>=0) {
        !            39:                        p->op = MOV; p->subop = LONG;
        !            40:                        p->pop = 0;
        !            41:                        nchange++;
        !            42:                        goto case_mov;
        !            43:                }
        !            44:                if(p->op == CVT) {
        !            45:                        if (r1>=0) savereg(r1, regs[RT1], p->subop);
        !            46:                } else
        !            47:                        ccloc[0] = 0;
        !            48:                break;
        !            49: 
        !            50:        case MOV:
        !            51:        case_mov:
        !            52:                splitrand(p);
        !            53:                if ((r = findrand(regs[RT1],p->subop)) >= 0) {
        !            54:                        if (r == isreg(regs[RT2]))
        !            55:                                if(p->forw->op!=CBR) {
        !            56:                                        delnode(p); redunm++; nchange++; break;
        !            57:                                } else {
        !            58:                                        p->op=TST; p->pop=0;
        !            59:                                        while(*p->code++ != ',');
        !            60:                                        redunm++; nchange++;
        !            61:                                        goto case_tst;
        !            62:                                }
        !            63:                }
        !            64:                repladdr(p);
        !            65:                r = isreg(regs[RT1]);
        !            66:                r1 = isreg(regs[RT2]);
        !            67:                dest(regs[RT2],p->subop, 1);
        !            68:                if ((regs[ACC][0]) && equstr(regs[RT2],regs[ACC]+1))
        !            69:                        *(short *)(regs[ACC]) = 0;
        !            70:                if (r>=0) {
        !            71:                        if (r1>=0) {
        !            72:                                if (r == r1 && p->forw->op!=CBR) {
        !            73:                                        delnode(p); redunm++; nchange++;
        !            74:                                        break;
        !            75:                                }
        !            76:                                if(regs[r][0])
        !            77:                                        savereg(r1, regs[r]+1, p->subop);
        !            78:                        } else
        !            79:                                savereg(r, regs[RT2], p->subop);
        !            80:                } else if (r1>=0)
        !            81:                        savereg(r1, regs[RT1], p->subop);
        !            82:                else
        !            83:                        setcon(regs[RT1], regs[RT2], p->subop);
        !            84:                break;
        !            85: 
        !            86: /* .rx,.wx or .rx,.rx,.wx */
        !            87:        case ADD:
        !            88:        case SUB:
        !            89:        case AND:
        !            90:        case OR:
        !            91:        case XOR:
        !            92:        case MUL:
        !            93:        case DIV:
        !            94: #ifdef EMOD
        !            95:        case EDIV:
        !            96:        case EMOD:
        !            97: #endif EMOD
        !            98:        case SHAL:
        !            99:        case SHAR:
        !           100:        case SHL:
        !           101:        case SHR:
        !           102:        case ADDA:
        !           103:        case SUBA:
        !           104: /* .rx,.wx */
        !           105:        case MFPR:
        !           106:        case COM:
        !           107:        case NEG:
        !           108:                splitrand(p);
        !           109:                repladdr(p);
        !           110:                dest(lastrand,p->subop, p->op!=ADDA && p->op!=SUBA);
        !           111:                break;
        !           112: 
        !           113: /* .mx or .wx */
        !           114:        case STF:
        !           115:                if(equstr(p->code, regs[ACC]+1) && p->subop==regs[ACC][0]) {
        !           116:                        delnode(p);
        !           117:                        nst++; nchange++; break;
        !           118:                }
        !           119:                savereg(ACC, p->code, p->subop);
        !           120:        case INC:
        !           121:        case DEC:
        !           122:        case CVFL:
        !           123:                dest(p->code,p->subop, 1);
        !           124:                break;
        !           125: 
        !           126:        case CLR:
        !           127:                dest(p->code,p->subop, 1);
        !           128:                if ((regs[ACC][0]) && equstr(p->code,regs[ACC]+1))
        !           129:                        *(short *)(regs[ACC]) = 0;
        !           130:                if ((r = isreg(p->code)) < 0)
        !           131:                        setcon("$0", p->code, p->subop);
        !           132:                else
        !           133:                        savereg(r, "$0", p->subop);
        !           134:                break;
        !           135: 
        !           136: /* .rx */
        !           137:        case LDF:
        !           138:                if(equstr(p->code, regs[ACC]+1) && p->subop==regs[ACC][0]) {
        !           139:                        delnode(p);
        !           140:                        nld++; nchange++; break;
        !           141:                }
        !           142:                savereg(ACC, p->code, p->subop);
        !           143:                goto case_tst;
        !           144:        case LNF:
        !           145:                if(equstr(p->code, regs[ACC]+1) && p->subop==regs[ACC][0]) {
        !           146:                        p->op = NEGF; p->pop = 0; p->code = 0;
        !           147:                        regs[ACC][0] = 0;
        !           148:                        break;
        !           149:                }
        !           150:        case CVLF:
        !           151:        case LDFD:
        !           152:        case ADDF:
        !           153:        case SUBF:
        !           154:        case MULF:
        !           155:        case DIVF:
        !           156:                regs[ACC][0] = 0;
        !           157:        case TST:
        !           158:        case_tst:
        !           159:        case PUSH:
        !           160:                splitrand(p);
        !           161:                lastrand=regs[RT1+1]; /* fool repladdr into doing 1 operand */
        !           162:                repladdr(p);
        !           163:                lastrand=regs[RT1];
        !           164:                if (p->op==TST && equstr(lastrand, ccloc+1)
        !           165:                  && ((0xf&(ccloc[0]>>4))==p->subop || equtype(ccloc[0],p->subop))) {
        !           166:                        delnode(p); nrtst++; nchange++; break;
        !           167:                }
        !           168:                if (p->op==PUSH && p->subop!=LONG &&
        !           169:                 (isreg(lastrand)>=0 || *lastrand=='$')) {
        !           170:                        p->subop = LONG;
        !           171:                        p->pop = 0;
        !           172:                        nchange++;
        !           173:                }
        !           174:                if (p->op==TST || p->op==PUSH)
        !           175:                        setcc(lastrand,p->subop);
        !           176:                break;
        !           177: 
        !           178: /* .rx,.rx,.rx */
        !           179:        case PROBE:
        !           180:        case CASE:
        !           181: /* .rx,.rx */
        !           182:        case MTPR:
        !           183:        case CALLS:
        !           184:        case CALLF:
        !           185:        case CMP:
        !           186:        case BIT:
        !           187:        case CMPF:
        !           188:        case CMPF2:
        !           189:                splitrand(p);
        !           190:                /* fool repladdr into doing right number of operands */
        !           191:                lastrand=byondrd(p);
        !           192:                if (p->op==CALLF || p->op==CALLS) clearreg();
        !           193:                else repladdr(p);
        !           194:        case TSTF:
        !           195:                ccloc[0]=0;
        !           196:        case PUSHD:
        !           197:                break;
        !           198: 
        !           199: /* acc only */
        !           200:        case CVDF:
        !           201:        case NEGF:
        !           202:        case SINF:
        !           203:        case COSF:
        !           204:        case ATANF:
        !           205:        case LOGF:
        !           206:        case SQRTF:
        !           207:        case EXPF:
        !           208:                regs[ACC][0] = 0;
        !           209:                break;
        !           210: 
        !           211: #ifndef EMOD
        !           212: /* .rx,.rx,.wx,.wx */
        !           213:        case EDIV:
        !           214:                splitrand(p);
        !           215:                lastrand = regs[RT3];
        !           216:                repladdr(p);
        !           217:                dest(regs[RT3], p->subop, 1);
        !           218:                dest(regs[RT4], p->subop, 0);
        !           219:                break;
        !           220: #endif EMOD
        !           221: 
        !           222: /* .rx,.rx,.rx,wx */
        !           223:        case EMUL:
        !           224:                splitrand(p);
        !           225:                lastrand = regs[RT4];
        !           226:                repladdr(p);
        !           227:                dest(regs[RT4],QUAD, 1); /* fourth operand is a quad */
        !           228:                break;
        !           229:        case CBR:
        !           230:                if (p->subop>=JBC) {
        !           231:                        splitrand(p);
        !           232:                        lastrand=regs[RT3]; /* 2 operands can be optimized */
        !           233:                        repladdr(p);
        !           234:                        ccloc[0] = 0;
        !           235:                } else
        !           236:                        reduncbr(p);
        !           237:                break;
        !           238: 
        !           239:        case JBR:
        !           240:                redunbr(p);
        !           241: 
        !           242:        default:
        !           243:                clearreg();
        !           244:        }
        !           245:        }
        !           246: }
        !           247: 
        !           248: jumpsw()
        !           249: {
        !           250:        register struct node *p, *p1, *pt;
        !           251:        register int t, nj;
        !           252: 
        !           253:        t = 0;
        !           254:        nj = 0;
        !           255:        for (p=first.forw; p!=0; p = p->forw)
        !           256:                p->seq = ++t;
        !           257:        for (p=first.forw; p!=0; p = p1) {
        !           258:                p1 = p->forw;
        !           259:                if (p->op == CBR && p1->op==JBR && p->ref && p1->ref
        !           260:                 && abs(p->seq - p->ref->seq) > abs(p1->seq - p1->ref->seq)) {
        !           261:                        if (p->ref==p1->ref)
        !           262:                                continue;
        !           263:                        p->subop = revbr[p->subop];
        !           264:                        p->pop=0;
        !           265:                        pt = p1->ref;
        !           266:                        p1->ref = p->ref;
        !           267:                        p->ref = pt;
        !           268:                        t = p1->labno;
        !           269:                        p1->labno = p->labno;
        !           270:                        p->labno = t;
        !           271: #ifdef COPYCODE
        !           272:                        if (p->labno == 0) {
        !           273:                                pt = (struct node *)p1->code; p1->code = p->code; p->code = (char *)pt;
        !           274:                        }
        !           275: #endif
        !           276:                        nrevbr++;
        !           277:                        nj++;
        !           278:                }
        !           279:        }
        !           280:        return(nj);
        !           281: }
        !           282: 
        !           283: addaob()
        !           284: {
        !           285:        register struct node *p, *p1, *p2, *p3;
        !           286: 
        !           287:        for (p = &first; (p1 = p->forw)!=0; p = p1) {
        !           288:        if (p->op==INC && p->subop==LONG) {
        !           289:                if (p1->op==LABEL && p1->refc==1 && p1->forw->op==CMP && p1->forw->subop==LONG
        !           290:                  && (p2=p1->forw->forw)->op==CBR && p2->subop==JLE
        !           291:                  && (p3=p2->ref->back)->op==JBR && p3->subop==0 && p3->ref==p1
        !           292:                  && p3->forw->op==LABEL && p3->forw==p2->ref) {
        !           293:                        /* change       INC LAB: CMP    to      LAB: INC CMP */
        !           294:                        p->back->forw=p1; p1->back=p->back;
        !           295:                        p->forw=p1->forw; p1->forw->back=p;
        !           296:                        p->back=p1; p1->forw=p;
        !           297:                        p1=p->forw;
        !           298:                        /* adjust beginning value by 1 */
        !           299:                        p2=alloc(sizeof first); p2->op = DEC; p2->subop = LONG;
        !           300:                        p2->pop=0;
        !           301:                        p2->forw=p3; p2->back=p3->back; p3->back->forw=p2;
        !           302:                        p3->back=p2; p2->code=p->code; p2->labno=0;
        !           303:                }
        !           304:                if (p1->op==CMP && p1->subop==LONG &&
        !           305:                  (p2=p1->forw)->op==CBR && p2->forw->op!=CBR) {
        !           306:                        register char *cp1,*cp2;
        !           307:                        splitrand(p1); if (!equstr(p->code,regs[RT1])) continue;
        !           308:                        if ((p2->subop==JLE || p2->subop==JLT) &&
        !           309:                            checkaobdisp(p2)){
        !           310:                                if (p2->subop==JLE) p->op = AOBLEQ; else p->op = AOBLSS; p->subop = 0;
        !           311:                                cp2=regs[RT1]; cp1=regs[RT2]; while (*cp2++= *cp1++); /* limit */
        !           312:                                cp2=regs[RT2]; cp1=p->code; while (*cp2++= *cp1++); /* index */
        !           313:                                p->pop=0; newcode(p);
        !           314:                                p->labno = p2->labno; delnode(p2); delnode(p1); naob++;
        !           315:                        }
        !           316:                }
        !           317:        }
        !           318:        }
        !           319: }
        !           320: 
        !           321: ispow2(n) register long n; {/* -1 -> no; else -> log to base 2 */
        !           322:        register int log;
        !           323:        if (n==0 || n&(n-1)) return(-1); log=0;
        !           324:        for (;;) {n >>= 1; if (n==0) return(log); ++log; if (n== -1) return(log);}
        !           325: }
        !           326: 
        !           327: equop(p1, p2)
        !           328: register struct node *p1, *p2;
        !           329: {
        !           330:        register char *cp1, *cp2;
        !           331: 
        !           332:        if (p1->op != p2->op || p1->subop != p2->subop)
        !           333:                return(0);
        !           334:        if (p1->op != NIL && ord(p1->op) < ord(MOV))
        !           335:                return(0);
        !           336:        if (p1->op==MOVA && p1->labno!=p2->labno) return(0);
        !           337:        cp1 = p1->code;
        !           338:        cp2 = p2->code;
        !           339:        if (cp1==0 && cp2==0)
        !           340:                return(1);
        !           341:        if (cp1==0 || cp2==0)
        !           342:                return(0);
        !           343:        while (*cp1 == *cp2++)
        !           344:                if (*cp1++ == 0)
        !           345:                        return(1);
        !           346:        return(0);
        !           347: }
        !           348: 
        !           349: delnode(p) register struct node *p; {
        !           350:        p->back->forw = p->forw;
        !           351:        p->forw->back = p->back;
        !           352: }
        !           353: 
        !           354: decref(p)
        !           355: register struct node *p;
        !           356: {
        !           357:        if (p && --p->refc <= 0) {
        !           358:                nrlab++; nchange++;
        !           359:                delnode(p);
        !           360:        }
        !           361: }
        !           362: 
        !           363: struct node *
        !           364: nonlab(ap)
        !           365: struct node *ap;
        !           366: {
        !           367:        register struct node *p;
        !           368: 
        !           369:        p = ap;
        !           370:        while (p && p->op==LABEL)
        !           371:                p = p->forw;
        !           372:        return(p);
        !           373: }
        !           374: 
        !           375: clearuse() {
        !           376:        register struct node **i;
        !           377:        register short *p;
        !           378:        for (i=uses+NREG; i>uses;) *--i=0;
        !           379:        useacc = 0;
        !           380:        for (p=usecnt+NUSE; p>usecnt;) *--p=0;
        !           381: }
        !           382: 
        !           383: clearreg() {
        !           384:        register char **i;
        !           385:        for (i=regs+NREG+1; i>regs;){ **--i=0; **i=0; }
        !           386:        conloc[0] = 0; ccloc[0] = 0;
        !           387: }
        !           388: 
        !           389: savereg(ai, s, type)
        !           390: register char *s;
        !           391: {
        !           392:        register char *p, *sp;
        !           393: 
        !           394:        sp = p = regs[ai];
        !           395:        /* if any indexing, must be parameter or local */
        !           396:        /* indirection (as in "*-4(fp)") is ok, however */
        !           397:        *p++ = type;
        !           398:        if (*s=='*' || *s=='$')
        !           399:                *p++ = *s++;
        !           400:        if (natural(s))
        !           401:                strcpy(p, s);
        !           402:        else {*sp = 0; return;}
        !           403: }
        !           404: 
        !           405: dest(s,type, ccflg)
        !           406: register char *s;
        !           407: {
        !           408:        register int i;
        !           409: 
        !           410:        if ((i = isreg(s)) >= 0) {
        !           411:                *(short *)(regs[i]) = 0; /* if register destination, that reg is a goner */
        !           412:                if (DOUBLE==(type&0xF) || DOUBLE==((type>>4)&0xF) || type==QUAD)
        !           413:                        *(short *)(regs[i+1]) = 0;
        !           414:        }
        !           415:        for (i=NREG; --i>=0;)
        !           416:                if (regs[i][1]=='*' && equstr(s, regs[i]+2))
        !           417:                        *(short *)(regs[i]) = 0; /* previous indirection through destination is invalid */
        !           418:        while ((i = findrand(s,0)) >= 0) /* previous values of destination are invalid */
        !           419:                *(short *)(regs[i]) = 0;
        !           420: 
        !           421:        if (!natural(s)) {/* wild store, everything except constants vanishes */
        !           422:                for (i=NREG; --i>=0;) if (regs[i][1] != '$') *(short *)(regs[i]) = 0;
        !           423:                conloc[0] = 0; ccloc[0] = 0;
        !           424:        } else {
        !           425:                if(ccflg)setcc(s,type); /* natural destinations set condition codes */
        !           426:                if (equstr(s, conloc))
        !           427:                        conloc[0] = 0;
        !           428:        }
        !           429: }
        !           430: 
        !           431: splitrand(p) struct node *p; {
        !           432: /* separate operands at commas, set up 'regs' and 'lastrand' */
        !           433: register char *p1, *p2; register char **preg;
        !           434: 
        !           435:        preg=regs+RT1;
        !           436:        if (p1=p->code) while (*p1) {
        !           437:                lastrand=p2= *preg++;
        !           438:                while (*p1) if (','==(*p2++= *p1++)) {--p2; break;}
        !           439:                *p2=0;
        !           440:        }
        !           441:        while (preg<(regs+RT1+5)) *(*preg++)=0;
        !           442: }
        !           443: 
        !           444: compat(have, want)
        !           445: register int have, want;
        !           446: {
        !           447:        register int hsrc, hdst;
        !           448:        extern int bitsize[];
        !           449: 
        !           450:        if (0==(want &= 0xF)) return(1); /* anything satisfies a wildcard want */
        !           451:        hsrc=have&0xF; if (0==(hdst=((have>>4)&0xF)) || hdst>=OP2) hdst=hsrc;
        !           452:        if (want>=QUAD)
        !           453:                return(bitsize[hdst]==bitsize[want] && bitsize[hsrc]==bitsize[want]);
        !           454:        return(hsrc==want && hdst>=want && hdst<QUAD);
        !           455: }
        !           456: 
        !           457: equtype(t1,t2) {return(compat(t1,t2) && compat(t2,t1));}
        !           458: 
        !           459: findrand(as, type)
        !           460: char *as;
        !           461: {
        !           462:        register char **i;
        !           463:        for (i = regs+NREG; --i>=regs;) {
        !           464:                if (**i && equstr(*i+1, as) && compat(**i,type))
        !           465:                        return(i-regs);
        !           466:        }
        !           467:        return(-1);
        !           468: }
        !           469: 
        !           470: isreg(s)
        !           471: register char *s;
        !           472: {
        !           473:        if (*s++!='r' || !isdigit(*s++)) return(-1);
        !           474:        if (*s==0) return(*--s-'0');
        !           475:        if (*(s-1)=='1' && isdigit(*s++) && *s==0) return(10+*--s-'0');
        !           476:        return(-1);
        !           477: }
        !           478: 
        !           479: /*
        !           480: check()
        !           481: {
        !           482:        register struct node *p, *lp;
        !           483: 
        !           484:        lp = &first;
        !           485:        for (p=first.forw; p!=0; p = p->forw) {
        !           486:                if (p->back != lp)
        !           487:                        abort(-1);
        !           488:                lp = p;
        !           489:        }
        !           490: }
        !           491: */
        !           492: 
        !           493: newcode(p) struct node *p; {
        !           494:        register char *p1,*p2,**preg;
        !           495: 
        !           496:        preg=regs+RT1; p2=line;
        !           497:        while (*(p1= *preg++)) {while (*p2++= *p1++); *(p2-1)=',';}
        !           498:        *--p2=0;
        !           499:        p->code=copy(line);
        !           500: }
        !           501: 
        !           502: repladdr(p)
        !           503: struct node *p;
        !           504: {
        !           505:        register int r;
        !           506:        register char *p1;
        !           507:        register char **preg;
        !           508:        register int nrepl;
        !           509: 
        !           510:        preg=regs+RT1; nrepl=0;
        !           511:        while (lastrand!=(p1= *preg++))
        !           512:                if (0<=(r=findrand(p1,p->subop))) {
        !           513:                        *p1++='r'; if (r>9) {*p1++='1'; r -= 10;} *p1++=r+'0'; *p1=0;
        !           514:                        nchange++; nrepl++; nsaddr++;
        !           515:                }
        !           516:        if (nrepl) newcode(p);
        !           517: }
        !           518: 
        !           519: /* conditional branches which are never/always taken */
        !           520: reduncbr(p)
        !           521: register struct node *p;
        !           522: {
        !           523:        register struct node *p1;
        !           524:        register char *ap1, *ap2;
        !           525: 
        !           526:        p1 = p->back;
        !           527:        if (p1->op==CMP) {
        !           528:                splitrand(p1);
        !           529:                ap1 = findcon(regs[RT1], p1->subop);
        !           530:                ap2 = findcon(regs[RT2], p1->subop);
        !           531:        } else {
        !           532:                if(!ccloc[0])
        !           533:                        return;
        !           534:                ap1 = findcon(ccloc+1, ccloc[0]);
        !           535:                ap2 = "$0";
        !           536:        }
        !           537:        switch (compare(p->subop, ap1, ap2)) {
        !           538:        case 0:         /* branch never taken */
        !           539:                delnode(p);
        !           540:                nredunj++;
        !           541:                nchange++;
        !           542:                decref(p->ref);
        !           543:                if(p->forw->op!=CBR && (p1->op==TST || p1->op==CMP)) {
        !           544:                        delnode(p1);
        !           545:                        nrtst++;
        !           546:                }
        !           547:                break;
        !           548:        case 1:         /* branch always taken */
        !           549:                p->op = JBR;
        !           550:                p->subop = 0;
        !           551:                p->pop = 0;
        !           552:                nchange++;
        !           553:                if(nonlab(p->ref)->op!=CBR && (p1->op==TST || p1->op==CMP)) {
        !           554:                        delnode(p1);
        !           555:                        nrtst++;
        !           556:                }
        !           557:        }
        !           558: }
        !           559: 
        !           560: /* a jump to a redundant compare (start of a 'for') */
        !           561: redunbr(p)
        !           562: register struct node *p;
        !           563: {
        !           564:        register struct node *p1;
        !           565:        register char *ap1, *ap2;
        !           566: 
        !           567:        if ((p1 = p->ref) == 0)
        !           568:                return;
        !           569:        p1 = nonlab(p1);
        !           570:        if (p1->op==TST || p1->op==CMP)
        !           571:                splitrand(p1);
        !           572:        else
        !           573:                return;
        !           574:        if (p1->forw->op==CBR) {
        !           575:                ap1 = findcon(regs[RT1], p1->subop);
        !           576:                if (p1->op==TST)
        !           577:                        ap2 = "$0";
        !           578:                else
        !           579:                        ap2 = findcon(regs[RT2], p1->subop);
        !           580:                p1 = p1->forw;
        !           581:                if (compare(p1->subop, ap1, ap2) > 0) {
        !           582:                        nredunj++;
        !           583:                        nchange++;
        !           584:                        decref(p->ref);
        !           585:                        p->ref = p1->ref;
        !           586:                        p->labno = p1->labno;
        !           587: #ifdef COPYCODE
        !           588:                        if (p->labno == 0)
        !           589:                                p->code = p1->code;
        !           590:                        if (p->ref)
        !           591: #endif
        !           592:                                p->ref->refc++;
        !           593:                }
        !           594:        } else if (p1->op==TST && equstr(regs[RT1],ccloc+1) &&
        !           595:                        equtype(ccloc[0],p1->subop)) {
        !           596:                p1=insertl(p1->forw); decref(p->ref); p->ref=p1; 
        !           597:                nrtst++; nchange++;
        !           598:        }
        !           599: }
        !           600: 
        !           601: char *
        !           602: findcon(p, type)
        !           603:        register char *p;
        !           604: {
        !           605:        register int r;
        !           606: 
        !           607:        if (*p=='$')
        !           608:                return(p);
        !           609:        if ((r = isreg(p)) >= 0 && compat(regs[r][0],type))
        !           610:                return(regs[r]+1);
        !           611:        if (equstr(p, conloc) && equtype(conloc[0], type))
        !           612:                return(conval+1);
        !           613:        return(p);
        !           614: }
        !           615: 
        !           616: /* compare constants: 0 - branch taken; 1 - not taken; -1 - don't know */
        !           617: compare(op, acp1, acp2)
        !           618: char *acp1, *acp2;
        !           619: {
        !           620:        register char *cp1, *cp2;
        !           621:        register int n1, n2, sign;
        !           622: 
        !           623:        cp1 = acp1;
        !           624:        cp2 = acp2;
        !           625:        if (*cp1++ != '$' || *cp2++ != '$')
        !           626:                return(-1);
        !           627:        n1 = 0; sign=1; if (*cp1=='-') {++cp1; sign= -1;}
        !           628:        while (isdigit(*cp1)) {n1 *= 10; n1 += *cp1++ - '0';}
        !           629:        n1 *= sign;
        !           630:        n2 = 0; sign=1; if (*cp2=='-') {++cp2; sign= -1;}
        !           631:        while (isdigit(*cp2)) {n2 *= 10; n2 += *cp2++ - '0';}
        !           632:        n2 *= sign;
        !           633:        if (*cp1=='+')
        !           634:                cp1++;
        !           635:        if (*cp2=='+')
        !           636:                cp2++;
        !           637:        do {
        !           638:                if (*cp1++ != *cp2)
        !           639:                        return(-1);
        !           640:        } while (*cp2++);
        !           641:        switch(op) {
        !           642: 
        !           643:        case JEQ:
        !           644:                return(n1 == n2);
        !           645:        case JNE:
        !           646:                return(n1 != n2);
        !           647:        case JLE:
        !           648:                return(n1 <= n2);
        !           649:        case JGE:
        !           650:                return(n1 >= n2);
        !           651:        case JLT:
        !           652:                return(n1 < n2);
        !           653:        case JGT:
        !           654:                return(n1 > n2);
        !           655:        case JLO:
        !           656:                return((unsigned)n1 < (unsigned)n2);
        !           657:        case JHI:
        !           658:                return((unsigned)n1 > (unsigned)n2);
        !           659:        case JLOS:
        !           660:                return((unsigned)n1 <= (unsigned)n2);
        !           661:        case JHIS:
        !           662:                return((unsigned)n1 >= (unsigned)n2);
        !           663:        }
        !           664:        return(-1);
        !           665: }
        !           666: 
        !           667: setcon(cv, cl, type)
        !           668: register char *cv, *cl;
        !           669: {
        !           670:        register char *p;
        !           671: 
        !           672:        if (*cv != '$')
        !           673:                return;
        !           674:        if (!natural(cl))
        !           675:                return;
        !           676:        p = conloc;
        !           677:        while (*p++ = *cl++);
        !           678:        p = conval;
        !           679:        *p++ = type;
        !           680:        while (*p++ = *cv++);
        !           681: }
        !           682: 
        !           683: setcc(ap,type)
        !           684: char *ap;
        !           685: {
        !           686:        register char *p, *p1;
        !           687: 
        !           688:        p = ap;
        !           689:        if (!natural(p)) {
        !           690:                ccloc[0] = 0;
        !           691:                return;
        !           692:        }
        !           693:        p1 = ccloc;
        !           694:        *p1++ = type;
        !           695:        while (*p1++ = *p++);
        !           696: }
        !           697: 
        !           698: indexa(p) register char *p; {/* 1-> uses [r] addressing mode; 0->doesn't */
        !           699:        while (*p) if (*p++=='[') return(1);
        !           700:        return(0);
        !           701: }
        !           702: 
        !           703: natural(p)
        !           704: register char *p;
        !           705: {/* 1->simple local, parameter, global, or register; 0->otherwise */
        !           706: 
        !           707:        if (*p=='*' || *p=='(' || *p=='$')
        !           708:                return(0);
        !           709:        while (*p++);
        !           710:        p--;
        !           711:        if (*--p==']' || *p==')' &&
        !           712:         !(*(p-2)=='f' || fortflg && (*--p=='1' || *p=='2') && *--p=='1'))
        !           713:                return(0);
        !           714:        return(1);
        !           715: }
        !           716: 
        !           717: /*
        !           718: ** Tell if an argument is most likely static.
        !           719: */
        !           720: 
        !           721: isstatic(cp)
        !           722: register char  *cp;
        !           723: {
        !           724:        if (*cp == '_' || *cp == 'L')
        !           725:                return (1);
        !           726:        return (0);
        !           727: }
        !           728: 
        !           729: 
        !           730: checkaobdisp(p)
        !           731: register struct node *p;
        !           732: {
        !           733: register struct node *q;
        !           734: register int i;
        !           735:        
        !           736: 
        !           737: if (!aobflag) return(1);
        !           738: /*  backward search */
        !           739:        i = 0;
        !           740:        q = p; 
        !           741:        while (i++ < MAXAOBDISP && ((q= q->back) !=&first))
        !           742:        {
        !           743:                if (p->ref == q) 
        !           744:                   return(1);
        !           745:        }
        !           746: 
        !           747: /*  forward search */
        !           748:        i = 0;
        !           749:        q = p; 
        !           750:        while (i++ < MAXAOBDISP && ((q= q->forw) !=0))
        !           751:        {
        !           752:                if (p->ref == q) 
        !           753:                   return(1);
        !           754:        }
        !           755:        return(0);
        !           756: }
        !           757: 
        !           758: 
        !           759: struct intleavetab intltab[] = {
        !           760:        ADDF,   FLOAT,          1,
        !           761:        ADDF,   DOUBLE,         1,
        !           762:        SUBF,   FLOAT,          1,
        !           763:        SUBF,   DOUBLE,         1,
        !           764:        MULF,   FLOAT,          1,
        !           765:        MULF,   DOUBLE,         1,
        !           766:        DIVF,   FLOAT,          1,
        !           767:        DIVF,   DOUBLE,         1,
        !           768:        SINF,   FLOAT,          1,
        !           769:        COSF,   FLOAT,          1,
        !           770:        ATANF,  FLOAT,          1,
        !           771:        LOGF,   FLOAT,          1,
        !           772:        SQRTF,  FLOAT,          1,
        !           773:        EXPF,   FLOAT,          1,
        !           774:        LDF,    FLOAT,          0,
        !           775:        LDF,    DOUBLE,         0,
        !           776:        LNF,    FLOAT,          0,
        !           777:        LNF,    DOUBLE,         0,
        !           778:        STF,    FLOAT,          0,
        !           779:        CMPF,   FLOAT,          0,
        !           780:        CMPF,   DOUBLE,         0,
        !           781:        CMPF2,  FLOAT,          0,
        !           782:        TSTF,   FLOAT,          0,
        !           783:        TSTF,   DOUBLE,         0,
        !           784:        PUSHD,  DOUBLE,         0,
        !           785:        CVLF,   U(LONG,FLOAT),  0,
        !           786:        CVFL,   U(FLOAT,LONG),  0, 
        !           787:        LDFD,   U(FLOAT,DOUBLE),0, 
        !           788:        CVDF,   U(DOUBLE,FLOAT),0,
        !           789:        NEGF,   FLOAT,          0,
        !           790:        NIL,    0,              0};
        !           791: 
        !           792: interleave()
        !           793: {
        !           794:        register struct node *p, *p1;
        !           795: 
        !           796:        register struct intleavetab *t;
        !           797:        register int r;
        !           798:        int count;
        !           799:        for (p= first.forw; p!=0; p = p->forw){
        !           800:                count = 0;
        !           801:                for  (t =intltab; t->op != NIL; t++){
        !           802:                        if (t->op == p->op && t->subop == p->subop){
        !           803:                        count = t->intleavect;
        !           804:                        break;
        !           805:                        }
        !           806:                }
        !           807:                if (count < 1) continue;
        !           808:                p1 = p->forw;
        !           809:                clearuse();
        !           810:                clearreg();
        !           811:                while ((p1 != 0) && (p1->op != CBR) &&
        !           812:                      (p1->subop == FLOAT || p1->subop == DOUBLE ||
        !           813:                      ((p1->subop&0xF0)==DOUBLE<<4) || ((p1->subop&0xF)==DOUBLE )||
        !           814:                      ((p1->subop&0xF0)==FLOAT<<4) || (p1->subop&0xF)==FLOAT))
        !           815:                {
        !           816:                        if (((r = isreg(p1->code)) >= 0)){
        !           817:                        uses[r] = p1;
        !           818:                        if ((p1->subop == DOUBLE) || ((p->subop&0xF0)==DOUBLE<<4) || 
        !           819:                           ((p->subop&0xF)==DOUBLE)) 
        !           820:                                uses[r+1] = p1;
        !           821:                        }
        !           822:                        else checkreg(p1,p1->code);
        !           823:                        p1 = p1->forw;
        !           824: 
        !           825:                }
        !           826:                if (p1 == 0) return;
        !           827:                if (!(sideeffect(p, p1)))
        !           828:                        insertblk(p,p1);
        !           829:        }
        !           830:                
        !           831: }
        !           832: 
        !           833: 
        !           834: insertblk(p, p1)
        !           835: struct node *p, *p1;
        !           836: {
        !           837:        p1->back->forw = p1->forw;
        !           838:        p1->forw->back = p1->back;
        !           839:        p1->forw = p->forw;
        !           840:        p->forw->back = p1;
        !           841:        p->forw = p1;
        !           842:        p1->back = p;
        !           843: }
        !           844: 
        !           845: OpCode termop[] = {
        !           846:        JBR, CBR, JMP, LABEL, DLABEL, EROU, JSW, TST, CMP, BIT,
        !           847:        CALLF, CALLS, CASE, AOBLEQ, AOBLSS, CMPF, CMPF2, TSTF, MOVBLK, MFPR,
        !           848:        MTPR, PROBE, MOVO, TEXT, DATA, BSS, ALIGN, END, LGEN, SET,
        !           849:        LCOMM, COMM, NIL
        !           850: }; 
        !           851: 
        !           852: sideeffect(p,p1)
        !           853: struct node *p, *p1;
        !           854: {
        !           855:        register struct node *q;
        !           856:        register int r;
        !           857:        register OpCode *t;
        !           858:        register char *cp;
        !           859:        int i;
        !           860: 
        !           861:        if (p1->op == NIL) return(1);  /*  special instructions */
        !           862: 
        !           863:        for (t = termop; *t!=NIL; t++){
        !           864:                if (*t == p1->op) return(1);
        !           865:        }
        !           866:        if ((p1->forw != NULL) && (p1->forw->op == CBR))
        !           867:                return(1);
        !           868:        splitrand(p1);
        !           869:        r = isreg(lastrand);
        !           870:        if (uses[r] &&  r >= 0 ) return(1);
        !           871:        if ((p1->op == EDIV) && (r = isreg(regs[RT3]) >= 0) &&
        !           872:           (uses[r]))  return(1);
        !           873: 
        !           874:        for (q = p1->back ; q!=p; q=q->back)
        !           875:        {
        !           876:                if ((p1->op == PUSH || p1->op == PUSHA) &&
        !           877:                    (q->op == PUSHD || q->op == PUSH || q->op == PUSHA))  
        !           878:                     return(1);                      /* keep args in order */
        !           879:                if (((i = strlen(q->code)) >= 5 &&    /* cvdl -(sp); pushl r0*/
        !           880:                    (strcmp(q->code+i-5,"-(sp)") == 0 )) || 
        !           881:                    (strcmp(lastrand,"-(sp)") == 0)) return(1);
        !           882:                if (equstr(q->code, lastrand))
        !           883:                    return(1);
        !           884:                if (q->op == STF || q->op == CVFL || q->op == CVLF) 
        !           885:                   {
        !           886:                    if (equstr(q->code, regs[RT1])) return(1);
        !           887:                if (has3ops(p1) || p1->op == EMUL || p1->op == EDIV)
        !           888:                    if (equstr(q->code, regs[RT2]))
        !           889:                       return(1);
        !           890:                /*  handle the case  std -56(fp) pushl -60(fp) pushl
        !           891:                    -56(fp);
        !           892:                */
        !           893:                if ((p1->forw != NULL) &&  (q->op == STF) &&
        !           894:                (q->subop == DOUBLE)){ 
        !           895:                if (!strncmp(q->code,p1->forw->code,strlen(q->code)))
        !           896:                        return(1);
        !           897:                }
        !           898:                }
        !           899:        }
        !           900:        return(0);
        !           901: }
        !           902: checkreg(p,s)
        !           903: struct node *p;
        !           904: char *s;
        !           905: {
        !           906: char *cp2;  
        !           907: register int r;
        !           908:        /* check for (r),[r] */
        !           909:        do if (*s=='(' || *s=='[') {/* get register number */
        !           910:                char t;
        !           911:                cp2= ++s; while (*++s!=')' && *s!=']'); t= *s; *s=0;
        !           912:                if ((r=isreg(cp2)) >= 0)  {
        !           913:                        uses[r]=p; 
        !           914:                }
        !           915:                *s=t;
        !           916:        } while (*++s);
        !           917: }

unix.superglobalmegacorp.com

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