1 #ifndef lint 2 static char sccsid[] = "@(#)c22.c 1.5 (Berkeley/CCI) 08/07/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 71 if (r>=0) { 72 if (r1>=0) { 73 if (r == r1 && p->forw->op!=CBR) { 74 delnode(p); redunm++; nchange++; break; 75 } 76 if(regs[r][0]) 77 savereg(r1, regs[r]+1, p->subop); 78 } else savereg(r, regs[RT2], p->subop); 79 } else if (r1>=0) savereg(r1, regs[RT1], p->subop); 80 else setcon(regs[RT1], regs[RT2], p->subop); 81 break; 82 83 /* .rx,.wx or .rx,.rx,.wx */ 84 case ADD: 85 case SUB: 86 case AND: 87 case OR: 88 case XOR: 89 case MUL: 90 case DIV: 91 #ifdef EMOD 92 case EDIV: 93 case EMOD: 94 #endif EMOD 95 case SHAL: 96 case SHAR: 97 case SHL: 98 case SHR: 99 case ADDA: 100 case SUBA: 101 /* .rx,.wx */ 102 case MFPR: 103 case COM: 104 case NEG: 105 splitrand(p); 106 repladdr(p); 107 dest(lastrand,p->subop, p->op!=ADDA && p->op!=SUBA); 108 break; 109 110 /* .mx or .wx */ 111 case STF: 112 if(equstr(p->code, regs[ACC]+1) && p->subop==regs[ACC][0]) { 113 delnode(p); 114 nst++; nchange++; break; 115 } 116 savereg(ACC, p->code, p->subop); 117 case CLR: 118 case INC: 119 case DEC: 120 case CVFL: 121 dest(p->code,p->subop, 1); 122 if (p->op==CLR) 123 if ((r = isreg(p->code)) >= 0) 124 savereg(r, "$0", p->subop); 125 else 126 setcon("$0", p->code, p->subop); 127 break; 128 129 /* .rx */ 130 case LDF: 131 if(equstr(p->code, regs[ACC]+1) && p->subop==regs[ACC][0]) { 132 delnode(p); 133 nld++; nchange++; break; 134 } 135 savereg(ACC, p->code, p->subop); 136 goto case_tst; 137 case LNF: 138 if(equstr(p->code, regs[ACC]+1) && p->subop==regs[ACC][0]) { 139 p->op = NEGF; p->pop = 0; p->code = 0; 140 regs[ACC][0] = 0; 141 break; 142 } 143 case CVLF: 144 case LDFD: 145 case ADDF: 146 case SUBF: 147 case MULF: 148 case DIVF: 149 regs[ACC][0] = 0; 150 case TST: 151 case_tst: 152 case PUSH: 153 splitrand(p); 154 lastrand=regs[RT1+1]; /* fool repladdr into doing 1 operand */ 155 repladdr(p); 156 lastrand=regs[RT1]; 157 if (p->op==TST && equstr(lastrand, ccloc+1) 158 && ((0xf&(ccloc[0]>>4))==p->subop || equtype(ccloc[0],p->subop))) { 159 delnode(p); nrtst++; nchange++; break; 160 } 161 if (p->op==PUSH && p->subop!=LONG && 162 (isreg(lastrand)>=0 || *lastrand=='$')) { 163 p->subop = LONG; 164 p->pop = 0; 165 nchange++; 166 } 167 if (p->op==TST || p->op==PUSH) 168 setcc(lastrand,p->subop); 169 break; 170 171 /* .rx,.rx,.rx */ 172 case PROBE: 173 case CASE: 174 /* .rx,.rx */ 175 case MTPR: 176 case CALLS: 177 case CALLF: 178 case CMP: 179 case BIT: 180 case CMPF: 181 case CMPF2: 182 splitrand(p); 183 /* fool repladdr into doing right number of operands */ 184 lastrand=byondrd(p); 185 if (p->op==CALLF || p->op==CALLS) clearreg(); 186 else repladdr(p); 187 case TSTF: 188 ccloc[0]=0; 189 case PUSHD: 190 break; 191 192 /* acc only */ 193 case CVDF: 194 case NEGF: 195 case SINF: 196 case COSF: 197 case ATANF: 198 case LOGF: 199 case SQRTF: 200 case EXPF: 201 regs[ACC][0] = 0; 202 break; 203 204 #ifndef EMOD 205 /* .rx,.rx,.wx,.wx */ 206 case EDIV: 207 splitrand(p); 208 lastrand = regs[RT3]; 209 repladdr(p); 210 dest(regs[RT3], p->subop, 1); 211 dest(regs[RT4], p->subop, 0); 212 break; 213 #endif EMOD 214 215 /* .rx,.rx,.rx,wx */ 216 case EMUL: 217 splitrand(p); 218 lastrand = regs[RT4]; 219 repladdr(p); 220 dest(regs[RT4],QUAD, 1); /* fourth operand is a quad */ 221 break; 222 case CBR: 223 if (p->subop>=JBC) { 224 splitrand(p); 225 lastrand=regs[RT3]; /* 2 operands can be optimized */ 226 repladdr(p); 227 ccloc[0] = 0; 228 } else 229 reduncbr(p); 230 break; 231 232 case JBR: 233 redunbr(p); 234 235 default: 236 clearreg(); 237 } 238 } 239 } 240 241 jumpsw() 242 { 243 register struct node *p, *p1, *pt; 244 register int t, nj; 245 246 t = 0; 247 nj = 0; 248 for (p=first.forw; p!=0; p = p->forw) 249 p->seq = ++t; 250 for (p=first.forw; p!=0; p = p1) { 251 p1 = p->forw; 252 if (p->op == CBR && p1->op==JBR && p->ref && p1->ref 253 && abs(p->seq - p->ref->seq) > abs(p1->seq - p1->ref->seq)) { 254 if (p->ref==p1->ref) 255 continue; 256 p->subop = revbr[p->subop]; 257 p->pop=0; 258 pt = p1->ref; 259 p1->ref = p->ref; 260 p->ref = pt; 261 t = p1->labno; 262 p1->labno = p->labno; 263 p->labno = t; 264 #ifdef COPYCODE 265 if (p->labno == 0) { 266 pt = (struct node *)p1->code; p1->code = p->code; p->code = (char *)pt; 267 } 268 #endif 269 nrevbr++; 270 nj++; 271 } 272 } 273 return(nj); 274 } 275 276 addaob() 277 { 278 register struct node *p, *p1, *p2, *p3; 279 280 for (p = &first; (p1 = p->forw)!=0; p = p1) { 281 if (p->op==INC && p->subop==LONG) { 282 if (p1->op==LABEL && p1->refc==1 && p1->forw->op==CMP && p1->forw->subop==LONG 283 && (p2=p1->forw->forw)->op==CBR && p2->subop==JLE 284 && (p3=p2->ref->back)->op==JBR && p3->subop==0 && p3->ref==p1 285 && p3->forw->op==LABEL && p3->forw==p2->ref) { 286 /* change INC LAB: CMP to LAB: INC CMP */ 287 p->back->forw=p1; p1->back=p->back; 288 p->forw=p1->forw; p1->forw->back=p; 289 p->back=p1; p1->forw=p; 290 p1=p->forw; 291 /* adjust beginning value by 1 */ 292 p2=alloc(sizeof first); p2->op = DEC; p2->subop = LONG; 293 p2->pop=0; 294 p2->forw=p3; p2->back=p3->back; p3->back->forw=p2; 295 p3->back=p2; p2->code=p->code; p2->labno=0; 296 } 297 if (p1->op==CMP && p1->subop==LONG && 298 (p2=p1->forw)->op==CBR && p2->forw->op!=CBR) { 299 register char *cp1,*cp2; 300 splitrand(p1); if (!equstr(p->code,regs[RT1])) continue; 301 if ((p2->subop==JLE || p2->subop==JLT) && 302 checkaobdisp(p2)){ 303 if (p2->subop==JLE) p->op = AOBLEQ; else p->op = AOBLSS; p->subop = 0; 304 cp2=regs[RT1]; cp1=regs[RT2]; while (*cp2++= *cp1++); /* limit */ 305 cp2=regs[RT2]; cp1=p->code; while (*cp2++= *cp1++); /* index */ 306 p->pop=0; newcode(p); 307 p->labno = p2->labno; delnode(p2); delnode(p1); naob++; 308 } 309 } 310 } 311 } 312 } 313 314 ispow2(n) register long n; {/* -1 -> no; else -> log to base 2 */ 315 register int log; 316 if (n==0 || n&(n-1)) return(-1); log=0; 317 for (;;) {n >>= 1; if (n==0) return(log); ++log; if (n== -1) return(log);} 318 } 319 320 equop(p1, p2) 321 register struct node *p1, *p2; 322 { 323 register char *cp1, *cp2; 324 325 if (p1->op != p2->op || p1->subop != p2->subop) 326 return(0); 327 if (p1->op>0 && p1->op<MOV) 328 return(0); 329 if (p1->op==MOVA && p1->labno!=p2->labno) return(0); 330 cp1 = p1->code; 331 cp2 = p2->code; 332 if (cp1==0 && cp2==0) 333 return(1); 334 if (cp1==0 || cp2==0) 335 return(0); 336 while (*cp1 == *cp2++) 337 if (*cp1++ == 0) 338 return(1); 339 return(0); 340 } 341 342 delnode(p) register struct node *p; { 343 p->back->forw = p->forw; 344 p->forw->back = p->back; 345 } 346 347 decref(p) 348 register struct node *p; 349 { 350 if (p && --p->refc <= 0) { 351 nrlab++; nchange++; 352 delnode(p); 353 } 354 } 355 356 struct node * 357 nonlab(ap) 358 struct node *ap; 359 { 360 register struct node *p; 361 362 p = ap; 363 while (p && p->op==LABEL) 364 p = p->forw; 365 return(p); 366 } 367 368 clearuse() { 369 register struct node **i; 370 for (i=uses+NREG; i>uses;) *--i=0; 371 useacc = 0; 372 } 373 374 clearreg() { 375 register char **i; 376 for (i=regs+NREG+1; i>regs;){ **--i=0; **i=0; } 377 conloc[0] = 0; ccloc[0] = 0; 378 } 379 380 savereg(ai, s, type) 381 register char *s; 382 { 383 register char *p, *sp; 384 385 sp = p = regs[ai]; 386 /* if any indexing, must be parameter or local */ 387 /* indirection (as in "*-4(fp)") is ok, however */ 388 *p++ = type; 389 if (*s=='*' || *s=='$') 390 *p++ = *s++; 391 if (natural(s)) 392 strcpy(p, s); 393 else {*sp = 0; return;} 394 } 395 396 dest(s,type, ccflg) 397 register char *s; 398 { 399 register int i; 400 401 if ((i = isreg(s)) >= 0) { 402 *(short *)(regs[i]) = 0; /* if register destination, that reg is a goner */ 403 if (DOUBLE==(type&0xF) || DOUBLE==((type>>4)&0xF) || type==QUAD) 404 *(short *)(regs[i+1]) = 0; 405 } 406 for (i=NREG; --i>=0;) 407 if (regs[i][1]=='*' && equstr(s, regs[i]+2)) 408 *(short *)(regs[i]) = 0; /* previous indirection through destination is invalid */ 409 while ((i = findrand(s,0)) >= 0) /* previous values of destination are invalid */ 410 *(short *)(regs[i]) = 0; 411 412 if (!natural(s)) {/* wild store, everything except constants vanishes */ 413 for (i=NREG; --i>=0;) if (regs[i][1] != '$') *(short *)(regs[i]) = 0; 414 conloc[0] = 0; ccloc[0] = 0; 415 } else { 416 if(ccflg)setcc(s,type); /* natural destinations set condition codes */ 417 if (equstr(s, conloc)) 418 conloc[0] = 0; 419 } 420 } 421 422 splitrand(p) struct node *p; { 423 /* separate operands at commas, set up 'regs' and 'lastrand' */ 424 register char *p1, *p2; register char **preg; 425 426 preg=regs+RT1; 427 if (p1=p->code) while (*p1) { 428 lastrand=p2= *preg++; 429 while (*p1) if (','==(*p2++= *p1++)) {--p2; break;} 430 *p2=0; 431 } 432 while (preg<(regs+RT1+5)) *(*preg++)=0; 433 } 434 435 compat(have, want) 436 register int have, want; 437 { 438 register int hsrc, hdst; 439 extern int bitsize[]; 440 441 if (0==(want &= 0xF)) return(1); /* anything satisfies a wildcard want */ 442 hsrc=have&0xF; if (0==(hdst=((have>>4)&0xF)) || hdst>=OP2) hdst=hsrc; 443 if (want>=QUAD) 444 return(bitsize[hdst]==bitsize[want] && bitsize[hsrc]==bitsize[want]); 445 return(hsrc==want && hdst>=want && hdst<QUAD); 446 } 447 448 equtype(t1,t2) {return(compat(t1,t2) && compat(t2,t1));} 449 450 findrand(as, type) 451 char *as; 452 { 453 register char **i; 454 for (i = regs+NREG; --i>=regs;) { 455 if (**i && equstr(*i+1, as) && compat(**i,type)) 456 return(i-regs); 457 } 458 return(-1); 459 } 460 461 isreg(s) 462 register char *s; 463 { 464 if (*s++!='r' || !isdigit(*s++)) return(-1); 465 if (*s==0) return(*--s-'0'); 466 if (*(s-1)=='1' && isdigit(*s++) && *s==0) return(10+*--s-'0'); 467 return(-1); 468 } 469 470 /* 471 check() 472 { 473 register struct node *p, *lp; 474 475 lp = &first; 476 for (p=first.forw; p!=0; p = p->forw) { 477 if (p->back != lp) 478 abort(-1); 479 lp = p; 480 } 481 } 482 */ 483 484 newcode(p) struct node *p; { 485 register char *p1,*p2,**preg; 486 487 preg=regs+RT1; p2=line; 488 while (*(p1= *preg++)) {while (*p2++= *p1++); *(p2-1)=',';} 489 *--p2=0; 490 p->code=copy(line); 491 } 492 493 repladdr(p) 494 struct node *p; 495 { 496 register int r; 497 register char *p1; 498 register char **preg; 499 register int nrepl; 500 501 preg=regs+RT1; nrepl=0; 502 while (lastrand!=(p1= *preg++)) 503 if (0<=(r=findrand(p1,p->subop))) { 504 *p1++='r'; if (r>9) {*p1++='1'; r -= 10;} *p1++=r+'0'; *p1=0; 505 nchange++; nrepl++; nsaddr++; 506 } 507 if (nrepl) newcode(p); 508 } 509 510 /* conditional branches which are never/always taken */ 511 reduncbr(p) 512 register struct node *p; 513 { 514 register struct node *p1; 515 register char *ap1, *ap2; 516 517 p1 = p->back; 518 if (p1->op==CMP) { 519 splitrand(p1); 520 ap1 = findcon(regs[RT1], p1->subop); 521 ap2 = findcon(regs[RT2], p1->subop); 522 } else { 523 if(!ccloc[0]) 524 return; 525 ap1 = findcon(ccloc+1, ccloc[0]); 526 ap2 = "$0"; 527 } 528 switch (compare(p->subop, ap1, ap2)) { 529 case 0: /* branch never taken */ 530 delnode(p); 531 nredunj++; 532 nchange++; 533 decref(p->ref); 534 if(p->forw->op!=CBR && (p1->op==TST || p1->op==CMP)) { 535 delnode(p1); 536 nrtst++; 537 } 538 break; 539 case 1: /* branch always taken */ 540 p->op = JBR; 541 p->subop = 0; 542 p->pop = 0; 543 nchange++; 544 if(nonlab(p->ref)->op!=CBR && (p1->op==TST || p1->op==CMP)) { 545 delnode(p1); 546 nrtst++; 547 } 548 } 549 } 550 551 /* a jump to a redundant compare (start of a 'for') */ 552 redunbr(p) 553 register struct node *p; 554 { 555 register struct node *p1; 556 register char *ap1, *ap2; 557 558 if ((p1 = p->ref) == 0) 559 return; 560 p1 = nonlab(p1); 561 if (p1->op==TST || p1->op==CMP) 562 splitrand(p1); 563 else 564 return; 565 if (p1->forw->op==CBR) { 566 ap1 = findcon(regs[RT1], p1->subop); 567 if (p1->op==TST) 568 ap2 = "$0"; 569 else 570 ap2 = findcon(regs[RT2], p1->subop); 571 p1 = p1->forw; 572 if (compare(p1->subop, ap1, ap2) > 0) { 573 nredunj++; 574 nchange++; 575 decref(p->ref); 576 p->ref = p1->ref; 577 p->labno = p1->labno; 578 #ifdef COPYCODE 579 if (p->labno == 0) 580 p->code = p1->code; 581 if (p->ref) 582 #endif 583 p->ref->refc++; 584 } 585 } else if (p1->op==TST && equstr(regs[RT1],ccloc+1) && 586 equtype(ccloc[0],p1->subop)) { 587 p1=insertl(p1->forw); decref(p->ref); p->ref=p1; 588 nrtst++; nchange++; 589 } 590 } 591 592 char * 593 findcon(p, type) 594 register char *p; 595 { 596 register int r; 597 598 if (*p=='$') 599 return(p); 600 if ((r = isreg(p)) >= 0 && compat(regs[r][0],type)) 601 return(regs[r]+1); 602 if (equstr(p, conloc) && equtype(conloc[0], type)) 603 return(conval+1); 604 return(p); 605 } 606 607 /* compare constants: 0 - branch taken; 1 - not taken; -1 - don't know */ 608 compare(op, acp1, acp2) 609 char *acp1, *acp2; 610 { 611 register char *cp1, *cp2; 612 register int n1, n2, sign; 613 614 cp1 = acp1; 615 cp2 = acp2; 616 if (*cp1++ != '$' || *cp2++ != '$') 617 return(-1); 618 n1 = 0; sign=1; if (*cp1=='-') {++cp1; sign= -1;} 619 while (isdigit(*cp1)) {n1 *= 10; n1 += *cp1++ - '0';} 620 n1 *= sign; 621 n2 = 0; sign=1; if (*cp2=='-') {++cp2; sign= -1;} 622 while (isdigit(*cp2)) {n2 *= 10; n2 += *cp2++ - '0';} 623 n2 *= sign; 624 if (*cp1=='+') 625 cp1++; 626 if (*cp2=='+') 627 cp2++; 628 do { 629 if (*cp1++ != *cp2) 630 return(-1); 631 } while (*cp2++); 632 switch(op) { 633 634 case JEQ: 635 return(n1 == n2); 636 case JNE: 637 return(n1 != n2); 638 case JLE: 639 return(n1 <= n2); 640 case JGE: 641 return(n1 >= n2); 642 case JLT: 643 return(n1 < n2); 644 case JGT: 645 return(n1 > n2); 646 case JLO: 647 return((unsigned)n1 < (unsigned)n2); 648 case JHI: 649 return((unsigned)n1 > (unsigned)n2); 650 case JLOS: 651 return((unsigned)n1 <= (unsigned)n2); 652 case JHIS: 653 return((unsigned)n1 >= (unsigned)n2); 654 } 655 return(-1); 656 } 657 658 setcon(cv, cl, type) 659 register char *cv, *cl; 660 { 661 register char *p; 662 663 if (*cv != '$') 664 return; 665 if (!natural(cl)) 666 return; 667 p = conloc; 668 while (*p++ = *cl++); 669 p = conval; 670 *p++ = type; 671 while (*p++ = *cv++); 672 } 673 674 setcc(ap,type) 675 char *ap; 676 { 677 register char *p, *p1; 678 679 p = ap; 680 if (!natural(p)) { 681 ccloc[0] = 0; 682 return; 683 } 684 p1 = ccloc; 685 *p1++ = type; 686 while (*p1++ = *p++); 687 } 688 689 indexa(p) register char *p; {/* 1-> uses [r] addressing mode; 0->doesn't */ 690 while (*p) if (*p++=='[') return(1); 691 return(0); 692 } 693 694 natural(p) 695 register char *p; 696 {/* 1->simple local, parameter, global, or register; 0->otherwise */ 697 698 if (*p=='*' || *p=='(' || *p=='$') 699 return(0); 700 while (*p++); 701 p--; 702 if (*--p==']' || *p==')' && 703 !(*(p-2)=='f' || fortflg && (*--p=='1' || *p=='2') && *--p=='1')) 704 return(0); 705 return(1); 706 } 707 708 /* 709 ** Tell if an argument is most likely static. 710 */ 711 712 isstatic(cp) 713 register char *cp; 714 { 715 if (*cp == '_' || *cp == 'L') 716 return (1); 717 return (0); 718 } 719 720 721 checkaobdisp(p) 722 register struct node *p; 723 { 724 register struct node *q; 725 register int i; 726 727 728 if (!aobflag) return(1); 729 /* backward search */ 730 i = 0; 731 q = p; 732 while (i++ < MAXAOBDISP && ((q= q->back) !=&first)) 733 { 734 if (p->ref == q) 735 return(1); 736 } 737 738 /* forward search */ 739 i = 0; 740 q = p; 741 while (i++ < MAXAOBDISP && ((q= q->forw) !=0)) 742 { 743 if (p->ref == q) 744 return(1); 745 } 746 return(0); 747 } 748 749 750 struct intleavetab intltab[] = { 751 ADDF, FLOAT, 1, 752 ADDF, DOUBLE, 1, 753 SUBF, FLOAT, 1, 754 SUBF, DOUBLE, 1, 755 MULF, FLOAT, 1, 756 MULF, DOUBLE, 1, 757 DIVF, FLOAT, 1, 758 DIVF, DOUBLE, 1, 759 SINF, FLOAT, 1, 760 COSF, FLOAT, 1, 761 ATANF, FLOAT, 1, 762 LOGF, FLOAT, 1, 763 SQRTF, FLOAT, 1, 764 EXPF, FLOAT, 1, 765 LDF, FLOAT, 0, 766 LDF, DOUBLE, 0, 767 LNF, FLOAT, 0, 768 LNF, DOUBLE, 0, 769 STF, FLOAT, 0, 770 CMPF, FLOAT, 0, 771 CMPF, DOUBLE, 0, 772 CMPF2, FLOAT, 0, 773 TSTF, FLOAT, 0, 774 TSTF, DOUBLE, 0, 775 PUSHD, DOUBLE, 0, 776 CVLF, U(LONG,FLOAT), 0, 777 CVFL, U(FLOAT,LONG), 0, 778 LDFD, U(FLOAT,DOUBLE),0, 779 CVDF, U(DOUBLE,FLOAT),0, 780 NEGF, FLOAT, 0, 781 0, 0, 0}; 782 783 interleave() 784 { 785 register struct node *p, *p1; 786 787 register struct intleavetab *t; 788 register int r; 789 int count; 790 for (p= first.forw; p!=0; p = p->forw){ 791 count = 0; 792 for (t =intltab; t->op != 0; t++){ 793 if (t->op == p->op && t->subop == p->subop){ 794 count = t->intleavect; 795 break; 796 } 797 } 798 if (count < 1) continue; 799 p1 = p->forw; 800 clearuse(); 801 clearreg(); 802 while ((p1 != 0) && (p1->op != CBR) && 803 (p1->subop == FLOAT || p1->subop == DOUBLE || 804 ((p1->subop&0xF0)==DOUBLE<<4) || ((p1->subop&0xF)==DOUBLE )|| 805 ((p1->subop&0xF0)==FLOAT<<4) || (p1->subop&0xF)==FLOAT)) 806 { 807 if (((r = isreg(p1->code)) >= 0)){ 808 uses[r] = p1; 809 if ((p1->subop == DOUBLE) || ((p->subop&0xF0)==DOUBLE<<4) || 810 ((p->subop&0xF)==DOUBLE)) 811 uses[r+1] = p1; 812 } 813 else checkreg(p1,p1->code); 814 p1 = p1->forw; 815 816 } 817 if (p1 == 0) return; 818 if (!(sideeffect(p, p1))) 819 insertblk(p,p1); 820 } 821 822 } 823 824 825 insertblk(p, p1) 826 struct node *p, *p1; 827 { 828 p1->back->forw = p1->forw; 829 p1->forw->back = p1->back; 830 p1->forw = p->forw; 831 p->forw->back = p1; 832 p->forw = p1; 833 p1->back = p; 834 } 835 836 int termop[] = { 837 JBR, CBR, JMP, LABEL, DLABEL, EROU, JSW, TST, CMP, BIT, 838 CALLF, CALLS, CASE, AOBLEQ, AOBLSS, CMPF, CMPF2, TSTF, MOVBLK, MFPR, 839 MTPR, PROBE, MOVO, TEXT, DATA, BSS, ALIGN, END, LGEN, SET, 840 LCOMM, COMM, 0 841 }; 842 843 sideeffect(p,p1) 844 struct node *p, *p1; 845 { 846 register struct node *q; 847 register int r; 848 register int *t; 849 register char *cp; 850 int i; 851 852 if (p1->op == 0) return(1); /* special instructions */ 853 854 for (t = termop; *t!=0; t++){ 855 if (*t == p1->op) return(1); 856 } 857 if ((p1->forw != NULL) && (p1->forw->op == CBR)) 858 return(1); 859 splitrand(p1); 860 r = isreg(lastrand); 861 if (uses[r] && r >= 0 ) return(1); 862 if ((p1->op == EDIV) && (r = isreg(regs[RT3]) >= 0) && 863 (uses[r])) return(1); 864 865 for (q = p1->back ; q!=p; q=q->back) 866 { 867 if ((p1->op == PUSH || p1->op == PUSHA) && 868 (q->op == PUSHD || q->op == PUSH || q->op == PUSHA)) 869 return(1); /* keep args in order */ 870 if (((i = strlen(q->code)) >= 5 && /* cvdl -(sp); pushl r0*/ 871 (strcmp(q->code+i-5,"-(sp)") == 0 )) || 872 (strcmp(lastrand,"-(sp)") == 0)) return(1); 873 if (equstr(q->code, lastrand)) 874 return(1); 875 if (q->op == STF || q->op == CVFL || q->op == CVLF) 876 { 877 if (equstr(q->code, regs[RT1])) return(1); 878 if (OP3 == ((p1->subop >> 4)&0xF) || p1->op == EMUL 879 || p1->op == EDIV) 880 if (equstr(q->code, regs[RT2])) 881 return(1); 882 /* handle the case std -56(fp) pushl -60(fp) pushl 883 -56(fp); 884 */ 885 if ((p1->forw != NULL) && (q->op == STF) && 886 (q->subop == DOUBLE)){ 887 if (!strncmp(q->code,p1->forw->code,strlen(q->code))) 888 return(1); 889 } 890 } 891 } 892 return(0); 893 } 894 checkreg(p,s) 895 struct node *p; 896 char *s; 897 { 898 char *cp2; 899 register int r; 900 /* check for (r),[r] */ 901 do if (*s=='(' || *s=='[') {/* get register number */ 902 char t; 903 cp2= ++s; while (*++s!=')' && *s!=']'); t= *s; *s=0; 904 if ((r=isreg(cp2)) >= 0) { 905 uses[r]=p; 906 } 907 *s=t; 908 } while (*++s); 909 } 910