1 /****************************************************************
2 Copyright 1990 by AT&T Bell Laboratories and Bellcore.
4 Permission to use, copy, modify, and distribute this software
5 and its documentation for any purpose and without fee is hereby
6 granted, provided that the above copyright notice appear in all
7 copies and that both that the copyright notice and this
8 permission notice and warranty disclaimer appear in supporting
9 documentation, and that the names of AT&T Bell Laboratories or
10 Bellcore or any of their entities not be used in advertising or
11 publicity pertaining to distribution of the software without
12 specific, written prior permission.
14 AT&T and Bellcore disclaim all warranties with regard to this
15 software, including all implied warranties of merchantability
16 and fitness. In no event shall AT&T or Bellcore be liable for
17 any special, indirect or consequential damages or any damages
18 whatsoever resulting from loss of use, data or profits, whether
19 in an action of contract, negligence or other tortious action,
20 arising out of or in connection with the use or performance of
22 ****************************************************************/
25 * INTERMEDIATE CODE GENERATION PROCEDURES COMMON TO BOTH
26 * JOHNSON (PORTABLE) AND RITCHIE FAMILIES OF SECOND PASSES
30 #include "names.h" /* For LOCAL_CONST_NAME */
34 /* Definitions for putconst() */
44 "??", "+", "-", "*", "/", "**", "-",
45 "OR", "AND", "EQV", "NEQV", "NOT",
47 "<", "==", ">", "<=", "!=", ">=",
48 " of ", " ofC ", " = ", " += ", " *= ", " CONV ", " << ", " % ",
50 " abs ", " min ", " max ", " addr ", " indirect ",
51 " bitor ", " bitand ", " bitxor ", " bitnot ", " >> ",
55 /* Each of these values is defined in pccdefs */
59 P2BAD, P2PLUS, P2MINUS, P2STAR, P2SLASH, P2BAD, P2NEG,
60 P2OROR, P2ANDAND, P2EQ, P2NE, P2NOT,
62 P2LT, P2EQ, P2GT, P2LE, P2NE, P2GE,
63 P2CALL, P2CALL, P2ASSIGN, P2PLUSEQ, P2STAREQ, P2CONV, P2LSHIFT, P2MOD,
64 P2COMOP, P2QUEST, P2COLON,
65 1, P2BAD, P2BAD, P2BAD, P2BAD,
66 P2BITOR, P2BITAND, P2BITXOR, P2BITNOT, P2RSHIFT,
67 P2BAD, P2BAD, P2BAD, P2BAD, P2BAD, P2BAD, P2BAD, P2BAD, P2BAD,
68 P2BAD, P2BAD, P2BAD, P2BAD,
69 1,1,1,1,1, /* OPNEG1, OPDMIN, OPDMAX, OPASSIGNI, OPIDENTITY */
70 1,1,1,1 /* OPCHARCAST, OPDABS, OPMIN2, OPMAX2 */
76 P2BAD, P2INT|P2PTR, P2SHORT, P2LONG, P2REAL, P2DREAL,
77 P2REAL, P2DREAL, P2LONG, P2CHAR, P2INT, P2BAD
83 types2[TYLOGICAL] = types2[tylogical];
84 typesize[TYLOGICAL] = typesize[tylogical];
85 typealign[TYLOGICAL] = typealign[tylogical];
92 /* Write the expression to the p1 file */
94 p = (expptr) putx (fixtype (p));
102 expptr putassign(lp, rp)
105 return putx(fixexpr((Exprp)mkexpr(OPASSIGN, lp, rp)));
114 putexpr(mkexpr(OPASSIGN, lp, rp) );
120 /* put code for a *= b */
125 return putx( fixexpr((Exprp)
126 mkexpr(OPSTAREQ, cpexpr((expptr)a), cpexpr((expptr)b))));
132 Addrp mkfield(res, f, ty)
149 if (p -> uname_tag == UNAM_CONST && ISCOMPLEX (p->vtype)) {
150 return (Addrp)mkrealcon (p -> vtype + TYREAL - TYCOMPLEX,
151 p->user.kludge.vstg1 ? p->user.Const.cds[0]
152 : cds(dtos(p->user.Const.cd[0]),CNULL));
153 } /* if p -> uname_tag */
155 q = (Addrp) cpexpr((expptr) p);
156 if( ISCOMPLEX(p->vtype) )
157 q = mkfield (q, "r", p -> vtype + TYREAL - TYCOMPLEX);
171 if( ISCOMPLEX(p->vtype) )
173 if (p -> uname_tag == UNAM_CONST)
174 return mkrealcon (p -> vtype + TYREAL - TYCOMPLEX,
175 p->user.kludge.vstg1 ? p->user.Const.cds[1]
176 : cds(dtos(p->user.Const.cd[1]),CNULL));
177 q = (Addrp) cpexpr((expptr) p);
178 q = mkfield (q, "i", p -> vtype + TYREAL - TYCOMPLEX);
179 return( (expptr) q );
183 /* Cast an integer type onto a Double Real type */
185 return( mkrealcon( ISINT(p->vtype) ? TYDREAL : p->vtype , "0"));
192 /* ncat -- computes the number of adjacent concatenation operations */
197 if(p->tag==TEXPR && p->exprblock.opcode==OPCONCAT)
198 return( ncat(p->exprblock.leftp) + ncat(p->exprblock.rightp) );
205 /* lencat -- returns the length of the concatenated string. Each
206 substring must have a static (i.e. compile-time) fixed length */
211 if(p->tag==TEXPR && p->exprblock.opcode==OPCONCAT)
212 return( lencat(p->exprblock.leftp) + lencat(p->exprblock.rightp) );
213 else if( p->headblock.vleng!=NULL && ISICON(p->headblock.vleng) )
214 return(p->headblock.vleng->constblock.Const.ci);
215 else if(p->tag==TADDR && p->addrblock.varleng!=0)
216 return(p->addrblock.varleng);
219 err("impossible element in concatenation");
224 /* putconst -- Creates a new Addrp value which maps onto the input
225 constant value. The Addrp doesn't retain the value of the constant,
226 instead that value is copied into a table of constants (called
227 litpool, for pool of literal values). The only way to retrieve the
228 actual value of the constant is to look at the memno field of the
229 Addrp result. You know that the associated literal is the one referred
230 to by q when (q -> memno == litp -> litnum).
237 struct Literal *litp, *lastlit;
241 char cdsbuf0[64], cdsbuf1[64], *ds[2];
243 if( p->tag != TCONST )
244 badtag("putconst", p->tag);
246 q = ALLOC(Addrblock);
249 q->vtype = ( type==TYADDR ? tyint : type );
250 q->vleng = (expptr) cpexpr(p->vleng);
253 /* Create the new label for the constant. This is wasteful of labels
254 because when the constant value already exists in the literal pool,
255 this label gets thrown away and is never reclaimed. It might be
256 cleaner to move this down past the first switch() statement below */
258 q->memno = newlabel();
259 q->memoffset = ICON(0);
260 q -> uname_tag = UNAM_CONST;
262 /* Copy the constant info into the Addrblock; do this by copying the
263 largest storage elts */
265 q -> user.Const = p -> Const;
266 q->user.kludge.vstg1 = p->vstg; /* distinguish string from binary fp */
268 /* check for value in literal pool, and update pool if necessary */
271 switch(type = p->vtype)
274 /* Treat all character strings as too long for literal table */
275 q -> memno = BAD_MEMNO;
281 cd[1] = atof(ds[1] = p->Const.cds[1]);
283 ds[1] = cds(dtos(cd[1] = p->Const.cd[1]), cdsbuf1);
286 litflavor = LIT_FLOAT;
288 cd[0] = atof(ds[0] = p->Const.cds[0]);
290 ds[0] = cds(dtos(cd[0] = p->Const.cd[0]), cdsbuf0);
302 /* Scan the literal pool for this constant value. If this same constant
303 has been assigned before, use the same label. Note that this routine
304 does NOT consider two differently-typed constants with the same bit
305 pattern to be the same constant */
308 lastlit = litpool + nliterals;
309 for(litp = litpool ; litp<lastlit ; ++litp)
311 /* Remove this type checking to ensure that all bit patterns are reused */
313 if(type == litp->littype) switch(litflavor)
316 if(cd[0] == litp->litval.litdval[0]
317 && !strcmp(ds[0], litp->cds[0])
319 cd[1] == litp->litval.litdval[1]
320 && !strcmp(ds[1], litp->cds[1]))) {
322 q->memno = litp->litnum;
329 if(p->Const.ci == litp->litval.litival)
334 /* If there's room in the literal pool, add this new value to the pool */
336 if(nliterals < MAXLITERALS)
340 /* litp now points to the next free elt */
342 litp->littype = type;
343 litp->litnum = q->memno;
347 litp->litval.litdval[0] = cd[0];
348 litp->cds[0] = copys(ds[0]);
350 litp->litval.litdval[1] = cd[1];
351 litp->cds[1] = copys(ds[1]);
356 litp->litval.litival = p->Const.ci;
358 } /* switch (litflavor) */
359 } /* if (nliternals < MAXLITERALS) */
361 Addrp t = Mktemp(type, q -> vleng);
362 puteq (cpexpr((expptr)t), (expptr)p);
371 badtype ("putconst", p -> vtype);