1 /*-
2 * Copyright (c) 1980 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * %sccs.include.proprietary.c%
6 */
7
8 #ifndef lint
9 static char sccsid[] = "@(#)put.c 5.3 (Berkeley) 04/12/91";
10 #endif /* not lint */
11
12 /*
13 * put.c
14 *
15 * Intermediate code generation procedures common to both
16 * Johnson (Portable) and Ritchie families of second passes
17 *
18 * University of Utah CS Dept modification history:
19 *
20 * $Log: put.c,v $
21 * Revision 3.2 85/05/04 15:41:24 mckusick
22 * Fix alignment problem -- change code to match comment...
23 *
24 * Revision 3.2 85/04/29 21:36:07 donn
25 * Fix alignment problem -- change code to match comment...
26 *
27 * Revision 3.1 85/02/27 19:12:04 donn
28 * Changed to use pcc.h instead of pccdefs.h.
29 *
30 * Revision 2.1 84/07/19 12:04:21 donn
31 * Changed comment headers for UofU.
32 *
33 * Revision 1.2 84/04/02 14:40:21 donn
34 * Added fixes from Conrad Huang at UCSF for calculating the length of a
35 * concatenation of strings correctly.
36 *
37 */
38
39 #include "defs.h"
40
41 #if FAMILY == PCC
42 # include <pcc.h>
43 #else
44 # include "dmrdefs.h"
45 #endif
46
47 /*
48 char *ops [ ] =
49 {
50 "??", "+", "-", "*", "/", "**", "-",
51 "OR", "AND", "EQV", "NEQV", "NOT",
52 "CONCAT",
53 "<", "==", ">", "<=", "!=", ">=",
54 " of ", " ofC ", " = ", " += ", " *= ", " CONV ", " << ", " % ",
55 " , ", " ? ", " : "
56 " abs ", " min ", " max ", " addr ", " indirect ",
57 " bitor ", " bitand ", " bitxor ", " bitnot ", " >> ", " () "
58 };
59 */
60
61 int ops2 [ ] =
62 {
63 PCC_ERROR, PCC_PLUS, PCC_MINUS, PCC_MUL, PCC_DIV, PCC_ERROR, PCC_UMINUS,
64 PCC_OROR, PCC_ANDAND, PCC_EQ, PCC_NE, PCC_NOT,
65 PCC_ERROR,
66 PCC_LT, PCC_EQ, PCC_GT, PCC_LE, PCC_NE, PCC_GE,
67 PCC_CALL, PCC_CALL, PCC_ASSIGN, PCC_PLUSEQ, PCC_MULEQ, PCC_SCONV, PCC_LS, PCC_MOD,
68 PCC_COMOP, PCC_QUEST, PCC_COLON,
69 PCC_ERROR, PCC_ERROR, PCC_ERROR, PCC_ERROR, PCC_DEREF,
70 PCC_OR, PCC_AND, PCC_ER, PCC_COMPL, PCC_RS, PCC_ERROR
71 };
72
73
74 int types2 [ ] =
75 {
76 PCC_ERROR, PCCT_INT|PCCTM_PTR, PCCT_SHORT, PCCT_LONG, PCCT_FLOAT, PCCT_DOUBLE,
77 #if TARGET == INTERDATA
78 PCC_ERROR, PCC_ERROR, PCCT_LONG, PCCT_CHAR, PCCT_INT, PCC_ERROR
79 #else
80 PCCT_FLOAT, PCCT_DOUBLE, PCCT_LONG, PCCT_CHAR, PCCT_INT, PCC_ERROR
81 #endif
82 };
83
84
setlog()85 setlog()
86 {
87 types2[TYLOGICAL] = types2[tylogical];
88 typesize[TYLOGICAL] = typesize[tylogical];
89 typealign[TYLOGICAL] = typealign[tylogical];
90 }
91
92
putex1(p)93 putex1(p)
94 expptr p;
95 {
96 putx( fixtype(p) );
97
98 if (!optimflag)
99 {
100 templist = hookup(templist, holdtemps);
101 holdtemps = NULL;
102 }
103 }
104
105
106
107
108
putassign(lp,rp)109 putassign(lp, rp)
110 expptr lp, rp;
111 {
112 putx( fixexpr( mkexpr(OPASSIGN, lp, rp) ));
113 }
114
115
116
117
puteq(lp,rp)118 puteq(lp, rp)
119 expptr lp, rp;
120 {
121 putexpr( mkexpr(OPASSIGN, lp, rp) );
122 }
123
124
125
126
127 /* put code for a *= b */
128
putsteq(a,b)129 putsteq(a, b)
130 expptr a, b;
131 {
132 putx( fixexpr( mkexpr(OPSTAREQ, cpexpr(a), cpexpr(b)) ));
133 }
134
135
136
137
138
realpart(p)139 Addrp realpart(p)
140 register Addrp p;
141 {
142 register Addrp q;
143
144 q = (Addrp) cpexpr(p);
145 if( ISCOMPLEX(p->vtype) )
146 q->vtype += (TYREAL-TYCOMPLEX);
147 return(q);
148 }
149
150
151
152
imagpart(p)153 expptr imagpart(p)
154 register expptr p;
155 {
156 register Addrp q;
157 expptr mkrealcon();
158
159 if (ISCONST(p))
160 {
161 if (ISCOMPLEX(p->constblock.vtype))
162 return(mkrealcon(p->constblock.vtype == TYCOMPLEX ?
163 TYREAL : TYDREAL,
164 p->constblock.constant.cd[1]));
165 else if (p->constblock.vtype == TYDREAL)
166 return(mkrealcon(TYDREAL, 0.0));
167 else
168 return(mkrealcon(TYREAL, 0.0));
169 }
170 else if (p->tag == TADDR)
171 {
172 if( ISCOMPLEX(p->addrblock.vtype) )
173 {
174 q = (Addrp) cpexpr(p);
175 q->vtype += (TYREAL-TYCOMPLEX);
176 q->memoffset = mkexpr(OPPLUS, q->memoffset,
177 ICON(typesize[q->vtype]));
178 return( (expptr) q );
179 }
180 else
181 return( mkrealcon( ISINT(p->addrblock.vtype) ?
182 TYDREAL : p->addrblock.vtype , 0.0));
183 }
184 else
185 badtag("imagpart", p->tag);
186 }
187
188
189
190
ncat(p)191 ncat(p)
192 register expptr p;
193 {
194 if(p->tag==TEXPR && p->exprblock.opcode==OPCONCAT)
195 return( ncat(p->exprblock.leftp) + ncat(p->exprblock.rightp) );
196 else return(1);
197 }
198
199
200
201
lencat(p)202 ftnint lencat(p)
203 register expptr p;
204 {
205 if(p->tag==TEXPR && p->exprblock.opcode==OPCONCAT)
206 return( lencat(p->exprblock.leftp) + lencat(p->exprblock.rightp) );
207 else if( p->headblock.vleng!=NULL && ISICON(p->headblock.vleng) )
208 return(p->headblock.vleng->constblock.constant.ci);
209 else if(p->tag==TADDR && p->addrblock.varleng!=0)
210 return(p->addrblock.varleng);
211 else if(p->tag==TTEMP && p->tempblock.varleng!=0)
212 return(p->tempblock.varleng);
213 else
214 {
215 err("impossible element in concatenation");
216 return(0);
217 }
218 }
219
putconst(p)220 Addrp putconst(p)
221 register Constp p;
222 {
223 register Addrp q;
224 struct Literal *litp, *lastlit;
225 int i, k, type;
226 int litflavor;
227
228 if( p->tag != TCONST )
229 badtag("putconst", p->tag);
230
231 q = ALLOC(Addrblock);
232 q->tag = TADDR;
233 type = p->vtype;
234 q->vtype = ( type==TYADDR ? TYINT : type );
235 q->vleng = (expptr) cpexpr(p->vleng);
236 q->vstg = STGCONST;
237 q->memno = newlabel();
238 q->memoffset = ICON(0);
239
240 /* check for value in literal pool, and update pool if necessary */
241
242 switch(type = p->vtype)
243 {
244 case TYCHAR:
245 if(p->vleng->constblock.constant.ci > XL)
246 break; /* too long for literal table */
247 litflavor = 1;
248 goto loop;
249
250 case TYREAL:
251 case TYDREAL:
252 litflavor = 2;
253 goto loop;
254
255 case TYLOGICAL:
256 type = tylogical;
257 case TYSHORT:
258 case TYLONG:
259 litflavor = 3;
260
261 loop:
262 lastlit = litpool + nliterals;
263 for(litp = litpool ; litp<lastlit ; ++litp)
264 if(type == litp->littype) switch(litflavor)
265 {
266 case 1:
267 if(p->vleng->constblock.constant.ci != litp->litval.litcval.litclen)
268 break;
269 if(! eqn( (int) p->vleng->constblock.constant.ci, p->constant.ccp,
270 litp->litval.litcval.litcstr) )
271 break;
272
273 ret:
274 q->memno = litp->litnum;
275 frexpr(p);
276 return(q);
277
278 case 2:
279 if(p->constant.cd[0] == litp->litval.litdval)
280 goto ret;
281 break;
282
283 case 3:
284 if(p->constant.ci == litp->litval.litival)
285 goto ret;
286 break;
287 }
288 if(nliterals < MAXLITERALS)
289 {
290 ++nliterals;
291 litp->littype = type;
292 litp->litnum = q->memno;
293 switch(litflavor)
294 {
295 case 1:
296 litp->litval.litcval.litclen =
297 p->vleng->constblock.constant.ci;
298 cpn( (int) litp->litval.litcval.litclen,
299 p->constant.ccp,
300 litp->litval.litcval.litcstr);
301 break;
302
303 case 2:
304 litp->litval.litdval = p->constant.cd[0];
305 break;
306
307 case 3:
308 litp->litval.litival = p->constant.ci;
309 break;
310 }
311 }
312 default:
313 break;
314 }
315
316 preven(typealign[ type==TYCHAR ? TYLONG : type ]);
317 prlabel(asmfile, q->memno);
318
319 k = 1;
320 switch(type)
321 {
322 case TYLOGICAL:
323 case TYSHORT:
324 case TYLONG:
325 prconi(asmfile, type, p->constant.ci);
326 break;
327
328 case TYCOMPLEX:
329 k = 2;
330 case TYREAL:
331 type = TYREAL;
332 goto flpt;
333
334 case TYDCOMPLEX:
335 k = 2;
336 case TYDREAL:
337 type = TYDREAL;
338
339 flpt:
340 for(i = 0 ; i < k ; ++i)
341 prconr(asmfile, type, p->constant.cd[i]);
342 break;
343
344 case TYCHAR:
345 putstr(asmfile, p->constant.ccp,
346 (int) (p->vleng->constblock.constant.ci) );
347 break;
348
349 case TYADDR:
350 prcona(asmfile, p->constant.ci);
351 break;
352
353 default:
354 badtype("putconst", p->vtype);
355 }
356
357 frexpr(p);
358 return( q );
359 }
360
361 /*
362 * put out a character string constant. begin every one on
363 * a long integer boundary, and pad with nulls
364 */
putstr(fp,s,n)365 putstr(fp, s, n)
366 FILEP fp;
367 register char *s;
368 register int n;
369 {
370 int b[SZLONG];
371 register int i;
372
373 i = 0;
374 while(--n >= 0)
375 {
376 b[i++] = *s++;
377 if(i == SZLONG)
378 {
379 prchars(fp, b);
380 prchars(fp, b+SZSHORT);
381 i = 0;
382 }
383 }
384
385 while(i < SZLONG)
386 b[i++] = '\0';
387 prchars(fp, b);
388 prchars(fp, b+SZSHORT);
389 }
390