xref: /csrg-svn/usr.bin/f77/pass1.tahoe/put.c (revision 46306)
143221Sbostic /*
243221Sbostic  * Copyright (c) 1980 Regents of the University of California.
343221Sbostic  * All rights reserved.  The Berkeley software License Agreement
443221Sbostic  * specifies the terms and conditions for redistribution.
543221Sbostic  */
643221Sbostic 
743221Sbostic #ifndef lint
843221Sbostic static char sccsid[] = "@(#)put.c	5.1 (Berkeley) 6/7/85";
943221Sbostic #endif not lint
1043221Sbostic 
1143221Sbostic /*
1243221Sbostic  * put.c
1343221Sbostic  *
1443221Sbostic  * Intermediate code generation procedures common to both
1543221Sbostic  * Johnson (Portable) and Ritchie families of second passes
1643221Sbostic  *
1743221Sbostic  * University of Utah CS Dept modification history:
1843221Sbostic  *
1943221Sbostic  * $Log:	put.c,v $
2043221Sbostic  * Revision 3.2  85/05/04  15:41:24  mckusick
2143221Sbostic  * Fix alignment problem -- change code to match comment...
2243221Sbostic  *
2343221Sbostic  * Revision 3.2  85/04/29  21:36:07  donn
2443221Sbostic  * Fix alignment problem -- change code to match comment...
2543221Sbostic  *
2643221Sbostic  * Revision 3.1  85/02/27  19:12:04  donn
2743221Sbostic  * Changed to use pcc.h instead of pccdefs.h.
2843221Sbostic  *
2943221Sbostic  * Revision 2.1  84/07/19  12:04:21  donn
3043221Sbostic  * Changed comment headers for UofU.
3143221Sbostic  *
3243221Sbostic  * Revision 1.2  84/04/02  14:40:21  donn
3343221Sbostic  * Added fixes from Conrad Huang at UCSF for calculating the length of a
3443221Sbostic  * concatenation of strings correctly.
3543221Sbostic  *
3643221Sbostic  */
3743221Sbostic 
3843221Sbostic #include "defs.h"
3943221Sbostic 
4043221Sbostic #if FAMILY == PCC
4143221Sbostic #	include <pcc.h>
4243221Sbostic #else
4343221Sbostic #	include "dmrdefs.h"
4443221Sbostic #endif
4543221Sbostic 
4643221Sbostic /*
4743221Sbostic char *ops [ ] =
4843221Sbostic 	{
4943221Sbostic 	"??", "+", "-", "*", "/", "**", "-",
5043221Sbostic 	"OR", "AND", "EQV", "NEQV", "NOT",
5143221Sbostic 	"CONCAT",
5243221Sbostic 	"<", "==", ">", "<=", "!=", ">=",
5343221Sbostic 	" of ", " ofC ", " = ", " += ", " *= ", " CONV ", " << ", " % ",
5443221Sbostic 	" , ", " ? ", " : "
5543221Sbostic 	" abs ", " min ", " max ", " addr ", " indirect ",
5643221Sbostic 	" bitor ", " bitand ", " bitxor ", " bitnot ", " >> ", " () "
5743221Sbostic 	};
5843221Sbostic */
5943221Sbostic 
6043221Sbostic int ops2 [ ] =
6143221Sbostic 	{
6243221Sbostic 	PCC_ERROR, PCC_PLUS, PCC_MINUS, PCC_MUL, PCC_DIV, PCC_ERROR, PCC_UMINUS,
6343221Sbostic 	PCC_OROR, PCC_ANDAND, PCC_EQ, PCC_NE, PCC_NOT,
6443221Sbostic 	PCC_ERROR,
6543221Sbostic 	PCC_LT, PCC_EQ, PCC_GT, PCC_LE, PCC_NE, PCC_GE,
6643221Sbostic 	PCC_CALL, PCC_CALL, PCC_ASSIGN, PCC_PLUSEQ, PCC_MULEQ, PCC_SCONV, PCC_LS, PCC_MOD,
6743221Sbostic 	PCC_COMOP, PCC_QUEST, PCC_COLON,
6843221Sbostic 	PCC_ERROR, PCC_ERROR, PCC_ERROR, PCC_ERROR, PCC_DEREF,
6943221Sbostic 	PCC_OR, PCC_AND, PCC_ER, PCC_COMPL, PCC_RS, PCC_ERROR
7043221Sbostic 	};
7143221Sbostic 
7243221Sbostic 
7343221Sbostic int types2 [ ] =
7443221Sbostic 	{
7543221Sbostic 	PCC_ERROR, PCCT_INT|PCCTM_PTR, PCCT_SHORT, PCCT_LONG, PCCT_FLOAT, PCCT_DOUBLE,
7643221Sbostic #if TARGET == INTERDATA
7743221Sbostic 	PCC_ERROR, PCC_ERROR, PCCT_LONG, PCCT_CHAR, PCCT_INT, PCC_ERROR
7843221Sbostic #else
7943221Sbostic 	PCCT_FLOAT, PCCT_DOUBLE, PCCT_LONG, PCCT_CHAR, PCCT_INT, PCC_ERROR
8043221Sbostic #endif
8143221Sbostic 	};
8243221Sbostic 
8343221Sbostic 
8443221Sbostic setlog()
8543221Sbostic {
8643221Sbostic types2[TYLOGICAL] = types2[tylogical];
8743221Sbostic typesize[TYLOGICAL] = typesize[tylogical];
8843221Sbostic typealign[TYLOGICAL] = typealign[tylogical];
8943221Sbostic }
9043221Sbostic 
9143221Sbostic 
9243221Sbostic putex1(p)
9343221Sbostic expptr p;
9443221Sbostic {
9543221Sbostic putx( fixtype(p) );
9643221Sbostic 
9743221Sbostic if (!optimflag)
9843221Sbostic 	{
9943221Sbostic 	templist = hookup(templist, holdtemps);
10043221Sbostic 	holdtemps = NULL;
10143221Sbostic 	}
10243221Sbostic }
10343221Sbostic 
10443221Sbostic 
10543221Sbostic 
10643221Sbostic 
10743221Sbostic 
10843221Sbostic putassign(lp, rp)
10943221Sbostic expptr lp, rp;
11043221Sbostic {
11143221Sbostic putx( fixexpr( mkexpr(OPASSIGN, lp, rp) ));
11243221Sbostic }
11343221Sbostic 
11443221Sbostic 
11543221Sbostic 
11643221Sbostic 
11743221Sbostic puteq(lp, rp)
11843221Sbostic expptr lp, rp;
11943221Sbostic {
12043221Sbostic putexpr( mkexpr(OPASSIGN, lp, rp) );
12143221Sbostic }
12243221Sbostic 
12343221Sbostic 
12443221Sbostic 
12543221Sbostic 
12643221Sbostic /* put code for  a *= b */
12743221Sbostic 
12843221Sbostic putsteq(a, b)
12943221Sbostic expptr a, b;
13043221Sbostic {
13143221Sbostic putx( fixexpr( mkexpr(OPSTAREQ, cpexpr(a), cpexpr(b)) ));
13243221Sbostic }
13343221Sbostic 
13443221Sbostic 
13543221Sbostic 
13643221Sbostic 
13743221Sbostic 
13843221Sbostic Addrp realpart(p)
13943221Sbostic register Addrp p;
14043221Sbostic {
14143221Sbostic register Addrp q;
14243221Sbostic 
14343221Sbostic q = (Addrp) cpexpr(p);
14443221Sbostic if( ISCOMPLEX(p->vtype) )
14543221Sbostic 	q->vtype += (TYREAL-TYCOMPLEX);
14643221Sbostic return(q);
14743221Sbostic }
14843221Sbostic 
14943221Sbostic 
15043221Sbostic 
15143221Sbostic 
15243221Sbostic expptr imagpart(p)
15343221Sbostic register expptr p;
15443221Sbostic {
15543221Sbostic register Addrp q;
15643221Sbostic expptr mkrealcon();
15743221Sbostic 
15843221Sbostic if (ISCONST(p))
15943221Sbostic 	{
16043221Sbostic 	if (ISCOMPLEX(p->constblock.vtype))
16143221Sbostic 		return(mkrealcon(p->constblock.vtype == TYCOMPLEX ?
16243221Sbostic 					TYREAL : TYDREAL,
163*46306Sbostic 				p->constblock.constant.cd[1]));
16443221Sbostic 	else if (p->constblock.vtype == TYDREAL)
16543221Sbostic 		return(mkrealcon(TYDREAL, 0.0));
16643221Sbostic 	else
16743221Sbostic 		return(mkrealcon(TYREAL, 0.0));
16843221Sbostic 	}
16943221Sbostic else if (p->tag == TADDR)
17043221Sbostic 	{
17143221Sbostic 	if( ISCOMPLEX(p->addrblock.vtype) )
17243221Sbostic 		{
17343221Sbostic 		q = (Addrp) cpexpr(p);
17443221Sbostic 		q->vtype += (TYREAL-TYCOMPLEX);
17543221Sbostic 		q->memoffset = mkexpr(OPPLUS, q->memoffset,
17643221Sbostic 					ICON(typesize[q->vtype]));
17743221Sbostic 		return( (expptr) q );
17843221Sbostic 		}
17943221Sbostic 	else
18043221Sbostic 		return( mkrealcon( ISINT(p->addrblock.vtype) ?
18143221Sbostic 			TYDREAL : p->addrblock.vtype , 0.0));
18243221Sbostic 	}
18343221Sbostic else
18443221Sbostic 	badtag("imagpart", p->tag);
18543221Sbostic }
18643221Sbostic 
18743221Sbostic 
18843221Sbostic 
18943221Sbostic 
19043221Sbostic ncat(p)
19143221Sbostic register expptr p;
19243221Sbostic {
19343221Sbostic if(p->tag==TEXPR && p->exprblock.opcode==OPCONCAT)
19443221Sbostic 	return( ncat(p->exprblock.leftp) + ncat(p->exprblock.rightp) );
19543221Sbostic else	return(1);
19643221Sbostic }
19743221Sbostic 
19843221Sbostic 
19943221Sbostic 
20043221Sbostic 
20143221Sbostic ftnint lencat(p)
20243221Sbostic register expptr p;
20343221Sbostic {
20443221Sbostic if(p->tag==TEXPR && p->exprblock.opcode==OPCONCAT)
20543221Sbostic 	return( lencat(p->exprblock.leftp) + lencat(p->exprblock.rightp) );
20643221Sbostic else if( p->headblock.vleng!=NULL && ISICON(p->headblock.vleng) )
207*46306Sbostic 	return(p->headblock.vleng->constblock.constant.ci);
20843221Sbostic else if(p->tag==TADDR && p->addrblock.varleng!=0)
20943221Sbostic 	return(p->addrblock.varleng);
21043221Sbostic else if(p->tag==TTEMP && p->tempblock.varleng!=0)
21143221Sbostic 	return(p->tempblock.varleng);
21243221Sbostic else
21343221Sbostic 	{
21443221Sbostic 	err("impossible element in concatenation");
21543221Sbostic 	return(0);
21643221Sbostic 	}
21743221Sbostic }
21843221Sbostic 
21943221Sbostic Addrp putconst(p)
22043221Sbostic register Constp p;
22143221Sbostic {
22243221Sbostic register Addrp q;
22343221Sbostic struct Literal *litp, *lastlit;
22443221Sbostic int i, k, type;
22543221Sbostic int litflavor;
22643221Sbostic 
22743221Sbostic if( p->tag != TCONST )
22843221Sbostic 	badtag("putconst", p->tag);
22943221Sbostic 
23043221Sbostic q = ALLOC(Addrblock);
23143221Sbostic q->tag = TADDR;
23243221Sbostic type = p->vtype;
23343221Sbostic q->vtype = ( type==TYADDR ? TYINT : type );
23443221Sbostic q->vleng = (expptr) cpexpr(p->vleng);
23543221Sbostic q->vstg = STGCONST;
23643221Sbostic q->memno = newlabel();
23743221Sbostic q->memoffset = ICON(0);
23843221Sbostic 
23943221Sbostic /* check for value in literal pool, and update pool if necessary */
24043221Sbostic 
24143221Sbostic switch(type = p->vtype)
24243221Sbostic 	{
24343221Sbostic 	case TYCHAR:
244*46306Sbostic 		if(p->vleng->constblock.constant.ci > XL)
24543221Sbostic 			break;	/* too long for literal table */
24643221Sbostic 		litflavor = 1;
24743221Sbostic 		goto loop;
24843221Sbostic 
24943221Sbostic 	case TYREAL:
25043221Sbostic 	case TYDREAL:
25143221Sbostic 		litflavor = 2;
25243221Sbostic 		goto loop;
25343221Sbostic 
25443221Sbostic 	case TYLOGICAL:
25543221Sbostic 		type = tylogical;
25643221Sbostic 	case TYSHORT:
25743221Sbostic 	case TYLONG:
25843221Sbostic 		litflavor = 3;
25943221Sbostic 
26043221Sbostic 	loop:
26143221Sbostic 		lastlit = litpool + nliterals;
26243221Sbostic 		for(litp = litpool ; litp<lastlit ; ++litp)
26343221Sbostic 			if(type == litp->littype) switch(litflavor)
26443221Sbostic 				{
26543221Sbostic 			case 1:
266*46306Sbostic 				if(p->vleng->constblock.constant.ci != litp->litval.litcval.litclen)
26743221Sbostic 					break;
268*46306Sbostic 				if(! eqn( (int) p->vleng->constblock.constant.ci, p->constant.ccp,
26943221Sbostic 					litp->litval.litcval.litcstr) )
27043221Sbostic 						break;
27143221Sbostic 
27243221Sbostic 			ret:
27343221Sbostic 				q->memno = litp->litnum;
27443221Sbostic 				frexpr(p);
27543221Sbostic 				return(q);
27643221Sbostic 
27743221Sbostic 			case 2:
278*46306Sbostic 				if(p->constant.cd[0] == litp->litval.litdval)
27943221Sbostic 					goto ret;
28043221Sbostic 				break;
28143221Sbostic 
28243221Sbostic 			case 3:
283*46306Sbostic 				if(p->constant.ci == litp->litval.litival)
28443221Sbostic 					goto ret;
28543221Sbostic 				break;
28643221Sbostic 				}
28743221Sbostic 		if(nliterals < MAXLITERALS)
28843221Sbostic 			{
28943221Sbostic 			++nliterals;
29043221Sbostic 			litp->littype = type;
29143221Sbostic 			litp->litnum = q->memno;
29243221Sbostic 			switch(litflavor)
29343221Sbostic 				{
29443221Sbostic 				case 1:
29543221Sbostic 					litp->litval.litcval.litclen =
296*46306Sbostic 						p->vleng->constblock.constant.ci;
29743221Sbostic 					cpn( (int) litp->litval.litcval.litclen,
298*46306Sbostic 						p->constant.ccp,
29943221Sbostic 						litp->litval.litcval.litcstr);
30043221Sbostic 					break;
30143221Sbostic 
30243221Sbostic 				case 2:
303*46306Sbostic 					litp->litval.litdval = p->constant.cd[0];
30443221Sbostic 					break;
30543221Sbostic 
30643221Sbostic 				case 3:
307*46306Sbostic 					litp->litval.litival = p->constant.ci;
30843221Sbostic 					break;
30943221Sbostic 				}
31043221Sbostic 			}
31143221Sbostic 	default:
31243221Sbostic 		break;
31343221Sbostic 	}
31443221Sbostic 
31543221Sbostic preven(typealign[ type==TYCHAR ? TYLONG : type ]);
31643221Sbostic prlabel(asmfile, q->memno);
31743221Sbostic 
31843221Sbostic k = 1;
31943221Sbostic switch(type)
32043221Sbostic 	{
32143221Sbostic 	case TYLOGICAL:
32243221Sbostic 	case TYSHORT:
32343221Sbostic 	case TYLONG:
324*46306Sbostic 		prconi(asmfile, type, p->constant.ci);
32543221Sbostic 		break;
32643221Sbostic 
32743221Sbostic 	case TYCOMPLEX:
32843221Sbostic 		k = 2;
32943221Sbostic 	case TYREAL:
33043221Sbostic 		type = TYREAL;
33143221Sbostic 		goto flpt;
33243221Sbostic 
33343221Sbostic 	case TYDCOMPLEX:
33443221Sbostic 		k = 2;
33543221Sbostic 	case TYDREAL:
33643221Sbostic 		type = TYDREAL;
33743221Sbostic 
33843221Sbostic 	flpt:
33943221Sbostic 		for(i = 0 ; i < k ; ++i)
340*46306Sbostic 			prconr(asmfile, type, p->constant.cd[i]);
34143221Sbostic 		break;
34243221Sbostic 
34343221Sbostic 	case TYCHAR:
344*46306Sbostic 		putstr(asmfile, p->constant.ccp,
345*46306Sbostic 			(int) (p->vleng->constblock.constant.ci) );
34643221Sbostic 		break;
34743221Sbostic 
34843221Sbostic 	case TYADDR:
349*46306Sbostic 		prcona(asmfile, p->constant.ci);
35043221Sbostic 		break;
35143221Sbostic 
35243221Sbostic 	default:
35343221Sbostic 		badtype("putconst", p->vtype);
35443221Sbostic 	}
35543221Sbostic 
35643221Sbostic frexpr(p);
35743221Sbostic return( q );
35843221Sbostic }
35943221Sbostic 
36043221Sbostic /*
36143221Sbostic  * put out a character string constant.  begin every one on
36243221Sbostic  * a long integer boundary, and pad with nulls
36343221Sbostic  */
36443221Sbostic putstr(fp, s, n)
36543221Sbostic FILEP fp;
36643221Sbostic register char *s;
36743221Sbostic register int n;
36843221Sbostic {
36943221Sbostic int b[SZLONG];
37043221Sbostic register int i;
37143221Sbostic 
37243221Sbostic i = 0;
37343221Sbostic while(--n >= 0)
37443221Sbostic 	{
37543221Sbostic 	b[i++] = *s++;
37643221Sbostic 	if(i == SZLONG)
37743221Sbostic 		{
37843221Sbostic 		prchars(fp, b);
37943221Sbostic 		prchars(fp, b+SZSHORT);
38043221Sbostic 		i = 0;
38143221Sbostic 		}
38243221Sbostic 	}
38343221Sbostic 
38443221Sbostic while(i < SZLONG)
38543221Sbostic 	b[i++] = '\0';
38643221Sbostic prchars(fp, b);
38743221Sbostic prchars(fp, b+SZSHORT);
38843221Sbostic }
389