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