1 #ifndef lint 2 static char sccsid[] = "@(#)c22.c 1.9 (Berkeley/CCI) 05/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 } 925