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