1: # 2: /* 3: * C object code improver-- second part 4: */ 5: 6: #include "c2.h" 7: 8: rmove() 9: { 10: register struct node *p; 11: register int r; 12: register r1, flt; 13: 14: for (p=first.forw; p!=0; p = p->forw) { 15: flt = 0; 16: switch (p->op) { 17: 18: case MOVF: 19: case MOVFO: 20: case MOVOF: 21: flt = NREG; 22: 23: case MOV: 24: if (p->subop==BYTE) 25: goto dble; 26: dualop(p); 27: if ((r = findrand(regs[RT1], flt)) >= 0) { 28: if (r == flt+isreg(regs[RT2]) && p->forw->op!=CBR 29: && p->forw->op!=SXT 30: && p->forw->op!=CFCC) { 31: p->forw->back = p->back; 32: p->back->forw = p->forw; 33: redunm++; 34: continue; 35: } 36: } 37: if (equstr(regs[RT1], "$0")) { 38: p->op = CLR; 39: strcpy(regs[RT1], regs[RT2]); 40: regs[RT2][0] = 0; 41: p->code = copy(1, regs[RT1]); 42: goto sngl; 43: } 44: repladdr(p, 0, flt); 45: r = isreg(regs[RT1]); 46: r1 = isreg(regs[RT2]); 47: dest(regs[RT2], flt); 48: if (r >= 0) 49: if (r1 >= 0) 50: savereg(r1+flt, regs[r+flt]); 51: else 52: savereg(r+flt, regs[RT2]); 53: else 54: if (r1 >= 0) 55: savereg(r1+flt, regs[RT1]); 56: else 57: setcon(regs[RT1], regs[RT2]); 58: source(regs[RT1]); 59: setcc(regs[RT2]); 60: continue; 61: 62: case ADDF: 63: case SUBF: 64: case DIVF: 65: case MULF: 66: flt = NREG; 67: goto dble; 68: 69: case ADD: 70: case SUB: 71: case BIC: 72: case BIS: 73: case MUL: 74: case DIV: 75: case ASH: 76: dble: 77: dualop(p); 78: if (p->op==BIC && (equstr(regs[RT1], "$-1") || equstr(regs[RT1], "$177777"))) { 79: p->op = CLR; 80: strcpy(regs[RT1], regs[RT2]); 81: regs[RT2][0] = 0; 82: p->code = copy(1, regs[RT1]); 83: goto sngl; 84: } 85: if ((p->op==BIC || p->op==BIS) && equstr(regs[RT1], "$0")) { 86: if (p->forw->op!=CBR) { 87: p->back->forw = p->forw; 88: p->forw->back = p->back; 89: continue; 90: } 91: } 92: repladdr(p, 0, flt); 93: source(regs[RT1]); 94: dest(regs[RT2], flt); 95: if (p->op==DIV && (r = isreg(regs[RT2])>=0)) 96: regs[r+1][0] = 0; 97: ccloc[0] = 0; 98: continue; 99: 100: case CLRF: 101: case NEGF: 102: flt = NREG; 103: 104: case CLR: 105: case COM: 106: case INC: 107: case DEC: 108: case NEG: 109: case ASR: 110: case ASL: 111: case SXT: 112: singop(p); 113: sngl: 114: dest(regs[RT1], flt); 115: if (p->op==CLR && flt==0) 116: if ((r = isreg(regs[RT1])) >= 0) 117: savereg(r, "$0"); 118: else 119: setcon("$0", regs[RT1]); 120: ccloc[0] = 0; 121: continue; 122: 123: case TSTF: 124: flt = NREG; 125: 126: case TST: 127: singop(p); 128: repladdr(p, 0, flt); 129: source(regs[RT1]); 130: if (equstr(regs[RT1], ccloc)) { 131: p->back->forw = p->forw; 132: p->forw->back = p->back; 133: p = p->back; 134: nrtst++; 135: nchange++; 136: } 137: continue; 138: 139: case CMPF: 140: flt = NREG; 141: 142: case CMP: 143: case BIT: 144: dualop(p); 145: source(regs[RT1]); 146: source(regs[RT2]); 147: if(p->op==BIT) { 148: if (equstr(regs[RT1], "$-1") || equstr(regs[RT1], "$177777")) { 149: p->op = TST; 150: strcpy(regs[RT1], regs[RT2]); 151: regs[RT2][0] = 0; 152: p->code = copy(1, regs[RT1]); 153: nchange++; 154: nsaddr++; 155: } else if (equstr(regs[RT2], "$-1") || equstr(regs[RT2], "$177777")) { 156: p->op = TST; 157: regs[RT2][0] = 0; 158: p->code = copy(1, regs[RT1]); 159: nchange++; 160: nsaddr++; 161: } 162: if (equstr(regs[RT1], "$0")) { 163: p->op = TST; 164: regs[RT2][0] = 0; 165: p->code = copy(1, regs[RT1]); 166: nchange++; 167: nsaddr++; 168: } else if (equstr(regs[RT2], "$0")) { 169: p->op = TST; 170: strcpy(regs[RT1], regs[RT2]); 171: regs[RT2][0] = 0; 172: p->code = copy(1, regs[RT1]); 173: nchange++; 174: nsaddr++; 175: } 176: } 177: repladdr(p, 1, flt); 178: ccloc[0] = 0; 179: continue; 180: 181: case CBR: 182: if (p->back->op==TST || p->back->op==CMP) { 183: if (p->back->op==TST) { 184: singop(p->back); 185: savereg(RT2, "$0"); 186: } else 187: dualop(p->back); 188: r = compare(p->subop, findcon(RT1), findcon(RT2)); 189: if (r==0) { 190: p->back->back->forw = p->forw; 191: p->forw->back = p->back->back; 192: decref(p->ref); 193: p = p->back->back; 194: nchange++; 195: } else if (r>0) { 196: p->op = JBR; 197: p->subop = 0; 198: p->back->back->forw = p; 199: p->back = p->back->back; 200: p = p->back; 201: nchange++; 202: } 203: } 204: case CFCC: 205: ccloc[0] = 0; 206: continue; 207: 208: case JBR: 209: redunbr(p); 210: 211: default: 212: clearreg(); 213: } 214: } 215: } 216: 217: jumpsw() 218: { 219: register struct node *p, *p1; 220: register t; 221: register struct node *tp; 222: int nj; 223: 224: t = 0; 225: nj = 0; 226: for (p=first.forw; p!=0; p = p->forw) 227: p->refc = ++t; 228: for (p=first.forw; p!=0; p = p1) { 229: p1 = p->forw; 230: if (p->op == CBR && p1->op==JBR && p->ref && p1->ref 231: && abs(p->refc - p->ref->refc) > abs(p1->refc - p1->ref->refc)) { 232: if (p->ref==p1->ref) 233: continue; 234: p->subop = revbr[p->subop]; 235: tp = p1->ref; 236: p1->ref = p->ref; 237: p->ref = tp; 238: t = p1->labno; 239: p1->labno = p->labno; 240: p->labno = t; 241: nrevbr++; 242: nj++; 243: } 244: } 245: return(nj); 246: } 247: 248: addsob() 249: { 250: register struct node *p, *p1; 251: 252: for (p = &first; (p1 = p->forw)!=0; p = p1) { 253: if (p->op==DEC && isreg(p->code)>=0 254: && p1->op==CBR && p1->subop==JNE) { 255: if (p->refc < p1->ref->refc) 256: continue; 257: if (toofar(p1)) 258: continue; 259: p->labno = p1->labno; 260: p->op = SOB; 261: p->subop = 0; 262: p1->forw->back = p; 263: p->forw = p1->forw; 264: nsob++; 265: } 266: } 267: } 268: 269: toofar(p) 270: struct node *p; 271: { 272: register struct node *p1; 273: int len; 274: 275: len = 0; 276: for (p1 = p->ref; p1 && p1!=p; p1 = p1->forw) 277: len += ilen(p1); 278: if (len < 128) 279: return(0); 280: return(1); 281: } 282: 283: ilen(p) 284: register struct node *p; 285: { 286: register l; 287: 288: switch (p->op) { 289: case LABEL: 290: case DLABEL: 291: case TEXT: 292: case EROU: 293: case EVEN: 294: return(0); 295: 296: case CBR: 297: return(6); 298: 299: default: 300: dualop(p); 301: return(2 + adrlen(regs[RT1]) + adrlen(regs[RT2])); 302: } 303: } 304: 305: adrlen(s) 306: register char *s; 307: { 308: if (*s == 0) 309: return(0); 310: if (*s=='r') 311: return(0); 312: if (*s=='(' && *(s+1)=='r') 313: return(0); 314: if (*s=='-' && *(s+1)=='(') 315: return(0); 316: return(2); 317: } 318: 319: abs(x) 320: { 321: return(x<0? -x: x); 322: } 323: 324: equop(ap1, p2) 325: struct node *ap1, *p2; 326: { 327: register char *cp1, *cp2; 328: register struct node *p1; 329: 330: p1 = ap1; 331: if (p1->op!=p2->op || p1->subop!=p2->subop) 332: return(0); 333: if (p1->op>0 && p1->op<MOV) 334: return(0); 335: cp1 = p1->code; 336: cp2 = p2->code; 337: if (cp1==0 && cp2==0) 338: return(1); 339: if (cp1==0 || cp2==0) 340: return(0); 341: while (*cp1 == *cp2++) 342: if (*cp1++ == 0) 343: return(1); 344: return(0); 345: } 346: 347: decref(p) 348: register struct node *p; 349: { 350: if (--p->refc <= 0) { 351: nrlab++; 352: p->back->forw = p->forw; 353: p->forw->back = p->back; 354: } 355: } 356: 357: struct node * 358: nonlab(p) 359: struct node *p; 360: { 361: while (p && p->op==LABEL) 362: p = p->forw; 363: return(p); 364: } 365: 366: char * 367: alloc(n) 368: register n; 369: { 370: register char *p; 371: 372: n++; 373: n &= ~01; 374: if (lasta+n >= lastr) { 375: if (sbrk(2000) == (char *)-1) { 376: fprintf(stderr, "C Optimizer: out of space\n"); 377: exit(1); 378: } 379: lastr += 2000; 380: } 381: p = lasta; 382: lasta += n; 383: return(p); 384: } 385: 386: clearreg() 387: { 388: register int i; 389: 390: for (i=0; i<2*NREG; i++) 391: regs[i][0] = '\0'; 392: conloc[0] = 0; 393: ccloc[0] = 0; 394: } 395: 396: savereg(ai, as) 397: char *as; 398: { 399: register char *p, *s, *sp; 400: 401: sp = p = regs[ai]; 402: s = as; 403: if (source(s)) 404: return; 405: while (*p++ = *s) { 406: if (s[0]=='(' && s[1]=='r' && s[2]<'5') { 407: *sp = 0; 408: return; 409: } 410: if (*s++ == ',') 411: break; 412: } 413: *--p = '\0'; 414: } 415: 416: dest(as, flt) 417: char *as; 418: { 419: register char *s; 420: register int i; 421: 422: s = as; 423: source(s); 424: if ((i = isreg(s)) >= 0) 425: regs[i+flt][0] = 0; 426: for (i=0; i<NREG+NREG; i++) 427: if (*regs[i]=='*' && equstr(s, regs[i]+1)) 428: regs[i][0] = 0; 429: while ((i = findrand(s, flt)) >= 0) 430: regs[i][0] = 0; 431: while (*s) { 432: if ((*s=='(' && (*(s+1)!='r' || *(s+2)!='5')) || *s++=='*') { 433: for (i=0; i<NREG+NREG; i++) { 434: if (regs[i][0] != '$') 435: regs[i][0] = 0; 436: conloc[0] = 0; 437: } 438: return; 439: } 440: } 441: } 442: 443: singop(ap) 444: struct node *ap; 445: { 446: register char *p1, *p2; 447: 448: p1 = ap->code; 449: p2 = regs[RT1]; 450: while (*p2++ = *p1++); 451: regs[RT2][0] = 0; 452: } 453: 454: 455: dualop(ap) 456: struct node *ap; 457: { 458: register char *p1, *p2; 459: register struct node *p; 460: 461: p = ap; 462: p1 = p->code; 463: p2 = regs[RT1]; 464: while (*p1 && *p1!=',') 465: *p2++ = *p1++; 466: *p2++ = 0; 467: p2 = regs[RT2]; 468: *p2 = 0; 469: if (*p1++ !=',') 470: return; 471: while (*p2++ = *p1++); 472: } 473: 474: findrand(as, flt) 475: char *as; 476: { 477: register int i; 478: for (i = flt; i<NREG+flt; i++) { 479: if (equstr(regs[i], as)) 480: return(i); 481: } 482: return(-1); 483: } 484: 485: isreg(as) 486: char *as; 487: { 488: register char *s; 489: 490: s = as; 491: if (s[0]=='r' && s[1]>='0' && s[1]<='4' && s[2]==0) 492: return(s[1]-'0'); 493: return(-1); 494: } 495: 496: check() 497: { 498: register struct node *p, *lp; 499: 500: lp = &first; 501: for (p=first.forw; p!=0; p = p->forw) { 502: if (p->back != lp) 503: abort(); 504: lp = p; 505: } 506: } 507: 508: source(ap) 509: char *ap; 510: { 511: register char *p1, *p2; 512: 513: p1 = ap; 514: p2 = p1; 515: if (*p1==0) 516: return(0); 517: while (*p2++); 518: if (*p1=='-' && *(p1+1)=='(' 519: || *p1=='*' && *(p1+1)=='-' && *(p1+2)=='(' 520: || *(p2-2)=='+') { 521: while (*p1 && *p1++!='r'); 522: if (*p1>='0' && *p1<='4') 523: regs[*p1 - '0'][0] = 0; 524: return(1); 525: } 526: return(0); 527: } 528: 529: repladdr(p, f, flt) 530: struct node *p; 531: { 532: register r; 533: int r1; 534: register char *p1, *p2; 535: static char rt1[50], rt2[50]; 536: 537: if (f) 538: r1 = findrand(regs[RT2], flt); 539: else 540: r1 = -1; 541: r = findrand(regs[RT1], flt); 542: if (r1 >= NREG) 543: r1 -= NREG; 544: if (r >= NREG) 545: r -= NREG; 546: if (r>=0 || r1>=0) { 547: p2 = regs[RT1]; 548: for (p1 = rt1; *p1++ = *p2++;); 549: if (regs[RT2][0]) { 550: p1 = rt2; 551: *p1++ = ','; 552: for (p2 = regs[RT2]; *p1++ = *p2++;); 553: } else 554: rt2[0] = 0; 555: if (r>=0) { 556: rt1[0] = 'r'; 557: rt1[1] = r + '0'; 558: rt1[2] = 0; 559: nsaddr++; 560: } 561: if (r1>=0) { 562: rt2[1] = 'r'; 563: rt2[2] = r1 + '0'; 564: rt2[3] = 0; 565: nsaddr++; 566: } 567: p->code = copy(2, rt1, rt2); 568: } 569: } 570: 571: movedat() 572: { 573: register struct node *p1, *p2; 574: struct node *p3; 575: register seg; 576: struct node data; 577: struct node *datp; 578: 579: if (first.forw == 0) 580: return; 581: if (lastseg != TEXT && lastseg != -1) { 582: p1 = (struct node *)alloc(sizeof(first)); 583: p1->op = lastseg; 584: p1->subop = 0; 585: p1->code = NULL; 586: p1->forw = first.forw; 587: p1->back = &first; 588: first.forw->back = p1; 589: first.forw = p1; 590: } 591: datp = &data; 592: for (p1 = first.forw; p1!=0; p1 = p1->forw) { 593: if (p1->op == DATA) { 594: p2 = p1->forw; 595: while (p2 && p2->op!=TEXT) 596: p2 = p2->forw; 597: if (p2==0) 598: break; 599: p3 = p1->back; 600: p1->back->forw = p2->forw; 601: p2->forw->back = p3; 602: p2->forw = 0; 603: datp->forw = p1; 604: p1->back = datp; 605: p1 = p3; 606: datp = p2; 607: } 608: } 609: if (data.forw) { 610: datp->forw = first.forw; 611: first.forw->back = datp; 612: data.forw->back = &first; 613: first.forw = data.forw; 614: } 615: seg = lastseg; 616: for (p1 = first.forw; p1!=0; p1 = p1->forw) { 617: if (p1->op==TEXT||p1->op==DATA||p1->op==BSS) { 618: if (p2 = p1->forw) { 619: if (p2->op==TEXT||p2->op==DATA||p2->op==BSS) 620: p1->op = p2->op; 621: } 622: if (p1->op == seg || p1->forw&&p1->forw->op==seg) { 623: p1->back->forw = p1->forw; 624: p1->forw->back = p1->back; 625: p1 = p1->back; 626: continue; 627: } 628: seg = p1->op; 629: } 630: } 631: } 632: 633: redunbr(p) 634: register struct node *p; 635: { 636: register struct node *p1; 637: register char *ap1; 638: char *ap2; 639: 640: if ((p1 = p->ref) == 0) 641: return; 642: p1 = nonlab(p1); 643: if (p1->op==TST) { 644: singop(p1); 645: savereg(RT2, "$0"); 646: } else if (p1->op==CMP) 647: dualop(p1); 648: else 649: return; 650: if (p1->forw->op!=CBR) 651: return; 652: ap1 = findcon(RT1); 653: ap2 = findcon(RT2); 654: p1 = p1->forw; 655: if (compare(p1->subop, ap1, ap2)>0) { 656: nredunj++; 657: nchange++; 658: decref(p->ref); 659: p->ref = p1->ref; 660: p->labno = p1->labno; 661: p->ref->refc++; 662: } 663: } 664: 665: char * 666: findcon(i) 667: { 668: register char *p; 669: register r; 670: 671: p = regs[i]; 672: if (*p=='$') 673: return(p); 674: if ((r = isreg(p)) >= 0) 675: return(regs[r]); 676: if (equstr(p, conloc)) 677: return(conval); 678: return(p); 679: } 680: 681: compare(oper, cp1, cp2) 682: register char *cp1, *cp2; 683: { 684: register unsigned n1, n2; 685: 686: if (*cp1++ != '$' || *cp2++ != '$') 687: return(-1); 688: n1 = 0; 689: while (*cp2 >= '0' && *cp2 <= '7') { 690: n1 <<= 3; 691: n1 += *cp2++ - '0'; 692: } 693: n2 = n1; 694: n1 = 0; 695: while (*cp1 >= '0' && *cp1 <= '7') { 696: n1 <<= 3; 697: n1 += *cp1++ - '0'; 698: } 699: if (*cp1=='+') 700: cp1++; 701: if (*cp2=='+') 702: cp2++; 703: do { 704: if (*cp1++ != *cp2) 705: return(-1); 706: } while (*cp2++); 707: switch(oper) { 708: 709: case JEQ: 710: return(n1 == n2); 711: case JNE: 712: return(n1 != n2); 713: case JLE: 714: return((int)n1 <= (int)n2); 715: case JGE: 716: return((int)n1 >= (int)n2); 717: case JLT: 718: return((int)n1 < (int)n2); 719: case JGT: 720: return((int)n1 > (int)n2); 721: case JLO: 722: return(n1 < n2); 723: case JHI: 724: return(n1 > n2); 725: case JLOS: 726: return(n1 <= n2); 727: case JHIS: 728: return(n1 >= n2); 729: } 730: return(-1); 731: } 732: 733: setcon(ar1, ar2) 734: char *ar1, *ar2; 735: { 736: register char *cl, *cv, *p; 737: 738: cl = ar2; 739: cv = ar1; 740: if (*cv != '$') 741: return; 742: if (!natural(cl)) 743: return; 744: p = conloc; 745: while (*p++ = *cl++); 746: p = conval; 747: while (*p++ = *cv++); 748: } 749: 750: equstr(ap1, ap2) 751: char *ap1, *ap2; 752: { 753: char *p1, *p2; 754: 755: p1 = ap1; 756: p2 = ap2; 757: do { 758: if (*p1++ != *p2) 759: return(0); 760: } while (*p2++); 761: return(1); 762: } 763: 764: setcc(ap) 765: char *ap; 766: { 767: register char *p, *p1; 768: 769: p = ap; 770: if (!natural(p)) { 771: ccloc[0] = 0; 772: return; 773: } 774: p1 = ccloc; 775: while (*p1++ = *p++); 776: } 777: 778: natural(ap) 779: char *ap; 780: { 781: register char *p; 782: 783: p = ap; 784: if (*p=='*' || *p=='(' || *p=='-'&&*(p+1)=='(') 785: return(0); 786: while (*p++); 787: p--; 788: if (*--p == '+' || *p ==')' && *--p != '5') 789: return(0); 790: return(1); 791: }