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