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: nchange++; 35: continue; 36: } 37: } 38: if (equstr(regs[RT1], "$0")) { 39: p->op = CLR; 40: strcpy(regs[RT1], regs[RT2]); 41: regs[RT2][0] = 0; 42: p->code = copy(1, regs[RT1]); 43: nchange++; 44: goto sngl; 45: } 46: repladdr(p, 0, flt); 47: r = isreg(regs[RT1]); 48: r1 = isreg(regs[RT2]); 49: dest(regs[RT2], flt); 50: if (r >= 0) 51: if (r1 >= 0) 52: savereg(r1+flt, regs[r+flt]); 53: else 54: savereg(r+flt, regs[RT2]); 55: else 56: if (r1 >= 0) 57: savereg(r1+flt, regs[RT1]); 58: else 59: setcon(regs[RT1], regs[RT2]); 60: source(regs[RT1]); 61: setcc(regs[RT2]); 62: continue; 63: 64: case ADDF: 65: case SUBF: 66: case DIVF: 67: case MULF: 68: flt = NREG; 69: goto dble; 70: 71: case ADD: 72: case SUB: 73: case BIC: 74: case BIS: 75: case MUL: 76: case DIV: 77: case ASH: 78: dble: 79: dualop(p); 80: if (p->op==BIC && (equstr(regs[RT1], "$-1") || equstr(regs[RT1], "$177777"))) { 81: p->op = CLR; 82: strcpy(regs[RT1], regs[RT2]); 83: regs[RT2][0] = 0; 84: p->code = copy(1, regs[RT1]); 85: nchange++; 86: goto sngl; 87: } 88: if ((p->op==BIC || p->op==BIS) && equstr(regs[RT1], "$0")) { 89: if (p->forw->op!=CBR) { 90: p->back->forw = p->forw; 91: p->forw->back = p->back; 92: nchange++; 93: continue; 94: } 95: } 96: /* 97: * the next block of code looks for the sequences (which extract the 98: * high byte of a word or the low byte respectively): 99: * ash $-10,r 100: * bic $-400,r 101: * or 102: * mov natural,r 103: * bic $-400,r 104: * and transforms them into: 105: * clrb r 106: * swab r 107: * or 108: * clr r 109: * bisb natural,r 110: * These constructs occur often enough in the kernel (dealing with major/minor 111: * device numbers, etc) it's worth a little extra work at compile time. 112: */ 113: if (p->op == BIC && (equstr(regs[RT1],"$-400") || 114: equstr(regs[RT1],"$-177400"))) { 115: if (p->back->op == ASH) { 116: r = isreg(regs[RT2]); 117: dualop(p->back); 118: if ((equstr(regs[RT1], "$-10") || 119: equstr(regs[RT1], "$177770")) && 120: r == isreg(regs[RT2])) { 121: strcpy(regs[RT1], regs[RT2]); 122: regs[RT2][0] = 0; 123: p->back->op = CLR; 124: p->back->subop = BYTE; 125: p->back->code = copy(1, regs[RT1]); 126: p->op = SWAB; 127: p->code = copy(1, regs[RT1]); 128: nchange++; 129: goto sngl; 130: } 131: } 132: else if (p->back->op == MOV && p->forw->op != CBR) { 133: char temp[50]; 134: 135: r = isreg(regs[RT2]); 136: if (r < 0 && !xnatural(regs[RT2])) 137: goto out; 138: strcpy(temp, regs[RT2]); 139: dualop(p->back); 140: if (isreg(regs[RT2]) == r && natural(regs[RT1])) { 141: if (r < 0 && (!xnatural(regs[RT2]) || !equstr(temp, regs[RT2]))) 142: goto out; 143: /* 144: * XXX - the sequence "movb rN,rN; bic $-400,rN" can not be transformed 145: * because the 'clr' would lose all information about 'rN'. The best that can 146: * be done is to remove the 'movb' instruction and leave the 'bic'. 147: */ 148: if (isreg(regs[RT1]) == r && r >= 0) { 149: p = p->back; 150: p->forw->back = p->back; 151: p->back->forw = p->forw; 152: nchange++; 153: continue; 154: } 155: dest(regs[RT1], flt); 156: p->back->op = CLR; 157: p->back->subop = 0; 158: p->back->code = copy(1, regs[RT2]); 159: p->op = BIS; 160: p->subop = BYTE; 161: strcat(regs[RT1], ","); 162: p->code = copy(2, regs[RT1], regs[RT2]); 163: nchange++; 164: } 165: } 166: out: dualop(p); /* restore banged up parsed operands */ 167: } 168: repladdr(p, 0, flt); 169: source(regs[RT1]); 170: dest(regs[RT2], flt); 171: if (p->op==DIV && (r = isreg(regs[RT2]))>=0) 172: regs[r|1][0] = 0; 173: switch (p->op) 174: { 175: case ADD: 176: case SUB: 177: case BIC: 178: case BIS: 179: case ASH: 180: setcc(regs[RT2]); 181: break; 182: default: 183: ccloc[0] = 0; 184: } 185: continue; 186: 187: case SXT: 188: singop(p); 189: if (p->forw->op == CLR && p->forw->subop != BYTE && 190: xnatural(regs[RT1]) && !strcmp(p->code, p->forw->code)){ 191: p->forw->back = p->back; 192: p->back->forw = p->forw; 193: nchange++; 194: continue; 195: } 196: goto sngl; 197: case CLRF: 198: case NEGF: 199: flt = NREG; 200: 201: case CLR: 202: case COM: 203: case INC: 204: case DEC: 205: case NEG: 206: case ASR: 207: case ASL: 208: case SWAB: 209: singop(p); 210: sngl: 211: dest(regs[RT1], flt); 212: if (p->op==CLR && flt==0) 213: { 214: if ((r = isreg(regs[RT1])) >= 0) 215: savereg(r, "$0"); 216: else 217: setcon("$0", regs[RT1]); 218: ccloc[0] = 0; 219: } 220: else 221: setcc(regs[RT1]); 222: continue; 223: 224: case TSTF: 225: flt = NREG; 226: 227: case TST: 228: singop(p); 229: repladdr(p, 0, flt); 230: source(regs[RT1]); 231: if (p->back->op == TST && !flt && not_sp(regs[RT1])) { 232: char rt1[MAXCPS + 2]; 233: strcpy(rt1, regs[RT1]); 234: singop(p->back); 235: if (!strcmp("(sp)+", regs[RT1])) { 236: p->back->subop = p->subop; 237: p->back->forw = p->forw; 238: p->forw->back = p->back; 239: p = p->back; 240: p->op = MOV; 241: p->code = copy(2, rt1, ",(sp)+"); 242: nrtst++; 243: nchange++; 244: continue; 245: } 246: singop(p); 247: } 248: if (p->back->op == MOV && p->back->subop == BYTE) { 249: dualop(p->back); 250: setcc(regs[RT2]); 251: singop(p); 252: } 253: if (equstr(regs[RT1], ccloc) && p->subop == p->back->subop) { 254: p->back->forw = p->forw; 255: p->forw->back = p->back; 256: p = p->back; 257: nrtst++; 258: nchange++; 259: } 260: else 261: setcc(regs[RT1]); /* XXX - double TST in a row */ 262: continue; 263: 264: case CMPF: 265: flt = NREG; 266: 267: case CMP: 268: case BIT: 269: dualop(p); 270: source(regs[RT1]); 271: source(regs[RT2]); 272: if(p->op==BIT) { 273: if (equstr(regs[RT1], "$-1") || equstr(regs[RT1], "$177777")) { 274: p->op = TST; 275: strcpy(regs[RT1], regs[RT2]); 276: regs[RT2][0] = 0; 277: p->code = copy(1, regs[RT1]); 278: nchange++; 279: nsaddr++; 280: } else if (equstr(regs[RT2], "$-1") || equstr(regs[RT2], "$177777")) { 281: p->op = TST; 282: regs[RT2][0] = 0; 283: p->code = copy(1, regs[RT1]); 284: nchange++; 285: nsaddr++; 286: } 287: if (equstr(regs[RT1], "$0")) { 288: p->op = TST; 289: regs[RT2][0] = 0; 290: p->code = copy(1, regs[RT1]); 291: nchange++; 292: nsaddr++; 293: } else if (equstr(regs[RT2], "$0")) { 294: p->op = TST; 295: strcpy(regs[RT1], regs[RT2]); 296: regs[RT2][0] = 0; 297: p->code = copy(1, regs[RT1]); 298: nchange++; 299: nsaddr++; 300: } 301: } 302: repladdr(p, 1, flt); 303: ccloc[0] = 0; 304: continue; 305: 306: case CBR: 307: r = -1; 308: if (p->back->op==TST || p->back->op==CMP) { 309: if (p->back->op==TST) { 310: singop(p->back); 311: savereg(RT2, "$0"); 312: } else 313: dualop(p->back); 314: if (equstr(regs[RT1], regs[RT2]) 315: && natural(regs[RT1]) && natural(regs[RT2])) 316: r = compare(p->subop, "$1", "$1"); 317: else 318: r = compare(p->subop, findcon(RT1), findcon(RT2)); 319: if (r==0) { 320: if (p->forw->op==CBR 321: || p->forw->op==SXT 322: || p->forw->op==CFCC) { 323: p->back->forw = p->forw; 324: p->forw->back = p->back; 325: } else { 326: p->back->back->forw = p->forw; 327: p->forw->back = p->back->back; 328: } 329: decref(p->ref); 330: p = p->back->back; 331: nchange++; 332: } else if (r>0) { 333: p->op = JBR; 334: p->subop = 0; 335: p->back->back->forw = p; 336: p->back = p->back->back; 337: p = p->back; 338: nchange++; 339: } 340: /* 341: * If the instruction prior to the conditional branch was a 'tst' then 342: * save the condition code status. The C construct: 343: * if (x) 344: * if (x > 0) 345: * generates "tst _x; jeq ...; tst _x; jmi ...;jeq ...". The code below removes 346: * the second "tst _x", leaving "tst _x; jeq ...;jmi ...; jeq ...". 347: */ 348: if (p->back->op == TST) { 349: singop(p->back); 350: setcc(regs[RT1]); 351: break; 352: } 353: } 354: /* 355: * If the previous instruction was also a conditional branch then 356: * attempt to merge the two into a single branch. 357: */ 358: if (p->back->op == CBR) 359: fixupbr(p); 360: case CFCC: 361: ccloc[0] = 0; 362: continue; 363: 364: /* 365: * Unrecognized (unparsed) instructions, assignments (~foo=r2), and 366: * data arrive here. In order to prevent throwing away information 367: * about register contents just because a local assignment is done 368: * we check for the first character being a tilde. 369: */ 370: case 0: 371: if (p->code[0] != '~') 372: clearreg(); 373: continue; 374: 375: case JBR: 376: redunbr(p); 377: 378: default: 379: clearreg(); 380: } 381: } 382: } 383: 384: /* 385: * This table is used to convert two branches to the same label after a 386: * 'tst' (which clears the C and V condition codes) into a single branch. 387: * Entries which translate to JBR could eventually cause the 'tst' instruction 388: * to be eliminated as well, but that can wait for now. There are unused or 389: * impossible combinations ('tst' followed by 'jlo' for example. since 390: * 'tst' clears C it makes little sense to 'jlo/bcs') in the table, it 391: * would have cost more in code to remove them than the entries themselves. 392: * 393: * Example: "tst _x; jmi L3; jeq L3". Find the row for 'jmi', then look 394: * at the column for 'jeq', the resulting "opcode" is 'jle'. 395: */ 396: char brtable[12][12] = { 397: /* jeq jne jle jge jlt jgt jlo jhi jlos jhis jpl jmi */ 398: /* jeq */ {JEQ ,JBR ,JLE ,JGE ,JLE ,JGE ,JEQ ,JBR ,JEQ ,JBR ,JGE ,JLE}, 399: /* jne */ {JBR ,JNE ,JBR ,JBR ,JNE ,JNE ,JNE ,JNE ,JBR ,JBR ,JBR ,JNE}, 400: /* jle */ {JLE ,JBR ,JLE ,JBR ,JLE ,JBR ,JLE ,JBR ,JLE ,JBR ,JBR ,JLE}, 401: /* jge */ {JGE ,JBR ,JBR ,JGE ,JBR ,JGE ,JGE ,JBR ,JGE ,JBR ,JGE ,JBR}, 402: /* jlt */ {JLE ,JNE ,JLE ,JBR ,JLT ,JNE ,JLT ,JBR ,JLE ,JBR ,JBR ,JLT}, 403: /* jgt */ {JGE ,JNE ,JBR ,JGE ,JNE ,JGT ,JGT ,JGT ,JBR ,JGE ,JGE ,JNE}, 404: /* jlo */ {JEQ ,JNE ,JLE ,JGE ,JLT ,JGT ,JLO ,JHI ,JLOS,JHIS,JPL ,JMI}, 405: /* jhi */ {JBR ,JNE ,JBR ,JBR ,JNE ,JNE ,JNE ,JNE ,JBR ,JBR ,JBR ,JNE}, 406: /* jlos*/ {JEQ ,JBR ,JLE ,JGE ,JLE ,JGE ,JLE ,JBR ,JEQ ,JBR ,JGE ,JLE}, 407: /* jhis*/ {JBR ,JBR ,JBR ,JBR ,JBR ,JBR ,JBR ,JBR ,JBR ,JBR ,JBR ,JBR}, 408: /* jpl */ {JGE ,JBR ,JBR ,JGE ,JBR ,JGE ,JGE ,JBR ,JGE ,JBR ,JGE ,JBR}, 409: /* jmi */ {JLE ,JNE ,JLE ,JBR ,JLT ,JNE ,JLT ,JNE ,JLE ,JLT ,JBR ,JLT} 410: }; 411: 412: fixupbr(p) 413: register struct node *p; 414: { 415: register struct node *p1, *p2; 416: int op; 417: 418: p1 = p->back; 419: p2 = p1->back; 420: if (p->labno != p1->labno) 421: return; 422: if (p2->op != TST) { 423: if (p2->op == CBR && p2->back->op == TST) 424: goto ok; 425: return; 426: } 427: ok: p->subop = brtable[p->subop][p1->subop]; 428: nchange++; 429: nredunj++; 430: p2->forw = p; 431: p->back = p1->back; 432: } 433: 434: jumpsw() 435: { 436: register struct node *p, *p1; 437: register t; 438: register struct node *tp; 439: int nj; 440: 441: t = 0; 442: nj = 0; 443: for (p=first.forw; p!=0; p = p->forw) 444: p->refc = ++t; 445: for (p=first.forw; p!=0; p = p1) { 446: p1 = p->forw; 447: if (p->op == CBR && p1->op==JBR && p->ref && p1->ref 448: && abs(p->refc - p->ref->refc) > abs(p1->refc - p1->ref->refc)) { 449: if (p->ref==p1->ref) 450: continue; 451: p->subop = revbr[p->subop]; 452: tp = p1->ref; 453: p1->ref = p->ref; 454: p->ref = tp; 455: t = p1->labno; 456: p1->labno = p->labno; 457: p->labno = t; 458: nrevbr++; 459: nj++; 460: } 461: } 462: return(nj); 463: } 464: 465: addsob() 466: { 467: register struct node *p, *p1; 468: 469: for (p = &first; (p1 = p->forw)!=0; p = p1) { 470: if (p->op==DEC && isreg(p->code)>=0 471: && p1->op==CBR && p1->subop==JNE) { 472: if (p->refc < p1->ref->refc) 473: continue; 474: if (toofar(p1)) 475: continue; 476: p->labno = p1->labno; 477: p->op = SOB; 478: p->subop = 0; 479: p1->forw->back = p; 480: p->forw = p1->forw; 481: nsob++; 482: } 483: } 484: } 485: 486: toofar(p) 487: struct node *p; 488: { 489: register struct node *p1; 490: int len; 491: 492: len = 0; 493: for (p1 = p->ref; p1 && p1!=p; p1 = p1->forw) 494: len += ilen(p1); 495: if (len < 128) 496: return(0); 497: return(1); 498: } 499: 500: ilen(p) 501: register struct node *p; 502: { 503: 504: switch (p->op) { 505: case LABEL: 506: case DLABEL: 507: case TEXT: 508: case EROU: 509: case EVEN: 510: return(0); 511: 512: case CBR: 513: return(6); 514: 515: default: 516: dualop(p); 517: return(2 + adrlen(regs[RT1]) + adrlen(regs[RT2])); 518: } 519: } 520: 521: adrlen(s) 522: register char *s; 523: { 524: if (*s == 0) 525: return(0); 526: if (*s=='r') 527: return(0); 528: if (*s=='(' && *(s+1)=='r') 529: return(0); 530: if (*s=='-' && *(s+1)=='(') 531: return(0); 532: return(2); 533: } 534: 535: abs(x) 536: register int x; 537: { 538: return(x<0? -x: x); 539: } 540: 541: equop(ap1, p2) 542: struct node *ap1, *p2; 543: { 544: register char *cp1, *cp2; 545: register struct node *p1; 546: 547: p1 = ap1; 548: if (p1->op!=p2->op || p1->subop!=p2->subop) 549: return(0); 550: if (p1->op>0 && p1->op<MOV) 551: return(0); 552: cp1 = p1->code; 553: cp2 = p2->code; 554: if (cp1==0 && cp2==0) 555: return(1); 556: if (cp1==0 || cp2==0) 557: return(0); 558: while (*cp1 == *cp2++) 559: if (*cp1++ == 0) 560: return(1); 561: return(0); 562: } 563: 564: decref(p) 565: register struct node *p; 566: { 567: if (--p->refc <= 0) { 568: nrlab++; 569: p->back->forw = p->forw; 570: p->forw->back = p->back; 571: } 572: } 573: 574: struct node * 575: nonlab(p) 576: register struct node *p; 577: { 578: CHECK(10); 579: while (p && p->op==LABEL) 580: p = p->forw; 581: return(p); 582: } 583: 584: char * 585: alloc(n) 586: register n; 587: { 588: register char *p; 589: 590: #define round(a,b) ((((a)+(b)-1)/(b))*(b)) 591: n=round(n,sizeof(char *)); 592: if (alasta+n < alastr) { 593: p = alasta; 594: alasta += n; 595: return(p); 596: } 597: if (lasta+n >= lastr) { 598: if (sbrk(2000) == (char *)-1) { 599: fprintf(stderr, "C Optimizer: out of space\n"); 600: exit(1); 601: } 602: lastr += 2000; 603: } 604: p = lasta; 605: lasta += n; 606: return(p); 607: } 608: 609: clearreg() 610: { 611: register int i; 612: 613: for (i=0; i<2*NREG; i++) 614: regs[i][0] = '\0'; 615: conloc[0] = 0; 616: ccloc[0] = 0; 617: } 618: 619: savereg(ai, as) 620: char *as; 621: { 622: register char *p, *s, *sp; 623: 624: sp = p = regs[ai]; 625: s = as; 626: if (source(s)) 627: return; 628: while (*p++ = *s) { 629: if (s[0]=='(' && s[1]=='r' && s[2]<'5') { 630: *sp = 0; 631: return; 632: } 633: if (*s++ == ',') 634: break; 635: } 636: *--p = '\0'; 637: } 638: 639: dest(as, flt) 640: char *as; 641: { 642: register char *s; 643: register int i; 644: 645: s = as; 646: source(s); 647: if ((i = isreg(s)) >= 0) 648: regs[i+flt][0] = 0; 649: /* v7orig: 650: * for (i=0; i<NREG+NREG; i++) 651: */ 652: for (i=flt; i<flt+NREG; i++) 653: if (*regs[i]=='*' && equstr(s, regs[i]+1)) 654: regs[i][0] = 0; 655: if (equstr(s, conloc)) 656: conloc[0] = '\0'; 657: while ((i = findrand(s, flt)) >= 0) 658: regs[i][0] = 0; 659: while (*s) { 660: if ((*s=='(' && (*(s+1)!='r' || *(s+2)!='5')) || *s++=='*') { 661: /* v7.orig: 662: * for (i=0; i<NREG+NREG; i++) { 663: */ 664: for (i=flt; i<flt+NREG; i++) { 665: if (regs[i][0] != '$') 666: regs[i][0] = 0; 667: conloc[0] = 0; 668: } 669: return; 670: } 671: } 672: } 673: 674: singop(ap) 675: struct node *ap; 676: { 677: register char *p1, *p2; 678: 679: p1 = ap->code; 680: p2 = regs[RT1]; 681: while (*p2++ = *p1++); 682: regs[RT2][0] = 0; 683: } 684: 685: 686: dualop(ap) 687: struct node *ap; 688: { 689: register char *p1, *p2; 690: register struct node *p; 691: 692: p = ap; 693: p1 = p->code; 694: p2 = regs[RT1]; 695: while (*p1 && *p1!=',') 696: *p2++ = *p1++; 697: *p2++ = 0; 698: p2 = regs[RT2]; 699: *p2 = 0; 700: if (*p1++ !=',') 701: return; 702: while (*p1==' ' || *p1=='\t') 703: p1++; 704: while (*p2++ = *p1++) 705: ; 706: } 707: 708: findrand(as, flt) 709: char *as; 710: { 711: register int i; 712: for (i = flt; i<NREG+flt; i++) { 713: if (equstr(regs[i], as)) 714: return(i); 715: } 716: return(-1); 717: } 718: 719: isreg(as) 720: char *as; 721: { 722: register char *s; 723: 724: s = as; 725: if (s[0]=='r' && s[1]>='0' && s[1]<='4' && s[2]==0) 726: return(s[1]-'0'); 727: return(-1); 728: } 729: 730: check() 731: { 732: register struct node *p, *lp; 733: register count; 734: 735: lp = &first; 736: count = 0; 737: for (p=first.forw; p!=0; p = p->forw) { 738: if (++count > 10000) 739: abort(0); 740: if (p->back != lp) 741: abort(1); 742: lp = p; 743: } 744: } 745: 746: source(ap) 747: char *ap; 748: { 749: register char *p1, *p2; 750: 751: p1 = ap; 752: p2 = p1; 753: if (*p1==0) 754: return(0); 755: while (*p2++); 756: if (*p1=='-' && *(p1+1)=='(' 757: || *p1=='*' && *(p1+1)=='-' && *(p1+2)=='(' 758: || *(p2-2)=='+') { 759: while (*p1 && *p1++!='r'); 760: if (*p1>='0' && *p1<='4') 761: regs[*p1 - '0'][0] = 0; 762: return(1); 763: } 764: return(0); 765: } 766: 767: repladdr(p, f, flt) 768: struct node *p; 769: { 770: register r; 771: int r1; 772: register char *p1, *p2; 773: static char rt1[50], rt2[50]; 774: 775: if (f) 776: r1 = findrand(regs[RT2], flt); 777: else 778: r1 = -1; 779: r = findrand(regs[RT1], flt); 780: if (r1 >= NREG) 781: r1 -= NREG; 782: if (r >= NREG) 783: r -= NREG; 784: if (r>=0 || r1>=0) { 785: p2 = regs[RT1]; 786: for (p1 = rt1; *p1++ = *p2++;); 787: if (regs[RT2][0]) { 788: p1 = rt2; 789: *p1++ = ','; 790: for (p2 = regs[RT2]; *p1++ = *p2++;); 791: } else 792: rt2[0] = 0; 793: if (r>=0) { 794: rt1[0] = 'r'; 795: rt1[1] = r + '0'; 796: rt1[2] = 0; 797: nsaddr++; 798: nchange++; 799: } 800: if (r1>=0) { 801: rt2[1] = 'r'; 802: rt2[2] = r1 + '0'; 803: rt2[3] = 0; 804: nsaddr++; 805: nchange++; 806: } 807: p->code = copy(2, rt1, rt2); 808: } 809: } 810: 811: movedat() 812: { 813: register struct node *p1, *p2; 814: struct node *p3; 815: register seg; 816: struct node data; 817: struct node *datp; 818: 819: if (first.forw == 0) 820: return; 821: if (lastseg != TEXT && lastseg != -1) { 822: p1 = (struct node *)alloc(sizeof(first)); 823: p1->op = lastseg; 824: p1->subop = 0; 825: p1->code = NULL; 826: p1->forw = first.forw; 827: p1->back = &first; 828: first.forw->back = p1; 829: first.forw = p1; 830: } 831: datp = &data; 832: for (p1 = first.forw; p1!=0; p1 = p1->forw) { 833: if (p1->op == DATA) { 834: p2 = p1->forw; 835: while (p2 && p2->op!=TEXT) 836: p2 = p2->forw; 837: if (p2==0) 838: break; 839: p3 = p1->back; 840: p1->back->forw = p2->forw; 841: p2->forw->back = p3; 842: p2->forw = 0; 843: datp->forw = p1; 844: p1->back = datp; 845: p1 = p3; 846: datp = p2; 847: } 848: } 849: if (data.forw) { 850: datp->forw = first.forw; 851: first.forw->back = datp; 852: data.forw->back = &first; 853: first.forw = data.forw; 854: } 855: seg = lastseg; 856: for (p1 = first.forw; p1!=0; p1 = p1->forw) { 857: if (p1->op==TEXT||p1->op==DATA||p1->op==BSS) { 858: if (p2 = p1->forw) { 859: if (p2->op==TEXT||p2->op==DATA||p2->op==BSS) 860: p1->op = p2->op; 861: } 862: if (p1->op == seg || p1->forw&&p1->forw->op==seg) { 863: p1->back->forw = p1->forw; 864: p1->forw->back = p1->back; 865: p1 = p1->back; 866: continue; 867: } 868: seg = p1->op; 869: } 870: } 871: } 872: 873: redunbr(p) 874: register struct node *p; 875: { 876: register struct node *p1; 877: register char *ap1; 878: char *ap2; 879: 880: if ((p1 = p->ref) == 0) 881: return; 882: p1 = nonlab(p1); 883: if (p1->op==TST) { 884: singop(p1); 885: savereg(RT2, "$0"); 886: } else if (p1->op==CMP) 887: dualop(p1); 888: else 889: return; 890: if (p1->forw->op!=CBR) 891: return; 892: ap1 = findcon(RT1); 893: ap2 = findcon(RT2); 894: p1 = p1->forw; 895: if (compare(p1->subop, ap1, ap2)>0) { 896: nredunj++; 897: nchange++; 898: decref(p->ref); 899: p->ref = p1->ref; 900: p->labno = p1->labno; 901: p->ref->refc++; 902: } 903: } 904: 905: char * 906: findcon(i) 907: { 908: register char *p; 909: register r; 910: 911: p = regs[i]; 912: if (*p=='$') 913: return(p); 914: if ((r = isreg(p)) >= 0) 915: return(regs[r]); 916: if (equstr(p, conloc)) 917: return(conval); 918: return(p); 919: } 920: 921: compare(oper, cp1, cp2) 922: register char *cp1, *cp2; 923: { 924: register unsigned n1, n2; 925: 926: if (*cp1++ != '$' || *cp2++ != '$') 927: return(-1); 928: n1 = 0; 929: while (*cp2 >= '0' && *cp2 <= '7') { 930: n1 <<= 3; 931: n1 += *cp2++ - '0'; 932: } 933: n2 = n1; 934: n1 = 0; 935: while (*cp1 >= '0' && *cp1 <= '7') { 936: n1 <<= 3; 937: n1 += *cp1++ - '0'; 938: } 939: if (*cp1=='+') 940: cp1++; 941: if (*cp2=='+') 942: cp2++; 943: do { 944: if (*cp1++ != *cp2) 945: return(-1); 946: } while (*cp2++); 947: switch(oper) { 948: 949: case JEQ: 950: return(n1 == n2); 951: case JNE: 952: return(n1 != n2); 953: case JLE: 954: return((int)n1 <= (int)n2); 955: case JGE: 956: return((int)n1 >= (int)n2); 957: case JLT: 958: return((int)n1 < (int)n2); 959: case JGT: 960: return((int)n1 > (int)n2); 961: case JLO: 962: return(n1 < n2); 963: case JHI: 964: return(n1 > n2); 965: case JLOS: 966: return(n1 <= n2); 967: case JHIS: 968: return(n1 >= n2); 969: } 970: return(-1); 971: } 972: 973: setcon(ar1, ar2) 974: char *ar1, *ar2; 975: { 976: register char *cl, *cv, *p; 977: 978: cl = ar2; 979: cv = ar1; 980: if (*cv != '$') 981: return; 982: if (!natural(cl)) 983: return; 984: p = conloc; 985: while (*p++ = *cl++); 986: p = conval; 987: while (*p++ = *cv++); 988: } 989: 990: equstr(ap1, ap2) 991: char *ap1, *ap2; 992: { 993: register char *p1, *p2; 994: 995: p1 = ap1; 996: p2 = ap2; 997: do { 998: if (*p1++ != *p2) 999: return(0); 1000: } while (*p2++); 1001: return(1); 1002: } 1003: 1004: setcc(ap) 1005: char *ap; 1006: { 1007: register char *p, *p1; 1008: 1009: p = ap; 1010: if (!natural(p)) { 1011: ccloc[0] = 0; 1012: return; 1013: } 1014: p1 = ccloc; 1015: while (*p1++ = *p++); 1016: } 1017: 1018: natural(ap) 1019: char *ap; 1020: { 1021: register char *p; 1022: 1023: p = ap; 1024: if (*p=='*' || *p=='(' || *p=='-'&&*(p+1)=='(') 1025: return(0); 1026: while (*p++); 1027: p--; 1028: if (*--p == '+' || *p ==')' && *--p != '5') 1029: return(0); 1030: return(1); 1031: } 1032: 1033: xnatural(ap) 1034: char *ap; 1035: { 1036: if (natural(ap)) 1037: return(1); 1038: return(equstr("(sp)", ap)); 1039: } 1040: 1041: not_sp(ap) 1042: register char *ap; 1043: { 1044: char c; 1045: 1046: while (c = *ap++) 1047: if (c == '(') return(*ap == 's' && ap[1] == 'p'); 1048: return(1); 1049: }