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