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