|
|
1.1 ! root 1: #include <u.h> ! 2: #include <libc.h> ! 3: #include <bio.h> ! 4: #include <ctype.h> ! 5: #define Extern extern ! 6: #include "parl.h" ! 7: #include "globl.h" ! 8: #include "y.tab.h" ! 9: ! 10: static int slot; ! 11: ! 12: char *itab[] = ! 13: { ! 14: "XXX", ! 15: "ADD", ! 16: "ADDCC", ! 17: "ADDX", ! 18: "ADDXCC", ! 19: "AND", ! 20: "ANDCC", ! 21: "ANDN", ! 22: "ANDNCC", ! 23: "BA", ! 24: "BCC", ! 25: "BCS", ! 26: "BE", ! 27: "BG", ! 28: "BGE", ! 29: "BGU", ! 30: "BL", ! 31: "BLE", ! 32: "BLEU", ! 33: "BN", ! 34: "BNE", ! 35: "BNEG", ! 36: "BPOS", ! 37: "BVC", ! 38: "BVS", ! 39: "CB0", ! 40: "CB01", ! 41: "CB012", ! 42: "CB013", ! 43: "CB02", ! 44: "CB023", ! 45: "CB03", ! 46: "CB1", ! 47: "CB12", ! 48: "CB123", ! 49: "CB13", ! 50: "CB2", ! 51: "CB23", ! 52: "CB3", ! 53: "CBA", ! 54: "CBN", ! 55: "CMP", ! 56: "CPOP1", ! 57: "CPOP2", ! 58: "DATA", ! 59: "DIV", ! 60: "DIVL", ! 61: "FABSD", ! 62: "FABSF", ! 63: "FABSX", ! 64: "FADDD", ! 65: "FADDF", ! 66: "FADDX", ! 67: "FBA", ! 68: "FBE", ! 69: "FBG", ! 70: "FBGE", ! 71: "FBL", ! 72: "FBLE", ! 73: "FBLG", ! 74: "FBN", ! 75: "FBNE", ! 76: "FBO", ! 77: "FBU", ! 78: "FBUE", ! 79: "FBUG", ! 80: "FBUGE", ! 81: "FBUL", ! 82: "FBULE", ! 83: "FCMPD", ! 84: "FCMPED", ! 85: "FCMPEF", ! 86: "FCMPEX", ! 87: "FCMPF", ! 88: "FCMPX", ! 89: "FDIVD", ! 90: "FDIVF", ! 91: "FDIVX", ! 92: "FMOVD", ! 93: "FMOVDF", ! 94: "FMOVDW", ! 95: "FMOVDX", ! 96: "FMOVF", ! 97: "FMOVFD", ! 98: "FMOVFW", ! 99: "FMOVFX", ! 100: "FMOVWD", ! 101: "FMOVWF", ! 102: "FMOVWX", ! 103: "FMOVX", ! 104: "FMOVXD", ! 105: "FMOVXF", ! 106: "FMOVXW", ! 107: "FMULD", ! 108: "FMULF", ! 109: "FMULX", ! 110: "FNEGD", ! 111: "FNEGF", ! 112: "FNEGX", ! 113: "FSQRTD", ! 114: "FSQRTF", ! 115: "FSQRTX", ! 116: "FSUBD", ! 117: "FSUBF", ! 118: "FSUBX", ! 119: "GLOBL", ! 120: "GOK", ! 121: "HISTORY", ! 122: "IFLUSH", ! 123: "JMPL", ! 124: "JMP", ! 125: "MOD", ! 126: "MODL", ! 127: "MOVB", ! 128: "MOVBU", ! 129: "MOVD", ! 130: "MOVH", ! 131: "MOVHU", ! 132: "MOVW", ! 133: "MUL", ! 134: "MULSCC", ! 135: "NAME", ! 136: "NOP", ! 137: "OR", ! 138: "ORCC", ! 139: "ORN", ! 140: "ORNCC", ! 141: "RESTORE", ! 142: "RETT", ! 143: "RETURN", ! 144: "SAVE", ! 145: "SLL", ! 146: "SRA", ! 147: "SRL", ! 148: "SUB", ! 149: "SUBCC", ! 150: "SUBX", ! 151: "SUBXCC", ! 152: "SWAP", ! 153: "TA", ! 154: "TADDCC", ! 155: "TADDCCTV", ! 156: "TAS", ! 157: "TCC", ! 158: "TCS", ! 159: "TE", ! 160: "TEXT", ! 161: "TG", ! 162: "TGE", ! 163: "TGU", ! 164: "TL", ! 165: "TLE", ! 166: "TLEU", ! 167: "TN", ! 168: "TNE", ! 169: "TNEG", ! 170: "TPOS", ! 171: "TSUBCC", ! 172: "TSUBCCTV", ! 173: "TVC", ! 174: "TVS", ! 175: "UNIMP", ! 176: "WORD", ! 177: "XNOR", ! 178: "XNORCC", ! 179: "XOR", ! 180: "XORCC", ! 181: "END", ! 182: "DYNT", ! 183: "INIT", ! 184: "LAST", ! 185: }; ! 186: ! 187: char rcmap[256] = ! 188: { ! 189: ['\0'] 'z', ! 190: ['\n'] 'n', ! 191: ['\r'] 'r', ! 192: ['\t'] 't', ! 193: ['\b'] 'b', ! 194: ['\f'] 'f', ! 195: ['\a'] 'a', ! 196: ['\v'] 'v', ! 197: ['\\'] '\\', ! 198: ['"'] '"', ! 199: }; ! 200: ! 201: void ! 202: vwrite(Biobuf *b, Inst *i, int sf, int st) ! 203: { ! 204: char io[100], *bp; ! 205: ! 206: io[0] = i->op; ! 207: if(i->reg == Nreg) ! 208: io[1] = NREG; ! 209: else ! 210: io[1] = i->reg; ! 211: ! 212: io[2] = i->lineno; ! 213: io[3] = i->lineno>>8; ! 214: io[4] = i->lineno>>16; ! 215: io[5] = i->lineno>>24; ! 216: ! 217: bp = vaddr(io+6, &i->src1, sf); ! 218: bp = vaddr(bp, &i->dst, st); ! 219: ! 220: Bwrite(b, io, bp-io); ! 221: } ! 222: ! 223: void ! 224: outhist(Biobuf *b) ! 225: { ! 226: Hist *h; ! 227: char *p, *q; ! 228: Inst pg; ! 229: int n; ! 230: ! 231: pg.op = AHISTORY; ! 232: pg.src1.type = A_NONE; ! 233: pg.dst.reg = Nreg; ! 234: pg.reg = Nreg; ! 235: for(h = hist; h != H; h = h->link) { ! 236: p = h->name; ! 237: while(p) { ! 238: q = strchr(p, '/'); ! 239: if(q) { ! 240: n = q-p; ! 241: if(n == 0) ! 242: n = 1; /* leading "/" */ ! 243: q++; ! 244: } else { ! 245: n = strlen(p); ! 246: q = 0; ! 247: } ! 248: if(n) { ! 249: Bputc(b, ANAME); ! 250: Bputc(b, D_FILE); ! 251: Bputc(b, 1); ! 252: Bputc(b, '<'); ! 253: Bwrite(b, p, n); ! 254: Bputc(b, 0); ! 255: } ! 256: p = q; ! 257: } ! 258: pg.lineno = h->line; ! 259: pg.dst.ival = h->offset; ! 260: pg.dst.type = A_NONE; ! 261: if(h->offset) ! 262: pg.dst.type = A_CONST; ! 263: ! 264: vwrite(b, &pg, 0, 0); ! 265: } ! 266: } ! 267: ! 268: void ! 269: sfile(char *name) ! 270: { ! 271: int f; ! 272: Inst *i; ! 273: Biobuf b; ! 274: ! 275: f = create(name, OWRITE|OTRUNC, 0666); ! 276: if(f < 0) { ! 277: diag(ZeroN, "cannot open %s: %r", name); ! 278: return; ! 279: } ! 280: Binit(&b, f, OWRITE); ! 281: ! 282: for(i = proghead; i; i = i->next) { ! 283: if(i->dst.type == A_BRANCH) ! 284: i->dst.ival -= i->pc; ! 285: ! 286: Bprint(&b, "%i\n", i); ! 287: } ! 288: ! 289: Bflush(&b); ! 290: close(f); ! 291: } ! 292: ! 293: void ! 294: objfile(char *name) ! 295: { ! 296: Inst *i; ! 297: Biobuf b; ! 298: Inst end; ! 299: int f, sfrom, sto; ! 300: ! 301: f = create(name, OWRITE|OTRUNC, 0666); ! 302: if(f < 0) { ! 303: diag(ZeroN, "cannot open %s: %r", name); ! 304: return; ! 305: } ! 306: Binit(&b, f, OWRITE); ! 307: Bseek(&b, 0L, 2); ! 308: ! 309: outhist(&b); ! 310: ! 311: memset(scache, 0, sizeof(scache)); ! 312: ! 313: for(i = proghead; i; i = i->next) { ! 314: sto = 0; ! 315: sfrom = 0; ! 316: do{ ! 317: switch(i->src1.type) { ! 318: case A_CONST: ! 319: case A_INDREG: ! 320: if(i->src1.class) ! 321: sfrom = vcache(&b, &i->src1); ! 322: } ! 323: switch(i->dst.type) { ! 324: case A_CONST: ! 325: case A_INDREG: ! 326: if(i->dst.class) ! 327: sto = vcache(&b, &i->dst); ! 328: } ! 329: }while(sfrom == sto && sfrom != 0); ! 330: ! 331: vwrite(&b, i, sfrom, sto); ! 332: } ! 333: ! 334: end = zprog; ! 335: end.op = AEND; ! 336: vwrite(&b, &end, 0, 0); ! 337: ! 338: Bflush(&b); ! 339: close(f); ! 340: } ! 341: ! 342: int ! 343: vcache(Biobuf *b, Adres *a) ! 344: { ! 345: Sym *s; ! 346: Scache *c; ! 347: ! 348: s = a->sym; ! 349: ! 350: if(s->slot) { ! 351: c = &scache[s->slot]; ! 352: if(c->s == s) ! 353: if(c->class == a->class) ! 354: return s->slot; ! 355: } ! 356: ! 357: slot++; ! 358: if(slot >= NSYM) ! 359: slot = 1; ! 360: ! 361: c = &scache[slot]; ! 362: c->s = s; ! 363: c->class = a->class; ! 364: ! 365: vname(b, a->class, s->name, slot); ! 366: ! 367: return slot; ! 368: } ! 369: ! 370: void ! 371: vname(Biobuf *b, char class, char *name, int slot) ! 372: { ! 373: char io[4]; ! 374: ! 375: io[0] = ANAME; ! 376: switch(class) { ! 377: default: ! 378: fatal("vcache %d", class); ! 379: case Dfile: ! 380: io[1] = D_FILE; ! 381: break; ! 382: case Internal: ! 383: io[1] = D_STATIC; ! 384: break; ! 385: case External: ! 386: case Global: ! 387: io[1] = D_EXTERN; ! 388: break; ! 389: case Parameter: ! 390: io[1] = D_PARAM; ! 391: break; ! 392: case Automatic: ! 393: io[1] = D_AUTO; ! 394: break; ! 395: } ! 396: io[2] = slot; ! 397: ! 398: Bwrite(b, io, 3); ! 399: Bwrite(b, name, strlen(name)+1); ! 400: } ! 401: ! 402: char* ! 403: vaddr(char *bp, Adres *a, int s) ! 404: { ! 405: long l; ! 406: Ieee e; ! 407: ! 408: bp[0] = D_NONE; ! 409: bp[1] = NREG; ! 410: bp[2] = 0; ! 411: bp[3] = D_NONE; ! 412: ! 413: switch(a->type) { ! 414: default: ! 415: fatal("vaddr %a", a); ! 416: ! 417: case A_NONE: ! 418: bp += 4; ! 419: break; ! 420: ! 421: case A_CONST: ! 422: bp[0] = D_CONST; ! 423: if(a->reg != Nreg) ! 424: bp[1] = a->reg; ! 425: bp[2] = s; ! 426: l = a->ival; ! 427: switch(a->class) { ! 428: default: ! 429: bp[3] = D_NONE; ! 430: break; ! 431: case Internal: ! 432: bp[3] = D_STATIC; ! 433: break; ! 434: case External: ! 435: case Global: ! 436: bp[3] = D_EXTERN; ! 437: break; ! 438: case Parameter: ! 439: bp[3] = D_PARAM; ! 440: break; ! 441: case Automatic: ! 442: bp[3] = D_AUTO; ! 443: break; ! 444: } ! 445: bp[4] = l; ! 446: bp[5] = l>>8; ! 447: bp[6] = l>>16; ! 448: bp[7] = l>>24; ! 449: bp += 8; ! 450: break; ! 451: ! 452: case A_FCONST: ! 453: bp[0] = D_FCONST; ! 454: ieeedtod(&e, a->fval); ! 455: l = e.l; ! 456: bp[4] = l; ! 457: bp[5] = l>>8; ! 458: bp[6] = l>>16; ! 459: bp[7] = l>>24; ! 460: l = e.h; ! 461: bp[8] = l; ! 462: bp[9] = l>>8; ! 463: bp[10] = l>>16; ! 464: bp[11] = l>>24; ! 465: bp += 12; ! 466: break; ! 467: ! 468: case A_REG: ! 469: bp[0] = D_REG; ! 470: bp[1] = a->reg; ! 471: bp += 4; ! 472: break; ! 473: ! 474: case A_FREG: ! 475: bp[0] = D_FREG; ! 476: bp[1] = a->reg; ! 477: bp += 4; ! 478: break; ! 479: ! 480: case A_INDREG: ! 481: bp[0] = D_OREG; ! 482: bp[2] = s; ! 483: l = a->ival; ! 484: switch(a->class) { ! 485: default: ! 486: bp[1] = a->reg; ! 487: bp[3] = D_NONE; ! 488: break; ! 489: case Internal: ! 490: bp[1] = NREG; ! 491: bp[3] = D_STATIC; ! 492: break; ! 493: case External: ! 494: case Global: ! 495: bp[1] = NREG; ! 496: bp[3] = D_EXTERN; ! 497: break; ! 498: case Parameter: ! 499: bp[1] = NREG; ! 500: bp[3] = D_PARAM; ! 501: break; ! 502: case Automatic: ! 503: bp[1] = NREG; ! 504: bp[3] = D_AUTO; ! 505: break; ! 506: } ! 507: bp[4] = l; ! 508: bp[5] = l>>8; ! 509: bp[6] = l>>16; ! 510: bp[7] = l>>24; ! 511: bp += 8; ! 512: break; ! 513: ! 514: case A_BRANCH: ! 515: bp[0] = D_BRANCH; ! 516: l = a->ival; ! 517: bp[4] = l; ! 518: bp[5] = l>>8; ! 519: bp[6] = l>>16; ! 520: bp[7] = l>>24; ! 521: bp += 8; ! 522: break; ! 523: ! 524: case A_STRING: ! 525: bp[0] = D_SCONST; ! 526: memmove(bp+4, a->str, NSNAME); ! 527: bp += 4+NSNAME; ! 528: break; ! 529: } ! 530: return bp; ! 531: } ! 532: ! 533: /* Quoted string printer */ ! 534: int ! 535: qconv(void *o, Fconv *f) ! 536: { ! 537: char buf[64], *b; ! 538: char *p; ! 539: int i; ! 540: ! 541: p = *((char**)o); ! 542: b = buf; ! 543: for(i = 0; i < 8; i++) { ! 544: if(rcmap[*p]) { ! 545: b[0] = '\\'; ! 546: b[1] = rcmap[*p++]; ! 547: b += 2; ! 548: } ! 549: else ! 550: *b++ = *p++; ! 551: } ! 552: *b = '\0'; ! 553: strconv(buf, f); ! 554: return sizeof(p); ! 555: } ! 556: ! 557: /* Instruction printer */ ! 558: int ! 559: iconv(void *o, Fconv *f) ! 560: { ! 561: Inst *i; ! 562: char c, buf[128]; ! 563: ! 564: i = *((Inst **)o); ! 565: ! 566: if(i->op == ADATA || i->op == AINIT || i->op == ADYNT) ! 567: sprint(buf, "\t%s\t%a/%d,%a", itab[i->op], &i->src1, i->reg, &i->dst); ! 568: else ! 569: if(i->reg == Nreg) { ! 570: if(i->dst.type == A_NONE) ! 571: sprint(buf, "\t%s\t%a", itab[i->op], &i->src1); ! 572: else ! 573: sprint(buf, "\t%s\t%a,%a", itab[i->op], &i->src1, &i->dst); ! 574: } ! 575: else { ! 576: c = 'R'; ! 577: if(i->src1.type == A_FREG) ! 578: c = 'F'; ! 579: sprint(buf, "\t%s\t%a,%c%d,%a", itab[i->op], ! 580: &i->src1, c, i->reg, &i->dst); ! 581: } ! 582: ! 583: strconv(buf, f); ! 584: return sizeof(i); ! 585: } ! 586: ! 587: int ! 588: mconv(void *o, Fconv *f) ! 589: { ! 590: Adres *adr; ! 591: char buf[128]; ! 592: ! 593: adr = *((Adres **)o); ! 594: ! 595: switch(adr->class) { ! 596: default: ! 597: sprint(buf, "Addr(%d/%d)", adr->class, adr->ival); ! 598: break; ! 599: ! 600: case External: ! 601: case Global: ! 602: sprint(buf, "%s+%d(SB)", adr->sym->name, adr->ival); ! 603: break; ! 604: ! 605: case Internal: ! 606: sprint(buf, "%s<>+%d(SB)", adr->sym->name, adr->ival); ! 607: break; ! 608: ! 609: case Parameter: ! 610: sprint(buf, "%s+%d(FP)", adr->sym->name, adr->ival); ! 611: break; ! 612: ! 613: case Automatic: ! 614: sprint(buf, "%s%d(SP)", adr->sym->name, adr->ival); ! 615: break; ! 616: } ! 617: ! 618: strconv(buf, f); ! 619: return sizeof(adr); ! 620: ! 621: } ! 622: ! 623: /* Address syllable printer */ ! 624: int ! 625: aconv(void *o, Fconv *f) ! 626: { ! 627: char buf[128]; ! 628: Adres *adr; ! 629: ! 630: adr = *((Adres **)o); ! 631: switch(adr->type) { ! 632: default: ! 633: sprint(buf, "Addr(%d)", adr->type); ! 634: break; ! 635: ! 636: case A_NONE: ! 637: buf[0] = 0; ! 638: break; ! 639: ! 640: case A_BRANCH: ! 641: sprint(buf, "%d(PC)", adr->ival); ! 642: break; ! 643: ! 644: case A_STRING: ! 645: sprint(buf, "$\"%q\"", adr->str); ! 646: break; ! 647: ! 648: case A_CONST: ! 649: if(adr->class) ! 650: sprint(buf, "$%m", adr); ! 651: else ! 652: if(adr->reg != Nreg) ! 653: sprint(buf, "$%d(R%d)", adr->ival, adr->reg); ! 654: else ! 655: sprint(buf, "$%d", adr->ival); ! 656: break; ! 657: ! 658: case A_FCONST: ! 659: sprint(buf, "$%#g", adr->fval); ! 660: break; ! 661: ! 662: case A_REG: ! 663: sprint(buf, "R%d", adr->reg); ! 664: break; ! 665: ! 666: case A_FREG: ! 667: sprint(buf, "F%d", adr->reg); ! 668: break; ! 669: ! 670: case A_INDREG: ! 671: if(adr->class) ! 672: sprint(buf, "%m", adr); ! 673: else ! 674: if(adr->ival == 0) ! 675: sprint(buf, "(R%d)", adr->reg); ! 676: else ! 677: sprint(buf, "%d(R%d)", adr->ival, adr->reg); ! 678: break; ! 679: } ! 680: ! 681: strconv(buf, f); ! 682: return sizeof(adr); ! 683: } ! 684: ! 685: typedef struct runtime Runtime; ! 686: struct runtime ! 687: { ! 688: char *name; ! 689: Node **p; ! 690: }runtime[] = { ! 691: "ALEF_proc", &procnode, ! 692: "ALEF_task", &tasknode, ! 693: "ALEF_send", &sendnode, ! 694: "ALEF_exit", &exitnode, ! 695: "ALEF_selrecv", &selrecv, ! 696: "ALEF_selsend", &selsend, ! 697: "ALEF_doselect", &doselect, ! 698: "ALEF_varselect", &varselect, ! 699: "ALEF_pfork", &pforknode, ! 700: "ALEF_pexit", &pexitnode, ! 701: "ALEF_pdone", &pdonenode, ! 702: "ALEF_csnd", &csndnode, ! 703: "ALEF_crcv", &crcvnode, ! 704: "ALEF_chana", &challocnode, ! 705: "ALEF_chanu", &chunallocnode, ! 706: "malloc", &allocnode, ! 707: "free", &unallocnode, ! 708: "ALEF_gin", &ginode, ! 709: "ALEF_gou", &gonode, ! 710: "memmove", &movenode, ! 711: "ALEFcheck", &checknode, ! 712: 0, 0, ! 713: }; ! 714: ! 715: void ! 716: outinit(void) ! 717: { ! 718: Node *n; ! 719: Type *t; ! 720: Runtime *rp; ! 721: ! 722: fmtinstall('i', iconv); /* Instructions */ ! 723: fmtinstall('a', aconv); /* Addresses */ ! 724: fmtinstall('q', qconv); /* Data */ ! 725: fmtinstall('m', mconv); /* Memeory addresses */ ! 726: fmtinstall('B', Bconv); /* Memeory addresses */ ! 727: ! 728: for(rp = runtime; rp->name; rp++) { ! 729: n = an(ONAME, nil, nil); ! 730: n->sym = enter(rp->name, Tid); ! 731: ! 732: t = builtype[TVOID]; ! 733: if(rp->p == &allocnode) ! 734: t = at(TIND, t); ! 735: t = at(TFUNC, t); ! 736: t->proto = an(ONAME, an(OVARARG, nil, nil), nil); ! 737: t->proto->sym = n->sym; ! 738: if(rp->p == &checknode) ! 739: t = at(TIND, t); ! 740: ! 741: n->t = t; ! 742: n->ti = ati(t, Global); ! 743: sucalc(n); ! 744: *(rp->p) = n; ! 745: } ! 746: ! 747: zprog.next = 0; ! 748: zprog.src1.type = A_NONE; ! 749: zprog.dst.type = A_NONE; ! 750: zprog.op = AGOK; ! 751: zprog.reg = Nreg; ! 752: } ! 753: ! 754: void ! 755: ieeedtod(Ieee *ieee, double native) ! 756: { ! 757: double fr, ho, f; ! 758: int exp; ! 759: ! 760: if(native < 0) { ! 761: ieeedtod(ieee, -native); ! 762: ieee->h |= 0x80000000L; ! 763: return; ! 764: } ! 765: if(native == 0) { ! 766: ieee->l = 0; ! 767: ieee->h = 0; ! 768: return; ! 769: } ! 770: fr = frexp(native, &exp); ! 771: f = 2097152L; /* shouldnt use fp constants here */ ! 772: fr = modf(fr*f, &ho); ! 773: ieee->h = ho; ! 774: ieee->h &= 0xfffffL; ! 775: ieee->h |= (exp+1022L) << 20; ! 776: f = 65536L; ! 777: fr = modf(fr*f, &ho); ! 778: ieee->l = ho; ! 779: ieee->l <<= 16; ! 780: ieee->l |= (long)(fr*f); ! 781: } ! 782: ! 783: void ! 784: init(Node *tab, Node *v) ! 785: { ! 786: Inst *i; ! 787: ! 788: i = ai(); ! 789: i->op = AINIT; ! 790: i->reg = builtype[TIND]->size; ! 791: mkaddr(tab, &i->src1, 0); ! 792: mkaddr(v, &i->dst, 0); ! 793: ilink(i); ! 794: } ! 795: ! 796: void ! 797: dynt(Node *tab, Node *ind) ! 798: { ! 799: Inst *i; ! 800: ! 801: i = ai(); ! 802: i->op = ADYNT; ! 803: if(tab) ! 804: mkaddr(tab, &i->src1, 0); ! 805: mkaddr(ind, &i->dst, 0); ! 806: ilink(i); ! 807: } ! 808: ! 809: void ! 810: dupok(void) ! 811: { ! 812: if(ipc->reg == Nreg) ! 813: ipc->reg = DUPOK; ! 814: else ! 815: ipc->reg |= DUPOK; ! 816: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.