xref: /csrg-svn/usr.bin/f77/pass1.tahoe/put.c (revision 43221)
1*43221Sbostic /*
2*43221Sbostic  * Copyright (c) 1980 Regents of the University of California.
3*43221Sbostic  * All rights reserved.  The Berkeley software License Agreement
4*43221Sbostic  * specifies the terms and conditions for redistribution.
5*43221Sbostic  */
6*43221Sbostic 
7*43221Sbostic #ifndef lint
8*43221Sbostic static char sccsid[] = "@(#)put.c	5.1 (Berkeley) 6/7/85";
9*43221Sbostic #endif not lint
10*43221Sbostic 
11*43221Sbostic /*
12*43221Sbostic  * put.c
13*43221Sbostic  *
14*43221Sbostic  * Intermediate code generation procedures common to both
15*43221Sbostic  * Johnson (Portable) and Ritchie families of second passes
16*43221Sbostic  *
17*43221Sbostic  * University of Utah CS Dept modification history:
18*43221Sbostic  *
19*43221Sbostic  * $Log:	put.c,v $
20*43221Sbostic  * Revision 3.2  85/05/04  15:41:24  mckusick
21*43221Sbostic  * Fix alignment problem -- change code to match comment...
22*43221Sbostic  *
23*43221Sbostic  * Revision 3.2  85/04/29  21:36:07  donn
24*43221Sbostic  * Fix alignment problem -- change code to match comment...
25*43221Sbostic  *
26*43221Sbostic  * Revision 3.1  85/02/27  19:12:04  donn
27*43221Sbostic  * Changed to use pcc.h instead of pccdefs.h.
28*43221Sbostic  *
29*43221Sbostic  * Revision 2.1  84/07/19  12:04:21  donn
30*43221Sbostic  * Changed comment headers for UofU.
31*43221Sbostic  *
32*43221Sbostic  * Revision 1.2  84/04/02  14:40:21  donn
33*43221Sbostic  * Added fixes from Conrad Huang at UCSF for calculating the length of a
34*43221Sbostic  * concatenation of strings correctly.
35*43221Sbostic  *
36*43221Sbostic  */
37*43221Sbostic 
38*43221Sbostic #include "defs.h"
39*43221Sbostic 
40*43221Sbostic #if FAMILY == PCC
41*43221Sbostic #	include <pcc.h>
42*43221Sbostic #else
43*43221Sbostic #	include "dmrdefs.h"
44*43221Sbostic #endif
45*43221Sbostic 
46*43221Sbostic /*
47*43221Sbostic char *ops [ ] =
48*43221Sbostic 	{
49*43221Sbostic 	"??", "+", "-", "*", "/", "**", "-",
50*43221Sbostic 	"OR", "AND", "EQV", "NEQV", "NOT",
51*43221Sbostic 	"CONCAT",
52*43221Sbostic 	"<", "==", ">", "<=", "!=", ">=",
53*43221Sbostic 	" of ", " ofC ", " = ", " += ", " *= ", " CONV ", " << ", " % ",
54*43221Sbostic 	" , ", " ? ", " : "
55*43221Sbostic 	" abs ", " min ", " max ", " addr ", " indirect ",
56*43221Sbostic 	" bitor ", " bitand ", " bitxor ", " bitnot ", " >> ", " () "
57*43221Sbostic 	};
58*43221Sbostic */
59*43221Sbostic 
60*43221Sbostic int ops2 [ ] =
61*43221Sbostic 	{
62*43221Sbostic 	PCC_ERROR, PCC_PLUS, PCC_MINUS, PCC_MUL, PCC_DIV, PCC_ERROR, PCC_UMINUS,
63*43221Sbostic 	PCC_OROR, PCC_ANDAND, PCC_EQ, PCC_NE, PCC_NOT,
64*43221Sbostic 	PCC_ERROR,
65*43221Sbostic 	PCC_LT, PCC_EQ, PCC_GT, PCC_LE, PCC_NE, PCC_GE,
66*43221Sbostic 	PCC_CALL, PCC_CALL, PCC_ASSIGN, PCC_PLUSEQ, PCC_MULEQ, PCC_SCONV, PCC_LS, PCC_MOD,
67*43221Sbostic 	PCC_COMOP, PCC_QUEST, PCC_COLON,
68*43221Sbostic 	PCC_ERROR, PCC_ERROR, PCC_ERROR, PCC_ERROR, PCC_DEREF,
69*43221Sbostic 	PCC_OR, PCC_AND, PCC_ER, PCC_COMPL, PCC_RS, PCC_ERROR
70*43221Sbostic 	};
71*43221Sbostic 
72*43221Sbostic 
73*43221Sbostic int types2 [ ] =
74*43221Sbostic 	{
75*43221Sbostic 	PCC_ERROR, PCCT_INT|PCCTM_PTR, PCCT_SHORT, PCCT_LONG, PCCT_FLOAT, PCCT_DOUBLE,
76*43221Sbostic #if TARGET == INTERDATA
77*43221Sbostic 	PCC_ERROR, PCC_ERROR, PCCT_LONG, PCCT_CHAR, PCCT_INT, PCC_ERROR
78*43221Sbostic #else
79*43221Sbostic 	PCCT_FLOAT, PCCT_DOUBLE, PCCT_LONG, PCCT_CHAR, PCCT_INT, PCC_ERROR
80*43221Sbostic #endif
81*43221Sbostic 	};
82*43221Sbostic 
83*43221Sbostic 
84*43221Sbostic setlog()
85*43221Sbostic {
86*43221Sbostic types2[TYLOGICAL] = types2[tylogical];
87*43221Sbostic typesize[TYLOGICAL] = typesize[tylogical];
88*43221Sbostic typealign[TYLOGICAL] = typealign[tylogical];
89*43221Sbostic }
90*43221Sbostic 
91*43221Sbostic 
92*43221Sbostic putex1(p)
93*43221Sbostic expptr p;
94*43221Sbostic {
95*43221Sbostic putx( fixtype(p) );
96*43221Sbostic 
97*43221Sbostic if (!optimflag)
98*43221Sbostic 	{
99*43221Sbostic 	templist = hookup(templist, holdtemps);
100*43221Sbostic 	holdtemps = NULL;
101*43221Sbostic 	}
102*43221Sbostic }
103*43221Sbostic 
104*43221Sbostic 
105*43221Sbostic 
106*43221Sbostic 
107*43221Sbostic 
108*43221Sbostic putassign(lp, rp)
109*43221Sbostic expptr lp, rp;
110*43221Sbostic {
111*43221Sbostic putx( fixexpr( mkexpr(OPASSIGN, lp, rp) ));
112*43221Sbostic }
113*43221Sbostic 
114*43221Sbostic 
115*43221Sbostic 
116*43221Sbostic 
117*43221Sbostic puteq(lp, rp)
118*43221Sbostic expptr lp, rp;
119*43221Sbostic {
120*43221Sbostic putexpr( mkexpr(OPASSIGN, lp, rp) );
121*43221Sbostic }
122*43221Sbostic 
123*43221Sbostic 
124*43221Sbostic 
125*43221Sbostic 
126*43221Sbostic /* put code for  a *= b */
127*43221Sbostic 
128*43221Sbostic putsteq(a, b)
129*43221Sbostic expptr a, b;
130*43221Sbostic {
131*43221Sbostic putx( fixexpr( mkexpr(OPSTAREQ, cpexpr(a), cpexpr(b)) ));
132*43221Sbostic }
133*43221Sbostic 
134*43221Sbostic 
135*43221Sbostic 
136*43221Sbostic 
137*43221Sbostic 
138*43221Sbostic Addrp realpart(p)
139*43221Sbostic register Addrp p;
140*43221Sbostic {
141*43221Sbostic register Addrp q;
142*43221Sbostic 
143*43221Sbostic q = (Addrp) cpexpr(p);
144*43221Sbostic if( ISCOMPLEX(p->vtype) )
145*43221Sbostic 	q->vtype += (TYREAL-TYCOMPLEX);
146*43221Sbostic return(q);
147*43221Sbostic }
148*43221Sbostic 
149*43221Sbostic 
150*43221Sbostic 
151*43221Sbostic 
152*43221Sbostic expptr imagpart(p)
153*43221Sbostic register expptr p;
154*43221Sbostic {
155*43221Sbostic register Addrp q;
156*43221Sbostic expptr mkrealcon();
157*43221Sbostic 
158*43221Sbostic if (ISCONST(p))
159*43221Sbostic 	{
160*43221Sbostic 	if (ISCOMPLEX(p->constblock.vtype))
161*43221Sbostic 		return(mkrealcon(p->constblock.vtype == TYCOMPLEX ?
162*43221Sbostic 					TYREAL : TYDREAL,
163*43221Sbostic 				p->constblock.const.cd[1]));
164*43221Sbostic 	else if (p->constblock.vtype == TYDREAL)
165*43221Sbostic 		return(mkrealcon(TYDREAL, 0.0));
166*43221Sbostic 	else
167*43221Sbostic 		return(mkrealcon(TYREAL, 0.0));
168*43221Sbostic 	}
169*43221Sbostic else if (p->tag == TADDR)
170*43221Sbostic 	{
171*43221Sbostic 	if( ISCOMPLEX(p->addrblock.vtype) )
172*43221Sbostic 		{
173*43221Sbostic 		q = (Addrp) cpexpr(p);
174*43221Sbostic 		q->vtype += (TYREAL-TYCOMPLEX);
175*43221Sbostic 		q->memoffset = mkexpr(OPPLUS, q->memoffset,
176*43221Sbostic 					ICON(typesize[q->vtype]));
177*43221Sbostic 		return( (expptr) q );
178*43221Sbostic 		}
179*43221Sbostic 	else
180*43221Sbostic 		return( mkrealcon( ISINT(p->addrblock.vtype) ?
181*43221Sbostic 			TYDREAL : p->addrblock.vtype , 0.0));
182*43221Sbostic 	}
183*43221Sbostic else
184*43221Sbostic 	badtag("imagpart", p->tag);
185*43221Sbostic }
186*43221Sbostic 
187*43221Sbostic 
188*43221Sbostic 
189*43221Sbostic 
190*43221Sbostic ncat(p)
191*43221Sbostic register expptr p;
192*43221Sbostic {
193*43221Sbostic if(p->tag==TEXPR && p->exprblock.opcode==OPCONCAT)
194*43221Sbostic 	return( ncat(p->exprblock.leftp) + ncat(p->exprblock.rightp) );
195*43221Sbostic else	return(1);
196*43221Sbostic }
197*43221Sbostic 
198*43221Sbostic 
199*43221Sbostic 
200*43221Sbostic 
201*43221Sbostic ftnint lencat(p)
202*43221Sbostic register expptr p;
203*43221Sbostic {
204*43221Sbostic if(p->tag==TEXPR && p->exprblock.opcode==OPCONCAT)
205*43221Sbostic 	return( lencat(p->exprblock.leftp) + lencat(p->exprblock.rightp) );
206*43221Sbostic else if( p->headblock.vleng!=NULL && ISICON(p->headblock.vleng) )
207*43221Sbostic 	return(p->headblock.vleng->constblock.const.ci);
208*43221Sbostic else if(p->tag==TADDR && p->addrblock.varleng!=0)
209*43221Sbostic 	return(p->addrblock.varleng);
210*43221Sbostic else if(p->tag==TTEMP && p->tempblock.varleng!=0)
211*43221Sbostic 	return(p->tempblock.varleng);
212*43221Sbostic else
213*43221Sbostic 	{
214*43221Sbostic 	err("impossible element in concatenation");
215*43221Sbostic 	return(0);
216*43221Sbostic 	}
217*43221Sbostic }
218*43221Sbostic 
219*43221Sbostic Addrp putconst(p)
220*43221Sbostic register Constp p;
221*43221Sbostic {
222*43221Sbostic register Addrp q;
223*43221Sbostic struct Literal *litp, *lastlit;
224*43221Sbostic int i, k, type;
225*43221Sbostic int litflavor;
226*43221Sbostic 
227*43221Sbostic if( p->tag != TCONST )
228*43221Sbostic 	badtag("putconst", p->tag);
229*43221Sbostic 
230*43221Sbostic q = ALLOC(Addrblock);
231*43221Sbostic q->tag = TADDR;
232*43221Sbostic type = p->vtype;
233*43221Sbostic q->vtype = ( type==TYADDR ? TYINT : type );
234*43221Sbostic q->vleng = (expptr) cpexpr(p->vleng);
235*43221Sbostic q->vstg = STGCONST;
236*43221Sbostic q->memno = newlabel();
237*43221Sbostic q->memoffset = ICON(0);
238*43221Sbostic 
239*43221Sbostic /* check for value in literal pool, and update pool if necessary */
240*43221Sbostic 
241*43221Sbostic switch(type = p->vtype)
242*43221Sbostic 	{
243*43221Sbostic 	case TYCHAR:
244*43221Sbostic 		if(p->vleng->constblock.const.ci > XL)
245*43221Sbostic 			break;	/* too long for literal table */
246*43221Sbostic 		litflavor = 1;
247*43221Sbostic 		goto loop;
248*43221Sbostic 
249*43221Sbostic 	case TYREAL:
250*43221Sbostic 	case TYDREAL:
251*43221Sbostic 		litflavor = 2;
252*43221Sbostic 		goto loop;
253*43221Sbostic 
254*43221Sbostic 	case TYLOGICAL:
255*43221Sbostic 		type = tylogical;
256*43221Sbostic 	case TYSHORT:
257*43221Sbostic 	case TYLONG:
258*43221Sbostic 		litflavor = 3;
259*43221Sbostic 
260*43221Sbostic 	loop:
261*43221Sbostic 		lastlit = litpool + nliterals;
262*43221Sbostic 		for(litp = litpool ; litp<lastlit ; ++litp)
263*43221Sbostic 			if(type == litp->littype) switch(litflavor)
264*43221Sbostic 				{
265*43221Sbostic 			case 1:
266*43221Sbostic 				if(p->vleng->constblock.const.ci != litp->litval.litcval.litclen)
267*43221Sbostic 					break;
268*43221Sbostic 				if(! eqn( (int) p->vleng->constblock.const.ci, p->const.ccp,
269*43221Sbostic 					litp->litval.litcval.litcstr) )
270*43221Sbostic 						break;
271*43221Sbostic 
272*43221Sbostic 			ret:
273*43221Sbostic 				q->memno = litp->litnum;
274*43221Sbostic 				frexpr(p);
275*43221Sbostic 				return(q);
276*43221Sbostic 
277*43221Sbostic 			case 2:
278*43221Sbostic 				if(p->const.cd[0] == litp->litval.litdval)
279*43221Sbostic 					goto ret;
280*43221Sbostic 				break;
281*43221Sbostic 
282*43221Sbostic 			case 3:
283*43221Sbostic 				if(p->const.ci == litp->litval.litival)
284*43221Sbostic 					goto ret;
285*43221Sbostic 				break;
286*43221Sbostic 				}
287*43221Sbostic 		if(nliterals < MAXLITERALS)
288*43221Sbostic 			{
289*43221Sbostic 			++nliterals;
290*43221Sbostic 			litp->littype = type;
291*43221Sbostic 			litp->litnum = q->memno;
292*43221Sbostic 			switch(litflavor)
293*43221Sbostic 				{
294*43221Sbostic 				case 1:
295*43221Sbostic 					litp->litval.litcval.litclen =
296*43221Sbostic 						p->vleng->constblock.const.ci;
297*43221Sbostic 					cpn( (int) litp->litval.litcval.litclen,
298*43221Sbostic 						p->const.ccp,
299*43221Sbostic 						litp->litval.litcval.litcstr);
300*43221Sbostic 					break;
301*43221Sbostic 
302*43221Sbostic 				case 2:
303*43221Sbostic 					litp->litval.litdval = p->const.cd[0];
304*43221Sbostic 					break;
305*43221Sbostic 
306*43221Sbostic 				case 3:
307*43221Sbostic 					litp->litval.litival = p->const.ci;
308*43221Sbostic 					break;
309*43221Sbostic 				}
310*43221Sbostic 			}
311*43221Sbostic 	default:
312*43221Sbostic 		break;
313*43221Sbostic 	}
314*43221Sbostic 
315*43221Sbostic preven(typealign[ type==TYCHAR ? TYLONG : type ]);
316*43221Sbostic prlabel(asmfile, q->memno);
317*43221Sbostic 
318*43221Sbostic k = 1;
319*43221Sbostic switch(type)
320*43221Sbostic 	{
321*43221Sbostic 	case TYLOGICAL:
322*43221Sbostic 	case TYSHORT:
323*43221Sbostic 	case TYLONG:
324*43221Sbostic 		prconi(asmfile, type, p->const.ci);
325*43221Sbostic 		break;
326*43221Sbostic 
327*43221Sbostic 	case TYCOMPLEX:
328*43221Sbostic 		k = 2;
329*43221Sbostic 	case TYREAL:
330*43221Sbostic 		type = TYREAL;
331*43221Sbostic 		goto flpt;
332*43221Sbostic 
333*43221Sbostic 	case TYDCOMPLEX:
334*43221Sbostic 		k = 2;
335*43221Sbostic 	case TYDREAL:
336*43221Sbostic 		type = TYDREAL;
337*43221Sbostic 
338*43221Sbostic 	flpt:
339*43221Sbostic 		for(i = 0 ; i < k ; ++i)
340*43221Sbostic 			prconr(asmfile, type, p->const.cd[i]);
341*43221Sbostic 		break;
342*43221Sbostic 
343*43221Sbostic 	case TYCHAR:
344*43221Sbostic 		putstr(asmfile, p->const.ccp,
345*43221Sbostic 			(int) (p->vleng->constblock.const.ci) );
346*43221Sbostic 		break;
347*43221Sbostic 
348*43221Sbostic 	case TYADDR:
349*43221Sbostic 		prcona(asmfile, p->const.ci);
350*43221Sbostic 		break;
351*43221Sbostic 
352*43221Sbostic 	default:
353*43221Sbostic 		badtype("putconst", p->vtype);
354*43221Sbostic 	}
355*43221Sbostic 
356*43221Sbostic frexpr(p);
357*43221Sbostic return( q );
358*43221Sbostic }
359*43221Sbostic 
360*43221Sbostic /*
361*43221Sbostic  * put out a character string constant.  begin every one on
362*43221Sbostic  * a long integer boundary, and pad with nulls
363*43221Sbostic  */
364*43221Sbostic putstr(fp, s, n)
365*43221Sbostic FILEP fp;
366*43221Sbostic register char *s;
367*43221Sbostic register int n;
368*43221Sbostic {
369*43221Sbostic int b[SZLONG];
370*43221Sbostic register int i;
371*43221Sbostic 
372*43221Sbostic i = 0;
373*43221Sbostic while(--n >= 0)
374*43221Sbostic 	{
375*43221Sbostic 	b[i++] = *s++;
376*43221Sbostic 	if(i == SZLONG)
377*43221Sbostic 		{
378*43221Sbostic 		prchars(fp, b);
379*43221Sbostic 		prchars(fp, b+SZSHORT);
380*43221Sbostic 		i = 0;
381*43221Sbostic 		}
382*43221Sbostic 	}
383*43221Sbostic 
384*43221Sbostic while(i < SZLONG)
385*43221Sbostic 	b[i++] = '\0';
386*43221Sbostic prchars(fp, b);
387*43221Sbostic prchars(fp, b+SZSHORT);
388*43221Sbostic }
389