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

1.1     ! root        1: #ifndef lint
        !             2: static char sccsid[] = "@(#)c22.c      1.9 (Berkeley/CCI) 5/12/88";
        !             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, p->op!=CVT || r<0);
        !            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 && p1->subop == 0 && p1->pop != p2->pop)
        !           335:                return(0);
        !           336:        if (p1->op != NIL && ord(p1->op) < ord(MOV))
        !           337:                return(0);
        !           338:        switch (p1->op) {
        !           339:        case EROU:      case JSW:       case TEXT:      case DATA:
        !           340:        case BSS:       case ALIGN:     case WGEN:      case END:
        !           341:                /* sufficient? */
        !           342:                return(0);
        !           343:        }
        !           344:        if (p1->op==MOVA && p1->labno!=p2->labno) return(0);
        !           345:        cp1 = p1->code;
        !           346:        cp2 = p2->code;
        !           347:        if (cp1==0 && cp2==0)
        !           348:                return(1);
        !           349:        if (cp1==0 || cp2==0)
        !           350:                return(0);
        !           351:        while (*cp1 == *cp2++)
        !           352:                if (*cp1++ == 0)
        !           353:                        return(1);
        !           354:        return(0);
        !           355: }
        !           356: 
        !           357: delnode(p) register struct node *p; {
        !           358:        p->back->forw = p->forw;
        !           359:        p->forw->back = p->back;
        !           360: }
        !           361: 
        !           362: decref(p)
        !           363: register struct node *p;
        !           364: {
        !           365:        if (p && --p->refc <= 0) {
        !           366:                nrlab++; nchange++;
        !           367:                delnode(p);
        !           368:        }
        !           369: }
        !           370: 
        !           371: struct node *
        !           372: nonlab(ap)
        !           373: struct node *ap;
        !           374: {
        !           375:        register struct node *p;
        !           376: 
        !           377:        p = ap;
        !           378:        while (p && p->op==LABEL)
        !           379:                p = p->forw;
        !           380:        return(p);
        !           381: }
        !           382: 
        !           383: clearuse() {
        !           384:        register struct node **i;
        !           385:        for (i=uses+NREG; i>uses;) *--i=0;
        !           386:        useacc = 0;
        !           387: }
        !           388: 
        !           389: clearreg() {
        !           390:        register char **i;
        !           391:        for (i=regs+NREG+1; i>regs;){ **--i=0; **i=0; }
        !           392:        conloc[0] = 0; ccloc[0] = 0;
        !           393: }
        !           394: 
        !           395: savereg(ai, s, type)
        !           396: register char *s;
        !           397: {
        !           398:        register char *p, *sp;
        !           399: 
        !           400:        sp = p = regs[ai];
        !           401:        /* if any indexing, must be parameter or local */
        !           402:        /* indirection (as in "*-4(fp)") is ok, however */
        !           403:        *p++ = type;
        !           404:        if (*s=='*' || *s=='$')
        !           405:                *p++ = *s++;
        !           406:        if (natural(s))
        !           407:                strcpy(p, s);
        !           408:        else {*sp = 0; return;}
        !           409: }
        !           410: 
        !           411: dest(s,type, ccflg)
        !           412: register char *s;
        !           413: {
        !           414:        register int i;
        !           415: 
        !           416:        if ((i = isreg(s)) >= 0) {
        !           417:                *(short *)(regs[i]) = 0; /* if register destination, that reg is a goner */
        !           418:                if (DOUBLE==(type&0xF) || DOUBLE==((type>>4)&0xF) || type==QUAD)
        !           419:                        *(short *)(regs[i+1]) = 0;
        !           420:        }
        !           421:        for (i=NREG; --i>=0;)
        !           422:                if (regs[i][1]=='*' && equstr(s, regs[i]+2))
        !           423:                        *(short *)(regs[i]) = 0; /* previous indirection through destination is invalid */
        !           424:        while ((i = findrand(s,0)) >= 0) /* previous values of destination are invalid */
        !           425:                *(short *)(regs[i]) = 0;
        !           426: 
        !           427:        if (!natural(s)) {/* wild store, everything except constants vanishes */
        !           428:                for (i=NREG; --i>=0;) if (regs[i][1] != '$') *(short *)(regs[i]) = 0;
        !           429:                conloc[0] = 0; ccloc[0] = 0;
        !           430:        } else {
        !           431:                if(ccflg)setcc(s,type); /* natural destinations set condition codes */
        !           432:                if (equstr(s, conloc))
        !           433:                        conloc[0] = 0;
        !           434:        }
        !           435: }
        !           436: 
        !           437: splitrand(p) struct node *p; {
        !           438: /* separate operands at commas, set up 'regs' and 'lastrand' */
        !           439: register char *p1, *p2; register char **preg;
        !           440: 
        !           441:        preg=regs+RT1;
        !           442:        if (p1=p->code) while (*p1) {
        !           443:                lastrand=p2= *preg++;
        !           444:                while (*p1) if (','==(*p2++= *p1++)) {--p2; break;}
        !           445:                *p2=0;
        !           446:        }
        !           447:        while (preg<(regs+RT1+5)) *(*preg++)=0;
        !           448: }
        !           449: 
        !           450: compat(have, want)
        !           451: register int have, want;
        !           452: {
        !           453:        register int hsrc, hdst;
        !           454:        extern int bitsize[];
        !           455: 
        !           456:        if (0==(want &= 0xF)) return(1); /* anything satisfies a wildcard want */
        !           457:        hsrc=have&0xF; if (0==(hdst=((have>>4)&0xF)) || hdst>=OP2) hdst=hsrc;
        !           458:        if (want>=QUAD)
        !           459:                return(bitsize[hdst]==bitsize[want] && bitsize[hsrc]==bitsize[want]);
        !           460:        return(hsrc==want && hdst>=want && hdst<QUAD);
        !           461: }
        !           462: 
        !           463: equtype(t1,t2) {return(compat(t1,t2) && compat(t2,t1));}
        !           464: 
        !           465: findrand(as, type)
        !           466: char *as;
        !           467: {
        !           468:        register char **i;
        !           469:        for (i = regs+NREG; --i>=regs;) {
        !           470:                if (**i && equstr(*i+1, as) && compat(**i,type))
        !           471:                        return(i-regs);
        !           472:        }
        !           473:        return(-1);
        !           474: }
        !           475: 
        !           476: isreg(s)
        !           477: register char *s;
        !           478: {
        !           479:        if (*s++!='r' || !isdigit(*s++)) return(-1);
        !           480:        if (*s==0) return(*--s-'0');
        !           481:        if (*(s-1)=='1' && isdigit(*s++) && *s==0) return(10+*--s-'0');
        !           482:        return(-1);
        !           483: }
        !           484: 
        !           485: /*
        !           486: check()
        !           487: {
        !           488:        register struct node *p, *lp;
        !           489: 
        !           490:        lp = &first;
        !           491:        for (p=first.forw; p!=0; p = p->forw) {
        !           492:                if (p->back != lp)
        !           493:                        abort(-1);
        !           494:                lp = p;
        !           495:        }
        !           496: }
        !           497: */
        !           498: 
        !           499: newcode(p) struct node *p; {
        !           500:        register char *p1,*p2,**preg;
        !           501: 
        !           502:        preg=regs+RT1; p2=line;
        !           503:        while (*(p1= *preg++)) {while (*p2++= *p1++); *(p2-1)=',';}
        !           504:        *--p2=0;
        !           505:        p->code=copy(line);
        !           506: }
        !           507: 
        !           508: repladdr(p)
        !           509: struct node *p;
        !           510: {
        !           511:        register int r;
        !           512:        register char *p1;
        !           513:        register char **preg;
        !           514:        register int nrepl;
        !           515: 
        !           516:        preg=regs+RT1; nrepl=0;
        !           517:        while (lastrand!=(p1= *preg++))
        !           518:                if (0<=(r=findrand(p1,p->subop))) {
        !           519:                        *p1++='r'; if (r>9) {*p1++='1'; r -= 10;} *p1++=r+'0'; *p1=0;
        !           520:                        nchange++; nrepl++; nsaddr++;
        !           521:                }
        !           522:        if (nrepl) newcode(p);
        !           523: }
        !           524: 
        !           525: /* conditional branches which are never/always taken */
        !           526: reduncbr(p)
        !           527: register struct node *p;
        !           528: {
        !           529:        register struct node *p1;
        !           530:        register char *ap1, *ap2;
        !           531: 
        !           532:        p1 = p->back;
        !           533:        if (p1->op==CMP) {
        !           534:                splitrand(p1);
        !           535:                ap1 = findcon(regs[RT1], p1->subop);
        !           536:                ap2 = findcon(regs[RT2], p1->subop);
        !           537:        } else {
        !           538:                if(!ccloc[0])
        !           539:                        return;
        !           540:                ap1 = findcon(ccloc+1, ccloc[0]);
        !           541:                ap2 = "$0";
        !           542:        }
        !           543:        switch (compare(p->subop, ap1, ap2)) {
        !           544:        case 0:         /* branch never taken */
        !           545:                delnode(p);
        !           546:                nredunj++;
        !           547:                nchange++;
        !           548:                decref(p->ref);
        !           549:                if(p->forw->op!=CBR && (p1->op==TST || p1->op==CMP)) {
        !           550:                        delnode(p1);
        !           551:                        nrtst++;
        !           552:                }
        !           553:                break;
        !           554:        case 1:         /* branch always taken */
        !           555:                p->op = JBR;
        !           556:                p->subop = 0;
        !           557:                p->pop = 0;
        !           558:                nchange++;
        !           559:                if(nonlab(p->ref)->op!=CBR && (p1->op==TST || p1->op==CMP)) {
        !           560:                        delnode(p1);
        !           561:                        nrtst++;
        !           562:                }
        !           563:        }
        !           564: }
        !           565: 
        !           566: /* a jump to a redundant compare (start of a 'for') */
        !           567: redunbr(p)
        !           568: register struct node *p;
        !           569: {
        !           570:        register struct node *p1;
        !           571:        register char *ap1, *ap2;
        !           572: 
        !           573:        if ((p1 = p->ref) == 0)
        !           574:                return;
        !           575:        p1 = nonlab(p1);
        !           576:        if (p1->op==TST || p1->op==CMP)
        !           577:                splitrand(p1);
        !           578:        else
        !           579:                return;
        !           580:        if (p1->forw->op==CBR) {
        !           581:                ap1 = findcon(regs[RT1], p1->subop);
        !           582:                if (p1->op==TST)
        !           583:                        ap2 = "$0";
        !           584:                else
        !           585:                        ap2 = findcon(regs[RT2], p1->subop);
        !           586:                p1 = p1->forw;
        !           587:                if (compare(p1->subop, ap1, ap2) > 0) {
        !           588:                        nredunj++;
        !           589:                        nchange++;
        !           590:                        decref(p->ref);
        !           591:                        p->ref = p1->ref;
        !           592:                        p->labno = p1->labno;
        !           593: #ifdef COPYCODE
        !           594:                        if (p->labno == 0)
        !           595:                                p->code = p1->code;
        !           596:                        if (p->ref)
        !           597: #endif
        !           598:                                p->ref->refc++;
        !           599:                }
        !           600:        } else if (p1->op==TST && equstr(regs[RT1],ccloc+1) &&
        !           601:                        equtype(ccloc[0],p1->subop)) {
        !           602:                p1=insertl(p1->forw); decref(p->ref); p->ref=p1; 
        !           603:                p->labno=p1->labno;
        !           604:                nrtst++; nchange++;
        !           605:        }
        !           606: }
        !           607: 
        !           608: char *
        !           609: findcon(p, type)
        !           610:        register char *p;
        !           611: {
        !           612:        register int r;
        !           613: 
        !           614:        if (*p=='$')
        !           615:                return(p);
        !           616:        if ((r = isreg(p)) >= 0 && compat(regs[r][0],type))
        !           617:                return(regs[r]+1);
        !           618:        if (equstr(p, conloc) && equtype(conloc[0], type))
        !           619:                return(conval+1);
        !           620:        return(p);
        !           621: }
        !           622: 
        !           623: /* compare constants: 0 - branch taken; 1 - not taken; -1 - don't know */
        !           624: compare(op, acp1, acp2)
        !           625: char *acp1, *acp2;
        !           626: {
        !           627:        register char *cp1, *cp2;
        !           628:        register int n1, n2, sign;
        !           629: 
        !           630:        cp1 = acp1;
        !           631:        cp2 = acp2;
        !           632:        if (*cp1++ != '$' || *cp2++ != '$')
        !           633:                return(-1);
        !           634:        n1 = 0; sign=1; if (*cp1=='-') {++cp1; sign= -1;}
        !           635:        while (isdigit(*cp1)) {n1 *= 10; n1 += *cp1++ - '0';}
        !           636:        n1 *= sign;
        !           637:        n2 = 0; sign=1; if (*cp2=='-') {++cp2; sign= -1;}
        !           638:        while (isdigit(*cp2)) {n2 *= 10; n2 += *cp2++ - '0';}
        !           639:        n2 *= sign;
        !           640:        if (*cp1=='+')
        !           641:                cp1++;
        !           642:        if (*cp2=='+')
        !           643:                cp2++;
        !           644:        do {
        !           645:                if (*cp1++ != *cp2)
        !           646:                        return(-1);
        !           647:        } while (*cp2++);
        !           648:        switch(op) {
        !           649: 
        !           650:        case JEQ:
        !           651:                return(n1 == n2);
        !           652:        case JNE:
        !           653:                return(n1 != n2);
        !           654:        case JLE:
        !           655:                return(n1 <= n2);
        !           656:        case JGE:
        !           657:                return(n1 >= n2);
        !           658:        case JLT:
        !           659:                return(n1 < n2);
        !           660:        case JGT:
        !           661:                return(n1 > n2);
        !           662:        case JLO:
        !           663:                return((unsigned)n1 < (unsigned)n2);
        !           664:        case JHI:
        !           665:                return((unsigned)n1 > (unsigned)n2);
        !           666:        case JLOS:
        !           667:                return((unsigned)n1 <= (unsigned)n2);
        !           668:        case JHIS:
        !           669:                return((unsigned)n1 >= (unsigned)n2);
        !           670:        }
        !           671:        return(-1);
        !           672: }
        !           673: 
        !           674: setcon(cv, cl, type)
        !           675: register char *cv, *cl;
        !           676: {
        !           677:        register char *p;
        !           678: 
        !           679:        if (*cv != '$')
        !           680:                return;
        !           681:        if (!natural(cl))
        !           682:                return;
        !           683:        p = conloc;
        !           684:        while (*p++ = *cl++);
        !           685:        p = conval;
        !           686:        *p++ = type;
        !           687:        while (*p++ = *cv++);
        !           688: }
        !           689: 
        !           690: setcc(ap,type)
        !           691: char *ap;
        !           692: {
        !           693:        register char *p, *p1;
        !           694: 
        !           695:        p = ap;
        !           696:        if (!natural(p)) {
        !           697:                ccloc[0] = 0;
        !           698:                return;
        !           699:        }
        !           700:        p1 = ccloc;
        !           701:        *p1++ = type;
        !           702:        while (*p1++ = *p++);
        !           703: }
        !           704: 
        !           705: indexa(p) register char *p; {/* 1-> uses [r] addressing mode; 0->doesn't */
        !           706:        while (*p) if (*p++=='[') return(1);
        !           707:        return(0);
        !           708: }
        !           709: 
        !           710: natural(p)
        !           711: register char *p;
        !           712: {/* 1->simple local, parameter, global, or register; 0->otherwise */
        !           713: 
        !           714:        if (*p=='*' || *p=='(' || *p=='$')
        !           715:                return(0);
        !           716:        while (*p++);
        !           717:        p--;
        !           718:        if (*--p==']' || *p==')' &&
        !           719:         !(*(p-2)=='f' || fortflg && (*--p=='1' || *p=='2') && *--p=='1'))
        !           720:                return(0);
        !           721:        return(1);
        !           722: }
        !           723: 
        !           724: /*
        !           725: ** Tell if an argument is most likely static.
        !           726: */
        !           727: 
        !           728: isstatic(cp)
        !           729: register char  *cp;
        !           730: {
        !           731:        if (*cp == '_' || *cp == 'L')
        !           732:                return (1);
        !           733:        return (0);
        !           734: }
        !           735: 
        !           736: 
        !           737: checkaobdisp(p)
        !           738: register struct node *p;
        !           739: {
        !           740: register struct node *q;
        !           741: register int i;
        !           742:        
        !           743: 
        !           744: if (!aobflag) return(1);
        !           745: /*  backward search */
        !           746:        i = 0;
        !           747:        q = p; 
        !           748:        while (i++ < MAXAOBDISP && ((q= q->back) !=&first))
        !           749:        {
        !           750:                if (p->ref == q) 
        !           751:                   return(1);
        !           752:        }
        !           753: 
        !           754: /*  forward search */
        !           755:        i = 0;
        !           756:        q = p; 
        !           757:        while (i++ < MAXAOBDISP && ((q= q->forw) !=0))
        !           758:        {
        !           759:                if (p->ref == q) 
        !           760:                   return(1);
        !           761:        }
        !           762:        return(0);
        !           763: }
        !           764: 
        !           765: 
        !           766: struct intleavetab intltab[] = {
        !           767:        ADDF,   FLOAT,          1,
        !           768:        ADDF,   DOUBLE,         1,
        !           769:        SUBF,   FLOAT,          1,
        !           770:        SUBF,   DOUBLE,         1,
        !           771:        MULF,   FLOAT,          1,
        !           772:        MULF,   DOUBLE,         1,
        !           773:        DIVF,   FLOAT,          1,
        !           774:        DIVF,   DOUBLE,         1,
        !           775:        SINF,   FLOAT,          1,
        !           776:        COSF,   FLOAT,          1,
        !           777:        ATANF,  FLOAT,          1,
        !           778:        LOGF,   FLOAT,          1,
        !           779:        SQRTF,  FLOAT,          1,
        !           780:        EXPF,   FLOAT,          1,
        !           781:        LDF,    FLOAT,          0,
        !           782:        LDF,    DOUBLE,         0,
        !           783:        LNF,    FLOAT,          0,
        !           784:        LNF,    DOUBLE,         0,
        !           785:        STF,    FLOAT,          0,
        !           786:        CMPF,   FLOAT,          0,
        !           787:        CMPF,   DOUBLE,         0,
        !           788:        CMPF2,  FLOAT,          0,
        !           789:        TSTF,   FLOAT,          0,
        !           790:        TSTF,   DOUBLE,         0,
        !           791:        PUSHD,  DOUBLE,         0,
        !           792:        CVLF,   U(LONG,FLOAT),  0,
        !           793:        CVFL,   U(FLOAT,LONG),  0, 
        !           794:        LDFD,   U(FLOAT,DOUBLE),0, 
        !           795:        CVDF,   U(DOUBLE,FLOAT),0,
        !           796:        NEGF,   FLOAT,          0,
        !           797:        NIL,    0,              0};
        !           798: 
        !           799: interleave()
        !           800: {
        !           801:        register struct node *p, *p1;
        !           802: 
        !           803:        register struct intleavetab *t;
        !           804:        register int r;
        !           805:        int count;
        !           806:        for (p= first.forw; p!=0; p = p->forw){
        !           807:                count = 0;
        !           808:                for  (t =intltab; t->op != NIL; t++){
        !           809:                        if (t->op == p->op && t->subop == p->subop){
        !           810:                        count = t->intleavect;
        !           811:                        break;
        !           812:                        }
        !           813:                }
        !           814:                if (count < 1) continue;
        !           815:                p1 = p->forw;
        !           816:                clearuse();
        !           817:                clearreg();
        !           818:                while ((p1 != 0) && (p1->op != CBR) &&
        !           819:                      (p1->subop == FLOAT || p1->subop == DOUBLE ||
        !           820:                      ((p1->subop&0xF0)==DOUBLE<<4) || ((p1->subop&0xF)==DOUBLE )||
        !           821:                      ((p1->subop&0xF0)==FLOAT<<4) || (p1->subop&0xF)==FLOAT))
        !           822:                {
        !           823:                        if (((r = isreg(p1->code)) >= 0)){
        !           824:                        uses[r] = p1;
        !           825:                        if ((p1->subop == DOUBLE) || ((p->subop&0xF0)==DOUBLE<<4) || 
        !           826:                           ((p->subop&0xF)==DOUBLE)) 
        !           827:                                uses[r+1] = p1;
        !           828:                        }
        !           829:                        else checkreg(p1,p1->code);
        !           830:                        p1 = p1->forw;
        !           831: 
        !           832:                }
        !           833:                if (p1 == 0) return;
        !           834:                if (!(sideeffect(p, p1)))
        !           835:                        insertblk(p,p1);
        !           836:        }
        !           837:                
        !           838: }
        !           839: 
        !           840: 
        !           841: insertblk(p, p1)
        !           842: struct node *p, *p1;
        !           843: {
        !           844:        p1->back->forw = p1->forw;
        !           845:        p1->forw->back = p1->back;
        !           846:        p1->forw = p->forw;
        !           847:        p->forw->back = p1;
        !           848:        p->forw = p1;
        !           849:        p1->back = p;
        !           850: }
        !           851: 
        !           852: OpCode termop[] = {
        !           853:        JBR, CBR, JMP, LABEL, DLABEL, EROU, JSW, TST, CMP, BIT,
        !           854:        CALLF, CALLS, CASE, AOBLEQ, AOBLSS, CMPF, CMPF2, TSTF, MOVBLK, MFPR,
        !           855:        MTPR, PROBE, MOVO, TEXT, DATA, BSS, ALIGN, END, LGEN, SET,
        !           856:        LCOMM, COMM, NIL
        !           857: }; 
        !           858: 
        !           859: sideeffect(p,p1)
        !           860: struct node *p, *p1;
        !           861: {
        !           862:        register struct node *q;
        !           863:        register int r;
        !           864:        register OpCode *t;
        !           865:        register char *cp;
        !           866:        int i;
        !           867: 
        !           868:        if (p1->op == NIL) return(1);  /*  special instructions */
        !           869: 
        !           870:        for (t = termop; *t!=NIL; t++){
        !           871:                if (*t == p1->op) return(1);
        !           872:        }
        !           873:        if ((p1->forw != NULL) && (p1->forw->op == CBR))
        !           874:                return(1);
        !           875:        splitrand(p1);
        !           876:        r = isreg(lastrand);
        !           877:        if (uses[r] &&  r >= 0 ) return(1);
        !           878:        if ((p1->op == EDIV) && (r = isreg(regs[RT3]) >= 0) &&
        !           879:           (uses[r]))  return(1);
        !           880: 
        !           881:        for (q = p1->back ; q!=p; q=q->back)
        !           882:        {
        !           883:                if ((p1->op == PUSH || p1->op == PUSHA) &&
        !           884:                    (q->op == PUSHD || q->op == PUSH || q->op == PUSHA))  
        !           885:                     return(1);                      /* keep args in order */
        !           886:                if (((i = strlen(q->code)) >= 5 &&    /* cvdl -(sp); pushl r0*/
        !           887:                    (strcmp(q->code+i-5,"-(sp)") == 0 )) || 
        !           888:                    (strcmp(lastrand,"-(sp)") == 0)) return(1);
        !           889:                if (equstr(q->code, lastrand))
        !           890:                    return(1);
        !           891:                if (q->op == STF || q->op == CVFL || q->op == CVLF) 
        !           892:                   {
        !           893:                    if (equstr(q->code, regs[RT1])) return(1);
        !           894:                if (has3ops(p1) || p1->op == EMUL || p1->op == EDIV)
        !           895:                    if (equstr(q->code, regs[RT2]))
        !           896:                       return(1);
        !           897:                /*  handle the case  std -56(fp) pushl -60(fp) pushl
        !           898:                    -56(fp);
        !           899:                */
        !           900:                if ((p1->forw != NULL) &&  (q->op == STF) &&
        !           901:                (q->subop == DOUBLE)){ 
        !           902:                if (!strncmp(q->code,p1->forw->code,strlen(q->code)))
        !           903:                        return(1);
        !           904:                }
        !           905:                }
        !           906:        }
        !           907:        return(0);
        !           908: }
        !           909: checkreg(p,s)
        !           910: struct node *p;
        !           911: char *s;
        !           912: {
        !           913: char *cp2;  
        !           914: register int r;
        !           915:        /* check for (r),[r] */
        !           916:        do if (*s=='(' || *s=='[') {/* get register number */
        !           917:                char t;
        !           918:                cp2= ++s; while (*++s!=')' && *s!=']'); t= *s; *s=0;
        !           919:                if ((r=isreg(cp2)) >= 0)  {
        !           920:                        uses[r]=p; 
        !           921:                }
        !           922:                *s=t;
        !           923:        } while (*++s);
        !           924: }

unix.superglobalmegacorp.com

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