|
|
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.