|
|
1.1 ! root 1: #include <stdio.h> ! 2: #include "pico.h" ! 3: ! 4: #define NJTAB 1000 ! 5: #define NGTAB 40 ! 6: #define NPTAB 200 ! 7: ! 8: static char *jtab[NJTAB]; ! 9: static int jtabi; ! 10: static int ninstr; ! 11: static int spoff; ! 12: ! 13: #define LJ 1 ! 14: #define CJ 2 ! 15: #define INF 100 ! 16: ! 17: struct ptab ! 18: { ! 19: char *at; ! 20: char *to; ! 21: short del; ! 22: short flag; ! 23: }; ! 24: ! 25: static struct ptab ptab[NPTAB]; ! 26: static int ptabi; ! 27: ! 28: #define TO 1 ! 29: #define AT 2 ! 30: struct gtab ! 31: { ! 32: long name; ! 33: char *ato; ! 34: short flag; ! 35: }; ! 36: ! 37: static struct gtab gtab[NGTAB]; ! 38: static int gtabi; ! 39: ! 40: static char *p; ! 41: ! 42: #define MAXJ 0x7F ! 43: Node zero = ! 44: { ! 45: CONST ! 46: }; ! 47: Node one = ! 48: { ! 49: CONST ! 50: }; ! 51: ! 52: /* ! 53: * Addressing modes ! 54: */ ! 55: #define _SP 0x7E /* -(sp) */ ! 56: #define SPPLUS 0x8E /* (sp)+ */ ! 57: #define OSP 0xAE /* x(SP) */ ! 58: #define STARPC 0x9F /* *(pc)+ */ ! 59: #define R0 0x50 ! 60: #define I0 0x40 ! 61: #define SHORTIM(c) c ! 62: #define LONGIM 0x8F /* 32 bit immediate */ ! 63: #define R(x) (R0|(x))/* register var */ ! 64: #define I(x) (I0|(x))/* indexed var */ ! 65: /* ! 66: * Instructions ! 67: */ ! 68: #define ADDL2 0xC0 ! 69: #define ADDL3 0xC1 ! 70: #define ASHL 0x78 ! 71: #define BEQL 0x13 ! 72: #define BICL2 0xCA ! 73: #define BICL3 0xCB ! 74: #define BGEQ 0x18 ! 75: #define BGTR 0x14 ! 76: #define BISL2 0xC8 ! 77: #define BISL3 0xC9 ! 78: #define BLEQ 0x15 ! 79: #define BLSS 0x19 ! 80: #define BNEQ 0x12 ! 81: #define BRB 0x11 ! 82: #define BRW 0x31 ! 83: #define JSB 0x16 ! 84: #define CALLS 0xFB ! 85: #define CLRL 0xD4 ! 86: #define CMPL 0xD1 ! 87: #define BITL 0xD3 ! 88: #define MCOML 0xD2 ! 89: #define MNEGL 0xCE ! 90: #define MOVL 0xD0 ! 91: #define MOVW 0xB0 ! 92: #define MOVB 0x90 ! 93: #define MOVZBL 0x9A ! 94: #define CLRB 0x94 ! 95: #define MULL2 0xC4 ! 96: #define MULL3 0xC5 ! 97: #define PUSHL 0xDD ! 98: #define RSB 0x05 ! 99: #define SUBL2 0xC2 ! 100: #define SUBL3 0xC3 ! 101: #define TSTL 0xD5 ! 102: #define XORL2 0xCC ! 103: #define XORL3 0xCD ! 104: #define DIVL2 0xC6 ! 105: #define DIVL3 0xC7 ! 106: #define JMP 0x17 ! 107: ! 108: #define stufflong(c) *((int *)p)=(c), p+=sizeof(long) ! 109: #define stuffword(c) *((short *)p)=(c), p+=sizeof(short) ! 110: ! 111: #define TOOMANY 6 /* r6 is not available for scratch */ ! 112: ! 113: char *program; ! 114: extern char seetree, optim; ! 115: ! 116: compile(n, progr) ! 117: Node *n; ! 118: char *progr; ! 119: { ! 120: register fd; ! 121: ! 122: program = progr; ! 123: one.arg = 1; ! 124: if (seetree && n) ptree(n, "ORIGINAL"); ! 125: if (optim) ! 126: { rewrite(n, 1); ! 127: if (seetree) ptree(n, "OPTIMIZED"); ! 128: } ! 129: gencode(n); ! 130: if((fd=creat("/tmp/pico.code", 0666))>=0) ! 131: { write(fd, program, p-program); ! 132: close(fd); ! 133: } ! 134: } ! 135: ! 136: gencode(n) ! 137: Node *n; ! 138: { ! 139: spoff = 0; ! 140: ninstr = 0; ! 141: jtabi = 0; ! 142: ptabi = 0; ! 143: gtabi = 0; ! 144: p = program; ! 145: codegen(n, 0, 1, 0); ! 146: emitins(RSB); ! 147: addptab(); ! 148: if(spoff != 0) ! 149: yyerror("phase error in spoff"); ! 150: } ! 151: ! 152: testgen(n, used, dest, true) ! 153: Node *n; ! 154: { ! 155: int j; ! 156: ! 157: j = BNEQ; ! 158: if(!true) ! 159: j = BEQL; ! 160: switch(n->type) { ! 161: default: ! 162: codegen(n, used, dest, 0); ! 163: break; ! 164: ! 165: case OCALL: ! 166: case CCALL: ! 167: codegen(n, used, dest, 0); ! 168: if(dest == 1) { ! 169: emitins(TSTL); ! 170: emitreg(dest); ! 171: } ! 172: break; ! 173: ! 174: case CONST: ! 175: case VAR: ! 176: case REG: ! 177: case OARG: ! 178: emitins(TSTL); ! 179: codegen(n, used, 0, 0); ! 180: break; ! 181: ! 182: case CONDI: ! 183: markj(0); ! 184: testgen(n->other, used, dest, 1); ! 185: markj(0); ! 186: testgen(n->right, used, dest, true); ! 187: markj(0); ! 188: markj(BRB); ! 189: patchj(2); ! 190: markj(0); ! 191: testgen(n->left, used, dest, true); ! 192: patchj(1); ! 193: combj(0); ! 194: combj(1); ! 195: return; ! 196: ! 197: case ONE: ! 198: case OLE: ! 199: case OGE: ! 200: case OEQ: ! 201: case OLT: ! 202: case OGT: ! 203: case OAND: ! 204: j = compareop(n, used, dest, true); ! 205: break; ! 206: ! 207: case ONOT: ! 208: testgen(n->left, used, dest, !true); ! 209: return; ! 210: ! 211: case OANDAND: ! 212: case OOROR: ! 213: if((n->type==OANDAND) ^ true) { ! 214: testgen(n->left, used, dest, true); ! 215: testgen(n->right, used, dest, true); ! 216: return; ! 217: } ! 218: markj(0); ! 219: testgen(n->left, used, dest, !true); ! 220: markj(0); ! 221: testgen(n->right, used, dest, true); ! 222: patchj(1); ! 223: combj(0); ! 224: return; ! 225: ! 226: case OCOMMA: ! 227: codegen(n->left, used, dest, 0); ! 228: testgen(n->right, used, dest, true); ! 229: return; ! 230: } ! 231: markj(j); ! 232: } ! 233: ! 234: patchj(bn) ! 235: { int i, l; ! 236: ! 237: jtab[jtabi] = 0; ! 238: l = jbn(bn); ! 239: for(i=l+1; jtab[i]; i++) { ! 240: ptab[ptabi].at = jtab[i]; ! 241: ptab[ptabi].to = p; ! 242: ptab[ptabi].del = 0; ! 243: ptab[ptabi].flag = 0; ! 244: if(jtab[i][-1] != BRB) ! 245: ptab[ptabi].flag |= CJ; ! 246: ptabi++; ! 247: if(ptabi >= NPTAB) ! 248: yyerror("NPTAB too small"); ! 249: } ! 250: while(i < jtabi) ! 251: jtab[l++] = jtab[i++]; ! 252: jtabi = l; ! 253: } ! 254: ! 255: pcmp(p1, p2) ! 256: struct ptab *p1, *p2; ! 257: { ! 258: return(p1->at - p2->at); ! 259: } ! 260: ! 261: addptab() ! 262: { char *q; ! 263: int i, j, f, d; ! 264: ! 265: for(i=0; i<gtabi; i++) ! 266: if(gtab[i].flag & AT) ! 267: { gtab[i].flag = 0; ! 268: for(j=0; j<gtabi; j++) ! 269: if(gtab[j].flag & TO && gtab[i].name == gtab[j].name) ! 270: { ptab[ptabi].at = gtab[i].ato; ! 271: ptab[ptabi].to = gtab[j].ato; ! 272: ptab[ptabi].del = 0; ! 273: ptab[ptabi].flag = 0; ! 274: ptabi++; ! 275: if(ptabi >= NPTAB) ! 276: yyerror("NPTAB too small"); ! 277: break; ! 278: } ! 279: if (j == gtabi) ! 280: yyerror("label not declared"); ! 281: } ! 282: ! 283: ptab[ptabi].at = program; ! 284: ptab[ptabi].to = p; ! 285: ptab[ptabi].del = 0; ! 286: ptab[ptabi].flag = LJ; ! 287: ptabi++; ! 288: qsort(ptab, ptabi, sizeof ptab[0], pcmp); ! 289: loop: ! 290: f = 0; ! 291: for(i=0; i<ptabi; i++) { ! 292: if(ptab[i].flag & LJ) ! 293: continue; ! 294: d = ptab[i].to - ptab[i].at - 1; ! 295: if(d < 0) ! 296: d = -d; ! 297: d += ptab[i].del; ! 298: if(d >= MAXJ) { ! 299: f++; ! 300: ptab[i].flag |= LJ; ! 301: for(j=0; j<ptabi; j++) ! 302: if(betwn(ptab[i].at, ptab[j])) { ! 303: ptab[j].del += 1; ! 304: if(ptab[i].flag & CJ) ! 305: ptab[j].del += 2; ! 306: } ! 307: } ! 308: } ! 309: if(f) ! 310: goto loop; ! 311: q = p; ! 312: p += ptab[0].del; ! 313: for(;;) { ! 314: *--p = *--q; ! 315: if(q > ptab[ptabi-1].at) ! 316: continue; ! 317: if(q <= program) ! 318: break; ! 319: ptabi--; ! 320: d = ptab[ptabi].to - ptab[ptabi].at - 1; ! 321: if(ptab[ptabi].to > ptab[ptabi].at) ! 322: d += ptab[ptabi].del; ! 323: else ! 324: d -= ptab[ptabi].del; ! 325: f = ptab[ptabi].flag; ! 326: if((f & LJ) == 0) { ! 327: *p = d; ! 328: continue; ! 329: } ! 330: p--; q--; ! 331: *(short *)p = d; ! 332: *--p = BRW; ! 333: if((f & CJ) == 0) ! 334: continue; ! 335: *--p = 3; ! 336: *--p = invrbr(*q & 0xFF); ! 337: ninstr++; ! 338: } ! 339: if(p != q) ! 340: yyerror("long jump phase error"); ! 341: p = ptab[0].to + ptab[0].del; ! 342: } ! 343: ! 344: betwn(p, j) ! 345: char *p; ! 346: struct ptab j; ! 347: { ! 348: ! 349: if(j.to > j.at) { ! 350: if(p > j.at && p < j.to) ! 351: return 1; ! 352: return 0; ! 353: } ! 354: if(p >= j.to && p <= j.at) ! 355: return 1; ! 356: return 0; ! 357: } ! 358: ! 359: combj(bn) ! 360: { ! 361: int i, l; ! 362: ! 363: l = jbn(bn); ! 364: i = l+1; ! 365: while(i < jtabi) ! 366: jtab[l++] = jtab[i++]; ! 367: jtabi = l; ! 368: } ! 369: ! 370: jbn(bn) ! 371: { ! 372: int i; ! 373: ! 374: i = jtabi; ! 375: while(bn >= 0) { ! 376: for(i--; jtab[i]; i--) ! 377: ; ! 378: bn--; ! 379: } ! 380: return i; ! 381: } ! 382: ! 383: markj(j) ! 384: { ! 385: ! 386: if(jtabi >= NJTAB) ! 387: yyerror("NJTAB too small"); ! 388: if(j == 0) { ! 389: jtab[jtabi++] = 0; ! 390: return; ! 391: } ! 392: emitins(j); ! 393: jtab[jtabi++] = p; ! 394: *p++ = 0; ! 395: } ! 396: ! 397: codegen(n, used, dest, brgen) ! 398: Node *n; ! 399: { ! 400: long c; ! 401: int o; ! 402: ! 403: markj(0); ! 404: if(p-program > NPROG-10) ! 405: yyerror("NPROG too small"); ! 406: ! 407: if(n) ! 408: switch(n->type) ! 409: { ! 410: default: ! 411: printf("unknown type = %d\n", n->type); ! 412: yyerror("unknown opcode in codegen"); ! 413: break; ! 414: ! 415: case LABL: ! 416: if(gtabi >= NGTAB) ! 417: yyerror("NGTAB too small"); ! 418: gtab[gtabi].name = n->arg; ! 419: gtab[gtabi].ato = p; ! 420: gtab[gtabi].flag = TO; ! 421: gtabi++; ! 422: codegen(n->left, used, dest, brgen); ! 423: break; ! 424: ! 425: case GOTO: ! 426: emitins(BRB); ! 427: if(gtabi >= NGTAB) ! 428: yyerror("NGTAB too small"); ! 429: gtab[gtabi].name = n->arg; ! 430: gtab[gtabi].ato = p; ! 431: gtab[gtabi].flag = AT; ! 432: gtabi++; ! 433: *p++ = 0; ! 434: break; ! 435: ! 436: case CONSTB: ! 437: if(n->arg & ~63) ! 438: if(!dest) { ! 439: *p++ = LONGIM; ! 440: *p++ = n->arg; ! 441: break; ! 442: } ! 443: case CONST: ! 444: if(dest) { ! 445: if(n->arg == 0) { ! 446: emitins(CLRL); ! 447: emitreg(dest); ! 448: break; ! 449: } ! 450: emitins(MOVL); ! 451: codegen(n, used, 0, 0); ! 452: emitreg(dest); ! 453: break; ! 454: } ! 455: emitcon(n->arg); ! 456: break; ! 457: ! 458: case VAR: ! 459: if(dest) { ! 460: emitins(MOVL); ! 461: codegen(n, used, 0, 0); ! 462: emitreg(dest); ! 463: break; ! 464: } ! 465: emitabs(n->arg); ! 466: break; ! 467: ! 468: case OARG: ! 469: if(dest) { ! 470: emitins(MOVL); ! 471: codegen(n, used, 0, 0); ! 472: emitreg(dest); ! 473: break; ! 474: } ! 475: *p++ = OSP; ! 476: emitcon((n->arg+1)*4 + spoff); ! 477: break; ! 478: ! 479: case REG: ! 480: if(dest) { ! 481: emitins(MOVL); ! 482: codegen(n, used, 0, 0); ! 483: emitreg(dest); ! 484: break; ! 485: } ! 486: *p++ = R(n->arg); ! 487: break; ! 488: ! 489: case CCALL: ! 490: case OCALL: ! 491: for(o=0; o<used; o++) { ! 492: emitins(MOVL); ! 493: *p++ = R(o); ! 494: *p++ = _SP; ! 495: spoff += 4; ! 496: } ! 497: c = pushargs(n->left); ! 498: if(n->type == CCALL) { ! 499: emitins(CALLS); ! 500: emitcon(c); ! 501: emitabs(n->arg); ! 502: } else { ! 503: emitins(JSB); ! 504: emitabs(n->arg); ! 505: if(c) { ! 506: emitins(ADDL2); ! 507: emitcon(c*4); ! 508: *p++ = R(0XE); ! 509: } ! 510: } ! 511: spoff -= 4*c; ! 512: if(dest != 1) { ! 513: emitins(MOVL); ! 514: *p++ = R(0); ! 515: *p++ = R(dest-1); ! 516: } ! 517: for(o=used-1; o>=0; o--) { ! 518: emitins(MOVL); ! 519: *p++ = SPPLUS; ! 520: *p++ = R(o); ! 521: spoff -= 4; ! 522: } ! 523: break; ! 524: ! 525: case CONDI: ! 526: markj(0); ! 527: if(!n->left) { ! 528: testgen(n->other, used, dest, 1); ! 529: codegen(n->right, used, dest, 0); ! 530: combj(0); ! 531: break; ! 532: } ! 533: if(!n->right) { ! 534: testgen(n->other, used, dest, 0); ! 535: codegen(n->left, used, dest, 0); ! 536: combj(0); ! 537: break; ! 538: } ! 539: testgen(n->other, used, dest, 1); ! 540: codegen(n->right, used, dest, 1); ! 541: patchj(1); ! 542: codegen(n->left, used, dest, 0); ! 543: combj(0); ! 544: break; ! 545: ! 546: case OADD: ! 547: binop(1, ADDL3, ADDL2, n, used, dest); ! 548: break; ! 549: ! 550: case OMUL: ! 551: if(n->right->type == CONST) { ! 552: c = n->right->arg; ! 553: if(c >= 2 && c <= 4) { ! 554: if(n->left->type == REG) { ! 555: emitins(ADDL3); ! 556: codegen(n->left, used, 0, 0); ! 557: codegen(n->left, used, 0, 0); ! 558: } else { ! 559: codegen(n->left, used, dest, 0); ! 560: emitins(ADDL3); ! 561: emitreg(dest); ! 562: emitreg(dest); ! 563: } ! 564: if(c == 3) { ! 565: *p++ = _SP; ! 566: emitins(ADDL3); ! 567: *p++ = SPPLUS; ! 568: if(n->left->type == REG) ! 569: codegen(n->left, used, 0, 0); ! 570: else ! 571: emitreg(dest); ! 572: } ! 573: if(c == 4) { ! 574: emitreg(dest); ! 575: emitins(ADDL3); ! 576: emitreg(dest); ! 577: emitreg(dest); ! 578: } ! 579: emitreg(dest); ! 580: break; ! 581: } ! 582: } ! 583: binop(1, MULL3, MULL2, n, used, dest); ! 584: break; ! 585: ! 586: case OPOW: ! 587: if(n->right->type == CONST) { ! 588: c = n->right->arg; ! 589: if(c >= 2 && c <= 4) { ! 590: if(n->left->type == REG) { ! 591: emitins(MULL3); ! 592: codegen(n->left, used, 0, 0); ! 593: codegen(n->left, used, 0, 0); ! 594: } else { ! 595: codegen(n->left, used, dest, 0); ! 596: emitins(MULL3); ! 597: emitreg(dest); ! 598: emitreg(dest); ! 599: } ! 600: if(c == 3) { ! 601: *p++ = _SP; ! 602: emitins(MULL2); ! 603: *p++ = SPPLUS; ! 604: } ! 605: if(c == 4) { ! 606: emitreg(dest); ! 607: emitins(MULL3); ! 608: emitreg(dest); ! 609: emitreg(dest); ! 610: } ! 611: emitreg(dest); ! 612: break; ! 613: } ! 614: } ! 615: yyerror("POW not implemented"); ! 616: break; ! 617: ! 618: case OXOR: ! 619: binop(1, XORL3, XORL2, n, used, dest); ! 620: break; ! 621: ! 622: case OOR: ! 623: binop(1, BISL3, BISL2, n, used, dest); ! 624: break; ! 625: ! 626: case OISUB: ! 627: invert(n, OSUB); ! 628: case OSUB: ! 629: binop(0, SUBL3, SUBL2, n, used, dest); ! 630: break; ! 631: ! 632: case OIDIV: ! 633: invert(n, ODIV); ! 634: case ODIV: ! 635: binop(0, DIVL3, DIVL2, n, used, dest); ! 636: break; ! 637: ! 638: case OBIC: ! 639: binop(0, BICL3, BICL2, n, used, dest); ! 640: break; ! 641: ! 642: case OAND: ! 643: binop(2, BICL3, BICL2, n, used, dest); ! 644: break; ! 645: ! 646: case ONEG: ! 647: unop(MCOML, n->left, used, dest); ! 648: break; ! 649: ! 650: case OMINUS: ! 651: unop(MNEGL, n->left, used, dest); ! 652: break; ! 653: ! 654: case OLSH: ! 655: if(n->right->type == CONST) { ! 656: c = n->right->arg; ! 657: if(c >= 1 && c <= 2) { ! 658: if(n->left->type == REG) { ! 659: emitins(ADDL3); ! 660: codegen(n->left, used, 0, 0); ! 661: codegen(n->left, used, 0, 0); ! 662: } else { ! 663: codegen(n->left, used, dest, 0); ! 664: emitins(ADDL3); ! 665: emitreg(dest); ! 666: emitreg(dest); ! 667: } ! 668: if(c == 2) { ! 669: emitreg(dest); ! 670: emitins(ADDL3); ! 671: emitreg(dest); ! 672: emitreg(dest); ! 673: } ! 674: emitreg(dest); ! 675: break; ! 676: } ! 677: n->right->type = CONSTB; ! 678: binop(0, ASHL, 0, n, used, dest); ! 679: n->right->type = CONST; ! 680: break; ! 681: } ! 682: binop(0, ASHL, 0, n, used, dest); ! 683: break; ! 684: ! 685: case OCOMMA: ! 686: codegen(n->left, used, dest, 0); ! 687: codegen(n->right, used, dest, 0); ! 688: break; ! 689: ! 690: case OLT: ! 691: case OLE: ! 692: case OEQ: ! 693: case ONE: ! 694: case OGT: ! 695: case OGE: ! 696: case ONOT: ! 697: case OOROR: ! 698: case OANDAND: ! 699: markj(0); ! 700: testgen(n, used, dest, 1); ! 701: codegen(&zero, used, dest, 1); ! 702: patchj(1); ! 703: codegen(&one, used, dest, 0); ! 704: combj(0); ! 705: break; ! 706: ! 707: case ORETURN: ! 708: codegen(n->left, 0, 1, 0); ! 709: emitins(RSB); ! 710: break; ! 711: ! 712: case OASS: ! 713: if(complex(n->left) == 0) { ! 714: codegen(n->right, used, dest, 0); ! 715: emitins(MOVL); ! 716: emitreg(dest); ! 717: codegen(n->left, used, 0, 0); ! 718: break; ! 719: } ! 720: o = n->left->type; ! 721: if(o != DEREFB && o != DEREFL && o != DEREFS) ! 722: { fprintf(stderr, "o == %d -> %d: ", OASS, o); ! 723: yyerror("assignment to non-lvalue"); ! 724: } ! 725: if(complex(n->left->left)) ! 726: yyerror("index of non-lvalue"); ! 727: if(o == DEREFB) ! 728: o = MOVB; ! 729: else if (o == DEREFL) ! 730: o = MOVL; ! 731: else ! 732: o = MOVW; ! 733: codegen(n->right, used, dest, 0); ! 734: if(n->left->right) { ! 735: if(n->left->right->type == REG) { ! 736: emitins(o); ! 737: emitreg(dest); ! 738: *p++ = I(n->left->right->arg); ! 739: } else { ! 740: codegen(n->left->right, used+1, used+2, 0); ! 741: emitins(o); ! 742: emitreg(dest); ! 743: *p++ = I(used+2-1); ! 744: } ! 745: codegen(n->left->left, used, 0, 0); ! 746: break; ! 747: } ! 748: emitins(o); ! 749: emitreg(dest); ! 750: codegen(n->left->left, used, 0, 0); ! 751: break; ! 752: ! 753: case DEREFL: ! 754: case DEREFS: ! 755: case DEREFB: ! 756: o = n->type; ! 757: if(o == DEREFB) ! 758: o = MOVZBL; ! 759: else if (o == DEREFL) ! 760: o = MOVL; ! 761: else ! 762: o = MOVW; ! 763: if(complex(n->left)) ! 764: yyerror("index of non-lvalue"); ! 765: if(n->right) { ! 766: if(n->right->type == REG) { ! 767: emitins(o); ! 768: *p++ = I(n->right->arg); ! 769: } else { ! 770: codegen(n->right, used, dest, 0); ! 771: emitins(o); ! 772: *p++ = I(dest-1); ! 773: } ! 774: } else { ! 775: emitins(o); ! 776: } ! 777: codegen(n->left, used, 0, 0); ! 778: emitreg(dest); ! 779: break; ! 780: ! 781: case COMP: ! 782: switch(listcount(n->left)) { ! 783: case 1: ! 784: movsp((Node *)0, 1, used, dest); ! 785: movsp(n->left, 3, used, dest); ! 786: break; ! 787: case 2: ! 788: movsp(n->left->right, 1, used, dest); ! 789: movsp(n->left->left, 3, used, dest); ! 790: break; ! 791: case 3: ! 792: movsp((Node *)0, 1, used, dest); ! 793: movsp(n->left->right->right, 1, used, dest); ! 794: movsp(n->left->right->left, 1, used, dest); ! 795: movsp(n->left->left, 1, used, dest); ! 796: break; ! 797: case 4: ! 798: movsp(n->left->right->right->right, 1, used, dest); ! 799: movsp(n->left->right->right->left, 1, used, dest); ! 800: movsp(n->left->right->left, 1, used, dest); ! 801: movsp(n->left->left, 1, used, dest); ! 802: break; ! 803: default: ! 804: yyerror("[] must have 1<=n<=4 args"); ! 805: } ! 806: emitins(MOVL); ! 807: *p++ = SPPLUS; ! 808: emitreg(dest); ! 809: spoff -= 4; ! 810: break; ! 811: } ! 812: if(brgen) ! 813: markj(BRB); ! 814: else ! 815: patchj(0); ! 816: } ! 817: ! 818: emitcon(c) ! 819: { ! 820: ! 821: if((c & ~63) == 0) { ! 822: *p++ = SHORTIM(c); ! 823: return; ! 824: } ! 825: *p++ = LONGIM; ! 826: stufflong(c); ! 827: } ! 828: ! 829: emitabs(c) ! 830: { ! 831: ! 832: *p++ = STARPC; ! 833: stufflong(c); ! 834: } ! 835: ! 836: pushargs(n) ! 837: Node *n; ! 838: { ! 839: register c; ! 840: ! 841: if(!n) ! 842: return 0; ! 843: if(n->type == ACOMMA) { ! 844: c = pushargs(n->right); ! 845: c += pushargs(n->left); ! 846: return c; ! 847: } ! 848: if(complex(n)) { ! 849: codegen(n, 0, 1, 0); ! 850: emitins(MOVL); ! 851: *p++ = R(0); ! 852: } else { ! 853: emitins(MOVL); ! 854: codegen(n, 0, 0, 0); ! 855: } ! 856: *p++ = _SP; ! 857: spoff += 4; ! 858: return 1; ! 859: } ! 860: ! 861: invert(n, o) ! 862: Node *n; ! 863: { ! 864: n->other = n->right; ! 865: n->right = n->left; ! 866: n->left = n->other; ! 867: n->other = 0; ! 868: n->type = o; ! 869: } ! 870: ! 871: listcount(n) ! 872: Node *n; ! 873: { ! 874: register i; ! 875: for(i=1; n->type==ACOMMA; i++, n=n->right) ! 876: ; ! 877: return i; ! 878: } ! 879: ! 880: movsp(n, count, used, dest) ! 881: Node *n; ! 882: { ! 883: register i, c; ! 884: if(n==0) { /* push 255 */ ! 885: emitins(MOVB); ! 886: *p++ = LONGIM; ! 887: *p++ = 255; ! 888: *p++ = _SP; ! 889: spoff += 1; ! 890: return; ! 891: } ! 892: c = complex(n); ! 893: for(i=0; i<count; i++) { ! 894: if(c == 0) { ! 895: if(n->type == CONST) { ! 896: if(n->arg == 0) { ! 897: emitins(CLRB); ! 898: *p++ = _SP; ! 899: spoff += 1; ! 900: continue; ! 901: } ! 902: n->type = CONSTB; ! 903: } ! 904: emitins(MOVB); ! 905: codegen(n, used, 0, 0); ! 906: *p++ = _SP; ! 907: spoff += 1; ! 908: continue; ! 909: } ! 910: if(i == 0) ! 911: codegen(n, used, dest, 0); ! 912: emitins(MOVB); ! 913: emitreg(dest); ! 914: *p++ = _SP; ! 915: spoff += 1; ! 916: } ! 917: } ! 918: ! 919: binop(comm, threeaddr, twoaddr, n, used, dest) ! 920: Node *n; ! 921: { ! 922: int cl, cr; ! 923: ! 924: cl = complex(n->left); ! 925: cr = complex(n->right); ! 926: if(cl == 0 && cr == 0) ! 927: if(comm != 2 && threeaddr) { ! 928: emitins(threeaddr); ! 929: codegen(n->right, used, 0, 0); ! 930: codegen(n->left, used, 0, 0); ! 931: emitreg(dest); ! 932: return; ! 933: } ! 934: if(cr == 0) { ! 935: if(comm == 2) { /* OAND hack */ ! 936: unop(MCOML, n->left, used, dest); ! 937: emitins(threeaddr); ! 938: emitreg(dest); ! 939: codegen(n->right, used, 0, 0); ! 940: emitreg(dest); ! 941: return; ! 942: } ! 943: codegen(n->left, used, dest, 0); ! 944: if(twoaddr) { ! 945: emitins(twoaddr); ! 946: codegen(n->right, used, 0, 0); ! 947: } else { ! 948: emitins(threeaddr); ! 949: codegen(n->right, used, 0, 0); ! 950: emitreg(dest); ! 951: } ! 952: emitreg(dest); ! 953: return; ! 954: } ! 955: if(cl == 0) { ! 956: if(comm == 2) { /* OAND hack */ ! 957: unop(MCOML, n->right, used, dest); ! 958: emitins(threeaddr); ! 959: emitreg(dest); ! 960: codegen(n->left, used, 0, 0); ! 961: emitreg(dest); ! 962: return; ! 963: } ! 964: codegen(n->right, used, dest, 0); ! 965: if(comm && twoaddr) { ! 966: emitins(twoaddr); ! 967: } else { ! 968: emitins(threeaddr); ! 969: emitreg(dest); ! 970: } ! 971: codegen(n->left, used, 0, 0); ! 972: emitreg(dest); ! 973: return; ! 974: } ! 975: if(cl >= cr) { ! 976: codegen(n->left, used, dest, 0); ! 977: codegen(n->right, used+1, used+2, 0); ! 978: if(comm == 2) { /* OAND hack */ ! 979: emitins(MCOML); ! 980: emitreg(used+2); ! 981: emitreg(used+2); ! 982: } ! 983: if(twoaddr) { ! 984: emitins(twoaddr); ! 985: emitreg(used+2); ! 986: } else { ! 987: emitins(threeaddr); ! 988: emitreg(used+2); ! 989: emitreg(dest); ! 990: } ! 991: emitreg(dest); ! 992: return; ! 993: } ! 994: codegen(n->right, used, dest, 0); ! 995: codegen(n->left, used+1, used+2, 0); ! 996: if(comm == 2) { /* OAND hack */ ! 997: emitins(MCOML); ! 998: emitreg(used+2); ! 999: emitreg(used+2); ! 1000: } ! 1001: if(comm && twoaddr) { ! 1002: emitins(twoaddr); ! 1003: } else { ! 1004: emitins(threeaddr); ! 1005: emitreg(dest); ! 1006: } ! 1007: emitreg(used+2); ! 1008: emitreg(dest); ! 1009: } ! 1010: ! 1011: compareop(n, used, dest, true) ! 1012: Node *n; ! 1013: { ! 1014: int o; ! 1015: int cl, cr; ! 1016: ! 1017: cl = complex(n->left); ! 1018: if(n->right == Z) { ! 1019: if(cl == 0) { ! 1020: emitins(TSTL); ! 1021: codegen(n->left, used, 0, 0); ! 1022: goto out; ! 1023: } ! 1024: codegen(n->left, used, dest, 0); ! 1025: o = n->left->type; ! 1026: if(o == OCALL || o == CCALL) ! 1027: if(dest == 1) { ! 1028: emitins(TSTL); ! 1029: emitreg(dest); ! 1030: } ! 1031: goto out; ! 1032: } ! 1033: cr = complex(n->right); ! 1034: o = CMPL; ! 1035: if(n->type == OAND) ! 1036: o = BITL; ! 1037: if(cl == 0 && cr == 0) { ! 1038: emitins(o); ! 1039: codegen(n->left, used, 0, 0); ! 1040: codegen(n->right, used, 0, 0); ! 1041: goto out; ! 1042: } ! 1043: if(cr == 0) { ! 1044: codegen(n->left, used, dest, 0); ! 1045: emitins(o); ! 1046: emitreg(dest); ! 1047: codegen(n->right, used, 0, 0); ! 1048: goto out; ! 1049: } ! 1050: if(cl == 0) { ! 1051: codegen(n->right, used, dest, 0); ! 1052: emitins(o); ! 1053: codegen(n->left, used, 0, 0); ! 1054: emitreg(dest); ! 1055: goto out; ! 1056: } ! 1057: if(cl >= cr) { ! 1058: codegen(n->left, used, dest, 0); ! 1059: codegen(n->right, used+1, used+2, 0); ! 1060: emitins(o); ! 1061: emitreg(dest); ! 1062: emitreg(used+2); ! 1063: goto out; ! 1064: } ! 1065: codegen(n->right, used, dest, 0); ! 1066: codegen(n->left, used+1, used+2, 0); ! 1067: emitins(o); ! 1068: emitreg(used+2); ! 1069: emitreg(dest); ! 1070: ! 1071: out: ! 1072: switch(n->type) ! 1073: { ! 1074: case ONE: ! 1075: case OAND: o = BNEQ; break; ! 1076: case OEQ: o = BEQL; break; ! 1077: case OLT: o = BLSS; break; ! 1078: case OLE: o = BLEQ; break; ! 1079: case OGE: o = BGEQ; break; ! 1080: case OGT: o = BGTR; break; ! 1081: default: yyerror("unknown compare"); ! 1082: } ! 1083: if(!true) ! 1084: o = invrbr(o); ! 1085: return o; ! 1086: } ! 1087: ! 1088: invrbr(o) ! 1089: { ! 1090: switch(o) ! 1091: { ! 1092: case BNEQ: o = BEQL; break; ! 1093: case BEQL: o = BNEQ; break; ! 1094: case BLSS: o = BGEQ; break; ! 1095: case BLEQ: o = BGTR; break; ! 1096: case BGEQ: o = BLSS; break; ! 1097: case BGTR: o = BLEQ; break; ! 1098: case BRB: o = BRW; break; ! 1099: default: yyerror("unknown branch"); ! 1100: } ! 1101: return o; ! 1102: } ! 1103: ! 1104: unop(inst, n, used, dest) ! 1105: Node *n; ! 1106: { ! 1107: int c; ! 1108: c = complex(n); ! 1109: if(c == 0) { ! 1110: emitins(inst); ! 1111: codegen(n, used, 0, 0); ! 1112: emitreg(dest); ! 1113: return; ! 1114: } ! 1115: codegen(n, used, dest, 0); ! 1116: emitins(inst); ! 1117: emitreg(dest); ! 1118: emitreg(dest); ! 1119: } ! 1120: ! 1121: complex(n) ! 1122: Node *n; ! 1123: { ! 1124: int cl, cr; ! 1125: ! 1126: switch(n->type) { ! 1127: case CONST: ! 1128: case CONSTB: ! 1129: case VAR: ! 1130: case REG: ! 1131: case OARG: ! 1132: case GOTO: ! 1133: return 0; ! 1134: ! 1135: case OCALL: ! 1136: case CCALL: ! 1137: return INF; ! 1138: ! 1139: case OADD: ! 1140: case OMUL: ! 1141: case OPOW: ! 1142: case OXOR: ! 1143: case OOR: ! 1144: case OSUB: ! 1145: case OISUB: ! 1146: case OBIC: ! 1147: case OAND: ! 1148: case OIDIV: ! 1149: case ODIV: ! 1150: case OLT: ! 1151: case OLE: ! 1152: case OEQ: ! 1153: case ONE: ! 1154: case OGT: ! 1155: case OGE: ! 1156: case OLSH: ! 1157: case DEREFB: ! 1158: case DEREFS: ! 1159: case DEREFL: ! 1160: cl = complex(n->left); ! 1161: cr = 0; ! 1162: if(n->right) ! 1163: cr = complex(n->right); ! 1164: if(cl == cr) ! 1165: return cl+1; ! 1166: if(cl > cr) ! 1167: return cl; ! 1168: return cr; ! 1169: ! 1170: case LABL: ! 1171: case ORETURN: ! 1172: cl = complex(n->left); ! 1173: if(cl == 0) ! 1174: cl++; ! 1175: return cl; ! 1176: ! 1177: case OASS: ! 1178: cl = complex(n->left); ! 1179: cr = complex(n->right); ! 1180: if(cl >= cr) ! 1181: return cl+1; ! 1182: return cr; ! 1183: ! 1184: case CONDI: ! 1185: cl = complex(n->left); ! 1186: cr = complex(n->right); ! 1187: if(cl < cr) ! 1188: cl = cr; ! 1189: cr = complex(n->other); ! 1190: if(cl < cr) ! 1191: cl = cr; ! 1192: if(cl == 0) ! 1193: cl++; ! 1194: return cl; ! 1195: ! 1196: case OANDAND: ! 1197: case OOROR: ! 1198: case OCOMMA: ! 1199: case ACOMMA: ! 1200: cl = complex(n->left); ! 1201: cr = complex(n->right); ! 1202: if(cl < cr) ! 1203: cl = cr; ! 1204: if(cl == 0) ! 1205: cl++; ! 1206: return cl; ! 1207: ! 1208: case ONEG: ! 1209: case ONOT: ! 1210: case OMINUS: ! 1211: case COMP: ! 1212: cl = complex(n->left); ! 1213: if(cl == 0) ! 1214: cl++; ! 1215: return cl; ! 1216: } ! 1217: yyerror("unknown operator in complex"); ! 1218: return 0; ! 1219: } ! 1220: ! 1221: emitins(o) ! 1222: { ! 1223: *p++ = o; ! 1224: ninstr++; ! 1225: } ! 1226: ! 1227: emitreg(dest) ! 1228: { ! 1229: if(dest>=TOOMANY) ! 1230: yyerror("TOOMANY too small"); ! 1231: *p++ = R(dest-1); ! 1232: } ! 1233: ! 1234: ptree(n, s) ! 1235: Node *n; ! 1236: char *s; ! 1237: { ! 1238: printf("== %s ==\n", s); ! 1239: prtree(n, 1, 0); ! 1240: } ! 1241: ! 1242: prtree(n, f, d) ! 1243: Node *n; ! 1244: { int i; ! 1245: ! 1246: if (f) ! 1247: for(i=0; i<d; i++) ! 1248: printf(" "); ! 1249: f = 0; ! 1250: d++; ! 1251: switch(n->type) { ! 1252: case LABL: printf("Lb%d\n", n->arg); break; ! 1253: case GOTO: printf("Gt%d\n", n->arg); return; ! 1254: case OCALL: ! 1255: case CCALL: printf("()%d\n", n->arg); f = 1; break; ! 1256: case REG: printf("R%d\n", n->arg); return; ! 1257: case VAR: printf("V%d\n", n->arg); return; ! 1258: case OARG: printf("A%d\n", n->arg); return; ! 1259: case CONST: printf("C%d\n", n->arg); return; ! 1260: case CONDI: printf("? "); prtree(n->other, f, d); f = 1; break; ! 1261: case COMP: printf("[]"); break; ! 1262: case ORETURN: printf("rt"); break; ! 1263: case DEREFB: printf("b*"); break; ! 1264: case DEREFS: printf("s*"); break; ! 1265: case DEREFL: printf("l*"); break; ! 1266: case OADD: printf("+ "); break; ! 1267: case OAND: printf("& "); break; ! 1268: case OANDAND: printf("&&"); break; ! 1269: case OASS: printf(":="); break; ! 1270: case OBIC: printf("&~"); break; ! 1271: case ACOMMA: printf(", "); break; ! 1272: case OCOMMA: printf("; "); break; ! 1273: case ODIV: printf("/ "); break; ! 1274: case OEQ: printf("=="); break; ! 1275: case OGE: printf(">="); break; ! 1276: case OGT: printf("> "); break; ! 1277: case OLE: printf("<="); break; ! 1278: case OLSH: printf("<<"); break; ! 1279: case OLT: printf("< "); break; ! 1280: case OMINUS: printf("u-"); break; ! 1281: case OMUL: printf("* "); break; ! 1282: case ONE: printf("!="); break; ! 1283: case ONEG: printf("~ "); break; ! 1284: case ONOT: printf("! "); break; ! 1285: case OOR: printf("| "); break; ! 1286: case OOROR: printf("||"); break; ! 1287: case OPOW: printf("**"); break; ! 1288: case OSUB: printf("- "); break; ! 1289: case OISUB: printf("-i"); break; ! 1290: case OXOR: printf("^ "); break; ! 1291: default: printf("@"); break; ! 1292: } ! 1293: if (n->left) { prtree(n->left, f, d); f = 1; } ! 1294: if (n->right) { prtree(n->right, f, d); f = 1; } ! 1295: if (!f) printf("\n"); ! 1296: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.