Pull in some of the lpt_port_test fixes from lpt.c.
[unix-history] / usr.bin / f2c / put.c
CommitLineData
f1525c23
WH
1/****************************************************************
2Copyright 1990, 1991, 1993 by AT&T Bell Laboratories and Bellcore.
3
4Permission to use, copy, modify, and distribute this software
5and its documentation for any purpose and without fee is hereby
6granted, provided that the above copyright notice appear in all
7copies and that both that the copyright notice and this
8permission notice and warranty disclaimer appear in supporting
9documentation, and that the names of AT&T Bell Laboratories or
10Bellcore or any of their entities not be used in advertising or
11publicity pertaining to distribution of the software without
12specific, written prior permission.
13
14AT&T and Bellcore disclaim all warranties with regard to this
15software, including all implied warranties of merchantability
16and fitness. In no event shall AT&T or Bellcore be liable for
17any special, indirect or consequential damages or any damages
18whatsoever resulting from loss of use, data or profits, whether
19in an action of contract, negligence or other tortious action,
20arising out of or in connection with the use or performance of
21this 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/*
42char *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
57int 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
74setlog()
75{
76 typesize[TYLOGICAL] = typesize[tylogical];
77 typealign[TYLOGICAL] = typealign[tylogical];
78}
79
80
81putexpr(p)
82expptr 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
94expptr putassign(lp, rp)
95expptr lp, rp;
96{
97 return putx(fixexpr((Exprp)mkexpr(OPASSIGN, lp, rp)));
98}
99
100
101
102
103void puteq(lp, rp)
104expptr lp, rp;
105{
106 putexpr(mkexpr(OPASSIGN, lp, rp) );
107}
108
109
110
111
112/* put code for a *= b */
113
114expptr putsteq(a, b)
115Addrp a, b;
116{
117 return putx( fixexpr((Exprp)
118 mkexpr(OPSTAREQ, cpexpr((expptr)a), cpexpr((expptr)b))));
119}
120
121
122
123
124Addrp mkfield(res, f, ty)
125register Addrp res;
126char *f;
127int ty;
128{
129 res -> vtype = ty;
130 res -> Field = f;
131 return res;
132} /* mkfield */
133
134
135Addrp realpart(p)
136register 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
158expptr imagpart(p)
159register 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
187ncat(p)
188register 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
201ftnint lencat(p)
202register 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
226Addrp putconst(p)
227register 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]))) {
339ret:
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}