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