|
|
1.1 ! root 1: #include "gencode.h" ! 2: #define NDNUM 400 ! 3: NODE myt[NDNUM]; ! 4: int ntree; ! 5: extern int bothdebug, nosharp; ! 6: #if M32 == 1 ! 7: char *regnames[] = {"%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7", ! 8: "%r8", "%fp", "%ap", "%r11", "%sp", "%r13", "%r14", "%pc"}; ! 9: char *frameptr = "%fp"; ! 10: char *argptr = "%ap"; ! 11: char *jeq = "je"; ! 12: char *jne = "jne"; ! 13: char *jgt = "jg"; ! 14: char *jge = "jge"; ! 15: char *jlt = "jl"; ! 16: char *jle = "jle"; ! 17: char *jugt = "jgu"; ! 18: char *juge = "jgeu"; ! 19: char *jult = "jlu"; ! 20: char *jule = "jleu"; ! 21: #define CHARCHAR 'b' ! 22: #define SHORTCHAR 'h' ! 23: #define LONGCHAR 'w' ! 24: #define FLOATCHAR 's' ! 25: #define DOUBLECHAR 'd' ! 26: #else if VAX == 1 ! 27: char *regnames[] = {"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", ! 28: "r9", "r10", "r11", "r12", "r13", "r14", "r15"}; ! 29: char *frameptr = "fp"; ! 30: char *argptr = "ap"; ! 31: char *jeq = "jeql"; ! 32: char *jne = "jneq"; ! 33: char *jgt = "jgtr"; ! 34: char *jge = "jgeq"; ! 35: char *jlt = "jlss"; ! 36: char *jle = "jleq"; ! 37: char *jugt = "jgtru"; ! 38: char *juge = "jgequ"; ! 39: char *jult = "jlssu"; ! 40: char *jule = "jlequ"; ! 41: #define CHARCHAR 'b' ! 42: #define SHORTCHAR 'w' ! 43: #define LONGCHAR 'l' ! 44: #define FLOATCHAR 'f' ! 45: #define DOUBLECHAR 'd' ! 46: #endif ! 47: char *bufend = (char *)bufs + sizeof(bufs); ! 48: pr(fmt, list) ! 49: char *fmt; long list; ! 50: { ! 51: char *sprintxl(); ! 52: nosharp = !bothdebug; ! 53: prptr = sprintxl(prptr, fmt, &list); ! 54: if(prptr > prbuf + sizeof(prbuf)) ! 55: cerror("prbuf overflow"); ! 56: nosharp = 0; ! 57: } ! 58: ! 59: outpr() ! 60: { ! 61: *prptr = 0; ! 62: printbuf(prbuf, prptr-prbuf); ! 63: } ! 64: NODE * ! 65: gimmenode() ! 66: { NODE *p; ! 67: p = myt + ntree++; ! 68: if(ntree > NDNUM) ! 69: cerror("out of temporary trees"); ! 70: return(p); ! 71: } ! 72: ! 73: NODE * ! 74: tempnode(p, flag) ! 75: NODE *p; ! 76: { NODE *x, *q = p->in.left; ! 77: int n; ! 78: extern int minrvar; ! 79: if(p->in.op == CONV) ! 80: q = p; /* CONV to double of float, versus (CMP double double) */ ! 81: x = gimmenode(); ! 82: x->in.type = q->in.type; ! 83: n = incrsize(q) == 8? 2: 1; ! 84: if(!(flag & ASADDR) && regvar >= REGVAR - 1 + n) { ! 85: x->in.op = REG; ! 86: x->tn.rval = regvar + 1 - n; ! 87: x->tn.lval = 1; /* SCRATCH marker !!!!! */ ! 88: regvar -= n; ! 89: if(minrvar > regvar) ! 90: minrvar = regvar; /* in case current routine recursive */ ! 91: return(x); ! 92: } ! 93: x->in.op = VAUTO; ! 94: x->tn.lval = gimmetemp(n); ! 95: /* scratch marker? */ ! 96: return(x); ! 97: } ! 98: ret ! 99: alloctmp(p) ! 100: NODE *p; ! 101: { ret s; ! 102: sprintf(buf, "%d(%s)", gimmetemp(incrsize(p) == 8? 2: 1), frameptr); ! 103: done(s, CANINDIR|SCRATCH, 0); ! 104: } ! 105: ret ! 106: checksize(p, s, regmask) ! 107: NODE *p; ! 108: ret s; ! 109: { ret t; ! 110: if(p->in.type != TDOUBLE) ! 111: return(s); ! 112: regmask |= s.regmask; ! 113: t = allocreg(p, regmask); ! 114: return(t); ! 115: } ! 116: ! 117: ret ! 118: allocreg(p, regmask) ! 119: NODE *p; ! 120: { int i, n; ! 121: ret s; ! 122: NODE *x; ! 123: if(p->in.type == TDOUBLE) ! 124: n = 2; ! 125: else ! 126: n = 1; ! 127: for(i = 0; i < REGVAR; i++) { ! 128: if(!(regmask & (1 << i))) ! 129: continue; ! 130: if(n == 2 & !(regmask & (1 << (1+i)))) ! 131: continue; ! 132: sprintx(buf, "%s", regnames[i]); ! 133: regmask = (1 << i); ! 134: if(n == 2) ! 135: regmask |= (1 << (i+1)); ! 136: done(s, SCRATCH|ISREG, regmask); ! 137: } ! 138: x = tempnode(p, 0); ! 139: if(x->in.op == REG) { ! 140: sprintx(buf, "%s", regnames[x->tn.rval]); ! 141: done(s, SCRATCH|ISREG, 0); ! 142: } ! 143: sprintx(buf, "%d(%s)", x->tn.lval, frameptr); ! 144: done(s, SCRATCH|CANINDIR, 0); ! 145: } ! 146: ! 147: gimmetemp(n) ! 148: { ! 149: if(VAX) ! 150: return(freetemp(n)/8 - maxboff/SZCHAR); ! 151: else ! 152: return(freetemp(n)/8 + maxboff/SZCHAR); ! 153: } ! 154: ! 155: isfloat(p) ! 156: NODE *p; ! 157: { ! 158: return(p->in.type == TFLOAT || p->in.type == TDOUBLE); ! 159: } ! 160: ! 161: childtype(p) ! 162: NODE *p; ! 163: { ! 164: return(type(p->in.left)); ! 165: } ! 166: ! 167: type(p) ! 168: NODE *p; ! 169: { int n = p->in.type; ! 170: switch(n) { ! 171: default: ! 172: return('?'); ! 173: case TCHAR: case TUCHAR: ! 174: return(CHARCHAR); ! 175: case TSHORT: case TUSHORT: ! 176: return(SHORTCHAR); ! 177: case TINT: case TUNSIGNED: case TLONG: case TULONG: ! 178: case TPOINT: case TSTRUCT: ! 179: return(LONGCHAR); ! 180: case TFLOAT: ! 181: return(FLOATCHAR); ! 182: case TDOUBLE: ! 183: return(DOUBLECHAR); ! 184: } ! 185: } ! 186: ! 187: shiftsize(p) ! 188: NODE *p; ! 189: { ! 190: switch(p->in.type) { ! 191: default: ! 192: return(0); /* 0 can't occur in an ICON under shift */ ! 193: case TCHAR: case TUCHAR: ! 194: return(0); ! 195: case TSHORT: case TUSHORT: ! 196: return(1); ! 197: case TINT: case TUNSIGNED: case TLONG: case TULONG: case TPOINT: ! 198: case TFLOAT: ! 199: return(2); ! 200: case TDOUBLE: ! 201: return(3); ! 202: } ! 203: } ! 204: ! 205: incrsize(p) ! 206: NODE *p; ! 207: { ! 208: switch(p->in.type) { ! 209: default: ! 210: return(0); /* 0 can't occur in an icon under incrop */ ! 211: case TCHAR: case TUCHAR: ! 212: return(1); ! 213: case TSHORT: case TUSHORT: ! 214: return(2); ! 215: case TINT: case TUNSIGNED: case TLONG: case TULONG: case TPOINT: ! 216: case TFLOAT: ! 217: return(4); ! 218: case TDOUBLE: ! 219: return(8); ! 220: } ! 221: } ! 222: ! 223: isunsigned(p) ! 224: NODE *p; ! 225: { ! 226: switch(p->in.type) { ! 227: #if VAX==1 ! 228: case TCHAR: ! 229: #endif ! 230: case TSHORT: case TINT: case TLONG: case TFLOAT: case TDOUBLE: ! 231: return(0); ! 232: #if M32==1 ! 233: case TCHAR: ! 234: #endif ! 235: default: ! 236: return(1); ! 237: } ! 238: } ! 239: ! 240: NODE * ! 241: copytree(p) ! 242: NODE *p; ! 243: { NODE *a, *b, *c; ! 244: switch(p->in.op) { ! 245: case ASG AND: case AND: case CALL: case CMP: case COMOP: ! 246: case DECR: case ASG DIV: case DIV: case ASG ER: case ER: ! 247: case INCR: case ASG LS: case LS: case ASG MINUS: case MINUS: ! 248: case ASG MOD: case MOD: case ASG MUL: case MUL: case ASG OR: ! 249: case OR: case ASG PLUS: case PLUS: case ASG RS: case RS: ! 250: case STASG: case STCALL: case ASSIGN: case CM: ! 251: a = copytree(p->in.left); ! 252: b = copytree(p->in.right); ! 253: c = gimmenode(); ! 254: *c = *p; ! 255: c->in.left = a; ! 256: c->in.right = b; ! 257: return(c); ! 258: case COMPL: case CONV: case FLD: case GENBR: case GENLAB: ! 259: case GENUBR: case STAR: case UNARY AND: case UNARY CALL: ! 260: case UNARY MINUS: case UNARY STCALL: case INIT: case FUNARG: ! 261: case STARG: ! 262: a = copytree(p->in.left); ! 263: c = gimmenode(); ! 264: *c = *p; ! 265: c->in.left = a; ! 266: return(c); ! 267: case VAUTO: case REG: case NAME: case VPARAM: case ICON: ! 268: case SNODE: case RNODE: case QNODE: ! 269: c = gimmenode(); ! 270: *c = *p; ! 271: return(c); ! 272: default: ! 273: cerror("unk node in copytree"); ! 274: } ! 275: } ! 276: /* rewrit A op B into (T = A, T) op B or A op (T = B, T) */ ! 277: totemp(p, flag) ! 278: NODE *p; ! 279: { NODE *a, *b, *c; ! 280: a = gimmenode(); ! 281: b = tempnode(p, flag); ! 282: c = gimmenode(); ! 283: if(flag & LEFT) ! 284: *a = *p->in.left; ! 285: else ! 286: *a = *p->in.right; ! 287: a->in.op = ASSIGN; ! 288: a->in.left = b; ! 289: if(flag & LEFT) ! 290: a->in.right = p->in.left; ! 291: else ! 292: a->in.right = p->in.right; ! 293: c->in.op = COMOP; ! 294: c->in.left = a; ! 295: c->in.right = b; ! 296: c->in.type = a->in.type; ! 297: if(flag & LEFT) ! 298: p->in.left = c; ! 299: else ! 300: p->in.right = c; ! 301: } ! 302: ! 303: funargs(p, regmask) ! 304: NODE *p; ! 305: { ret s, t; ! 306: int i; ! 307: switch(p->in.op) { ! 308: case CM: /* order depends on way stack grows */ ! 309: #ifdef LTORARGS ! 310: i = funargs(p->in.left, regmask); ! 311: i |= funargs(p->in.right, regmask); ! 312: #else ! 313: i = funargs(p->in.right, regmask); ! 314: i |= funargs(p->in.left, regmask); ! 315: #endif ! 316: return(i); ! 317: case FUNARG: ! 318: #if VAX==1 ! 319: t = tostack(); ! 320: s = doit(p->in.left, VALUE|TOSTACK, t, regmask); ! 321: #else if M32==1 ! 322: s = doit(p->in.left, VALUE|TOSTACK, 0, regmask); ! 323: #endif ! 324: return(s.flag & FAIL); ! 325: case STARG: ! 326: /* this has to have same cases as STASG */ ! 327: if(regmask != REGMASK) ! 328: return(FAILX); ! 329: s = doit(p->in.left, VAX?(ASADDR|VALUE):VALUE, 0, regmask); ! 330: /* this generates expensive code for small structures */ ! 331: i = p->stn.stsize / 8; ! 332: if(p->in.left->in.op == STASG) { ! 333: if(VAX && i != 4 && i != 8) { ! 334: pr("#\tsubl2\t$%d,sp\n", i); ! 335: pr("#\tsubl2\t$%d,r3\n", i); ! 336: pr("#\tmovc3\t$%d,(r3),(sp)\n", p->stn.stsize/8); ! 337: return(0); ! 338: } ! 339: else if(M32 && i >= 7 * 4) { ! 340: pr("#\taddw2\t&%d,%%sp\n", i); ! 341: pr("#\tsubw2\t&%d,%%r0\n", i/4); ! 342: goto moveit; ! 343: } ! 344: } ! 345: if(VAX) { ! 346: if(i == 4) ! 347: pr("#\tpushl\t%s\n", str(s)); ! 348: else if(i == 8) ! 349: pr("#\tmovq\t%s,-(sp)\n", str(s)); ! 350: else { ! 351: pr("#\tsubl2\t$%d,sp\n", i); ! 352: pr("#\tmovc3\t$%d,%s,(sp)\n", p->stn.stsize/8, str(s)); ! 353: } ! 354: } ! 355: else if(M32) { ! 356: pr("#\taddw2\t&%d,%%sp\n", i); ! 357: if(strcmp(str(s), "%r0")) ! 358: pr("#\tmovw\t%s,%r0\n", str(s)); ! 359: moveit: ! 360: pr("#\tmovaw\t-%d(%%sp),%r1\n", p->stn.stsize/8); ! 361: i = p->stn.stsize/32; ! 362: if(i >= 7) { ! 363: pr("#\tmovw\t&%d,%%r2\n", i); ! 364: pr("#\tMOVBLW\n"); ! 365: } ! 366: else ! 367: while(--i >= 0) ! 368: pr("#\tmovw\t%d(%r0),%d(%r1)\n", 4*i, 4*i); ! 369: } ! 370: return(s.flag & FAIL); ! 371: } ! 372: } ! 373: ! 374: strshift(s, n) ! 375: char *s; ! 376: { int i, j; ! 377: i = strlen(s); ! 378: if(n > 0) ! 379: for(j = i; j >= 0; j--) ! 380: s[j + n] = s[j]; ! 381: else ! 382: for(j = -n; j <= i; j++) ! 383: s[j + n] = s[j]; ! 384: } ! 385: ! 386: ret ! 387: tostack() ! 388: { ret s; ! 389: sprintx(buf, "-(sp)"); ! 390: done(s, 0, 0); ! 391: } ! 392: ! 393: ret ! 394: specialreg(p, regmask) ! 395: NODE *p; ! 396: { ret s; ! 397: int n, i; ! 398: n = p ->in.type == TDOUBLE? 2: 1; ! 399: i = 1; ! 400: if(n == 2) ! 401: i = 3; ! 402: sprintx(buf, "%s", regnames[0]); ! 403: if(i & ~regmask) ! 404: pr("#\specialreg not free\n"); ! 405: done(s, SCRATCH|ISREG, i); ! 406: } ! 407: /* these guys rewrite a1 = a2 = ... an = x ! 408: * as t = x; an = t; an-1 = an */ ! 409: NODE * ! 410: fromtemp(p, temp) ! 411: NODE *p, *temp; ! 412: { NODE *q; ! 413: q = gimmenode(); ! 414: *q = *p; ! 415: q->in.left = p; ! 416: q->in.op = ASSIGN; ! 417: q->in.right = temp; ! 418: return(q); ! 419: } ! 420: ! 421: NODE * ! 422: to(p, temp) ! 423: NODE *p, *temp; ! 424: { NODE *q; ! 425: q = gimmenode(); ! 426: *q = *p; ! 427: q->in.right = p; ! 428: q->in.op = ASSIGN; ! 429: q->in.left = temp; ! 430: return(q); ! 431: } ! 432: ! 433: NODE * ! 434: comnode(a, p) ! 435: NODE *a, *p; ! 436: { NODE *q; ! 437: q = gimmenode(); ! 438: *q = *p; ! 439: q->in.op = COMOP; ! 440: q->in.right = p; ! 441: q->in.left = a; ! 442: return(q); ! 443: } ! 444: ! 445: asgwrite(p) ! 446: NODE *p; ! 447: { NODE *q, *a, *temp; ! 448: temp = tempnode(p, 0); ! 449: a = fromtemp(p->in.left, temp); ! 450: for(q = p->in.right; q->in.op == ASSIGN; q = q->in.right) ! 451: a = comnode(fromtemp(q->in.left, temp), a); ! 452: a = comnode(to(q, temp), a); ! 453: *p = *a; ! 454: } ! 455: ! 456: char * ! 457: genjmp(n) ! 458: { ! 459: switch(n) { ! 460: default: ! 461: return("jweird"); ! 462: case EQ: ! 463: return(jeq); ! 464: case NE: ! 465: return(jne); ! 466: case GT: ! 467: return(jgt); ! 468: case GE: ! 469: return(jge); ! 470: case LT: ! 471: return(jlt); ! 472: case LE: ! 473: return(jle); ! 474: case UGT: ! 475: return(jugt); ! 476: case UGE: ! 477: return(juge); ! 478: case ULT: ! 479: return(jult); ! 480: case ULE: ! 481: return(jule); ! 482: } ! 483: } ! 484: ! 485: lsconv(p) ! 486: NODE *p; ! 487: { NODE *lft, *right; ! 488: lft = gimmenode(); ! 489: right = gimmenode(); ! 490: lft->in.op = right->in.op = CONV; ! 491: lft->in.type = right->in.type = TLONG; ! 492: lft->in.left = p->in.left; ! 493: right->in.left = p->in.right; ! 494: if(p->in.left->in.op != ICON) /* ICONS are longs anyway (see RS) */ ! 495: p->in.left = lft; ! 496: p->in.right = right; ! 497: } ! 498: /* only some ops have to be rewritten (addb and addl are the same at the bottom) */ ! 499: rewriteasgop(p) ! 500: NODE *p; ! 501: { NODE *a, *newop; ! 502: if(p->in.left->in.op != CONV) ! 503: return(0); ! 504: if(p->in.left->in.left->in.op == STAR) ! 505: longjmp(back, awfulstar(p)); ! 506: newop = gimmenode(); ! 507: *newop = *p; ! 508: switch(p->in.op) { ! 509: case ASG DIV: ! 510: newop->in.op = DIV; ! 511: break; ! 512: case ASG LS: ! 513: newop->in.op = LS; ! 514: break; ! 515: case ASG MOD: ! 516: newop->in.op = MOD; ! 517: break; ! 518: case ASG RS: ! 519: newop->in.op = RS; ! 520: break; ! 521: case ASG PLUS: ! 522: if(incrsize(p->in.left) != 8) ! 523: return(0); ! 524: newop->in.op = PLUS; ! 525: break; ! 526: case ASG MINUS: ! 527: if(incrsize(p->in.left) != 8) ! 528: return(0); ! 529: newop->in.op = MINUS; ! 530: break; ! 531: case ASG MUL: ! 532: if(incrsize(p->in.left) != 8) ! 533: return(0); ! 534: newop->in.op = MUL; ! 535: break; ! 536: ! 537: default: ! 538: cerror("codegen: rewriting asgop"); ! 539: } ! 540: a = gimmenode(); ! 541: *a = *p->in.left->in.left; ! 542: p->in.op = ASSIGN; ! 543: p->in.left = a; ! 544: p->in.right = newop; ! 545: return(1); ! 546: } ! 547: ! 548: rewriteconv(p) /* uns to float or double */ ! 549: NODE *p; ! 550: { NODE *a; ! 551: a = gimmenode(); ! 552: *a = *p; ! 553: a->in.type = TLONG; ! 554: p->in.left = a; ! 555: } ! 556: ! 557: mediumstar(p) ! 558: NODE *p; ! 559: { NODE *newtop, *tmp, *x, *y; ! 560: newtop = gimmenode(); ! 561: newtop->in.op = COMOP; ! 562: newtop->in.type = p->in.type; ! 563: x = gimmenode(); ! 564: x->in.op = ASSIGN; ! 565: x->in.type = TPOINT; ! 566: x->in.right = p->in.left->in.left; ! 567: newtop->in.left = x; ! 568: tmp = tempnode(newtop, 0); ! 569: tmp->in.type = TPOINT; ! 570: x->in.left = tmp; ! 571: y = gimmenode(); ! 572: y->in.op = COMOP; ! 573: y->in.type = p->in.type; ! 574: x = gimmenode(); ! 575: *x = *p; ! 576: newtop->in.right = y; ! 577: y->in.left = x; ! 578: y->in.right = x->in.left; ! 579: x->in.left->in.left = tmp; ! 580: *p = *newtop; ! 581: return(1); ! 582: } ! 583: ! 584: awfulstar(p) ! 585: NODE *p; ! 586: { NODE *newtop, *doleft, *x, *op, *equals; ! 587: newtop = gimmenode(); ! 588: newtop->in.op = COMOP; ! 589: newtop->in.type = p->in.type; ! 590: doleft = gimmenode(); ! 591: doleft->in.op = ASSIGN; ! 592: doleft->in.type = TPOINT; ! 593: doleft->in.right = p->in.left->in.left->in.left; ! 594: x = tempnode(doleft, 0); ! 595: doleft->in.left = x; ! 596: op = gimmenode(); ! 597: *op = *p; ! 598: op->in.op -= (ASG 0); /* crap for crap */ ! 599: op->in.left->in.left->in.left = x; /* so it's a dag, but x is harmless */ ! 600: equals = gimmenode(); ! 601: *equals = *p; ! 602: equals->in.right = op; ! 603: equals->in.left = p->in.left->in.left; ! 604: equals->in.op = ASSIGN; ! 605: *p = *newtop; ! 606: p->in.left = doleft; ! 607: p->in.right = equals; ! 608: return(1); ! 609: } ! 610: rewritefld(p) ! 611: NODE *p; ! 612: { NODE *q, *tmp, *left, *comop; ! 613: if((q = p->in.left->in.left)->in.op != STAR) { ! 614: rewfld(p); ! 615: return; ! 616: } ! 617: q = q->in.left; ! 618: tmp = tempnode(q, 0); ! 619: left = gimmenode(); ! 620: left->in.type = q->in.type; ! 621: left->in.op = ASSIGN; ! 622: left->in.left = tmp; ! 623: left->in.right = gimmenode(); ! 624: left->in.right = copytree(q); ! 625: *q = *tmp; ! 626: comop = gimmenode(); ! 627: comop->in.op = COMOP; ! 628: comop->in.left = left; ! 629: comop->in.right = copytree(p); ! 630: *p = *comop; ! 631: rewfld(p->in.right); ! 632: longjmp(back, 1); ! 633: } ! 634: rewfld(p) ! 635: NODE *p; ! 636: { NODE *x, *y, *z; ! 637: x = gimmenode(); ! 638: *x = *copytree(p); ! 639: y = gimmenode(); ! 640: *y = *copytree(p); ! 641: z = gimmenode(); ! 642: *z = *p; ! 643: z->in.left = x; ! 644: x->in.op = ASSIGN; ! 645: x->in.right = y; ! 646: if(p->in.op == DECR || p->in.op == ASG MINUS) ! 647: z->in.op = PLUS; ! 648: else ! 649: z->in.op = MINUS; ! 650: if(p->in.op == DECR) ! 651: y->in.op = MINUS; ! 652: else if(p->in.op == INCR) ! 653: y->in.op = PLUS; ! 654: else ! 655: y->in.op -= (ASG 0); /* good grief */ ! 656: if(p->in.op == DECR || p->in.op == INCR) ! 657: *p = *z; ! 658: else ! 659: *p = *x; ! 660: } ! 661: ! 662: ret ! 663: indirit(s) ! 664: ret s; ! 665: { ! 666: if(s.flag & ISREG) { ! 667: strcat(str(s), ")"); ! 668: strshift(str(s), 1); ! 669: str(s)[0] = '('; ! 670: return(s); ! 671: } ! 672: if(s.flag & CANINDIR) { ! 673: strshift(str(s), 1); ! 674: str(s)[0] = '*'; ! 675: return(s); ! 676: } ! 677: if(VAX && str(s)[0] == '(') { /* (r3)[r11] */ ! 678: strshift(str(s), 1); ! 679: str(s)[0] = '*'; ! 680: return(s); ! 681: } ! 682: if(VAX && str(s)[0] == '$') { /* an icon for structure returns */ ! 683: strshift(str(s), -1); ! 684: return(s); ! 685: } ! 686: s.flag = FAIL; ! 687: return(s); ! 688: } ! 689: /* not int = (...? int exprs) have a bogus tree */ ! 690: extracheck(p) ! 691: NODE *p; ! 692: { NODE *a; ! 693: if(p->in.right->in.op != GENLAB) ! 694: return; ! 695: a = gimmenode(); ! 696: *a = *p; ! 697: a->in.left = p->in.right; ! 698: a->in.op = CONV; ! 699: p->in.right = a; ! 700: } ! 701: ! 702: starasg(p) ! 703: NODE *p; ! 704: { NODE *tmp, *asg, *x; ! 705: tmp = tempnode(p->in.left->in.left, 0); ! 706: x = gimmenode(); ! 707: *x = *p; ! 708: asg = gimmenode(); ! 709: *asg = *p->in.left->in.left; ! 710: asg->in.op = ASSIGN; ! 711: asg->in.left = tmp; ! 712: asg->in.right = p->in.left->in.left; ! 713: x->in.left->in.left = tmp; ! 714: p->in.op = COMOP; ! 715: p->in.left = asg; ! 716: p->in.right = x; ! 717: } ! 718: stasgrewrite(p) ! 719: NODE *p; ! 720: { NODE *qa, *qb, *n, *left, *right; ! 721: if(VAX) { ! 722: totemp(p, RIGHT); ! 723: longjmp(back, 1); ! 724: } ! 725: if(M32) { ! 726: qa = tempnode(p->in.right, 0); ! 727: qb = tempnode(p->in.left, 0); ! 728: right = to(p->in.right, qa); ! 729: left = to(p->in.left, qb); ! 730: p->in.right = qa; ! 731: p->in.left = qb; ! 732: qa = gimmenode(); ! 733: qb = gimmenode(); ! 734: qa->in.op = qb->in.op = COMOP; ! 735: qa->in.left = left; ! 736: qa->in.right = qb; ! 737: qb->in.left = right; ! 738: n = gimmenode(); ! 739: *n = *p; ! 740: qb->in.right = n; ! 741: *p = *qa; ! 742: longjmp(back, 1); ! 743: } ! 744: } ! 745: ret ! 746: simpler(a, b) /* returns b (as dest) preferentially */ ! 747: ret a, b; ! 748: { ! 749: if(b.flag & ISREG) ! 750: return(b); ! 751: if(a.flag & ISREG) ! 752: return(a); ! 753: if(b.flag & SCRATCH) ! 754: return(b); ! 755: if(a.flag & SCRATCH) ! 756: return(a); ! 757: if(!(b.flag & INDEX)) ! 758: return(b); ! 759: if(!(a.flag & INDEX)) ! 760: return(a); ! 761: /* disallow *p++ = *q++ but not p[i]=q[i]*/ ! 762: if(!index(str(b), '-') && !index(str(b), '+')) ! 763: return(b); ! 764: if(!index(str(a), '-') && !index(str(a), '+')) ! 765: return(a); ! 766: b.flag |= USED; ! 767: return(b); ! 768: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.