1 #ifndef lint 2 static char sccsid[] = "@(#)c22.c 1.7 (Berkeley/CCI) 01/10/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, 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 && 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 nrtst++; nchange++; 604 } 605 } 606 607 char * 608 findcon(p, type) 609 register char *p; 610 { 611 register int r; 612 613 if (*p=='$') 614 return(p); 615 if ((r = isreg(p)) >= 0 && compat(regs[r][0],type)) 616 return(regs[r]+1); 617 if (equstr(p, conloc) && equtype(conloc[0], type)) 618 return(conval+1); 619 return(p); 620 } 621 622 /* compare constants: 0 - branch taken; 1 - not taken; -1 - don't know */ 623 compare(op, acp1, acp2) 624 char *acp1, *acp2; 625 { 626 register char *cp1, *cp2; 627 register int n1, n2, sign; 628 629 cp1 = acp1; 630 cp2 = acp2; 631 if (*cp1++ != '$' || *cp2++ != '$') 632 return(-1); 633 n1 = 0; sign=1; if (*cp1=='-') {++cp1; sign= -1;} 634 while (isdigit(*cp1)) {n1 *= 10; n1 += *cp1++ - '0';} 635 n1 *= sign; 636 n2 = 0; sign=1; if (*cp2=='-') {++cp2; sign= -1;} 637 while (isdigit(*cp2)) {n2 *= 10; n2 += *cp2++ - '0';} 638 n2 *= sign; 639 if (*cp1=='+') 640 cp1++; 641 if (*cp2=='+') 642 cp2++; 643 do { 644 if (*cp1++ != *cp2) 645 return(-1); 646 } while (*cp2++); 647 switch(op) { 648 649 case JEQ: 650 return(n1 == n2); 651 case JNE: 652 return(n1 != n2); 653 case JLE: 654 return(n1 <= n2); 655 case JGE: 656 return(n1 >= n2); 657 case JLT: 658 return(n1 < n2); 659 case JGT: 660 return(n1 > n2); 661 case JLO: 662 return((unsigned)n1 < (unsigned)n2); 663 case JHI: 664 return((unsigned)n1 > (unsigned)n2); 665 case JLOS: 666 return((unsigned)n1 <= (unsigned)n2); 667 case JHIS: 668 return((unsigned)n1 >= (unsigned)n2); 669 } 670 return(-1); 671 } 672 673 setcon(cv, cl, type) 674 register char *cv, *cl; 675 { 676 register char *p; 677 678 if (*cv != '$') 679 return; 680 if (!natural(cl)) 681 return; 682 p = conloc; 683 while (*p++ = *cl++); 684 p = conval; 685 *p++ = type; 686 while (*p++ = *cv++); 687 } 688 689 setcc(ap,type) 690 char *ap; 691 { 692 register char *p, *p1; 693 694 p = ap; 695 if (!natural(p)) { 696 ccloc[0] = 0; 697 return; 698 } 699 p1 = ccloc; 700 *p1++ = type; 701 while (*p1++ = *p++); 702 } 703 704 indexa(p) register char *p; {/* 1-> uses [r] addressing mode; 0->doesn't */ 705 while (*p) if (*p++=='[') return(1); 706 return(0); 707 } 708 709 natural(p) 710 register char *p; 711 {/* 1->simple local, parameter, global, or register; 0->otherwise */ 712 713 if (*p=='*' || *p=='(' || *p=='$') 714 return(0); 715 while (*p++); 716 p--; 717 if (*--p==']' || *p==')' && 718 !(*(p-2)=='f' || fortflg && (*--p=='1' || *p=='2') && *--p=='1')) 719 return(0); 720 return(1); 721 } 722 723 /* 724 ** Tell if an argument is most likely static. 725 */ 726 727 isstatic(cp) 728 register char *cp; 729 { 730 if (*cp == '_' || *cp == 'L') 731 return (1); 732 return (0); 733 } 734 735 736 checkaobdisp(p) 737 register struct node *p; 738 { 739 register struct node *q; 740 register int i; 741 742 743 if (!aobflag) return(1); 744 /* backward search */ 745 i = 0; 746 q = p; 747 while (i++ < MAXAOBDISP && ((q= q->back) !=&first)) 748 { 749 if (p->ref == q) 750 return(1); 751 } 752 753 /* forward search */ 754 i = 0; 755 q = p; 756 while (i++ < MAXAOBDISP && ((q= q->forw) !=0)) 757 { 758 if (p->ref == q) 759 return(1); 760 } 761 return(0); 762 } 763 764 765 struct intleavetab intltab[] = { 766 ADDF, FLOAT, 1, 767 ADDF, DOUBLE, 1, 768 SUBF, FLOAT, 1, 769 SUBF, DOUBLE, 1, 770 MULF, FLOAT, 1, 771 MULF, DOUBLE, 1, 772 DIVF, FLOAT, 1, 773 DIVF, DOUBLE, 1, 774 SINF, FLOAT, 1, 775 COSF, FLOAT, 1, 776 ATANF, FLOAT, 1, 777 LOGF, FLOAT, 1, 778 SQRTF, FLOAT, 1, 779 EXPF, FLOAT, 1, 780 LDF, FLOAT, 0, 781 LDF, DOUBLE, 0, 782 LNF, FLOAT, 0, 783 LNF, DOUBLE, 0, 784 STF, FLOAT, 0, 785 CMPF, FLOAT, 0, 786 CMPF, DOUBLE, 0, 787 CMPF2, FLOAT, 0, 788 TSTF, FLOAT, 0, 789 TSTF, DOUBLE, 0, 790 PUSHD, DOUBLE, 0, 791 CVLF, U(LONG,FLOAT), 0, 792 CVFL, U(FLOAT,LONG), 0, 793 LDFD, U(FLOAT,DOUBLE),0, 794 CVDF, U(DOUBLE,FLOAT),0, 795 NEGF, FLOAT, 0, 796 NIL, 0, 0}; 797 798 interleave() 799 { 800 register struct node *p, *p1; 801 802 register struct intleavetab *t; 803 register int r; 804 int count; 805 for (p= first.forw; p!=0; p = p->forw){ 806 count = 0; 807 for (t =intltab; t->op != NIL; t++){ 808 if (t->op == p->op && t->subop == p->subop){ 809 count = t->intleavect; 810 break; 811 } 812 } 813 if (count < 1) continue; 814 p1 = p->forw; 815 clearuse(); 816 clearreg(); 817 while ((p1 != 0) && (p1->op != CBR) && 818 (p1->subop == FLOAT || p1->subop == DOUBLE || 819 ((p1->subop&0xF0)==DOUBLE<<4) || ((p1->subop&0xF)==DOUBLE )|| 820 ((p1->subop&0xF0)==FLOAT<<4) || (p1->subop&0xF)==FLOAT)) 821 { 822 if (((r = isreg(p1->code)) >= 0)){ 823 uses[r] = p1; 824 if ((p1->subop == DOUBLE) || ((p->subop&0xF0)==DOUBLE<<4) || 825 ((p->subop&0xF)==DOUBLE)) 826 uses[r+1] = p1; 827 } 828 else checkreg(p1,p1->code); 829 p1 = p1->forw; 830 831 } 832 if (p1 == 0) return; 833 if (!(sideeffect(p, p1))) 834 insertblk(p,p1); 835 } 836 837 } 838 839 840 insertblk(p, p1) 841 struct node *p, *p1; 842 { 843 p1->back->forw = p1->forw; 844 p1->forw->back = p1->back; 845 p1->forw = p->forw; 846 p->forw->back = p1; 847 p->forw = p1; 848 p1->back = p; 849 } 850 851 OpCode termop[] = { 852 JBR, CBR, JMP, LABEL, DLABEL, EROU, JSW, TST, CMP, BIT, 853 CALLF, CALLS, CASE, AOBLEQ, AOBLSS, CMPF, CMPF2, TSTF, MOVBLK, MFPR, 854 MTPR, PROBE, MOVO, TEXT, DATA, BSS, ALIGN, END, LGEN, SET, 855 LCOMM, COMM, NIL 856 }; 857 858 sideeffect(p,p1) 859 struct node *p, *p1; 860 { 861 register struct node *q; 862 register int r; 863 register OpCode *t; 864 register char *cp; 865 int i; 866 867 if (p1->op == NIL) return(1); /* special instructions */ 868 869 for (t = termop; *t!=NIL; t++){ 870 if (*t == p1->op) return(1); 871 } 872 if ((p1->forw != NULL) && (p1->forw->op == CBR)) 873 return(1); 874 splitrand(p1); 875 r = isreg(lastrand); 876 if (uses[r] && r >= 0 ) return(1); 877 if ((p1->op == EDIV) && (r = isreg(regs[RT3]) >= 0) && 878 (uses[r])) return(1); 879 880 for (q = p1->back ; q!=p; q=q->back) 881 { 882 if ((p1->op == PUSH || p1->op == PUSHA) && 883 (q->op == PUSHD || q->op == PUSH || q->op == PUSHA)) 884 return(1); /* keep args in order */ 885 if (((i = strlen(q->code)) >= 5 && /* cvdl -(sp); pushl r0*/ 886 (strcmp(q->code+i-5,"-(sp)") == 0 )) || 887 (strcmp(lastrand,"-(sp)") == 0)) return(1); 888 if (equstr(q->code, lastrand)) 889 return(1); 890 if (q->op == STF || q->op == CVFL || q->op == CVLF) 891 { 892 if (equstr(q->code, regs[RT1])) return(1); 893 if (has3ops(p1) || p1->op == EMUL || p1->op == EDIV) 894 if (equstr(q->code, regs[RT2])) 895 return(1); 896 /* handle the case std -56(fp) pushl -60(fp) pushl 897 -56(fp); 898 */ 899 if ((p1->forw != NULL) && (q->op == STF) && 900 (q->subop == DOUBLE)){ 901 if (!strncmp(q->code,p1->forw->code,strlen(q->code))) 902 return(1); 903 } 904 } 905 } 906 return(0); 907 } 908 checkreg(p,s) 909 struct node *p; 910 char *s; 911 { 912 char *cp2; 913 register int r; 914 /* check for (r),[r] */ 915 do if (*s=='(' || *s=='[') {/* get register number */ 916 char t; 917 cp2= ++s; while (*++s!=')' && *s!=']'); t= *s; *s=0; 918 if ((r=isreg(cp2)) >= 0) { 919 uses[r]=p; 920 } 921 *s=t; 922 } while (*++s); 923 } 924