xref: /csrg-svn/usr.bin/f77/pass1.vax/put.c (revision 47955)
1*47955Sbostic /*-
2*47955Sbostic  * Copyright (c) 1980 The Regents of the University of California.
3*47955Sbostic  * All rights reserved.
4*47955Sbostic  *
5*47955Sbostic  * %sccs.include.proprietary.c%
622864Smckusick  */
722864Smckusick 
822864Smckusick #ifndef lint
9*47955Sbostic static char sccsid[] = "@(#)put.c	5.3 (Berkeley) 04/12/91";
10*47955Sbostic #endif /* not lint */
1122864Smckusick 
1222864Smckusick /*
1322864Smckusick  * put.c
1422864Smckusick  *
1522864Smckusick  * Intermediate code generation procedures common to both
1622864Smckusick  * Johnson (Portable) and Ritchie families of second passes
1722864Smckusick  *
1822864Smckusick  * University of Utah CS Dept modification history:
1922864Smckusick  *
2022864Smckusick  * $Log:	put.c,v $
2122864Smckusick  * Revision 3.2  85/05/04  15:41:24  mckusick
2222864Smckusick  * Fix alignment problem -- change code to match comment...
2322864Smckusick  *
2422864Smckusick  * Revision 3.2  85/04/29  21:36:07  donn
2522864Smckusick  * Fix alignment problem -- change code to match comment...
2622864Smckusick  *
2722864Smckusick  * Revision 3.1  85/02/27  19:12:04  donn
2822864Smckusick  * Changed to use pcc.h instead of pccdefs.h.
2922864Smckusick  *
3022864Smckusick  * Revision 2.1  84/07/19  12:04:21  donn
3122864Smckusick  * Changed comment headers for UofU.
3222864Smckusick  *
3322864Smckusick  * Revision 1.2  84/04/02  14:40:21  donn
3422864Smckusick  * Added fixes from Conrad Huang at UCSF for calculating the length of a
3522864Smckusick  * concatenation of strings correctly.
3622864Smckusick  *
3722864Smckusick  */
3822864Smckusick 
3922864Smckusick #include "defs.h"
4022864Smckusick 
4122864Smckusick #if FAMILY == PCC
4222864Smckusick #	include <pcc.h>
4322864Smckusick #else
4422864Smckusick #	include "dmrdefs.h"
4522864Smckusick #endif
4622864Smckusick 
4722864Smckusick /*
4822864Smckusick char *ops [ ] =
4922864Smckusick 	{
5022864Smckusick 	"??", "+", "-", "*", "/", "**", "-",
5122864Smckusick 	"OR", "AND", "EQV", "NEQV", "NOT",
5222864Smckusick 	"CONCAT",
5322864Smckusick 	"<", "==", ">", "<=", "!=", ">=",
5422864Smckusick 	" of ", " ofC ", " = ", " += ", " *= ", " CONV ", " << ", " % ",
5522864Smckusick 	" , ", " ? ", " : "
5622864Smckusick 	" abs ", " min ", " max ", " addr ", " indirect ",
5722864Smckusick 	" bitor ", " bitand ", " bitxor ", " bitnot ", " >> ", " () "
5822864Smckusick 	};
5922864Smckusick */
6022864Smckusick 
6122864Smckusick int ops2 [ ] =
6222864Smckusick 	{
6322864Smckusick 	PCC_ERROR, PCC_PLUS, PCC_MINUS, PCC_MUL, PCC_DIV, PCC_ERROR, PCC_UMINUS,
6422864Smckusick 	PCC_OROR, PCC_ANDAND, PCC_EQ, PCC_NE, PCC_NOT,
6522864Smckusick 	PCC_ERROR,
6622864Smckusick 	PCC_LT, PCC_EQ, PCC_GT, PCC_LE, PCC_NE, PCC_GE,
6722864Smckusick 	PCC_CALL, PCC_CALL, PCC_ASSIGN, PCC_PLUSEQ, PCC_MULEQ, PCC_SCONV, PCC_LS, PCC_MOD,
6822864Smckusick 	PCC_COMOP, PCC_QUEST, PCC_COLON,
6922864Smckusick 	PCC_ERROR, PCC_ERROR, PCC_ERROR, PCC_ERROR, PCC_DEREF,
7022864Smckusick 	PCC_OR, PCC_AND, PCC_ER, PCC_COMPL, PCC_RS, PCC_ERROR
7122864Smckusick 	};
7222864Smckusick 
7322864Smckusick 
7422864Smckusick int types2 [ ] =
7522864Smckusick 	{
7622864Smckusick 	PCC_ERROR, PCCT_INT|PCCTM_PTR, PCCT_SHORT, PCCT_LONG, PCCT_FLOAT, PCCT_DOUBLE,
7722864Smckusick #if TARGET == INTERDATA
7822864Smckusick 	PCC_ERROR, PCC_ERROR, PCCT_LONG, PCCT_CHAR, PCCT_INT, PCC_ERROR
7922864Smckusick #else
8022864Smckusick 	PCCT_FLOAT, PCCT_DOUBLE, PCCT_LONG, PCCT_CHAR, PCCT_INT, PCC_ERROR
8122864Smckusick #endif
8222864Smckusick 	};
8322864Smckusick 
8422864Smckusick 
setlog()8522864Smckusick setlog()
8622864Smckusick {
8722864Smckusick types2[TYLOGICAL] = types2[tylogical];
8822864Smckusick typesize[TYLOGICAL] = typesize[tylogical];
8922864Smckusick typealign[TYLOGICAL] = typealign[tylogical];
9022864Smckusick }
9122864Smckusick 
9222864Smckusick 
putex1(p)9322864Smckusick putex1(p)
9422864Smckusick expptr p;
9522864Smckusick {
9622864Smckusick putx( fixtype(p) );
9722864Smckusick 
9822864Smckusick if (!optimflag)
9922864Smckusick 	{
10022864Smckusick 	templist = hookup(templist, holdtemps);
10122864Smckusick 	holdtemps = NULL;
10222864Smckusick 	}
10322864Smckusick }
10422864Smckusick 
10522864Smckusick 
10622864Smckusick 
10722864Smckusick 
10822864Smckusick 
putassign(lp,rp)10922864Smckusick putassign(lp, rp)
11022864Smckusick expptr lp, rp;
11122864Smckusick {
11222864Smckusick putx( fixexpr( mkexpr(OPASSIGN, lp, rp) ));
11322864Smckusick }
11422864Smckusick 
11522864Smckusick 
11622864Smckusick 
11722864Smckusick 
puteq(lp,rp)11822864Smckusick puteq(lp, rp)
11922864Smckusick expptr lp, rp;
12022864Smckusick {
12122864Smckusick putexpr( mkexpr(OPASSIGN, lp, rp) );
12222864Smckusick }
12322864Smckusick 
12422864Smckusick 
12522864Smckusick 
12622864Smckusick 
12722864Smckusick /* put code for  a *= b */
12822864Smckusick 
putsteq(a,b)12922864Smckusick putsteq(a, b)
13022864Smckusick expptr a, b;
13122864Smckusick {
13222864Smckusick putx( fixexpr( mkexpr(OPSTAREQ, cpexpr(a), cpexpr(b)) ));
13322864Smckusick }
13422864Smckusick 
13522864Smckusick 
13622864Smckusick 
13722864Smckusick 
13822864Smckusick 
realpart(p)13922864Smckusick Addrp realpart(p)
14022864Smckusick register Addrp p;
14122864Smckusick {
14222864Smckusick register Addrp q;
14322864Smckusick 
14422864Smckusick q = (Addrp) cpexpr(p);
14522864Smckusick if( ISCOMPLEX(p->vtype) )
14622864Smckusick 	q->vtype += (TYREAL-TYCOMPLEX);
14722864Smckusick return(q);
14822864Smckusick }
14922864Smckusick 
15022864Smckusick 
15122864Smckusick 
15222864Smckusick 
imagpart(p)15322864Smckusick expptr imagpart(p)
15422864Smckusick register expptr p;
15522864Smckusick {
15622864Smckusick register Addrp q;
15722864Smckusick expptr mkrealcon();
15822864Smckusick 
15922864Smckusick if (ISCONST(p))
16022864Smckusick 	{
16122864Smckusick 	if (ISCOMPLEX(p->constblock.vtype))
16222864Smckusick 		return(mkrealcon(p->constblock.vtype == TYCOMPLEX ?
16322864Smckusick 					TYREAL : TYDREAL,
16433257Sbostic 				p->constblock.constant.cd[1]));
16522864Smckusick 	else if (p->constblock.vtype == TYDREAL)
16622864Smckusick 		return(mkrealcon(TYDREAL, 0.0));
16722864Smckusick 	else
16822864Smckusick 		return(mkrealcon(TYREAL, 0.0));
16922864Smckusick 	}
17022864Smckusick else if (p->tag == TADDR)
17122864Smckusick 	{
17222864Smckusick 	if( ISCOMPLEX(p->addrblock.vtype) )
17322864Smckusick 		{
17422864Smckusick 		q = (Addrp) cpexpr(p);
17522864Smckusick 		q->vtype += (TYREAL-TYCOMPLEX);
17622864Smckusick 		q->memoffset = mkexpr(OPPLUS, q->memoffset,
17722864Smckusick 					ICON(typesize[q->vtype]));
17822864Smckusick 		return( (expptr) q );
17922864Smckusick 		}
18022864Smckusick 	else
18122864Smckusick 		return( mkrealcon( ISINT(p->addrblock.vtype) ?
18222864Smckusick 			TYDREAL : p->addrblock.vtype , 0.0));
18322864Smckusick 	}
18422864Smckusick else
18522864Smckusick 	badtag("imagpart", p->tag);
18622864Smckusick }
18722864Smckusick 
18822864Smckusick 
18922864Smckusick 
19022864Smckusick 
ncat(p)19122864Smckusick ncat(p)
19222864Smckusick register expptr p;
19322864Smckusick {
19422864Smckusick if(p->tag==TEXPR && p->exprblock.opcode==OPCONCAT)
19522864Smckusick 	return( ncat(p->exprblock.leftp) + ncat(p->exprblock.rightp) );
19622864Smckusick else	return(1);
19722864Smckusick }
19822864Smckusick 
19922864Smckusick 
20022864Smckusick 
20122864Smckusick 
lencat(p)20222864Smckusick ftnint lencat(p)
20322864Smckusick register expptr p;
20422864Smckusick {
20522864Smckusick if(p->tag==TEXPR && p->exprblock.opcode==OPCONCAT)
20622864Smckusick 	return( lencat(p->exprblock.leftp) + lencat(p->exprblock.rightp) );
20722864Smckusick else if( p->headblock.vleng!=NULL && ISICON(p->headblock.vleng) )
20833257Sbostic 	return(p->headblock.vleng->constblock.constant.ci);
20922864Smckusick else if(p->tag==TADDR && p->addrblock.varleng!=0)
21022864Smckusick 	return(p->addrblock.varleng);
21122864Smckusick else if(p->tag==TTEMP && p->tempblock.varleng!=0)
21222864Smckusick 	return(p->tempblock.varleng);
21322864Smckusick else
21422864Smckusick 	{
21522864Smckusick 	err("impossible element in concatenation");
21622864Smckusick 	return(0);
21722864Smckusick 	}
21822864Smckusick }
21922864Smckusick 
putconst(p)22022864Smckusick Addrp putconst(p)
22122864Smckusick register Constp p;
22222864Smckusick {
22322864Smckusick register Addrp q;
22422864Smckusick struct Literal *litp, *lastlit;
22522864Smckusick int i, k, type;
22622864Smckusick int litflavor;
22722864Smckusick 
22822864Smckusick if( p->tag != TCONST )
22922864Smckusick 	badtag("putconst", p->tag);
23022864Smckusick 
23122864Smckusick q = ALLOC(Addrblock);
23222864Smckusick q->tag = TADDR;
23322864Smckusick type = p->vtype;
23422864Smckusick q->vtype = ( type==TYADDR ? TYINT : type );
23522864Smckusick q->vleng = (expptr) cpexpr(p->vleng);
23622864Smckusick q->vstg = STGCONST;
23722864Smckusick q->memno = newlabel();
23822864Smckusick q->memoffset = ICON(0);
23922864Smckusick 
24022864Smckusick /* check for value in literal pool, and update pool if necessary */
24122864Smckusick 
24222864Smckusick switch(type = p->vtype)
24322864Smckusick 	{
24422864Smckusick 	case TYCHAR:
24533257Sbostic 		if(p->vleng->constblock.constant.ci > XL)
24622864Smckusick 			break;	/* too long for literal table */
24722864Smckusick 		litflavor = 1;
24822864Smckusick 		goto loop;
24922864Smckusick 
25022864Smckusick 	case TYREAL:
25122864Smckusick 	case TYDREAL:
25222864Smckusick 		litflavor = 2;
25322864Smckusick 		goto loop;
25422864Smckusick 
25522864Smckusick 	case TYLOGICAL:
25622864Smckusick 		type = tylogical;
25722864Smckusick 	case TYSHORT:
25822864Smckusick 	case TYLONG:
25922864Smckusick 		litflavor = 3;
26022864Smckusick 
26122864Smckusick 	loop:
26222864Smckusick 		lastlit = litpool + nliterals;
26322864Smckusick 		for(litp = litpool ; litp<lastlit ; ++litp)
26422864Smckusick 			if(type == litp->littype) switch(litflavor)
26522864Smckusick 				{
26622864Smckusick 			case 1:
26733257Sbostic 				if(p->vleng->constblock.constant.ci != litp->litval.litcval.litclen)
26822864Smckusick 					break;
26933257Sbostic 				if(! eqn( (int) p->vleng->constblock.constant.ci, p->constant.ccp,
27022864Smckusick 					litp->litval.litcval.litcstr) )
27122864Smckusick 						break;
27222864Smckusick 
27322864Smckusick 			ret:
27422864Smckusick 				q->memno = litp->litnum;
27522864Smckusick 				frexpr(p);
27622864Smckusick 				return(q);
27722864Smckusick 
27822864Smckusick 			case 2:
27933257Sbostic 				if(p->constant.cd[0] == litp->litval.litdval)
28022864Smckusick 					goto ret;
28122864Smckusick 				break;
28222864Smckusick 
28322864Smckusick 			case 3:
28433257Sbostic 				if(p->constant.ci == litp->litval.litival)
28522864Smckusick 					goto ret;
28622864Smckusick 				break;
28722864Smckusick 				}
28822864Smckusick 		if(nliterals < MAXLITERALS)
28922864Smckusick 			{
29022864Smckusick 			++nliterals;
29122864Smckusick 			litp->littype = type;
29222864Smckusick 			litp->litnum = q->memno;
29322864Smckusick 			switch(litflavor)
29422864Smckusick 				{
29522864Smckusick 				case 1:
29622864Smckusick 					litp->litval.litcval.litclen =
29733257Sbostic 						p->vleng->constblock.constant.ci;
29822864Smckusick 					cpn( (int) litp->litval.litcval.litclen,
29933257Sbostic 						p->constant.ccp,
30022864Smckusick 						litp->litval.litcval.litcstr);
30122864Smckusick 					break;
30222864Smckusick 
30322864Smckusick 				case 2:
30433257Sbostic 					litp->litval.litdval = p->constant.cd[0];
30522864Smckusick 					break;
30622864Smckusick 
30722864Smckusick 				case 3:
30833257Sbostic 					litp->litval.litival = p->constant.ci;
30922864Smckusick 					break;
31022864Smckusick 				}
31122864Smckusick 			}
31222864Smckusick 	default:
31322864Smckusick 		break;
31422864Smckusick 	}
31522864Smckusick 
31622864Smckusick preven(typealign[ type==TYCHAR ? TYLONG : type ]);
31722864Smckusick prlabel(asmfile, q->memno);
31822864Smckusick 
31922864Smckusick k = 1;
32022864Smckusick switch(type)
32122864Smckusick 	{
32222864Smckusick 	case TYLOGICAL:
32322864Smckusick 	case TYSHORT:
32422864Smckusick 	case TYLONG:
32533257Sbostic 		prconi(asmfile, type, p->constant.ci);
32622864Smckusick 		break;
32722864Smckusick 
32822864Smckusick 	case TYCOMPLEX:
32922864Smckusick 		k = 2;
33022864Smckusick 	case TYREAL:
33122864Smckusick 		type = TYREAL;
33222864Smckusick 		goto flpt;
33322864Smckusick 
33422864Smckusick 	case TYDCOMPLEX:
33522864Smckusick 		k = 2;
33622864Smckusick 	case TYDREAL:
33722864Smckusick 		type = TYDREAL;
33822864Smckusick 
33922864Smckusick 	flpt:
34022864Smckusick 		for(i = 0 ; i < k ; ++i)
34133257Sbostic 			prconr(asmfile, type, p->constant.cd[i]);
34222864Smckusick 		break;
34322864Smckusick 
34422864Smckusick 	case TYCHAR:
34533257Sbostic 		putstr(asmfile, p->constant.ccp,
34633257Sbostic 			(int) (p->vleng->constblock.constant.ci) );
34722864Smckusick 		break;
34822864Smckusick 
34922864Smckusick 	case TYADDR:
35033257Sbostic 		prcona(asmfile, p->constant.ci);
35122864Smckusick 		break;
35222864Smckusick 
35322864Smckusick 	default:
35422864Smckusick 		badtype("putconst", p->vtype);
35522864Smckusick 	}
35622864Smckusick 
35722864Smckusick frexpr(p);
35822864Smckusick return( q );
35922864Smckusick }
36022864Smckusick 
36122864Smckusick /*
36222864Smckusick  * put out a character string constant.  begin every one on
36322864Smckusick  * a long integer boundary, and pad with nulls
36422864Smckusick  */
putstr(fp,s,n)36522864Smckusick putstr(fp, s, n)
36622864Smckusick FILEP fp;
36722864Smckusick register char *s;
36822864Smckusick register int n;
36922864Smckusick {
37022864Smckusick int b[SZLONG];
37122864Smckusick register int i;
37222864Smckusick 
37322864Smckusick i = 0;
37422864Smckusick while(--n >= 0)
37522864Smckusick 	{
37622864Smckusick 	b[i++] = *s++;
37722864Smckusick 	if(i == SZLONG)
37822864Smckusick 		{
37922864Smckusick 		prchars(fp, b);
38022864Smckusick 		prchars(fp, b+SZSHORT);
38122864Smckusick 		i = 0;
38222864Smckusick 		}
38322864Smckusick 	}
38422864Smckusick 
38522864Smckusick while(i < SZLONG)
38622864Smckusick 	b[i++] = '\0';
38722864Smckusick prchars(fp, b);
38822864Smckusick prchars(fp, b+SZSHORT);
38922864Smckusick }
390