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