Annotation of 43BSDReno/libexec/pcc/c2.tahoe/c22.c, revision 1.1.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.