|
|
1.1 root 1: /****************************************************************
2: Copyright 1990, 1991, 1993 by AT&T Bell Laboratories and Bellcore.
3:
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.
13:
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
21: this software.
22: ****************************************************************/
23:
24: /*
25: * INTERMEDIATE CODE GENERATION PROCEDURES COMMON TO BOTH
26: * JOHNSON (PORTABLE) AND RITCHIE FAMILIES OF SECOND PASSES
27: */
28:
29: #include "defs.h"
30: #include "names.h" /* For LOCAL_CONST_NAME */
31: #include "pccdefs.h"
32: #include "p1defs.h"
33:
34: /* Definitions for putconst() */
35:
36: #define LIT_CHAR 1
37: #define LIT_FLOAT 2
38: #define LIT_INT 3
39:
40:
41: /*
42: char *ops [ ] =
43: {
44: "??", "+", "-", "*", "/", "**", "-",
45: "OR", "AND", "EQV", "NEQV", "NOT",
46: "CONCAT",
47: "<", "==", ">", "<=", "!=", ">=",
48: " of ", " ofC ", " = ", " += ", " *= ", " CONV ", " << ", " % ",
49: " , ", " ? ", " : "
50: " abs ", " min ", " max ", " addr ", " indirect ",
51: " bitor ", " bitand ", " bitxor ", " bitnot ", " >> ",
52: };
53: */
54:
55: /* Each of these values is defined in pccdefs */
56:
57: int ops2 [ ] =
58: {
59: P2BAD, P2PLUS, P2MINUS, P2STAR, P2SLASH, P2BAD, P2NEG,
60: P2OROR, P2ANDAND, P2EQ, P2NE, P2NOT,
61: P2BAD,
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 */
71: };
72:
73:
74: setlog()
75: {
76: typesize[TYLOGICAL] = typesize[tylogical];
77: typealign[TYLOGICAL] = typealign[tylogical];
78: }
79:
80:
81: putexpr(p)
82: expptr p;
83: {
84: /* Write the expression to the p1 file */
85:
86: p = (expptr) putx (fixtype (p));
87: p1_expr (p);
88: }
89:
90:
91:
92:
93:
94: expptr putassign(lp, rp)
95: expptr lp, rp;
96: {
97: return putx(fixexpr((Exprp)mkexpr(OPASSIGN, lp, rp)));
98: }
99:
100:
101:
102:
103: void puteq(lp, rp)
104: expptr lp, rp;
105: {
106: putexpr(mkexpr(OPASSIGN, lp, rp) );
107: }
108:
109:
110:
111:
112: /* put code for a *= b */
113:
114: expptr putsteq(a, b)
115: Addrp a, b;
116: {
117: return putx( fixexpr((Exprp)
118: mkexpr(OPSTAREQ, cpexpr((expptr)a), cpexpr((expptr)b))));
119: }
120:
121:
122:
123:
124: Addrp mkfield(res, f, ty)
125: register Addrp res;
126: char *f;
127: int ty;
128: {
129: res -> vtype = ty;
130: res -> Field = f;
131: return res;
132: } /* mkfield */
133:
134:
135: Addrp realpart(p)
136: register Addrp p;
137: {
138: register Addrp q;
139: expptr mkrealcon();
140:
141: if (p->tag == TADDR
142: && p->uname_tag == UNAM_CONST
143: && ISCOMPLEX (p->vtype))
144: return (Addrp)mkrealcon (p -> vtype + TYREAL - TYCOMPLEX,
145: p->user.kludge.vstg1 ? p->user.Const.cds[0]
146: : cds(dtos(p->user.Const.cd[0]),CNULL));
147:
148: q = (Addrp) cpexpr((expptr) p);
149: if( ISCOMPLEX(p->vtype) )
150: q = mkfield (q, "r", p -> vtype + TYREAL - TYCOMPLEX);
151:
152: return(q);
153: }
154:
155:
156:
157:
158: expptr imagpart(p)
159: register Addrp p;
160: {
161: register Addrp q;
162: expptr mkrealcon();
163:
164: if( ISCOMPLEX(p->vtype) )
165: {
166: if (p->tag == TADDR && p->uname_tag == UNAM_CONST)
167: return mkrealcon (p -> vtype + TYREAL - TYCOMPLEX,
168: p->user.kludge.vstg1 ? p->user.Const.cds[1]
169: : cds(dtos(p->user.Const.cd[1]),CNULL));
170: q = (Addrp) cpexpr((expptr) p);
171: q = mkfield (q, "i", p -> vtype + TYREAL - TYCOMPLEX);
172: return( (expptr) q );
173: }
174: else
175:
176: /* Cast an integer type onto a Double Real type */
177:
178: return( mkrealcon( ISINT(p->vtype) ? TYDREAL : p->vtype , "0"));
179: }
180:
181:
182:
183:
184:
185: /* ncat -- computes the number of adjacent concatenation operations */
186:
187: ncat(p)
188: register expptr p;
189: {
190: if(p->tag==TEXPR && p->exprblock.opcode==OPCONCAT)
191: return( ncat(p->exprblock.leftp) + ncat(p->exprblock.rightp) );
192: else return(1);
193: }
194:
195:
196:
197:
198: /* lencat -- returns the length of the concatenated string. Each
199: substring must have a static (i.e. compile-time) fixed length */
200:
201: ftnint lencat(p)
202: register expptr p;
203: {
204: if(p->tag==TEXPR && p->exprblock.opcode==OPCONCAT)
205: return( lencat(p->exprblock.leftp) + lencat(p->exprblock.rightp) );
206: else if( p->headblock.vleng!=NULL && ISICON(p->headblock.vleng) )
207: return(p->headblock.vleng->constblock.Const.ci);
208: else if(p->tag==TADDR && p->addrblock.varleng!=0)
209: return(p->addrblock.varleng);
210: else
211: {
212: err("impossible element in concatenation");
213: return(0);
214: }
215: }
216:
217: /* putconst -- Creates a new Addrp value which maps onto the input
218: constant value. The Addrp doesn't retain the value of the constant,
219: instead that value is copied into a table of constants (called
220: litpool, for pool of literal values). The only way to retrieve the
221: actual value of the constant is to look at the memno field of the
222: Addrp result. You know that the associated literal is the one referred
223: to by q when (q -> memno == litp -> litnum).
224: */
225:
226: Addrp putconst(p)
227: register Constp p;
228: {
229: register Addrp q;
230: struct Literal *litp, *lastlit;
231: int k, len, type;
232: int litflavor;
233: double cd[2];
234: ftnint nblanks;
235: char *strp;
236: char cdsbuf0[64], cdsbuf1[64], *ds[2];
237:
238: if (p->tag != TCONST)
239: badtag("putconst", p->tag);
240:
241: q = ALLOC(Addrblock);
242: q->tag = TADDR;
243: type = p->vtype;
244: q->vtype = ( type==TYADDR ? tyint : type );
245: q->vleng = (expptr) cpexpr(p->vleng);
246: q->vstg = STGCONST;
247:
248: /* Create the new label for the constant. This is wasteful of labels
249: because when the constant value already exists in the literal pool,
250: this label gets thrown away and is never reclaimed. It might be
251: cleaner to move this down past the first switch() statement below */
252:
253: q->memno = newlabel();
254: q->memoffset = ICON(0);
255: q -> uname_tag = UNAM_CONST;
256:
257: /* Copy the constant info into the Addrblock; do this by copying the
258: largest storage elts */
259:
260: q -> user.Const = p -> Const;
261: q->user.kludge.vstg1 = p->vstg; /* distinguish string from binary fp */
262:
263: /* check for value in literal pool, and update pool if necessary */
264:
265: k = 1;
266: switch(type)
267: {
268: case TYCHAR:
269: if (halign) {
270: strp = p->Const.ccp;
271: nblanks = p->Const.ccp1.blanks;
272: len = p->vleng->constblock.Const.ci;
273: litflavor = LIT_CHAR;
274: goto loop;
275: }
276: else
277: q->memno = BAD_MEMNO;
278: break;
279: case TYCOMPLEX:
280: case TYDCOMPLEX:
281: k = 2;
282: if (p->vstg)
283: cd[1] = atof(ds[1] = p->Const.cds[1]);
284: else
285: ds[1] = cds(dtos(cd[1] = p->Const.cd[1]), cdsbuf1);
286: case TYREAL:
287: case TYDREAL:
288: litflavor = LIT_FLOAT;
289: if (p->vstg)
290: cd[0] = atof(ds[0] = p->Const.cds[0]);
291: else
292: ds[0] = cds(dtos(cd[0] = p->Const.cd[0]), cdsbuf0);
293: goto loop;
294:
295: case TYLOGICAL1:
296: case TYLOGICAL2:
297: case TYLOGICAL:
298: type = tylogical;
299: goto lit_int_flavor;
300: case TYLONG:
301: type = tyint;
302: case TYSHORT:
303: case TYINT1:
304: #ifdef TYQUAD
305: case TYQUAD:
306: #endif
307: lit_int_flavor:
308: litflavor = LIT_INT;
309:
310: /* Scan the literal pool for this constant value. If this same constant
311: has been assigned before, use the same label. Note that this routine
312: does NOT consider two differently-typed constants with the same bit
313: pattern to be the same constant */
314:
315: loop:
316: lastlit = litpool + nliterals;
317: for(litp = litpool ; litp<lastlit ; ++litp)
318:
319: /* Remove this type checking to ensure that all bit patterns are reused */
320:
321: if(type == litp->littype) switch(litflavor)
322: {
323: case LIT_CHAR:
324: if (len == (int)litp->litval.litival2[0]
325: && nblanks == litp->litval.litival2[1]
326: && !memcmp(strp, litp->cds[0], len)) {
327: q->memno = litp->litnum;
328: frexpr((expptr)p);
329: q->user.Const.ccp1.ccp0 = litp->cds[0];
330: return(q);
331: }
332: break;
333: case LIT_FLOAT:
334: if(cd[0] == litp->litval.litdval[0]
335: && !strcmp(ds[0], litp->cds[0])
336: && (k == 1 ||
337: cd[1] == litp->litval.litdval[1]
338: && !strcmp(ds[1], litp->cds[1]))) {
339: ret:
340: q->memno = litp->litnum;
341: frexpr((expptr)p);
342: return(q);
343: }
344: break;
345:
346: case LIT_INT:
347: if(p->Const.ci == litp->litval.litival)
348: goto ret;
349: break;
350: }
351:
352: /* If there's room in the literal pool, add this new value to the pool */
353:
354: if(nliterals < maxliterals)
355: {
356: ++nliterals;
357:
358: /* litp now points to the next free elt */
359:
360: litp->littype = type;
361: litp->litnum = q->memno;
362: switch(litflavor)
363: {
364: case LIT_CHAR:
365: litp->litval.litival2[0] = len;
366: litp->litval.litival2[1] = nblanks;
367: q->user.Const.ccp = litp->cds[0] =
368: memcpy(gmem(len,0), strp, len);
369: break;
370:
371: case LIT_FLOAT:
372: litp->litval.litdval[0] = cd[0];
373: litp->cds[0] = copys(ds[0]);
374: if (k == 2) {
375: litp->litval.litdval[1] = cd[1];
376: litp->cds[1] = copys(ds[1]);
377: }
378: break;
379:
380: case LIT_INT:
381: litp->litval.litival = p->Const.ci;
382: break;
383: } /* switch (litflavor) */
384: }
385: else
386: many("literal constants", 'L', maxliterals);
387:
388: break;
389: case TYADDR:
390: break;
391: default:
392: badtype ("putconst", p -> vtype);
393: break;
394: } /* switch */
395:
396: if (type != TYCHAR || halign)
397: frexpr((expptr)p);
398: return( q );
399: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.