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