|
|
1.1 root 1: /* INTERMEDIATE CODE GENERATION FOR S C JOHNSON C COMPILERS */
2: /* NEW VERSION USING BINARY POLISH POSTFIX INTERMEDIATE */
3: #if FAMILY != SCJ
4: WRONG put FULE !!!!
5: #endif
6:
7: #include "defs"
8: #include "scjdefs"
9:
10: #define FOUR 4
11: extern int ops2[];
12: extern int types2[];
13:
14: #define P2BUFFMAX 128
15: static long int p2buff[P2BUFFMAX];
16: static long int *p2bufp = &p2buff[0];
17: static long int *p2bufend = &p2buff[P2BUFFMAX];
18:
19:
20: puthead(s, class)
21: char *s;
22: int class;
23: {
24: char buff[100];
25: #if TARGET == VAX
26: if(s)
27: p2pass( sprintf(buff, "\t.globl\t_%s", s) );
28: #endif
29: /* put out fake copy of left bracket line, to be redone later */
30: if( ! headerdone )
31: {
32: #if FAMILY==SCJ && OUTPUT==BINARY
33: p2flush();
34: #endif
35: headoffset = ftell(textfile);
36: prhead(textfile);
37: headerdone = YES;
38: p2triple(P2STMT, (strlen(infname)+FOUR-1)/FOUR, 0);
39: p2str(infname);
40: #if TARGET == PDP11
41: /* fake jump to start the optimizer */
42: if(class != CLBLOCK)
43: putgoto( fudgelabel = newlabel() );
44: #endif
45: }
46: }
47:
48:
49:
50:
51:
52: /* It is necessary to precede each procedure with a "left bracket"
53: * line that tells pass 2 how many register variables and how
54: * much automatic space is required for the function. This compiler
55: * does not know how much automatic space is needed until the
56: * entire procedure has been processed. Therefore, "puthead"
57: * is called at the begining to record the current location in textfile,
58: * then to put out a placeholder left bracket line. This procedure
59: * repositions the file and rewrites that line, then puts the
60: * file pointer back to the end of the file.
61: */
62:
63: putbracket()
64: {
65: long int hereoffset;
66:
67: #if FAMILY==SCJ && OUTPUT==BINARY
68: p2flush();
69: #endif
70: hereoffset = ftell(textfile);
71: if(fseek(textfile, headoffset, 0))
72: fatal("fseek failed");
73: prhead(textfile);
74: if(fseek(textfile, hereoffset, 0))
75: fatal("fseek failed 2");
76: }
77:
78:
79:
80:
81: putrbrack(k)
82: int k;
83: {
84: p2op(P2RBRACKET, k);
85: }
86:
87:
88:
89: putnreg()
90: {
91: }
92:
93:
94:
95:
96:
97:
98: puteof()
99: {
100: p2op(P2EOF, 0);
101: p2flush();
102: }
103:
104:
105:
106: putstmt()
107: {
108: p2triple(P2STMT, 0, lineno);
109: }
110:
111:
112:
113:
114: /* put out code for if( ! p) goto l */
115: putif(p,l)
116: register expptr p;
117: int l;
118: {
119: register int k;
120:
121: if( ( k = (p = fixtype(p))->vtype) != TYLOGICAL)
122: {
123: if(k != TYERROR)
124: err("non-logical expression in IF statement");
125: frexpr(p);
126: }
127: else
128: {
129: putex1(p);
130: p2icon( (long int) l , P2INT);
131: p2op(P2CBRANCH, 0);
132: putstmt();
133: }
134: }
135:
136:
137:
138:
139:
140: /* put out code for goto l */
141: putgoto(label)
142: int label;
143: {
144: p2triple(P2GOTO, 1, label);
145: putstmt();
146: }
147:
148:
149: /* branch to address constant or integer variable */
150: putbranch(p)
151: register struct addrblock *p;
152: {
153: putex1(p);
154: p2op(P2GOTO, P2INT);
155: putstmt();
156: }
157:
158:
159:
160: /* put out label l: */
161: putlabel(label)
162: int label;
163: {
164: p2op(P2LABEL, label);
165: }
166:
167:
168:
169:
170: putexpr(p)
171: expptr p;
172: {
173: putex1(p);
174: putstmt();
175: }
176:
177:
178:
179:
180: putcmgo(index, nlab, labs)
181: expptr index;
182: int nlab;
183: struct labelblock *labs[];
184: {
185: int i, labarray, skiplabel;
186:
187: if(! ISINT(index->vtype) )
188: {
189: execerr("computed goto index must be integer", NULL);
190: return;
191: }
192:
193: #if TARGET == VAX
194: /* use special case instruction */
195: vaxgoto(index, nlab, labs);
196: #else
197: labarray = newlabel();
198: preven(ALIADDR);
199: prlabel(asmfile, labarray);
200: prcona(asmfile, (ftnint) (skiplabel = newlabel()) );
201: for(i = 0 ; i < nlab ; ++i)
202: if( labs[i] )
203: prcona(asmfile, (ftnint)(labs[i]->labelno) );
204: prcmgoto(index, nlab, skiplabel, labarray);
205: putlabel(skiplabel);
206: #endif
207: }
208:
209: putx(p)
210: expptr p;
211: {
212: struct addrblock *putcall(), *putcx1(), *realpart();
213: char *memname();
214: int opc;
215: int ncomma;
216: int type, k;
217:
218: switch(p->tag)
219: {
220: case TERROR:
221: free(p);
222: break;
223:
224: case TCONST:
225: switch(type = p->vtype)
226: {
227: case TYLOGICAL:
228: type = tyint;
229: case TYLONG:
230: case TYSHORT:
231: p2icon(p->const.ci, types2[type]);
232: free(p);
233: break;
234:
235: case TYADDR:
236: p2triple(P2ICON, 1, P2INT|P2PTR);
237: p2word(0L);
238: p2name(memname(STGCONST, (int) p->const.ci) );
239: free(p);
240: break;
241:
242: default:
243: putx( putconst(p) );
244: break;
245: }
246: break;
247:
248: case TEXPR:
249: switch(opc = p->opcode)
250: {
251: case OPCALL:
252: case OPCCALL:
253: if( ISCOMPLEX(p->vtype) )
254: putcxop(p);
255: else putcall(p);
256: break;
257:
258: case OPMIN:
259: case OPMAX:
260: putmnmx(p);
261: break;
262:
263:
264: case OPASSIGN:
265: if( ISCOMPLEX(p->leftp->vtype) || ISCOMPLEX(p->rightp->vtype) )
266: frexpr( putcxeq(p) );
267: else if( ISCHAR(p) )
268: putcheq(p);
269: else
270: goto putopp;
271: break;
272:
273: case OPEQ:
274: case OPNE:
275: if( ISCOMPLEX(p->leftp->vtype) || ISCOMPLEX(p->rightp->vtype) )
276: {
277: putcxcmp(p);
278: break;
279: }
280: case OPLT:
281: case OPLE:
282: case OPGT:
283: case OPGE:
284: if(ISCHAR(p->leftp))
285: putchcmp(p);
286: else
287: goto putopp;
288: break;
289:
290: case OPPOWER:
291: putpower(p);
292: break;
293:
294: case OPSTAR:
295: #if FAMILY == SCJ
296: /* m * (2**k) -> m<<k */
297: if(INT(p->leftp->vtype) && ISICON(p->rightp) &&
298: ( (k = log2(p->rightp->const.ci))>0) )
299: {
300: p->opcode = OPLSHIFT;
301: frexpr(p->rightp);
302: p->rightp = ICON(k);
303: goto putopp;
304: }
305: #endif
306:
307: case OPMOD:
308: goto putopp;
309: case OPPLUS:
310: case OPMINUS:
311: case OPSLASH:
312: case OPNEG:
313: if( ISCOMPLEX(p->vtype) )
314: putcxop(p);
315: else goto putopp;
316: break;
317:
318: case OPCONV:
319: if( ISCOMPLEX(p->vtype) )
320: putcxop(p);
321: else if( ISCOMPLEX(p->leftp->vtype) )
322: {
323: ncomma = 0;
324: putx( mkconv(p->vtype,
325: realpart(putcx1(p->leftp, &ncomma))));
326: putcomma(ncomma, p->vtype, NO);
327: free(p);
328: }
329: else goto putopp;
330: break;
331:
332: case OPNOT:
333: case OPOR:
334: case OPAND:
335: case OPEQV:
336: case OPNEQV:
337: case OPADDR:
338: case OPPLUSEQ:
339: case OPSTAREQ:
340: case OPCOMMA:
341: case OPQUEST:
342: case OPCOLON:
343: case OPBITOR:
344: case OPBITAND:
345: case OPBITXOR:
346: case OPBITNOT:
347: case OPLSHIFT:
348: case OPRSHIFT:
349: putopp:
350: putop(p);
351: break;
352:
353: default:
354: fatal1("putx: invalid opcode %d", opc);
355: }
356: break;
357:
358: case TADDR:
359: putaddr(p, YES);
360: break;
361:
362: default:
363: fatal1("putx: impossible tag %d", p->tag);
364: }
365: }
366:
367:
368:
369: LOCAL putop(p)
370: expptr p;
371: {
372: int k;
373: expptr lp, tp;
374: int pt, lt;
375: int comma;
376:
377: switch(p->opcode) /* check for special cases and rewrite */
378: {
379: case OPCONV:
380: pt = p->vtype;
381: lp = p->leftp;
382: lt = lp->vtype;
383: while(p->tag==TEXPR && p->opcode==OPCONV &&
384: ( (ISREAL(pt)&&ISREAL(lt)) ||
385: (INT(pt)&&(ONEOF(lt,MSKINT|MSKADDR|MSKCHAR|M(TYSUBR)))) ))
386: {
387: #if SZINT < SZLONG
388: if(lp->tag != TEXPR)
389: {
390: if(pt==TYINT && lt==TYLONG)
391: break;
392: if(lt==TYINT && pt==TYLONG)
393: break;
394: }
395: #endif
396: free(p);
397: p = lp;
398: pt = lt;
399: lp = p->leftp;
400: lt = lp->vtype;
401: }
402: if(p->tag==TEXPR && p->opcode==OPCONV)
403: break;
404: putx(p);
405: return;
406:
407: case OPADDR:
408: comma = NO;
409: lp = p->leftp;
410: if(lp->tag != TADDR)
411: {
412: tp = mktemp(lp->vtype, lp->vleng);
413: putx( mkexpr(OPASSIGN, cpexpr(tp), lp) );
414: lp = tp;
415: comma = YES;
416: }
417: putaddr(lp, NO);
418: if(comma)
419: putcomma(1, TYINT, NO);
420: free(p);
421: return;
422: }
423:
424: if( (k = ops2[p->opcode]) <= 0)
425: fatal1("putop: invalid opcode %d", p->opcode);
426: putx(p->leftp);
427: if(p->rightp)
428: putx(p->rightp);
429: p2op(k, types2[p->vtype]);
430:
431: if(p->vleng)
432: frexpr(p->vleng);
433: free(p);
434: }
435:
436: putforce(t, p)
437: int t;
438: expptr p;
439: {
440: p = mkconv(t, fixtype(p));
441: putx(p);
442: p2op(P2FORCE,
443: (t==TYSHORT ? P2SHORT : (t==TYLONG ? P2LONG : P2DREAL)) );
444: putstmt();
445: }
446:
447:
448:
449: LOCAL putpower(p)
450: expptr p;
451: {
452: expptr base;
453: struct addrblock *t1, *t2;
454: ftnint k;
455: int type;
456: int ncomma;
457:
458: if(!ISICON(p->rightp) || (k = p->rightp->const.ci)<2)
459: fatal("putpower: bad call");
460: base = p->leftp;
461: type = base->vtype;
462: t1 = mktemp(type, NULL);
463: t2 = NULL;
464: ncomma = 1;
465: putassign(cpexpr(t1), cpexpr(base) );
466:
467: for( ; (k&1)==0 && k>2 ; k>>=1 )
468: {
469: ++ncomma;
470: putsteq(t1, t1);
471: }
472:
473: if(k == 2)
474: putx( mkexpr(OPSTAR, cpexpr(t1), cpexpr(t1)) );
475: else
476: {
477: t2 = mktemp(type, NULL);
478: ++ncomma;
479: putassign(cpexpr(t2), cpexpr(t1));
480:
481: for(k>>=1 ; k>1 ; k>>=1)
482: {
483: ++ncomma;
484: putsteq(t1, t1);
485: if(k & 1)
486: {
487: ++ncomma;
488: putsteq(t2, t1);
489: }
490: }
491: putx( mkexpr(OPSTAR, cpexpr(t2),
492: mkexpr(OPSTAR, cpexpr(t1), cpexpr(t1)) ));
493: }
494: putcomma(ncomma, type, NO);
495: frexpr(t1);
496: if(t2)
497: frexpr(t2);
498: frexpr(p);
499: }
500:
501:
502:
503:
504: LOCAL struct addrblock *intdouble(p, ncommap)
505: struct addrblock *p;
506: int *ncommap;
507: {
508: register struct addrblock *t;
509:
510: t = mktemp(TYDREAL, NULL);
511: ++*ncommap;
512: putassign(cpexpr(t), p);
513: return(t);
514: }
515:
516:
517:
518:
519:
520: LOCAL putcxeq(p)
521: register struct exprblock *p;
522: {
523: register struct addrblock *lp, *rp;
524: int ncomma;
525:
526: ncomma = 0;
527: lp = putcx1(p->leftp, &ncomma);
528: rp = putcx1(p->rightp, &ncomma);
529: putassign(realpart(lp), realpart(rp));
530: if( ISCOMPLEX(p->vtype) )
531: {
532: ++ncomma;
533: putassign(imagpart(lp), imagpart(rp));
534: }
535: putcomma(ncomma, TYREAL, NO);
536: frexpr(rp);
537: free(p);
538: return(lp);
539: }
540:
541:
542:
543: LOCAL putcxop(p)
544: expptr p;
545: {
546: struct addrblock *putcx1();
547: int ncomma;
548:
549: ncomma = 0;
550: putaddr( putcx1(p, &ncomma), NO);
551: putcomma(ncomma, TYINT, NO);
552: }
553:
554:
555:
556: LOCAL struct addrblock *putcx1(p, ncommap)
557: register expptr p;
558: int *ncommap;
559: {
560: struct addrblock *q, *lp, *rp;
561: register struct addrblock *resp;
562: int opcode;
563: int ltype, rtype;
564:
565: if(p == NULL)
566: return(NULL);
567:
568: switch(p->tag)
569: {
570: case TCONST:
571: if( ISCOMPLEX(p->vtype) )
572: p = putconst(p);
573: return( p );
574:
575: case TADDR:
576: if( ! addressable(p) )
577: {
578: ++*ncommap;
579: resp = mktemp(tyint, NULL);
580: putassign( cpexpr(resp), p->memoffset );
581: p->memoffset = resp;
582: }
583: return( p );
584:
585: case TEXPR:
586: if( ISCOMPLEX(p->vtype) )
587: break;
588: ++*ncommap;
589: resp = mktemp(TYDREAL, NO);
590: putassign( cpexpr(resp), p);
591: return(resp);
592:
593: default:
594: fatal1("putcx1: bad tag %d", p->tag);
595: }
596:
597: opcode = p->opcode;
598: if(opcode==OPCALL || opcode==OPCCALL)
599: {
600: ++*ncommap;
601: return( putcall(p) );
602: }
603: else if(opcode == OPASSIGN)
604: {
605: ++*ncommap;
606: return( putcxeq(p) );
607: }
608: resp = mktemp(p->vtype, NULL);
609: if(lp = putcx1(p->leftp, ncommap) )
610: ltype = lp->vtype;
611: if(rp = putcx1(p->rightp, ncommap) )
612: rtype = rp->vtype;
613:
614: switch(opcode)
615: {
616: case OPCOMMA:
617: frexpr(resp);
618: resp = rp;
619: rp = NULL;
620: break;
621:
622: case OPNEG:
623: putassign( realpart(resp), mkexpr(OPNEG, realpart(lp), NULL) );
624: putassign( imagpart(resp), mkexpr(OPNEG, imagpart(lp), NULL) );
625: *ncommap += 2;
626: break;
627:
628: case OPPLUS:
629: case OPMINUS:
630: putassign( realpart(resp), mkexpr(opcode, realpart(lp), realpart(rp) ));
631: if(rtype < TYCOMPLEX)
632: putassign( imagpart(resp), imagpart(lp) );
633: else if(ltype < TYCOMPLEX)
634: {
635: if(opcode == OPPLUS)
636: putassign( imagpart(resp), imagpart(rp) );
637: else putassign( imagpart(resp), mkexpr(OPNEG, imagpart(rp), NULL) );
638: }
639: else
640: putassign( imagpart(resp), mkexpr(opcode, imagpart(lp), imagpart(rp) ));
641:
642: *ncommap += 2;
643: break;
644:
645: case OPSTAR:
646: if(ltype < TYCOMPLEX)
647: {
648: if( ISINT(ltype) )
649: lp = intdouble(lp, ncommap);
650: putassign( realpart(resp), mkexpr(OPSTAR, cpexpr(lp), realpart(rp) ));
651: putassign( imagpart(resp), mkexpr(OPSTAR, cpexpr(lp), imagpart(rp) ));
652: }
653: else if(rtype < TYCOMPLEX)
654: {
655: if( ISINT(rtype) )
656: rp = intdouble(rp, ncommap);
657: putassign( realpart(resp), mkexpr(OPSTAR, cpexpr(rp), realpart(lp) ));
658: putassign( imagpart(resp), mkexpr(OPSTAR, cpexpr(rp), imagpart(lp) ));
659: }
660: else {
661: putassign( realpart(resp), mkexpr(OPMINUS,
662: mkexpr(OPSTAR, realpart(lp), realpart(rp)),
663: mkexpr(OPSTAR, imagpart(lp), imagpart(rp)) ));
664: putassign( imagpart(resp), mkexpr(OPPLUS,
665: mkexpr(OPSTAR, realpart(lp), imagpart(rp)),
666: mkexpr(OPSTAR, imagpart(lp), realpart(rp)) ));
667: }
668: *ncommap += 2;
669: break;
670:
671: case OPSLASH:
672: /* fixexpr has already replaced all divisions
673: * by a complex by a function call
674: */
675: if( ISINT(rtype) )
676: rp = intdouble(rp, ncommap);
677: putassign( realpart(resp), mkexpr(OPSLASH, realpart(lp), cpexpr(rp)) );
678: putassign( imagpart(resp), mkexpr(OPSLASH, imagpart(lp), cpexpr(rp)) );
679: *ncommap += 2;
680: break;
681:
682: case OPCONV:
683: putassign( realpart(resp), realpart(lp) );
684: if( ISCOMPLEX(lp->vtype) )
685: q = imagpart(lp);
686: else if(rp != NULL)
687: q = realpart(rp);
688: else
689: q = mkrealcon(TYDREAL, 0.0);
690: putassign( imagpart(resp), q);
691: *ncommap += 2;
692: break;
693:
694: default:
695: fatal1("putcx1 of invalid opcode %d", opcode);
696: }
697:
698: frexpr(lp);
699: frexpr(rp);
700: free(p);
701: return(resp);
702: }
703:
704:
705:
706:
707: LOCAL putcxcmp(p)
708: register struct exprblock *p;
709: {
710: int opcode;
711: int ncomma;
712: register struct addrblock *lp, *rp;
713: struct exprblock *q;
714:
715: ncomma = 0;
716: opcode = p->opcode;
717: lp = putcx1(p->leftp, &ncomma);
718: rp = putcx1(p->rightp, &ncomma);
719:
720: q = mkexpr( opcode==OPEQ ? OPAND : OPOR ,
721: mkexpr(opcode, realpart(lp), realpart(rp)),
722: mkexpr(opcode, imagpart(lp), imagpart(rp)) );
723: putx( fixexpr(q) );
724: putcomma(ncomma, TYINT, NO);
725:
726: free(lp);
727: free(rp);
728: free(p);
729: }
730:
731: LOCAL struct addrblock *putch1(p, ncommap)
732: register expptr p;
733: int * ncommap;
734: {
735: register struct addrblock *t;
736: struct addrblock *mktemp(), *putconst();
737:
738: switch(p->tag)
739: {
740: case TCONST:
741: return( putconst(p) );
742:
743: case TADDR:
744: return(p);
745:
746: case TEXPR:
747: ++*ncommap;
748:
749: switch(p->opcode)
750: {
751: case OPCALL:
752: case OPCCALL:
753: t = putcall(p);
754: break;
755:
756: case OPCONCAT:
757: t = mktemp(TYCHAR, cpexpr(p->vleng) );
758: putcat( cpexpr(t), p );
759: break;
760:
761: case OPCONV:
762: if(!ISICON(p->vleng) || p->vleng->const.ci!=1
763: || ! INT(p->leftp->vtype) )
764: fatal("putch1: bad character conversion");
765: t = mktemp(TYCHAR, ICON(1) );
766: putop( mkexpr(OPASSIGN, cpexpr(t), p) );
767: break;
768: default:
769: fatal1("putch1: invalid opcode %d", p->opcode);
770: }
771: return(t);
772:
773: default:
774: fatal1("putch1: bad tag %d", p->tag);
775: }
776: /* NOTREACHED */
777: }
778:
779:
780:
781:
782: LOCAL putchop(p)
783: expptr p;
784: {
785: int ncomma;
786:
787: ncomma = 0;
788: putaddr( putch1(p, &ncomma) , NO );
789: putcomma(ncomma, TYCHAR, YES);
790: }
791:
792:
793:
794:
795: LOCAL putcheq(p)
796: register struct exprblock *p;
797: {
798: int ncomma;
799:
800: ncomma = 0;
801: if( p->rightp->tag==TEXPR && p->rightp->opcode==OPCONCAT )
802: putcat(p->leftp, p->rightp);
803: else if( ISONE(p->leftp->vleng) && ISONE(p->rightp->vleng) )
804: {
805: putaddr( putch1(p->leftp, &ncomma) , YES );
806: putaddr( putch1(p->rightp, &ncomma) , YES );
807: putcomma(ncomma, TYINT, NO);
808: p2op(P2ASSIGN, P2CHAR);
809: }
810: else
811: {
812: putx( call2(TYINT, "s_copy", p->leftp, p->rightp) );
813: putcomma(ncomma, TYINT, NO);
814: }
815:
816: frexpr(p->vleng);
817: free(p);
818: }
819:
820:
821:
822:
823: LOCAL putchcmp(p)
824: register struct exprblock *p;
825: {
826: int ncomma;
827:
828: ncomma = 0;
829: if(ISONE(p->leftp->vleng) && ISONE(p->rightp->vleng) )
830: {
831: putaddr( putch1(p->leftp, &ncomma) , YES );
832: putaddr( putch1(p->rightp, &ncomma) , YES );
833: p2op(ops2[p->opcode], P2CHAR);
834: free(p);
835: putcomma(ncomma, TYINT, NO);
836: }
837: else
838: {
839: p->leftp = call2(TYINT,"s_cmp", p->leftp, p->rightp);
840: p->rightp = ICON(0);
841: putop(p);
842: }
843: }
844:
845:
846:
847:
848:
849: LOCAL putcat(lhs, rhs)
850: register struct addrblock *lhs;
851: register expptr rhs;
852: {
853: int n, ncomma;
854: struct addrblock *lp, *cp;
855:
856: ncomma = 0;
857: n = ncat(rhs);
858: lp = mktmpn(n, TYLENG, NULL);
859: cp = mktmpn(n, TYADDR, NULL);
860:
861: n = 0;
862: putct1(rhs, lp, cp, &n, &ncomma);
863:
864: putx( call4(TYSUBR, "s_cat", lhs, cp, lp, mkconv(TYLONG, ICON(n)) ) );
865: putcomma(ncomma, TYINT, NO);
866: }
867:
868:
869:
870:
871:
872: LOCAL ncat(p)
873: register expptr p;
874: {
875: if(p->tag==TEXPR && p->opcode==OPCONCAT)
876: return( ncat(p->leftp) + ncat(p->rightp) );
877: else return(1);
878: }
879:
880:
881:
882:
883: LOCAL putct1(q, lp, cp, ip, ncommap)
884: register expptr q;
885: register struct addrblock *lp, *cp;
886: int *ip, *ncommap;
887: {
888: int i;
889: struct addrblock *lp1, *cp1;
890:
891: if(q->tag==TEXPR && q->opcode==OPCONCAT)
892: {
893: putct1(q->leftp, lp, cp, ip, ncommap);
894: putct1(q->rightp, lp, cp , ip, ncommap);
895: frexpr(q->vleng);
896: free(q);
897: }
898: else
899: {
900: i = (*ip)++;
901: lp1 = cpexpr(lp);
902: lp1->memoffset = mkexpr(OPPLUS, lp1->memoffset, ICON(i*SZLENG));
903: cp1 = cpexpr(cp);
904: cp1->memoffset = mkexpr(OPPLUS, cp1->memoffset, ICON(i*SZADDR));
905: putassign( lp1, cpexpr(q->vleng) );
906: putassign( cp1, addrof(putch1(q,ncommap)) );
907: *ncommap += 2;
908: }
909: }
910:
911: LOCAL putaddr(p, indir)
912: register struct addrblock *p;
913: int indir;
914: {
915: int type, type2, funct;
916: ftnint offset, simoffset();
917: expptr offp, shorten();
918:
919: type = p->vtype;
920: type2 = types2[type];
921: funct = (p->vclass==CLPROC ? P2FUNCT<<2 : 0);
922:
923: offp = (p->memoffset ? cpexpr(p->memoffset) : NULL);
924:
925:
926: #if (FUDGEOFFSET != 1)
927: if(offp)
928: offp = mkexpr(OPSTAR, ICON(FUDGEOFFSET), offp);
929: #endif
930:
931: offset = simoffset( &offp );
932: #if SZINT < SZLONG
933: if(offp)
934: if(shortsubs)
935: offp = shorten(offp);
936: else
937: offp = mkconv(TYINT, offp);
938: #else
939: if(offp)
940: offp = mkconv(TYINT, offp);
941: #endif
942:
943: switch(p->vstg)
944: {
945: case STGAUTO:
946: if(indir && !offp)
947: {
948: p2oreg(offset, AUTOREG, type2);
949: break;
950: }
951:
952: if(!indir && !offp && !offset)
953: {
954: p2reg(AUTOREG, type2 | P2PTR);
955: break;
956: }
957:
958: p2reg(AUTOREG, type2 | P2PTR);
959: if(offp)
960: {
961: putx(offp);
962: if(offset)
963: p2icon(offset, P2INT);
964: }
965: else
966: p2icon(offset, P2INT);
967: if(offp && offset)
968: p2op(P2PLUS, type2 | P2PTR);
969: p2op(P2PLUS, type2 | P2PTR);
970: if(indir)
971: p2op(P2INDIRECT, type2);
972: break;
973:
974: case STGARG:
975: p2oreg(
976: #ifdef ARGOFFSET
977: ARGOFFSET +
978: #endif
979: (ftnint) (FUDGEOFFSET*p->memno),
980: ARGREG, type2 | P2PTR | funct );
981:
982: if(offp)
983: putx(offp);
984: if(offset)
985: p2icon(offset, P2INT);
986: if(offp && offset)
987: p2op(P2PLUS, type2 | P2PTR);
988: if(offp || offset)
989: p2op(P2PLUS, type2 | P2PTR);
990: if(indir)
991: p2op(P2INDIRECT, type2);
992: break;
993:
994: case STGLENG:
995: if(indir)
996: {
997: p2oreg(
998: #ifdef ARGOFFSET
999: ARGOFFSET +
1000: #endif
1001: (ftnint) (FUDGEOFFSET*p->memno),
1002: ARGREG, type2 | P2PTR );
1003: }
1004: else {
1005: p2reg(ARGREG, type2 | P2PTR );
1006: p2icon(
1007: #ifdef ARGOFFSET
1008: ARGOFFSET +
1009: #endif
1010: (ftnint) (FUDGEOFFSET*p->memno), P2INT);
1011: p2op(P2PLUS, type2 | P2PTR );
1012: }
1013: break;
1014:
1015:
1016: case STGBSS:
1017: case STGINIT:
1018: case STGEXT:
1019: case STGCOMMON:
1020: case STGEQUIV:
1021: case STGCONST:
1022: if(offp)
1023: {
1024: putx(offp);
1025: putmem(p, P2ICON, offset);
1026: p2op(P2PLUS, type2 | P2PTR);
1027: if(indir)
1028: p2op(P2INDIRECT, type2);
1029: }
1030: else
1031: putmem(p, (indir ? P2NAME : P2ICON), offset);
1032:
1033: break;
1034:
1035: case STGREG:
1036: if(indir)
1037: p2reg(p->memno, type2);
1038: else
1039: fatal("attempt to take address of a register");
1040: break;
1041:
1042: default:
1043: fatal1("putaddr: invalid vstg %d", p->vstg);
1044: }
1045: frexpr(p);
1046: }
1047:
1048:
1049:
1050:
1051: LOCAL putmem(p, class, offset)
1052: expptr p;
1053: int class;
1054: ftnint offset;
1055: {
1056: int type2;
1057: int funct;
1058: char *name, *memname();
1059:
1060: funct = (p->vclass==CLPROC ? P2FUNCT<<2 : 0);
1061: type2 = types2[p->vtype];
1062: if(p->vclass == CLPROC)
1063: type2 |= (P2FUNCT<<2);
1064: name = memname(p->vstg, p->memno);
1065: if(class == P2ICON)
1066: {
1067: p2triple(P2ICON, name[0]!='\0', type2|P2PTR);
1068: p2word(offset);
1069: if(name[0])
1070: p2name(name);
1071: }
1072: else
1073: {
1074: p2triple(P2NAME, offset!=0, type2);
1075: if(offset != 0)
1076: p2word(offset);
1077: p2name(name);
1078: }
1079: }
1080:
1081:
1082:
1083: LOCAL struct addrblock *putcall(p)
1084: struct exprblock *p;
1085: {
1086: chainp arglist, charsp, cp;
1087: int n, first;
1088: struct addrblock *t;
1089: struct exprblock *q;
1090: struct exprblock *fval;
1091: int type, type2, ctype, indir;
1092:
1093: type2 = types2[type = p->vtype];
1094: charsp = NULL;
1095: indir = (p->opcode == OPCCALL);
1096: n = 0;
1097: first = YES;
1098:
1099: if(p->rightp)
1100: {
1101: arglist = p->rightp->listp;
1102: free(p->rightp);
1103: }
1104: else
1105: arglist = NULL;
1106:
1107: for(cp = arglist ; cp ; cp = cp->nextp)
1108: if(indir)
1109: ++n;
1110: else {
1111: q = cp->datap;
1112: if(q->tag == TCONST)
1113: cp->datap = q = putconst(q);
1114: if( ISCHAR(q) )
1115: {
1116: charsp = hookup(charsp, mkchain(cpexpr(q->vleng), 0) );
1117: n += 2;
1118: }
1119: else if(q->vclass == CLPROC)
1120: {
1121: charsp = hookup(charsp, mkchain( ICON(0) , 0));
1122: n += 2;
1123: }
1124: else
1125: n += 1;
1126: }
1127:
1128: if(type == TYCHAR)
1129: {
1130: if( ISICON(p->vleng) )
1131: {
1132: fval = mktemp(TYCHAR, p->vleng);
1133: n += 2;
1134: }
1135: else {
1136: err("adjustable character function");
1137: return;
1138: }
1139: }
1140: else if( ISCOMPLEX(type) )
1141: {
1142: fval = mktemp(type, NULL);
1143: n += 1;
1144: }
1145: else
1146: fval = NULL;
1147:
1148: ctype = (fval ? P2INT : type2);
1149: putaddr(p->leftp, NO);
1150:
1151: if(fval)
1152: {
1153: first = NO;
1154: putaddr( cpexpr(fval), NO);
1155: if(type==TYCHAR)
1156: {
1157: putx( mkconv(TYLENG,p->vleng) );
1158: p2op(P2LISTOP, type2);
1159: }
1160: }
1161:
1162: for(cp = arglist ; cp ; cp = cp->nextp)
1163: {
1164: q = cp->datap;
1165: if(q->tag==TADDR && (indir || q->vstg!=STGREG) )
1166: putaddr(q, indir && q->vtype!=TYCHAR);
1167: else if( ISCOMPLEX(q->vtype) )
1168: putcxop(q);
1169: else if (ISCHAR(q) )
1170: putchop(q);
1171: else if( ! ISERROR(q) )
1172: {
1173: if(indir)
1174: putx(q);
1175: else {
1176: t = mktemp(q->vtype, q->vleng);
1177: putassign( cpexpr(t), q );
1178: putaddr(t, NO);
1179: putcomma(1, q->vtype, YES);
1180: }
1181: }
1182: if(first)
1183: first = NO;
1184: else
1185: p2op(P2LISTOP, type2);
1186: }
1187:
1188: if(arglist)
1189: frchain(&arglist);
1190: for(cp = charsp ; cp ; cp = cp->nextp)
1191: {
1192: putx( mkconv(TYLENG,cp->datap) );
1193: p2op(P2LISTOP, type2);
1194: }
1195: frchain(&charsp);
1196: p2op(n>0 ? P2CALL : P2CALL0 , ctype);
1197: free(p);
1198: return(fval);
1199: }
1200:
1201:
1202:
1203: LOCAL putmnmx(p)
1204: register struct exprblock *p;
1205: {
1206: int op, type;
1207: int ncomma;
1208: struct exprblock *qp;
1209: chainp p0, p1;
1210: struct addrblock *sp, *tp;
1211:
1212: type = p->vtype;
1213: op = (p->opcode==OPMIN ? OPLT : OPGT );
1214: p0 = p->leftp->listp;
1215: free(p->leftp);
1216: free(p);
1217:
1218: sp = mktemp(type, NULL);
1219: tp = mktemp(type, NULL);
1220: qp = mkexpr(OPCOLON, cpexpr(tp), cpexpr(sp));
1221: qp = mkexpr(OPQUEST, mkexpr(op, cpexpr(tp),cpexpr(sp)), qp);
1222: qp = fixexpr(qp);
1223:
1224: ncomma = 1;
1225: putassign( cpexpr(sp), p0->datap );
1226:
1227: for(p1 = p0->nextp ; p1 ; p1 = p1->nextp)
1228: {
1229: ++ncomma;
1230: putassign( cpexpr(tp), p1->datap );
1231: if(p1->nextp)
1232: {
1233: ++ncomma;
1234: putassign( cpexpr(sp), cpexpr(qp) );
1235: }
1236: else
1237: putx(qp);
1238: }
1239:
1240: putcomma(ncomma, type, NO);
1241: frtemp(sp);
1242: frtemp(tp);
1243: frchain( &p0 );
1244: }
1245:
1246:
1247:
1248:
1249: LOCAL putcomma(n, type, indir)
1250: int n, type, indir;
1251: {
1252: type = types2[type];
1253: if(indir)
1254: type |= P2PTR;
1255: while(--n >= 0)
1256: p2op(P2COMOP, type);
1257: }
1258:
1259:
1260:
1261:
1262: ftnint simoffset(p0)
1263: expptr *p0;
1264: {
1265: ftnint offset, prod;
1266: register expptr p, lp, rp;
1267:
1268: offset = 0;
1269: p = *p0;
1270: if(p == NULL)
1271: return(0);
1272:
1273: if( ! ISINT(p->vtype) )
1274: return(0);
1275:
1276: if(p->tag==TEXPR && p->opcode==OPSTAR)
1277: {
1278: lp = p->leftp;
1279: rp = p->rightp;
1280: if(ISICON(rp) && lp->tag==TEXPR && lp->opcode==OPPLUS && ISICON(lp->rightp))
1281: {
1282: p->opcode = OPPLUS;
1283: lp->opcode = OPSTAR;
1284: prod = rp->const.ci * lp->rightp->const.ci;
1285: lp->rightp->const.ci = rp->const.ci;
1286: rp->const.ci = prod;
1287: }
1288: }
1289:
1290: if(p->tag==TEXPR && p->opcode==OPPLUS && ISICON(p->rightp))
1291: {
1292: rp = p->rightp;
1293: lp = p->leftp;
1294: offset += rp->const.ci;
1295: frexpr(rp);
1296: free(p);
1297: *p0 = lp;
1298: }
1299:
1300: if(p->tag == TCONST)
1301: {
1302: offset += p->const.ci;
1303: frexpr(p);
1304: *p0 = NULL;
1305: }
1306:
1307: return(offset);
1308: }
1309:
1310:
1311:
1312:
1313:
1314: p2op(op, type)
1315: int op, type;
1316: {
1317: p2triple(op, 0, type);
1318: }
1319:
1320: p2icon(offset, type)
1321: ftnint offset;
1322: int type;
1323: {
1324: p2triple(P2ICON, 0, type);
1325: p2word(offset);
1326: }
1327:
1328:
1329:
1330:
1331: p2oreg(offset, reg, type)
1332: ftnint offset;
1333: int reg, type;
1334: {
1335: p2triple(P2OREG, reg, type);
1336: p2word(offset);
1337: p2name("");
1338: }
1339:
1340:
1341:
1342:
1343: p2reg(reg, type)
1344: int reg, type;
1345: {
1346: p2triple(P2REG, reg, type);
1347: }
1348:
1349:
1350:
1351: p2pass(s)
1352: char *s;
1353: {
1354: p2triple(P2PASS, (strlen(s) + FOUR-1)/FOUR, 0);
1355: p2str(s);
1356: }
1357:
1358:
1359:
1360:
1361: p2str(s)
1362: register char *s;
1363: {
1364: union { long int word; char str[FOUR]; } u;
1365: register int i;
1366:
1367: i = 0;
1368: u.word = 0;
1369: while(*s)
1370: {
1371: u.str[i++] = *s++;
1372: if(i == FOUR)
1373: {
1374: p2word(u.word);
1375: u.word = 0;
1376: i = 0;
1377: }
1378: }
1379: if(i > 0)
1380: p2word(u.word);
1381: }
1382:
1383:
1384:
1385:
1386: p2triple(op, var, type)
1387: int op, var, type;
1388: {
1389: register long word;
1390: word = op | (var<<8);
1391: word |= ( (long int) type) <<16;
1392: p2word(word);
1393: }
1394:
1395:
1396:
1397:
1398: p2name(s)
1399: char *s;
1400: {
1401: int i;
1402: union { long int word[2]; char str[8]; } u;
1403:
1404: u.word[0] = u.word[1] = 0;
1405: for(i = 0 ; i<8 && *s ; ++i)
1406: u.str[i] = *s++;
1407: p2word(u.word[0]);
1408: p2word(u.word[1]);
1409: }
1410:
1411:
1412:
1413:
1414: p2word(w)
1415: long int w;
1416: {
1417: *p2bufp++ = w;
1418: if(p2bufp >= p2bufend)
1419: p2flush();
1420: }
1421:
1422:
1423:
1424: p2flush()
1425: {
1426: if(p2bufp > p2buff)
1427: write(fileno(textfile), p2buff, (p2bufp-p2buff)*sizeof(long int));
1428: p2bufp = p2buff;
1429: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.