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