|
|
1.1 root 1: /*
2: * Copyright (c) 1980 Regents of the University of California.
3: * All rights reserved. The Berkeley software License Agreement
4: * specifies the terms and conditions for redistribution.
5: */
6:
7: #ifndef lint
8: static char sccsid[] = "@(#)putpcc.c 5.1 (Berkeley) 6/7/85";
9: #endif not lint
10:
11: /*
12: * putpcc.c
13: *
14: * Intermediate code generation for S. C. Johnson C compilers
15: * New version using binary polish postfix intermediate
16: *
17: * University of Utah CS Dept modification history:
18: *
19: * $Header: putpcc.c,v 3.2 85/03/25 09:35:57 root Exp $
20: * $Log: putpcc.c,v $
21: * Revision 3.2 85/03/25 09:35:57 root
22: * fseek return -1 on error.
23: *
24: * Revision 3.1 85/02/27 19:06:55 donn
25: * Changed to use pcc.h instead of pccdefs.h.
26: *
27: * Revision 2.12 85/02/22 01:05:54 donn
28: * putaddr() didn't know about intrinsic functions...
29: *
30: * Revision 2.11 84/11/28 21:28:49 donn
31: * Hacked putop() to handle any character expression being converted to int,
32: * not just function calls. Previously it bombed on concatenations.
33: *
34: * Revision 2.10 84/11/01 22:07:07 donn
35: * Yet another try at getting putop() to work right. It appears that the
36: * second pass can't abide certain explicit conversions (e.g. short to long)
37: * so the conversion code in putop() tries to remove them. I think this
38: * version (finally) works.
39: *
40: * Revision 2.9 84/10/29 02:30:57 donn
41: * Earlier fix to putop() for conversions was insufficient -- we NEVER want to
42: * see the type of the left operand of the thing left over from stripping off
43: * conversions...
44: *
45: * Revision 2.8 84/09/18 03:09:21 donn
46: * Fixed bug in putop() where the left operand of an addrblock was being
47: * extracted... This caused an extremely obscure conversion error when
48: * an array of longs was subscripted by a short.
49: *
50: * Revision 2.7 84/08/19 20:10:19 donn
51: * Removed stuff in putbranch that treats STGARG parameters specially -- the
52: * bug in the code generation pass that motivated it has been fixed.
53: *
54: * Revision 2.6 84/08/07 21:32:23 donn
55: * Bumped the size of the buffer for the intermediate code file from 0.5K
56: * to 4K on a VAX.
57: *
58: * Revision 2.5 84/08/04 20:26:43 donn
59: * Fixed a goof in the new putbranch() -- it now calls mkaltemp instead of
60: * mktemp(). Correction due to Jerry Berkman.
61: *
62: * Revision 2.4 84/07/24 19:07:15 donn
63: * Fixed bug reported by Craig Leres in which putmnmx() mistakenly assumed
64: * that mkaltemp() returns tempblocks, and tried to free them with frtemp().
65: *
66: * Revision 2.3 84/07/19 17:22:09 donn
67: * Changed putch1() so that OPPAREN expressions of type CHARACTER are legal.
68: *
69: * Revision 2.2 84/07/19 12:30:38 donn
70: * Fixed a type clash in Bob Corbett's new putbranch().
71: *
72: * Revision 2.1 84/07/19 12:04:27 donn
73: * Changed comment headers for UofU.
74: *
75: * Revision 1.8 84/07/19 11:38:23 donn
76: * Replaced putbranch() routine so that you can ASSIGN into argument variables.
77: * The code is from Bob Corbett, donated by Jerry Berkman.
78: *
79: * Revision 1.7 84/05/31 00:48:32 donn
80: * Fixed an extremely obscure bug dealing with the comparison of CHARACTER*1
81: * expressions -- a foulup in the order of COMOP and the comparison caused
82: * one operand of the comparison to be garbage.
83: *
84: * Revision 1.6 84/04/16 09:54:19 donn
85: * Backed out earlier fix for bug where items in the argtemplist were
86: * (incorrectly) being given away; this is now fixed in mkargtemp().
87: *
88: * Revision 1.5 84/03/23 22:49:48 donn
89: * Took out the initialization of the subroutine argument temporary list in
90: * putcall() -- it needs to be done once per statement instead of once per call.
91: *
92: * Revision 1.4 84/03/01 06:48:05 donn
93: * Fixed bug in Bob Corbett's code for argument temporaries that caused an
94: * addrblock to get thrown out inadvertently when it was needed for recycling
95: * purposes later on.
96: *
97: * Revision 1.3 84/02/26 06:32:38 donn
98: * Added Berkeley changes to move data definitions around and reduce offsets.
99: *
100: * Revision 1.2 84/02/26 06:27:45 donn
101: * Added code to catch TTEMP values passed to putx().
102: *
103: */
104:
105: #if FAMILY != PCC
106: WRONG put FILE !!!!
107: #endif
108:
109: #include "defs.h"
110: #include <pcc.h>
111:
112: Addrp putcall(), putcxeq(), putcx1(), realpart();
113: expptr imagpart();
114: ftnint lencat();
115:
116: #define FOUR 4
117: extern int ops2[];
118: extern int types2[];
119:
120: #if HERE==VAX || HERE == TAHOE
121: #define PCC_BUFFMAX 1024
122: #else
123: #define PCC_BUFFMAX 128
124: #endif
125: static long int p2buff[PCC_BUFFMAX];
126: static long int *p2bufp = &p2buff[0];
127: static long int *p2bufend = &p2buff[PCC_BUFFMAX];
128:
129:
130: puthead(s, class)
131: char *s;
132: int class;
133: {
134: char buff[100];
135: #if TARGET == VAX || TARGET == TAHOE
136: if(s)
137: p2ps("\t.globl\t_%s", s);
138: #endif
139: /* put out fake copy of left bracket line, to be redone later */
140: if( ! headerdone )
141: {
142: #if FAMILY == PCC
143: p2flush();
144: #endif
145: headoffset = ftell(textfile);
146: prhead(textfile);
147: headerdone = YES;
148: p2triple(PCCF_FEXPR, (strlen(infname)+ALILONG-1)/ALILONG, 0);
149: p2str(infname);
150: #if TARGET == PDP11
151: /* fake jump to start the optimizer */
152: if(class != CLBLOCK)
153: putgoto( fudgelabel = newlabel() );
154: #endif
155:
156: #if TARGET == VAX || TARGET == TAHOE
157: /* jump from top to bottom */
158: if(s!=CNULL && class!=CLBLOCK)
159: {
160: int proflab = newlabel();
161: p2pass("\t.align\t1");
162: p2ps("_%s:", s);
163: p2pi("\t.word\tLWM%d", procno);
164: prsave(proflab);
165: #if TARGET == VAX
166: p2pi("\tjbr\tL%d",
167: #else
168: putgoto(
169: #endif
170: fudgelabel = newlabel());
171: }
172: #endif
173: }
174: }
175:
176:
177:
178:
179:
180: /* It is necessary to precede each procedure with a "left bracket"
181: * line that tells pass 2 how many register variables and how
182: * much automatic space is required for the function. This compiler
183: * does not know how much automatic space is needed until the
184: * entire procedure has been processed. Therefore, "puthead"
185: * is called at the begining to record the current location in textfile,
186: * then to put out a placeholder left bracket line. This procedure
187: * repositions the file and rewrites that line, then puts the
188: * file pointer back to the end of the file.
189: */
190:
191: putbracket()
192: {
193: long int hereoffset;
194:
195: #if FAMILY == PCC
196: p2flush();
197: #endif
198: hereoffset = ftell(textfile);
199: if(fseek(textfile, headoffset, 0) == -1)
200: fatal("fseek failed");
201: prhead(textfile);
202: if(fseek(textfile, hereoffset, 0) == -1)
203: fatal("fseek failed 2");
204: }
205:
206:
207:
208:
209: putrbrack(k)
210: int k;
211: {
212: p2op(PCCF_FRBRAC, k);
213: }
214:
215:
216:
217: putnreg()
218: {
219: }
220:
221:
222:
223:
224:
225:
226: puteof()
227: {
228: p2op(PCCF_FEOF, 0);
229: p2flush();
230: }
231:
232:
233:
234: putstmt()
235: {
236: p2triple(PCCF_FEXPR, 0, lineno);
237: }
238:
239:
240:
241:
242: /* put out code for if( ! p) goto l */
243: putif(p,l)
244: register expptr p;
245: int l;
246: {
247: register int k;
248:
249: if( ( k = (p = fixtype(p))->headblock.vtype) != TYLOGICAL)
250: {
251: if(k != TYERROR)
252: err("non-logical expression in IF statement");
253: frexpr(p);
254: }
255: else
256: {
257: putex1(p);
258: p2icon( (long int) l , PCCT_INT);
259: p2op(PCC_CBRANCH, 0);
260: putstmt();
261: }
262: }
263:
264:
265:
266:
267:
268: /* put out code for goto l */
269: putgoto(label)
270: int label;
271: {
272: p2triple(PCC_GOTO, 1, label);
273: putstmt();
274: }
275:
276:
277: /* branch to address constant or integer variable */
278: putbranch(p)
279: register Addrp p;
280: {
281: putex1((expptr) p);
282: p2op(PCC_GOTO, PCCT_INT);
283: putstmt();
284: }
285:
286:
287:
288: /* put out label l: */
289: putlabel(label)
290: int label;
291: {
292: p2op(PCCF_FLABEL, label);
293: }
294:
295:
296:
297:
298: putexpr(p)
299: expptr p;
300: {
301: putex1(p);
302: putstmt();
303: }
304:
305:
306:
307:
308: putcmgo(index, nlab, labs)
309: expptr index;
310: int nlab;
311: struct Labelblock *labs[];
312: {
313: int i, labarray, skiplabel;
314:
315: if(! ISINT(index->headblock.vtype) )
316: {
317: execerr("computed goto index must be integer", CNULL);
318: return;
319: }
320:
321: #if TARGET == VAX || TARGET == TAHOE
322: /* use special case instruction */
323: casegoto(index, nlab, labs);
324: #else
325: labarray = newlabel();
326: preven(ALIADDR);
327: prlabel(asmfile, labarray);
328: prcona(asmfile, (ftnint) (skiplabel = newlabel()) );
329: for(i = 0 ; i < nlab ; ++i)
330: if( labs[i] )
331: prcona(asmfile, (ftnint)(labs[i]->labelno) );
332: prcmgoto(index, nlab, skiplabel, labarray);
333: putlabel(skiplabel);
334: #endif
335: }
336:
337: putx(p)
338: expptr p;
339: {
340: char *memname();
341: int opc;
342: int ncomma;
343: int type, k;
344:
345: if (!p)
346: return;
347:
348: switch(p->tag)
349: {
350: case TERROR:
351: free( (charptr) p );
352: break;
353:
354: case TCONST:
355: switch(type = p->constblock.vtype)
356: {
357: case TYLOGICAL:
358: type = tyint;
359: case TYLONG:
360: case TYSHORT:
361: p2icon(p->constblock.const.ci, types2[type]);
362: free( (charptr) p );
363: break;
364:
365: case TYADDR:
366: p2triple(PCC_ICON, 1, PCCT_INT|PCCTM_PTR);
367: p2word(0L);
368: p2name(memname(STGCONST,
369: (int) p->constblock.const.ci) );
370: free( (charptr) p );
371: break;
372:
373: default:
374: putx( putconst(p) );
375: break;
376: }
377: break;
378:
379: case TEXPR:
380: switch(opc = p->exprblock.opcode)
381: {
382: case OPCALL:
383: case OPCCALL:
384: if( ISCOMPLEX(p->exprblock.vtype) )
385: putcxop(p);
386: else putcall(p);
387: break;
388:
389: case OPMIN:
390: case OPMAX:
391: putmnmx(p);
392: break;
393:
394:
395: case OPASSIGN:
396: if(ISCOMPLEX(p->exprblock.leftp->headblock.vtype)
397: || ISCOMPLEX(p->exprblock.rightp->headblock.vtype) )
398: frexpr( putcxeq(p) );
399: else if( ISCHAR(p) )
400: putcheq(p);
401: else
402: goto putopp;
403: break;
404:
405: case OPEQ:
406: case OPNE:
407: if( ISCOMPLEX(p->exprblock.leftp->headblock.vtype) ||
408: ISCOMPLEX(p->exprblock.rightp->headblock.vtype) )
409: {
410: putcxcmp(p);
411: break;
412: }
413: case OPLT:
414: case OPLE:
415: case OPGT:
416: case OPGE:
417: if(ISCHAR(p->exprblock.leftp))
418: {
419: putchcmp(p);
420: break;
421: }
422: goto putopp;
423:
424: case OPPOWER:
425: putpower(p);
426: break;
427:
428: case OPSTAR:
429: #if FAMILY == PCC
430: /* m * (2**k) -> m<<k */
431: if(INT(p->exprblock.leftp->headblock.vtype) &&
432: ISICON(p->exprblock.rightp) &&
433: ( (k = log2(p->exprblock.rightp->constblock.const.ci))>0) )
434: {
435: p->exprblock.opcode = OPLSHIFT;
436: frexpr(p->exprblock.rightp);
437: p->exprblock.rightp = ICON(k);
438: goto putopp;
439: }
440: #endif
441:
442: case OPMOD:
443: goto putopp;
444: case OPPLUS:
445: case OPMINUS:
446: case OPSLASH:
447: case OPNEG:
448: if( ISCOMPLEX(p->exprblock.vtype) )
449: putcxop(p);
450: else goto putopp;
451: break;
452:
453: case OPCONV:
454: if( ISCOMPLEX(p->exprblock.vtype) )
455: putcxop(p);
456: else if( ISCOMPLEX(p->exprblock.leftp->headblock.vtype) )
457: {
458: ncomma = 0;
459: putx( mkconv(p->exprblock.vtype,
460: realpart(putcx1(p->exprblock.leftp,
461: &ncomma))));
462: putcomma(ncomma, p->exprblock.vtype, NO);
463: free( (charptr) p );
464: }
465: else goto putopp;
466: break;
467:
468: case OPNOT:
469: case OPOR:
470: case OPAND:
471: case OPEQV:
472: case OPNEQV:
473: case OPADDR:
474: case OPPLUSEQ:
475: case OPSTAREQ:
476: case OPCOMMA:
477: case OPQUEST:
478: case OPCOLON:
479: case OPBITOR:
480: case OPBITAND:
481: case OPBITXOR:
482: case OPBITNOT:
483: case OPLSHIFT:
484: case OPRSHIFT:
485: putopp:
486: putop(p);
487: break;
488:
489: case OPPAREN:
490: putx (p->exprblock.leftp);
491: break;
492: default:
493: badop("putx", opc);
494: }
495: break;
496:
497: case TADDR:
498: putaddr(p, YES);
499: break;
500:
501: case TTEMP:
502: /*
503: * This type is sometimes passed to putx when errors occur
504: * upstream, I don't know why.
505: */
506: frexpr(p);
507: break;
508:
509: default:
510: badtag("putx", p->tag);
511: }
512: }
513:
514:
515:
516: LOCAL putop(p)
517: expptr p;
518: {
519: int k;
520: expptr lp, tp;
521: int pt, lt, tt;
522: int comma;
523: Addrp putch1();
524:
525: switch(p->exprblock.opcode) /* check for special cases and rewrite */
526: {
527: case OPCONV:
528: tt = pt = p->exprblock.vtype;
529: lp = p->exprblock.leftp;
530: lt = lp->headblock.vtype;
531: #if TARGET == VAX
532: if (pt == TYREAL && lt == TYDREAL)
533: {
534: putx(lp);
535: p2op(PCC_SCONV, PCCT_FLOAT);
536: return;
537: }
538: #endif
539: while(p->tag==TEXPR && p->exprblock.opcode==OPCONV && (
540: #if TARGET != TAHOE
541: (ISREAL(pt)&&ISREAL(lt)) ||
542: #endif
543: (INT(pt)&&(ONEOF(lt,MSKINT|MSKADDR|MSKCHAR|M(TYSUBR)))) ))
544: {
545: #if SZINT < SZLONG
546: if(lp->tag != TEXPR)
547: {
548: if(pt==TYINT && lt==TYLONG)
549: break;
550: if(lt==TYINT && pt==TYLONG)
551: break;
552: }
553: #endif
554:
555: #if TARGET == VAX
556: if(pt==TYDREAL && lt==TYREAL)
557: {
558: if(lp->tag==TEXPR &&
559: lp->exprblock.opcode==OPCONV &&
560: lp->exprblock.leftp->headblock.vtype==TYDREAL)
561: {
562: putx(lp->exprblock.leftp);
563: p2op(PCC_SCONV, PCCT_FLOAT);
564: p2op(PCC_SCONV, PCCT_DOUBLE);
565: free( (charptr) p );
566: return;
567: }
568: else break;
569: }
570: #endif
571: if(lt==TYCHAR && lp->tag==TEXPR)
572: {
573: int ncomma = 0;
574: p->exprblock.leftp = (expptr) putch1(lp, &ncomma);
575: putop(p);
576: putcomma(ncomma, pt, NO);
577: free( (charptr) p );
578: return;
579: }
580: free( (charptr) p );
581: p = lp;
582: pt = lt;
583: if (p->tag == TEXPR)
584: {
585: lp = p->exprblock.leftp;
586: lt = lp->headblock.vtype;
587: }
588: }
589: if(p->tag==TEXPR && p->exprblock.opcode==OPCONV)
590: break;
591: putx(p);
592: if (types2[tt] != types2[pt] &&
593: ! ( (ISREAL(tt)&&ISREAL(pt)) ||
594: (INT(tt)&&(ONEOF(pt,MSKINT|MSKADDR|MSKCHAR|M(TYSUBR)))) ))
595: p2op(PCC_SCONV,types2[tt]);
596: return;
597:
598: case OPADDR:
599: comma = NO;
600: lp = p->exprblock.leftp;
601: if(lp->tag != TADDR)
602: {
603: tp = (expptr) mkaltemp
604: (lp->headblock.vtype,lp->headblock.vleng);
605: putx( mkexpr(OPASSIGN, cpexpr(tp), lp) );
606: lp = tp;
607: comma = YES;
608: }
609: putaddr(lp, NO);
610: if(comma)
611: putcomma(1, TYINT, NO);
612: free( (charptr) p );
613: return;
614: #if TARGET == VAX || TARGET == TAHOE
615: /* take advantage of a glitch in the code generator that does not check
616: the type clash in an assignment or comparison of an integer zero and
617: a floating left operand, and generates optimal code for the correct
618: type. (The PCC has no floating-constant node to encode this correctly.)
619: */
620: case OPASSIGN:
621: case OPLT:
622: case OPLE:
623: case OPGT:
624: case OPGE:
625: case OPEQ:
626: case OPNE:
627: if(ISREAL(p->exprblock.leftp->headblock.vtype) &&
628: ISREAL(p->exprblock.rightp->headblock.vtype) &&
629: ISCONST(p->exprblock.rightp) &&
630: p->exprblock.rightp->constblock.const.cd[0]==0)
631: {
632: p->exprblock.rightp->constblock.vtype = TYINT;
633: p->exprblock.rightp->constblock.const.ci = 0;
634: }
635: #endif
636: }
637:
638: if( (k = ops2[p->exprblock.opcode]) <= 0)
639: badop("putop", p->exprblock.opcode);
640: putx(p->exprblock.leftp);
641: if(p->exprblock.rightp)
642: putx(p->exprblock.rightp);
643: p2op(k, types2[p->exprblock.vtype]);
644:
645: if(p->exprblock.vleng)
646: frexpr(p->exprblock.vleng);
647: free( (charptr) p );
648: }
649:
650: putforce(t, p)
651: int t;
652: expptr p;
653: {
654: p = mkconv(t, fixtype(p));
655: putx(p);
656: p2op(PCC_FORCE,
657: #if TARGET == TAHOE
658: (t==TYLONG ? PCCT_LONG : (t==TYREAL ? PCCT_FLOAT : PCCT_DOUBLE)) );
659: #else
660: (t==TYSHORT ? PCCT_SHORT : (t==TYLONG ? PCCT_LONG : PCCT_DOUBLE)) );
661: #endif
662: putstmt();
663: }
664:
665:
666:
667: LOCAL putpower(p)
668: expptr p;
669: {
670: expptr base;
671: Addrp t1, t2;
672: ftnint k;
673: int type;
674: int ncomma;
675:
676: if(!ISICON(p->exprblock.rightp) ||
677: (k = p->exprblock.rightp->constblock.const.ci)<2)
678: fatal("putpower: bad call");
679: base = p->exprblock.leftp;
680: type = base->headblock.vtype;
681:
682: if ((k == 2) && base->tag == TADDR && ISCONST(base->addrblock.memoffset))
683: {
684: putx( mkexpr(OPSTAR,cpexpr(base),cpexpr(base)));
685:
686: return;
687: }
688: t1 = mkaltemp(type, PNULL);
689: t2 = NULL;
690: ncomma = 1;
691: putassign(cpexpr(t1), cpexpr(base) );
692:
693: for( ; (k&1)==0 && k>2 ; k>>=1 )
694: {
695: ++ncomma;
696: putsteq(t1, t1);
697: }
698:
699: if(k == 2)
700: putx( mkexpr(OPSTAR, cpexpr(t1), cpexpr(t1)) );
701: else
702: {
703: t2 = mkaltemp(type, PNULL);
704: ++ncomma;
705: putassign(cpexpr(t2), cpexpr(t1));
706:
707: for(k>>=1 ; k>1 ; k>>=1)
708: {
709: ++ncomma;
710: putsteq(t1, t1);
711: if(k & 1)
712: {
713: ++ncomma;
714: putsteq(t2, t1);
715: }
716: }
717: putx( mkexpr(OPSTAR, cpexpr(t2),
718: mkexpr(OPSTAR, cpexpr(t1), cpexpr(t1)) ));
719: }
720: putcomma(ncomma, type, NO);
721: frexpr(t1);
722: if(t2)
723: frexpr(t2);
724: frexpr(p);
725: }
726:
727:
728:
729:
730: LOCAL Addrp intdouble(p, ncommap)
731: Addrp p;
732: int *ncommap;
733: {
734: register Addrp t;
735:
736: t = mkaltemp(TYDREAL, PNULL);
737: ++*ncommap;
738: putassign(cpexpr(t), p);
739: return(t);
740: }
741:
742:
743:
744:
745:
746: LOCAL Addrp putcxeq(p)
747: register expptr p;
748: {
749: register Addrp lp, rp;
750: int ncomma;
751:
752: if(p->tag != TEXPR)
753: badtag("putcxeq", p->tag);
754:
755: ncomma = 0;
756: lp = putcx1(p->exprblock.leftp, &ncomma);
757: rp = putcx1(p->exprblock.rightp, &ncomma);
758: putassign(realpart(lp), realpart(rp));
759: if( ISCOMPLEX(p->exprblock.vtype) )
760: {
761: ++ncomma;
762: putassign(imagpart(lp), imagpart(rp));
763: }
764: putcomma(ncomma, TYREAL, NO);
765: frexpr(rp);
766: free( (charptr) p );
767: return(lp);
768: }
769:
770:
771:
772: LOCAL putcxop(p)
773: expptr p;
774: {
775: Addrp putcx1();
776: int ncomma;
777:
778: ncomma = 0;
779: putaddr( putcx1(p, &ncomma), NO);
780: putcomma(ncomma, TYINT, NO);
781: }
782:
783:
784:
785: LOCAL Addrp putcx1(p, ncommap)
786: register expptr p;
787: int *ncommap;
788: {
789: expptr q;
790: Addrp lp, rp;
791: register Addrp resp;
792: int opcode;
793: int ltype, rtype;
794: expptr mkrealcon();
795:
796: if(p == NULL)
797: return(NULL);
798:
799: switch(p->tag)
800: {
801: case TCONST:
802: if( ISCOMPLEX(p->constblock.vtype) )
803: p = (expptr) putconst(p);
804: return( (Addrp) p );
805:
806: case TADDR:
807: if( ! addressable(p) )
808: {
809: ++*ncommap;
810: resp = mkaltemp(tyint, PNULL);
811: putassign( cpexpr(resp), p->addrblock.memoffset );
812: p->addrblock.memoffset = (expptr)resp;
813: }
814: return( (Addrp) p );
815:
816: case TEXPR:
817: if( ISCOMPLEX(p->exprblock.vtype) )
818: break;
819: ++*ncommap;
820: resp = mkaltemp(TYDREAL, NO);
821: putassign( cpexpr(resp), p);
822: return(resp);
823:
824: default:
825: badtag("putcx1", p->tag);
826: }
827:
828: opcode = p->exprblock.opcode;
829: if(opcode==OPCALL || opcode==OPCCALL)
830: {
831: ++*ncommap;
832: return( putcall(p) );
833: }
834: else if(opcode == OPASSIGN)
835: {
836: ++*ncommap;
837: return( putcxeq(p) );
838: }
839: resp = mkaltemp(p->exprblock.vtype, PNULL);
840: if(lp = putcx1(p->exprblock.leftp, ncommap) )
841: ltype = lp->vtype;
842: if(rp = putcx1(p->exprblock.rightp, ncommap) )
843: rtype = rp->vtype;
844:
845: switch(opcode)
846: {
847: case OPPAREN:
848: frexpr (resp);
849: resp = lp;
850: lp = NULL;
851: break;
852:
853: case OPCOMMA:
854: frexpr(resp);
855: resp = rp;
856: rp = NULL;
857: break;
858:
859: case OPNEG:
860: putassign( realpart(resp), mkexpr(OPNEG, realpart(lp), ENULL) );
861: putassign( imagpart(resp), mkexpr(OPNEG, imagpart(lp), ENULL) );
862: *ncommap += 2;
863: break;
864:
865: case OPPLUS:
866: case OPMINUS:
867: putassign( realpart(resp),
868: mkexpr(opcode, realpart(lp), realpart(rp) ));
869: if(rtype < TYCOMPLEX)
870: putassign( imagpart(resp), imagpart(lp) );
871: else if(ltype < TYCOMPLEX)
872: {
873: if(opcode == OPPLUS)
874: putassign( imagpart(resp), imagpart(rp) );
875: else putassign( imagpart(resp),
876: mkexpr(OPNEG, imagpart(rp), ENULL) );
877: }
878: else
879: putassign( imagpart(resp),
880: mkexpr(opcode, imagpart(lp), imagpart(rp) ));
881:
882: *ncommap += 2;
883: break;
884:
885: case OPSTAR:
886: if(ltype < TYCOMPLEX)
887: {
888: if( ISINT(ltype) )
889: lp = intdouble(lp, ncommap);
890: putassign( realpart(resp),
891: mkexpr(OPSTAR, cpexpr(lp), realpart(rp) ));
892: putassign( imagpart(resp),
893: mkexpr(OPSTAR, cpexpr(lp), imagpart(rp) ));
894: }
895: else if(rtype < TYCOMPLEX)
896: {
897: if( ISINT(rtype) )
898: rp = intdouble(rp, ncommap);
899: putassign( realpart(resp),
900: mkexpr(OPSTAR, cpexpr(rp), realpart(lp) ));
901: putassign( imagpart(resp),
902: mkexpr(OPSTAR, cpexpr(rp), imagpart(lp) ));
903: }
904: else {
905: putassign( realpart(resp), mkexpr(OPMINUS,
906: mkexpr(OPSTAR, realpart(lp), realpart(rp)),
907: mkexpr(OPSTAR, imagpart(lp), imagpart(rp)) ));
908: putassign( imagpart(resp), mkexpr(OPPLUS,
909: mkexpr(OPSTAR, realpart(lp), imagpart(rp)),
910: mkexpr(OPSTAR, imagpart(lp), realpart(rp)) ));
911: }
912: *ncommap += 2;
913: break;
914:
915: case OPSLASH:
916: /* fixexpr has already replaced all divisions
917: * by a complex by a function call
918: */
919: if( ISINT(rtype) )
920: rp = intdouble(rp, ncommap);
921: putassign( realpart(resp),
922: mkexpr(OPSLASH, realpart(lp), cpexpr(rp)) );
923: putassign( imagpart(resp),
924: mkexpr(OPSLASH, imagpart(lp), cpexpr(rp)) );
925: *ncommap += 2;
926: break;
927:
928: case OPCONV:
929: putassign( realpart(resp), realpart(lp) );
930: if( ISCOMPLEX(lp->vtype) )
931: q = imagpart(lp);
932: else if(rp != NULL)
933: q = (expptr) realpart(rp);
934: else
935: q = mkrealcon(TYDREAL, 0.0);
936: putassign( imagpart(resp), q);
937: *ncommap += 2;
938: break;
939:
940: default:
941: badop("putcx1", opcode);
942: }
943:
944: frexpr(lp);
945: frexpr(rp);
946: free( (charptr) p );
947: return(resp);
948: }
949:
950:
951:
952:
953: LOCAL putcxcmp(p)
954: register expptr p;
955: {
956: int opcode;
957: int ncomma;
958: register Addrp lp, rp;
959: expptr q;
960:
961: if(p->tag != TEXPR)
962: badtag("putcxcmp", p->tag);
963:
964: ncomma = 0;
965: opcode = p->exprblock.opcode;
966: lp = putcx1(p->exprblock.leftp, &ncomma);
967: rp = putcx1(p->exprblock.rightp, &ncomma);
968:
969: q = mkexpr( opcode==OPEQ ? OPAND : OPOR ,
970: mkexpr(opcode, realpart(lp), realpart(rp)),
971: mkexpr(opcode, imagpart(lp), imagpart(rp)) );
972: putx( fixexpr(q) );
973: putcomma(ncomma, TYINT, NO);
974:
975: free( (charptr) lp);
976: free( (charptr) rp);
977: free( (charptr) p );
978: }
979:
980: LOCAL Addrp putch1(p, ncommap)
981: register expptr p;
982: int * ncommap;
983: {
984: register Addrp t;
985:
986: switch(p->tag)
987: {
988: case TCONST:
989: return( putconst(p) );
990:
991: case TADDR:
992: return( (Addrp) p );
993:
994: case TEXPR:
995: ++*ncommap;
996:
997: switch(p->exprblock.opcode)
998: {
999: expptr q;
1000:
1001: case OPCALL:
1002: case OPCCALL:
1003: t = putcall(p);
1004: break;
1005:
1006: case OPPAREN:
1007: --*ncommap;
1008: t = putch1(p->exprblock.leftp, ncommap);
1009: break;
1010:
1011: case OPCONCAT:
1012: t = mkaltemp(TYCHAR, ICON(lencat(p)) );
1013: q = (expptr) cpexpr(p->headblock.vleng);
1014: putcat( cpexpr(t), p );
1015: /* put the correct length on the block */
1016: frexpr(t->vleng);
1017: t->vleng = q;
1018:
1019: break;
1020:
1021: case OPCONV:
1022: if(!ISICON(p->exprblock.vleng)
1023: || p->exprblock.vleng->constblock.const.ci!=1
1024: || ! INT(p->exprblock.leftp->headblock.vtype) )
1025: fatal("putch1: bad character conversion");
1026: t = mkaltemp(TYCHAR, ICON(1) );
1027: putop( mkexpr(OPASSIGN, cpexpr(t), p) );
1028: break;
1029: default:
1030: badop("putch1", p->exprblock.opcode);
1031: }
1032: return(t);
1033:
1034: default:
1035: badtag("putch1", p->tag);
1036: }
1037: /* NOTREACHED */
1038: }
1039:
1040:
1041:
1042:
1043: LOCAL putchop(p)
1044: expptr p;
1045: {
1046: int ncomma;
1047:
1048: ncomma = 0;
1049: putaddr( putch1(p, &ncomma) , NO );
1050: putcomma(ncomma, TYCHAR, YES);
1051: }
1052:
1053:
1054:
1055:
1056: LOCAL putcheq(p)
1057: register expptr p;
1058: {
1059: int ncomma;
1060: expptr lp, rp;
1061:
1062: if(p->tag != TEXPR)
1063: badtag("putcheq", p->tag);
1064:
1065: ncomma = 0;
1066: lp = p->exprblock.leftp;
1067: rp = p->exprblock.rightp;
1068: if( rp->tag==TEXPR && rp->exprblock.opcode==OPCONCAT )
1069: putcat(lp, rp);
1070: else if( ISONE(lp->headblock.vleng) && ISONE(rp->headblock.vleng) )
1071: {
1072: putaddr( putch1(lp, &ncomma) , YES );
1073: putaddr( putch1(rp, &ncomma) , YES );
1074: putcomma(ncomma, TYINT, NO);
1075: p2op(PCC_ASSIGN, PCCT_CHAR);
1076: }
1077: else
1078: {
1079: putx( call2(TYINT, "s_copy", lp, rp) );
1080: putcomma(ncomma, TYINT, NO);
1081: }
1082:
1083: frexpr(p->exprblock.vleng);
1084: free( (charptr) p );
1085: }
1086:
1087:
1088:
1089:
1090: LOCAL putchcmp(p)
1091: register expptr p;
1092: {
1093: int ncomma;
1094: expptr lp, rp;
1095:
1096: if(p->tag != TEXPR)
1097: badtag("putchcmp", p->tag);
1098:
1099: ncomma = 0;
1100: lp = p->exprblock.leftp;
1101: rp = p->exprblock.rightp;
1102:
1103: if(ISONE(lp->headblock.vleng) && ISONE(rp->headblock.vleng) )
1104: {
1105: putaddr( putch1(lp, &ncomma) , YES );
1106: putcomma(ncomma, TYINT, NO);
1107: ncomma = 0;
1108: putaddr( putch1(rp, &ncomma) , YES );
1109: putcomma(ncomma, TYINT, NO);
1110: p2op(ops2[p->exprblock.opcode], PCCT_CHAR);
1111: free( (charptr) p );
1112: }
1113: else
1114: {
1115: p->exprblock.leftp = call2(TYINT,"s_cmp", lp, rp);
1116: p->exprblock.rightp = ICON(0);
1117: putop(p);
1118: }
1119: }
1120:
1121:
1122:
1123:
1124:
1125: LOCAL putcat(lhs, rhs)
1126: register Addrp lhs;
1127: register expptr rhs;
1128: {
1129: int n, ncomma;
1130: Addrp lp, cp;
1131:
1132: ncomma = 0;
1133: n = ncat(rhs);
1134: lp = mkaltmpn(n, TYLENG, PNULL);
1135: cp = mkaltmpn(n, TYADDR, PNULL);
1136:
1137: n = 0;
1138: putct1(rhs, lp, cp, &n, &ncomma);
1139:
1140: putx( call4(TYSUBR, "s_cat", lhs, cp, lp, mkconv(TYLONG, ICON(n)) ) );
1141: putcomma(ncomma, TYINT, NO);
1142: }
1143:
1144:
1145:
1146:
1147:
1148: LOCAL putct1(q, lp, cp, ip, ncommap)
1149: register expptr q;
1150: register Addrp lp, cp;
1151: int *ip, *ncommap;
1152: {
1153: int i;
1154: Addrp lp1, cp1;
1155:
1156: if(q->tag==TEXPR && q->exprblock.opcode==OPCONCAT)
1157: {
1158: putct1(q->exprblock.leftp, lp, cp, ip, ncommap);
1159: putct1(q->exprblock.rightp, lp, cp , ip, ncommap);
1160: frexpr(q->exprblock.vleng);
1161: free( (charptr) q );
1162: }
1163: else
1164: {
1165: i = (*ip)++;
1166: lp1 = (Addrp) cpexpr(lp);
1167: lp1->memoffset = mkexpr(OPPLUS,lp1->memoffset, ICON(i*SZLENG));
1168: cp1 = (Addrp) cpexpr(cp);
1169: cp1->memoffset = mkexpr(OPPLUS, cp1->memoffset, ICON(i*SZADDR));
1170: putassign( lp1, cpexpr(q->headblock.vleng) );
1171: putassign( cp1, addrof(putch1(q,ncommap)) );
1172: *ncommap += 2;
1173: }
1174: }
1175:
1176: LOCAL putaddr(p, indir)
1177: register Addrp p;
1178: int indir;
1179: {
1180: int type, type2, funct;
1181: ftnint offset, simoffset();
1182: expptr offp, shorten();
1183:
1184: if( p->tag==TERROR || (p->memoffset!=NULL && ISERROR(p->memoffset)) )
1185: {
1186: frexpr(p);
1187: return;
1188: }
1189: if (p->tag != TADDR) badtag ("putaddr",p->tag);
1190:
1191: type = p->vtype;
1192: type2 = types2[type];
1193: funct = (p->vclass==CLPROC ? PCCTM_FTN<<2 : 0);
1194:
1195: offp = (p->memoffset ? (expptr) cpexpr(p->memoffset) : (expptr)NULL );
1196:
1197:
1198: #if (FUDGEOFFSET != 1)
1199: if(offp)
1200: offp = mkexpr(OPSTAR, ICON(FUDGEOFFSET), offp);
1201: #endif
1202:
1203: offset = simoffset( &offp );
1204: #if SZINT < SZLONG
1205: if(offp)
1206: if(shortsubs)
1207: offp = shorten(offp);
1208: else
1209: offp = mkconv(TYINT, offp);
1210: #else
1211: if(offp)
1212: offp = mkconv(TYINT, offp);
1213: #endif
1214:
1215: if (p->vclass == CLVAR
1216: && (p->vstg == STGBSS || p->vstg == STGEQUIV)
1217: && SMALLVAR(p->varsize)
1218: && offset >= -32768 && offset <= 32767)
1219: {
1220: anylocals = YES;
1221: if (indir && !offp)
1222: p2ldisp(offset, memname(p->vstg, p->memno), type2);
1223: else
1224: {
1225: p2reg(LVARREG, type2 | PCCTM_PTR);
1226: p2triple(PCC_ICON, 1, PCCT_INT);
1227: p2word(offset);
1228: p2ndisp(memname(p->vstg, p->memno));
1229: p2op(PCC_PLUS, type2 | PCCTM_PTR);
1230: if (offp)
1231: {
1232: putx(offp);
1233: p2op(PCC_PLUS, type2 | PCCTM_PTR);
1234: }
1235: if (indir)
1236: p2op(PCC_DEREF, type2);
1237: }
1238: frexpr((tagptr) p);
1239: return;
1240: }
1241:
1242: switch(p->vstg)
1243: {
1244: case STGAUTO:
1245: if(indir && !offp)
1246: {
1247: p2oreg(offset, AUTOREG, type2);
1248: break;
1249: }
1250:
1251: if(!indir && !offp && !offset)
1252: {
1253: p2reg(AUTOREG, type2 | PCCTM_PTR);
1254: break;
1255: }
1256:
1257: p2reg(AUTOREG, type2 | PCCTM_PTR);
1258: if(offp)
1259: {
1260: putx(offp);
1261: if(offset)
1262: p2icon(offset, PCCT_INT);
1263: }
1264: else
1265: p2icon(offset, PCCT_INT);
1266: if(offp && offset)
1267: p2op(PCC_PLUS, type2 | PCCTM_PTR);
1268: p2op(PCC_PLUS, type2 | PCCTM_PTR);
1269: if(indir)
1270: p2op(PCC_DEREF, type2);
1271: break;
1272:
1273: case STGARG:
1274: p2oreg(
1275: #ifdef ARGOFFSET
1276: ARGOFFSET +
1277: #endif
1278: (ftnint) (FUDGEOFFSET*p->memno),
1279: ARGREG, type2 | PCCTM_PTR | funct );
1280:
1281: based:
1282: if(offset)
1283: {
1284: p2icon(offset, PCCT_INT);
1285: p2op(PCC_PLUS, type2 | PCCTM_PTR);
1286: }
1287: if(offp)
1288: {
1289: putx(offp);
1290: p2op(PCC_PLUS, type2 | PCCTM_PTR);
1291: }
1292: if(indir)
1293: p2op(PCC_DEREF, type2);
1294: break;
1295:
1296: case STGLENG:
1297: if(indir)
1298: {
1299: p2oreg(
1300: #ifdef ARGOFFSET
1301: ARGOFFSET +
1302: #endif
1303: (ftnint) (FUDGEOFFSET*p->memno),
1304: ARGREG, type2 );
1305: }
1306: else {
1307: p2reg(ARGREG, type2 | PCCTM_PTR );
1308: p2icon(
1309: #ifdef ARGOFFSET
1310: ARGOFFSET +
1311: #endif
1312: (ftnint) (FUDGEOFFSET*p->memno), PCCT_INT);
1313: p2op(PCC_PLUS, type2 | PCCTM_PTR );
1314: }
1315: break;
1316:
1317:
1318: case STGBSS:
1319: case STGINIT:
1320: case STGEXT:
1321: case STGINTR:
1322: case STGCOMMON:
1323: case STGEQUIV:
1324: case STGCONST:
1325: if(offp)
1326: {
1327: putx(offp);
1328: putmem(p, PCC_ICON, offset);
1329: p2op(PCC_PLUS, type2 | PCCTM_PTR);
1330: if(indir)
1331: p2op(PCC_DEREF, type2);
1332: }
1333: else
1334: putmem(p, (indir ? PCC_NAME : PCC_ICON), offset);
1335:
1336: break;
1337:
1338: case STGREG:
1339: if(indir)
1340: p2reg(p->memno, type2);
1341: else
1342: fatal("attempt to take address of a register");
1343: break;
1344:
1345: case STGPREG:
1346: if(indir && !offp)
1347: p2oreg(offset, p->memno, type2);
1348: else
1349: {
1350: p2reg(p->memno, type2 | PCCTM_PTR);
1351: goto based;
1352: }
1353: break;
1354:
1355: default:
1356: badstg("putaddr", p->vstg);
1357: }
1358: frexpr(p);
1359: }
1360:
1361:
1362:
1363:
1364: LOCAL putmem(p, class, offset)
1365: expptr p;
1366: int class;
1367: ftnint offset;
1368: {
1369: int type2;
1370: int funct;
1371: char *name, *memname();
1372:
1373: funct = (p->headblock.vclass==CLPROC ? PCCTM_FTN<<2 : 0);
1374: type2 = types2[p->headblock.vtype];
1375: if(p->headblock.vclass == CLPROC)
1376: type2 |= (PCCTM_FTN<<2);
1377: name = memname(p->addrblock.vstg, p->addrblock.memno);
1378: if(class == PCC_ICON)
1379: {
1380: p2triple(PCC_ICON, name[0]!='\0', type2|PCCTM_PTR);
1381: p2word(offset);
1382: if(name[0])
1383: p2name(name);
1384: }
1385: else
1386: {
1387: p2triple(PCC_NAME, offset!=0, type2);
1388: if(offset != 0)
1389: p2word(offset);
1390: p2name(name);
1391: }
1392: }
1393:
1394:
1395:
1396: LOCAL Addrp putcall(p)
1397: register Exprp p;
1398: {
1399: chainp arglist, charsp, cp;
1400: int n, first;
1401: Addrp t;
1402: register expptr q;
1403: Addrp fval, mkargtemp();
1404: int type, type2, ctype, qtype, indir;
1405:
1406: type2 = types2[type = p->vtype];
1407: charsp = NULL;
1408: indir = (p->opcode == OPCCALL);
1409: n = 0;
1410: first = YES;
1411:
1412: if(p->rightp)
1413: {
1414: arglist = p->rightp->listblock.listp;
1415: free( (charptr) (p->rightp) );
1416: }
1417: else
1418: arglist = NULL;
1419:
1420: for(cp = arglist ; cp ; cp = cp->nextp)
1421: {
1422: q = (expptr) cp->datap;
1423: if(indir)
1424: ++n;
1425: else {
1426: q = (expptr) (cp->datap);
1427: if( ISCONST(q) )
1428: {
1429: q = (expptr) putconst(q);
1430: cp->datap = (tagptr) q;
1431: }
1432: if( ISCHAR(q) && q->headblock.vclass!=CLPROC )
1433: {
1434: charsp = hookup(charsp,
1435: mkchain(cpexpr(q->headblock.vleng),
1436: CHNULL));
1437: n += 2;
1438: }
1439: else
1440: n += 1;
1441: }
1442: }
1443:
1444: if(type == TYCHAR)
1445: {
1446: if( ISICON(p->vleng) )
1447: {
1448: fval = mkargtemp(TYCHAR, p->vleng);
1449: n += 2;
1450: }
1451: else {
1452: err("adjustable character function");
1453: return;
1454: }
1455: }
1456: else if( ISCOMPLEX(type) )
1457: {
1458: fval = mkargtemp(type, PNULL);
1459: n += 1;
1460: }
1461: else
1462: fval = NULL;
1463:
1464: ctype = (fval ? PCCT_INT : type2);
1465: putaddr(p->leftp, NO);
1466:
1467: if(fval)
1468: {
1469: first = NO;
1470: putaddr( cpexpr(fval), NO);
1471: if(type==TYCHAR)
1472: {
1473: putx( mkconv(TYLENG,p->vleng) );
1474: p2op(PCC_CM, type2);
1475: }
1476: }
1477:
1478: for(cp = arglist ; cp ; cp = cp->nextp)
1479: {
1480: q = (expptr) (cp->datap);
1481: if(q->tag==TADDR && (indir || q->addrblock.vstg!=STGREG) )
1482: putaddr(q, indir && q->addrblock.vtype!=TYCHAR);
1483: else if( ISCOMPLEX(q->headblock.vtype) )
1484: putcxop(q);
1485: else if (ISCHAR(q) )
1486: putchop(q);
1487: else if( ! ISERROR(q) )
1488: {
1489: if(indir)
1490: putx(q);
1491: else {
1492: t = mkargtemp(qtype = q->headblock.vtype,
1493: q->headblock.vleng);
1494: putassign( cpexpr(t), q );
1495: putaddr(t, NO);
1496: putcomma(1, qtype, YES);
1497: }
1498: }
1499: if(first)
1500: first = NO;
1501: else
1502: p2op(PCC_CM, type2);
1503: }
1504:
1505: if(arglist)
1506: frchain(&arglist);
1507: for(cp = charsp ; cp ; cp = cp->nextp)
1508: {
1509: putx( mkconv(TYLENG,cp->datap) );
1510: p2op(PCC_CM, type2);
1511: }
1512: frchain(&charsp);
1513: #if TARGET == TAHOE
1514: if(indir && ctype==PCCT_FLOAT) /* function opcodes */
1515: p2op(PCC_FORTCALL, ctype);
1516: else
1517: #endif
1518: p2op(n>0 ? PCC_CALL : PCC_UCALL , ctype);
1519: free( (charptr) p );
1520: return(fval);
1521: }
1522:
1523:
1524:
1525: LOCAL putmnmx(p)
1526: register expptr p;
1527: {
1528: int op, type;
1529: int ncomma;
1530: expptr qp;
1531: chainp p0, p1;
1532: Addrp sp, tp;
1533:
1534: if(p->tag != TEXPR)
1535: badtag("putmnmx", p->tag);
1536:
1537: type = p->exprblock.vtype;
1538: op = (p->exprblock.opcode==OPMIN ? OPLT : OPGT );
1539: p0 = p->exprblock.leftp->listblock.listp;
1540: free( (charptr) (p->exprblock.leftp) );
1541: free( (charptr) p );
1542:
1543: sp = mkaltemp(type, PNULL);
1544: tp = mkaltemp(type, PNULL);
1545: qp = mkexpr(OPCOLON, cpexpr(tp), cpexpr(sp));
1546: qp = mkexpr(OPQUEST, mkexpr(op, cpexpr(tp),cpexpr(sp)), qp);
1547: qp = fixexpr(qp);
1548:
1549: ncomma = 1;
1550: putassign( cpexpr(sp), p0->datap );
1551:
1552: for(p1 = p0->nextp ; p1 ; p1 = p1->nextp)
1553: {
1554: ++ncomma;
1555: putassign( cpexpr(tp), p1->datap );
1556: if(p1->nextp)
1557: {
1558: ++ncomma;
1559: putassign( cpexpr(sp), cpexpr(qp) );
1560: }
1561: else
1562: putx(qp);
1563: }
1564:
1565: putcomma(ncomma, type, NO);
1566: frexpr(sp);
1567: frexpr(tp);
1568: frchain( &p0 );
1569: }
1570:
1571:
1572:
1573:
1574: LOCAL putcomma(n, type, indir)
1575: int n, type, indir;
1576: {
1577: type = types2[type];
1578: if(indir)
1579: type |= PCCTM_PTR;
1580: while(--n >= 0)
1581: p2op(PCC_COMOP, type);
1582: }
1583:
1584:
1585:
1586:
1587: ftnint simoffset(p0)
1588: expptr *p0;
1589: {
1590: ftnint offset, prod;
1591: register expptr p, lp, rp;
1592:
1593: offset = 0;
1594: p = *p0;
1595: if(p == NULL)
1596: return(0);
1597:
1598: if( ! ISINT(p->headblock.vtype) )
1599: return(0);
1600:
1601: if(p->tag==TEXPR && p->exprblock.opcode==OPSTAR)
1602: {
1603: lp = p->exprblock.leftp;
1604: rp = p->exprblock.rightp;
1605: if(ISICON(rp) && lp->tag==TEXPR &&
1606: lp->exprblock.opcode==OPPLUS && ISICON(lp->exprblock.rightp))
1607: {
1608: p->exprblock.opcode = OPPLUS;
1609: lp->exprblock.opcode = OPSTAR;
1610: prod = rp->constblock.const.ci *
1611: lp->exprblock.rightp->constblock.const.ci;
1612: lp->exprblock.rightp->constblock.const.ci = rp->constblock.const.ci;
1613: rp->constblock.const.ci = prod;
1614: }
1615: }
1616:
1617: if(p->tag==TEXPR && p->exprblock.opcode==OPPLUS &&
1618: ISICON(p->exprblock.rightp))
1619: {
1620: rp = p->exprblock.rightp;
1621: lp = p->exprblock.leftp;
1622: offset += rp->constblock.const.ci;
1623: frexpr(rp);
1624: free( (charptr) p );
1625: *p0 = lp;
1626: }
1627:
1628: if( ISCONST(p) )
1629: {
1630: offset += p->constblock.const.ci;
1631: frexpr(p);
1632: *p0 = NULL;
1633: }
1634:
1635: return(offset);
1636: }
1637:
1638:
1639:
1640:
1641:
1642: p2op(op, type)
1643: int op, type;
1644: {
1645: p2triple(op, 0, type);
1646: }
1647:
1648: p2icon(offset, type)
1649: ftnint offset;
1650: int type;
1651: {
1652: p2triple(PCC_ICON, 0, type);
1653: p2word(offset);
1654: }
1655:
1656:
1657:
1658:
1659: p2oreg(offset, reg, type)
1660: ftnint offset;
1661: int reg, type;
1662: {
1663: p2triple(PCC_OREG, reg, type);
1664: p2word(offset);
1665: p2name("");
1666: }
1667:
1668:
1669:
1670:
1671: p2reg(reg, type)
1672: int reg, type;
1673: {
1674: p2triple(PCC_REG, reg, type);
1675: }
1676:
1677:
1678:
1679: p2pi(s, i)
1680: char *s;
1681: int i;
1682: {
1683: char buff[100];
1684: sprintf(buff, s, i);
1685: p2pass(buff);
1686: }
1687:
1688:
1689:
1690: p2pij(s, i, j)
1691: char *s;
1692: int i, j;
1693: {
1694: char buff[100];
1695: sprintf(buff, s, i, j);
1696: p2pass(buff);
1697: }
1698:
1699:
1700:
1701:
1702: p2ps(s, t)
1703: char *s, *t;
1704: {
1705: char buff[100];
1706: sprintf(buff, s, t);
1707: p2pass(buff);
1708: }
1709:
1710:
1711:
1712:
1713: p2pass(s)
1714: char *s;
1715: {
1716: p2triple(PCCF_FTEXT, (strlen(s) + ALILONG-1)/ALILONG, 0);
1717: p2str(s);
1718: }
1719:
1720:
1721:
1722:
1723: p2str(s)
1724: register char *s;
1725: {
1726: union { long int word; char str[SZLONG]; } u;
1727: register int i;
1728:
1729: i = 0;
1730: u.word = 0;
1731: while(*s)
1732: {
1733: u.str[i++] = *s++;
1734: if(i == SZLONG)
1735: {
1736: p2word(u.word);
1737: u.word = 0;
1738: i = 0;
1739: }
1740: }
1741: if(i > 0)
1742: p2word(u.word);
1743: }
1744:
1745:
1746:
1747:
1748: p2triple(op, var, type)
1749: int op, var, type;
1750: {
1751: register long word;
1752: word = PCCM_TRIPLE(op, var, type);
1753: p2word(word);
1754: }
1755:
1756:
1757:
1758:
1759:
1760: p2name(s)
1761: register char *s;
1762: {
1763: register int i;
1764:
1765: #ifdef UCBPASS2
1766: /* arbitrary length names, terminated by a null,
1767: padded to a full word */
1768:
1769: # define WL sizeof(long int)
1770: union { long int word; char str[WL]; } w;
1771:
1772: w.word = 0;
1773: i = 0;
1774: while(w.str[i++] = *s++)
1775: if(i == WL)
1776: {
1777: p2word(w.word);
1778: w.word = 0;
1779: i = 0;
1780: }
1781: if(i > 0)
1782: p2word(w.word);
1783: #else
1784: /* standard intermediate, names are 8 characters long */
1785:
1786: union { long int word[2]; char str[8]; } u;
1787:
1788: u.word[0] = u.word[1] = 0;
1789: for(i = 0 ; i<8 && *s ; ++i)
1790: u.str[i] = *s++;
1791: p2word(u.word[0]);
1792: p2word(u.word[1]);
1793:
1794: #endif
1795:
1796: }
1797:
1798:
1799:
1800:
1801: p2word(w)
1802: long int w;
1803: {
1804: *p2bufp++ = w;
1805: if(p2bufp >= p2bufend)
1806: p2flush();
1807: }
1808:
1809:
1810:
1811: p2flush()
1812: {
1813: if(p2bufp > p2buff)
1814: write(fileno(textfile), p2buff, (p2bufp-p2buff)*sizeof(long int));
1815: p2bufp = p2buff;
1816: }
1817:
1818:
1819:
1820: LOCAL
1821: p2ldisp(offset, vname, type)
1822: ftnint offset;
1823: char *vname;
1824: int type;
1825: {
1826: char buff[100];
1827:
1828: sprintf(buff, "%s-v.%d", vname, bsslabel);
1829: p2triple(PCC_OREG, LVARREG, type);
1830: p2word(offset);
1831: p2name(buff);
1832: }
1833:
1834:
1835:
1836: p2ndisp(vname)
1837: char *vname;
1838: {
1839: char buff[100];
1840:
1841: sprintf(buff, "%s-v.%d", vname, bsslabel);
1842: p2name(buff);
1843: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.