Annotation of 43BSDTahoe/lib/old_compiler/c2/c2.tahoe/save2/c22.c, revision 1.1.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.