1 | /* $Id: trees.c,v 1.272.2.1 2011/03/01 17:39:28 ragge Exp $ */
|
---|
2 | /*
|
---|
3 | * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
|
---|
4 | * All rights reserved.
|
---|
5 | *
|
---|
6 | * Redistribution and use in source and binary forms, with or without
|
---|
7 | * modification, are permitted provided that the following conditions
|
---|
8 | * are met:
|
---|
9 | * 1. Redistributions of source code must retain the above copyright
|
---|
10 | * notice, this list of conditions and the following disclaimer.
|
---|
11 | * 2. Redistributions in binary form must reproduce the above copyright
|
---|
12 | * notice, this list of conditions and the following disclaimer in the
|
---|
13 | * documentation and/or other materials provided with the distribution.
|
---|
14 | * 3. The name of the author may not be used to endorse or promote products
|
---|
15 | * derived from this software without specific prior written permission
|
---|
16 | *
|
---|
17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
---|
18 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
---|
19 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
---|
20 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
---|
21 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
---|
22 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
---|
23 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
---|
24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
---|
25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
---|
26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
---|
27 | */
|
---|
28 |
|
---|
29 | /*
|
---|
30 | * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
|
---|
31 | *
|
---|
32 | * Redistribution and use in source and binary forms, with or without
|
---|
33 | * modification, are permitted provided that the following conditions
|
---|
34 | * are met:
|
---|
35 | *
|
---|
36 | * Redistributions of source code and documentation must retain the above
|
---|
37 | * copyright notice, this list of conditions and the following disclaimer.
|
---|
38 | * Redistributions in binary form must reproduce the above copyright
|
---|
39 | * notice, this list of conditionsand the following disclaimer in the
|
---|
40 | * documentation and/or other materials provided with the distribution.
|
---|
41 | * All advertising materials mentioning features or use of this software
|
---|
42 | * must display the following acknowledgement:
|
---|
43 | * This product includes software developed or owned by Caldera
|
---|
44 | * International, Inc.
|
---|
45 | * Neither the name of Caldera International, Inc. nor the names of other
|
---|
46 | * contributors may be used to endorse or promote products derived from
|
---|
47 | * this software without specific prior written permission.
|
---|
48 | *
|
---|
49 | * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
|
---|
50 | * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
|
---|
51 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
---|
52 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
---|
53 | * DISCLAIMED. IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE
|
---|
54 | * FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
---|
55 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
---|
56 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
---|
57 | * HOWEVER CAUSED AND ON ANY THEORY OFLIABILITY, WHETHER IN CONTRACT,
|
---|
58 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
---|
59 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
---|
60 | * POSSIBILITY OF SUCH DAMAGE.
|
---|
61 | */
|
---|
62 | /*
|
---|
63 | * Some of the changes from 32V include:
|
---|
64 | * - Understand "void" as type.
|
---|
65 | * - Handle enums as ints everywhere.
|
---|
66 | * - Convert some C-specific ops into branches.
|
---|
67 | */
|
---|
68 |
|
---|
69 | # include "pass1.h"
|
---|
70 | # include "pass2.h"
|
---|
71 |
|
---|
72 | # include <stdarg.h>
|
---|
73 | # include <string.h>
|
---|
74 |
|
---|
75 | /* standard macros conflict with identifiers in this file */
|
---|
76 | #ifdef true
|
---|
77 | #undef true
|
---|
78 | #undef false
|
---|
79 | #endif
|
---|
80 |
|
---|
81 | static void chkpun(NODE *p);
|
---|
82 | static int opact(NODE *p);
|
---|
83 | static int moditype(TWORD);
|
---|
84 | static NODE *strargs(NODE *);
|
---|
85 | static void rmcops(NODE *p);
|
---|
86 | void putjops(NODE *, void *);
|
---|
87 | static struct symtab *findmember(struct symtab *, char *);
|
---|
88 | int inftn; /* currently between epilog/prolog */
|
---|
89 |
|
---|
90 | static char *tnames[] = {
|
---|
91 | "undef",
|
---|
92 | "farg",
|
---|
93 | "char",
|
---|
94 | "unsigned char",
|
---|
95 | "short",
|
---|
96 | "unsigned short",
|
---|
97 | "int",
|
---|
98 | "unsigned int",
|
---|
99 | "long",
|
---|
100 | "unsigned long",
|
---|
101 | "long long",
|
---|
102 | "unsigned long long",
|
---|
103 | "float",
|
---|
104 | "double",
|
---|
105 | "long double",
|
---|
106 | "strty",
|
---|
107 | "unionty",
|
---|
108 | "enumty",
|
---|
109 | "moety",
|
---|
110 | "void",
|
---|
111 | "signed", /* pass1 */
|
---|
112 | "bool", /* pass1 */
|
---|
113 | "fimag", /* pass1 */
|
---|
114 | "dimag", /* pass1 */
|
---|
115 | "limag", /* pass1 */
|
---|
116 | "fcomplex", /* pass1 */
|
---|
117 | "dcomplex", /* pass1 */
|
---|
118 | "lcomplex", /* pass1 */
|
---|
119 | "enumty", /* pass1 */
|
---|
120 | "?", "?"
|
---|
121 | };
|
---|
122 |
|
---|
123 | /* some special actions, used in finding the type of nodes */
|
---|
124 | # define NCVT 01
|
---|
125 | # define PUN 02
|
---|
126 | # define TYPL 04
|
---|
127 | # define TYPR 010
|
---|
128 | # define TYMATCH 040
|
---|
129 | # define LVAL 0100
|
---|
130 | # define CVTO 0200
|
---|
131 | # define CVTL 0400
|
---|
132 | # define CVTR 01000
|
---|
133 | # define PTMATCH 02000
|
---|
134 | # define OTHER 04000
|
---|
135 | # define NCVTR 010000
|
---|
136 |
|
---|
137 | /* node conventions:
|
---|
138 |
|
---|
139 | NAME: rval>0 is stab index for external
|
---|
140 | rval<0 is -inlabel number
|
---|
141 | lval is offset in bits
|
---|
142 | ICON: lval has the value
|
---|
143 | rval has the STAB index, or - label number,
|
---|
144 | if a name whose address is in the constant
|
---|
145 | rval = NONAME means no name
|
---|
146 | REG: rval is reg. identification cookie
|
---|
147 |
|
---|
148 | */
|
---|
149 |
|
---|
150 | int bdebug = 0;
|
---|
151 | extern int negrel[];
|
---|
152 |
|
---|
153 | NODE *
|
---|
154 | buildtree(int o, NODE *l, NODE *r)
|
---|
155 | {
|
---|
156 | NODE *p, *q;
|
---|
157 | int actions;
|
---|
158 | int opty;
|
---|
159 | struct symtab *sp = NULL; /* XXX gcc */
|
---|
160 | NODE *lr, *ll;
|
---|
161 |
|
---|
162 | #ifdef PCC_DEBUG
|
---|
163 | if (bdebug) {
|
---|
164 | printf("buildtree(%s, %p, %p)\n", copst(o), l, r);
|
---|
165 | if (l) fwalk(l, eprint, 0);
|
---|
166 | if (r) fwalk(r, eprint, 0);
|
---|
167 | }
|
---|
168 | #endif
|
---|
169 | opty = coptype(o);
|
---|
170 |
|
---|
171 | /* check for constants */
|
---|
172 |
|
---|
173 | if (o == ANDAND || o == OROR || o == NOT) {
|
---|
174 | if (l->n_op == FCON) {
|
---|
175 | p = bcon(!FLOAT_ISZERO(l->n_dcon));
|
---|
176 | nfree(l);
|
---|
177 | l = p;
|
---|
178 | }
|
---|
179 | if (o != NOT && r->n_op == FCON) {
|
---|
180 | p = bcon(!FLOAT_ISZERO(r->n_dcon));
|
---|
181 | nfree(r);
|
---|
182 | r = p;
|
---|
183 | }
|
---|
184 | }
|
---|
185 |
|
---|
186 | if( opty == UTYPE && l->n_op == ICON ){
|
---|
187 |
|
---|
188 | switch( o ){
|
---|
189 |
|
---|
190 | case NOT:
|
---|
191 | case UMINUS:
|
---|
192 | case COMPL:
|
---|
193 | if( conval( l, o, l ) ) return(l);
|
---|
194 | break;
|
---|
195 | }
|
---|
196 | } else if (o == NOT && l->n_op == FCON) {
|
---|
197 | l = clocal(block(SCONV, l, NIL, INT, 0, MKAP(INT)));
|
---|
198 | } else if( o == UMINUS && l->n_op == FCON ){
|
---|
199 | l->n_dcon = FLOAT_NEG(l->n_dcon);
|
---|
200 | return(l);
|
---|
201 |
|
---|
202 | } else if( o==QUEST && l->n_op==ICON ) {
|
---|
203 | CONSZ c = l->n_lval;
|
---|
204 | nfree(l);
|
---|
205 | if (c) {
|
---|
206 | walkf(r->n_right, putjops, 0);
|
---|
207 | tfree(r->n_right);
|
---|
208 | l = r->n_left;
|
---|
209 | } else {
|
---|
210 | walkf(r->n_left, putjops, 0);
|
---|
211 | tfree(r->n_left);
|
---|
212 | l = r->n_right;
|
---|
213 | }
|
---|
214 | nfree(r);
|
---|
215 | return(l);
|
---|
216 | } else if( opty == BITYPE && l->n_op == ICON && r->n_op == ICON ){
|
---|
217 |
|
---|
218 | switch( o ){
|
---|
219 |
|
---|
220 | case PLUS:
|
---|
221 | case MINUS:
|
---|
222 | case MUL:
|
---|
223 | case DIV:
|
---|
224 | case MOD:
|
---|
225 | /*
|
---|
226 | * Do type propagation for simple types here.
|
---|
227 | * The constant value is correct anyway.
|
---|
228 | * Maybe this op shortcut should be removed?
|
---|
229 | */
|
---|
230 | if (l->n_sp == NULL && r->n_sp == NULL &&
|
---|
231 | l->n_type < BTMASK && r->n_type < BTMASK) {
|
---|
232 | if (l->n_type > r->n_type)
|
---|
233 | r->n_type = l->n_type;
|
---|
234 | else
|
---|
235 | l->n_type = r->n_type;
|
---|
236 | }
|
---|
237 | /* FALLTHROUGH */
|
---|
238 | case ULT:
|
---|
239 | case UGT:
|
---|
240 | case ULE:
|
---|
241 | case UGE:
|
---|
242 | case LT:
|
---|
243 | case GT:
|
---|
244 | case LE:
|
---|
245 | case GE:
|
---|
246 | case EQ:
|
---|
247 | case NE:
|
---|
248 | case ANDAND:
|
---|
249 | case OROR:
|
---|
250 | case AND:
|
---|
251 | case OR:
|
---|
252 | case ER:
|
---|
253 | case LS:
|
---|
254 | case RS:
|
---|
255 | if (!ISPTR(l->n_type) && !ISPTR(r->n_type)) {
|
---|
256 | if( conval( l, o, r ) ) {
|
---|
257 | nfree(r);
|
---|
258 | return(l);
|
---|
259 | }
|
---|
260 | }
|
---|
261 | break;
|
---|
262 | }
|
---|
263 | } else if (opty == BITYPE && (l->n_op == FCON || l->n_op == ICON) &&
|
---|
264 | (r->n_op == FCON || r->n_op == ICON) && (o == PLUS || o == MINUS ||
|
---|
265 | o == MUL || o == DIV || (o >= EQ && o <= GT) )) {
|
---|
266 | TWORD t;
|
---|
267 | #ifndef CC_DIV_0
|
---|
268 | if (o == DIV &&
|
---|
269 | ((r->n_op == ICON && r->n_lval == 0) ||
|
---|
270 | (r->n_op == FCON && r->n_dcon == 0.0)))
|
---|
271 | goto runtime; /* HW dependent */
|
---|
272 | #endif
|
---|
273 | if (l->n_op == ICON)
|
---|
274 | l->n_dcon = FLOAT_CAST(l->n_lval, l->n_type);
|
---|
275 | if (r->n_op == ICON)
|
---|
276 | r->n_dcon = FLOAT_CAST(r->n_lval, r->n_type);
|
---|
277 | switch(o){
|
---|
278 | case PLUS:
|
---|
279 | case MINUS:
|
---|
280 | case MUL:
|
---|
281 | case DIV:
|
---|
282 | switch (o) {
|
---|
283 | case PLUS:
|
---|
284 | l->n_dcon = FLOAT_PLUS(l->n_dcon, r->n_dcon);
|
---|
285 | break;
|
---|
286 | case MINUS:
|
---|
287 | l->n_dcon = FLOAT_MINUS(l->n_dcon, r->n_dcon);
|
---|
288 | break;
|
---|
289 | case MUL:
|
---|
290 | l->n_dcon = FLOAT_MUL(l->n_dcon, r->n_dcon);
|
---|
291 | break;
|
---|
292 | case DIV:
|
---|
293 | l->n_dcon = FLOAT_DIV(l->n_dcon, r->n_dcon);
|
---|
294 | break;
|
---|
295 | }
|
---|
296 | t = (l->n_type > r->n_type ? l->n_type : r->n_type);
|
---|
297 | l->n_op = FCON;
|
---|
298 | l->n_type = t;
|
---|
299 | l->n_ap = MKAP(t);
|
---|
300 | nfree(r);
|
---|
301 | return(l);
|
---|
302 | case EQ:
|
---|
303 | case NE:
|
---|
304 | case LE:
|
---|
305 | case LT:
|
---|
306 | case GE:
|
---|
307 | case GT:
|
---|
308 | switch (o) {
|
---|
309 | case EQ:
|
---|
310 | l->n_lval = FLOAT_EQ(l->n_dcon, r->n_dcon);
|
---|
311 | break;
|
---|
312 | case NE:
|
---|
313 | l->n_lval = FLOAT_NE(l->n_dcon, r->n_dcon);
|
---|
314 | break;
|
---|
315 | case LE:
|
---|
316 | l->n_lval = FLOAT_LE(l->n_dcon, r->n_dcon);
|
---|
317 | break;
|
---|
318 | case LT:
|
---|
319 | l->n_lval = FLOAT_LT(l->n_dcon, r->n_dcon);
|
---|
320 | break;
|
---|
321 | case GE:
|
---|
322 | l->n_lval = FLOAT_GE(l->n_dcon, r->n_dcon);
|
---|
323 | break;
|
---|
324 | case GT:
|
---|
325 | l->n_lval = FLOAT_GT(l->n_dcon, r->n_dcon);
|
---|
326 | break;
|
---|
327 | }
|
---|
328 | nfree(r);
|
---|
329 | r = bcon(l->n_lval);
|
---|
330 | nfree(l);
|
---|
331 | return r;
|
---|
332 | }
|
---|
333 | }
|
---|
334 | #ifndef CC_DIV_0
|
---|
335 | runtime:
|
---|
336 | #endif
|
---|
337 | /* its real; we must make a new node */
|
---|
338 |
|
---|
339 | p = block(o, l, r, INT, 0, MKAP(INT));
|
---|
340 |
|
---|
341 | actions = opact(p);
|
---|
342 |
|
---|
343 | if (actions & LVAL) { /* check left descendent */
|
---|
344 | if (notlval(p->n_left)) {
|
---|
345 | uerror("lvalue required");
|
---|
346 | nfree(p);
|
---|
347 | return l;
|
---|
348 | #ifdef notyet
|
---|
349 | } else {
|
---|
350 | if ((l->n_type > BTMASK && ISCON(l->n_qual)) ||
|
---|
351 | (l->n_type <= BTMASK && ISCON(l->n_qual << TSHIFT)))
|
---|
352 | if (blevel > 0)
|
---|
353 | uerror("lvalue is declared const");
|
---|
354 | #endif
|
---|
355 | }
|
---|
356 | }
|
---|
357 |
|
---|
358 | if( actions & NCVTR ){
|
---|
359 | p->n_left = pconvert( p->n_left );
|
---|
360 | }
|
---|
361 | else if( !(actions & NCVT ) ){
|
---|
362 | switch( opty ){
|
---|
363 |
|
---|
364 | case BITYPE:
|
---|
365 | p->n_right = pconvert( p->n_right );
|
---|
366 | case UTYPE:
|
---|
367 | p->n_left = pconvert( p->n_left );
|
---|
368 |
|
---|
369 | }
|
---|
370 | }
|
---|
371 |
|
---|
372 | if ((actions&PUN) && (o!=CAST))
|
---|
373 | chkpun(p);
|
---|
374 |
|
---|
375 | if( actions & (TYPL|TYPR) ){
|
---|
376 |
|
---|
377 | q = (actions&TYPL) ? p->n_left : p->n_right;
|
---|
378 |
|
---|
379 | p->n_type = q->n_type;
|
---|
380 | p->n_qual = q->n_qual;
|
---|
381 | p->n_df = q->n_df;
|
---|
382 | p->n_ap = q->n_ap;
|
---|
383 | }
|
---|
384 |
|
---|
385 | if( actions & CVTL ) p = convert( p, CVTL );
|
---|
386 | if( actions & CVTR ) p = convert( p, CVTR );
|
---|
387 | if( actions & TYMATCH ) p = tymatch(p);
|
---|
388 | if( actions & PTMATCH ) p = ptmatch(p);
|
---|
389 |
|
---|
390 | if( actions & OTHER ){
|
---|
391 | struct symtab *sp1;
|
---|
392 |
|
---|
393 | l = p->n_left;
|
---|
394 | r = p->n_right;
|
---|
395 |
|
---|
396 | switch(o){
|
---|
397 |
|
---|
398 | case NAME:
|
---|
399 | cerror("buildtree NAME");
|
---|
400 |
|
---|
401 | case STREF:
|
---|
402 | /* p->x turned into *(p+offset) */
|
---|
403 | /* rhs must be a name; check correctness */
|
---|
404 |
|
---|
405 | /* Find member symbol struct */
|
---|
406 | if (l->n_type != PTR+STRTY && l->n_type != PTR+UNIONTY){
|
---|
407 | uerror("struct or union required");
|
---|
408 | break;
|
---|
409 | }
|
---|
410 |
|
---|
411 | if ((sp1 = strmemb(l->n_ap)) == NULL) {
|
---|
412 | uerror("undefined struct or union");
|
---|
413 | break;
|
---|
414 | }
|
---|
415 |
|
---|
416 | if ((sp = findmember(sp1, r->n_name)) == NULL) {
|
---|
417 | uerror("member '%s' not declared", r->n_name);
|
---|
418 | break;
|
---|
419 | }
|
---|
420 |
|
---|
421 | r->n_sp = sp;
|
---|
422 | p = stref(p);
|
---|
423 | break;
|
---|
424 |
|
---|
425 | case UMUL:
|
---|
426 | if (l->n_op == ADDROF) {
|
---|
427 | nfree(p);
|
---|
428 | p = l->n_left;
|
---|
429 | nfree(l);
|
---|
430 | }
|
---|
431 | if( !ISPTR(l->n_type))uerror("illegal indirection");
|
---|
432 | p->n_type = DECREF(l->n_type);
|
---|
433 | p->n_qual = DECREF(l->n_qual);
|
---|
434 | p->n_df = l->n_df;
|
---|
435 | p->n_ap = l->n_ap;
|
---|
436 | break;
|
---|
437 |
|
---|
438 | case ADDROF:
|
---|
439 | switch( l->n_op ){
|
---|
440 |
|
---|
441 | case UMUL:
|
---|
442 | nfree(p);
|
---|
443 | p = l->n_left;
|
---|
444 | nfree(l);
|
---|
445 | case TEMP:
|
---|
446 | case NAME:
|
---|
447 | p->n_type = INCREF(l->n_type);
|
---|
448 | p->n_qual = INCQAL(l->n_qual);
|
---|
449 | p->n_df = l->n_df;
|
---|
450 | p->n_ap = l->n_ap;
|
---|
451 | break;
|
---|
452 |
|
---|
453 | case COMOP:
|
---|
454 | nfree(p);
|
---|
455 | lr = buildtree(ADDROF, l->n_right, NIL);
|
---|
456 | p = buildtree( COMOP, l->n_left, lr );
|
---|
457 | nfree(l);
|
---|
458 | break;
|
---|
459 |
|
---|
460 | case QUEST:
|
---|
461 | lr = buildtree( ADDROF, l->n_right->n_right, NIL );
|
---|
462 | ll = buildtree( ADDROF, l->n_right->n_left, NIL );
|
---|
463 | nfree(p); nfree(l->n_right);
|
---|
464 | p = buildtree( QUEST, l->n_left, buildtree( COLON, ll, lr ) );
|
---|
465 | nfree(l);
|
---|
466 | break;
|
---|
467 |
|
---|
468 | default:
|
---|
469 | uerror("unacceptable operand of &: %d", l->n_op );
|
---|
470 | break;
|
---|
471 | }
|
---|
472 | break;
|
---|
473 |
|
---|
474 | case LS:
|
---|
475 | case RS: /* must make type size at least int... */
|
---|
476 | if (p->n_type == CHAR || p->n_type == SHORT) {
|
---|
477 | p->n_left = makety(l, INT, 0, 0, MKAP(INT));
|
---|
478 | } else if (p->n_type == UCHAR || p->n_type == USHORT) {
|
---|
479 | p->n_left = makety(l, UNSIGNED, 0, 0,
|
---|
480 | MKAP(UNSIGNED));
|
---|
481 | }
|
---|
482 | l = p->n_left;
|
---|
483 | p->n_type = l->n_type;
|
---|
484 | p->n_qual = l->n_qual;
|
---|
485 | p->n_df = l->n_df;
|
---|
486 | p->n_ap = l->n_ap;
|
---|
487 |
|
---|
488 | /* FALLTHROUGH */
|
---|
489 | case LSEQ:
|
---|
490 | case RSEQ: /* ...but not for assigned types */
|
---|
491 | if(tsize(r->n_type, r->n_df, r->n_ap) > SZINT)
|
---|
492 | p->n_right = makety(r, INT, 0, 0, MKAP(INT));
|
---|
493 | break;
|
---|
494 |
|
---|
495 | case RETURN:
|
---|
496 | case ASSIGN:
|
---|
497 | case CAST:
|
---|
498 | /* structure assignment */
|
---|
499 | /* take the addresses of the two sides; then make an
|
---|
500 | * operator using STASG and
|
---|
501 | * the addresses of left and right */
|
---|
502 |
|
---|
503 | if (strmemb(l->n_ap) != strmemb(r->n_ap))
|
---|
504 | uerror("assignment of different structures");
|
---|
505 |
|
---|
506 | r = buildtree(ADDROF, r, NIL);
|
---|
507 |
|
---|
508 | l = block(STASG, l, r, r->n_type, r->n_df, r->n_ap);
|
---|
509 | l = clocal(l);
|
---|
510 |
|
---|
511 | if( o == RETURN ){
|
---|
512 | nfree(p);
|
---|
513 | p = l;
|
---|
514 | break;
|
---|
515 | }
|
---|
516 |
|
---|
517 | p->n_op = UMUL;
|
---|
518 | p->n_left = l;
|
---|
519 | p->n_right = NIL;
|
---|
520 | break;
|
---|
521 |
|
---|
522 | case QUEST: /* fixup types of : */
|
---|
523 | if (r->n_left->n_type != p->n_type)
|
---|
524 | r->n_left = makety(r->n_left, p->n_type,
|
---|
525 | p->n_qual, p->n_df, p->n_ap);
|
---|
526 | if (r->n_right->n_type != p->n_type)
|
---|
527 | r->n_right = makety(r->n_right, p->n_type,
|
---|
528 | p->n_qual, p->n_df, p->n_ap);
|
---|
529 | break;
|
---|
530 |
|
---|
531 | case COLON:
|
---|
532 | /* structure colon */
|
---|
533 |
|
---|
534 | if (strmemb(l->n_ap) != strmemb(r->n_ap))
|
---|
535 | uerror( "type clash in conditional" );
|
---|
536 | break;
|
---|
537 |
|
---|
538 | case CALL:
|
---|
539 | p->n_right = r = strargs(p->n_right);
|
---|
540 | p = funcode(p);
|
---|
541 | /* FALLTHROUGH */
|
---|
542 | case UCALL:
|
---|
543 | if (!ISPTR(l->n_type))
|
---|
544 | uerror("illegal function");
|
---|
545 | p->n_type = DECREF(l->n_type);
|
---|
546 | if (!ISFTN(p->n_type))
|
---|
547 | uerror("illegal function");
|
---|
548 | p->n_type = DECREF(p->n_type);
|
---|
549 | p->n_df = l->n_df+1; /* add one for prototypes */
|
---|
550 | p->n_ap = l->n_ap;
|
---|
551 | if (p->n_type == STRTY || p->n_type == UNIONTY) {
|
---|
552 | /* function returning structure */
|
---|
553 | /* make function really return ptr to str., with * */
|
---|
554 |
|
---|
555 | p->n_op += STCALL-CALL;
|
---|
556 | p->n_type = INCREF(p->n_type);
|
---|
557 | p = clocal(p); /* before recursing */
|
---|
558 | p = buildtree(UMUL, p, NIL);
|
---|
559 |
|
---|
560 | }
|
---|
561 | break;
|
---|
562 |
|
---|
563 | default:
|
---|
564 | cerror( "other code %d", o );
|
---|
565 | }
|
---|
566 |
|
---|
567 | }
|
---|
568 |
|
---|
569 | /*
|
---|
570 | * Allow (void)0 casts.
|
---|
571 | * XXX - anything on the right side must be possible to cast.
|
---|
572 | * XXX - remove void types further on.
|
---|
573 | */
|
---|
574 | if (p->n_op == CAST && p->n_type == VOID &&
|
---|
575 | p->n_right->n_op == ICON)
|
---|
576 | p->n_right->n_type = VOID;
|
---|
577 |
|
---|
578 | if (actions & CVTO)
|
---|
579 | p = oconvert(p);
|
---|
580 | p = clocal(p);
|
---|
581 |
|
---|
582 | #ifdef PCC_DEBUG
|
---|
583 | if (bdebug) {
|
---|
584 | printf("End of buildtree:\n");
|
---|
585 | fwalk(p, eprint, 0);
|
---|
586 | }
|
---|
587 | #endif
|
---|
588 |
|
---|
589 | return(p);
|
---|
590 |
|
---|
591 | }
|
---|
592 |
|
---|
593 | /* Find a member in a struct or union. May be an unnamed member */
|
---|
594 | static struct symtab *
|
---|
595 | findmember(struct symtab *sp, char *s)
|
---|
596 | {
|
---|
597 | struct symtab *sp2, *sp3;
|
---|
598 |
|
---|
599 | for (; sp != NULL; sp = sp->snext) {
|
---|
600 | if (sp->sname[0] == '*') {
|
---|
601 | /* unnamed member, recurse down */
|
---|
602 | if ((sp2 = findmember(strmemb(sp->sap), s))) {
|
---|
603 | sp3 = tmpalloc(sizeof (struct symtab));
|
---|
604 | *sp3 = *sp2;
|
---|
605 | sp3->soffset += sp->soffset;
|
---|
606 | return sp3;
|
---|
607 | }
|
---|
608 | } else if (sp->sname == s)
|
---|
609 | return sp;
|
---|
610 | }
|
---|
611 | return NULL;
|
---|
612 | }
|
---|
613 |
|
---|
614 |
|
---|
615 | /*
|
---|
616 | * Check if there will be a lost label destination inside of a ?:
|
---|
617 | * It cannot be reached so just print it out.
|
---|
618 | */
|
---|
619 | void
|
---|
620 | putjops(NODE *p, void *arg)
|
---|
621 | {
|
---|
622 | if (p->n_op == COMOP && p->n_left->n_op == GOTO)
|
---|
623 | plabel(p->n_left->n_left->n_lval+1);
|
---|
624 | }
|
---|
625 |
|
---|
626 | /*
|
---|
627 | * Build a name node based on a symtab entry.
|
---|
628 | * broken out from buildtree().
|
---|
629 | */
|
---|
630 | NODE *
|
---|
631 | nametree(struct symtab *sp)
|
---|
632 | {
|
---|
633 | NODE *p;
|
---|
634 |
|
---|
635 | p = block(NAME, NIL, NIL, sp->stype, sp->sdf, sp->sap);
|
---|
636 | p->n_qual = sp->squal;
|
---|
637 | p->n_sp = sp;
|
---|
638 |
|
---|
639 | #ifndef NO_C_BUILTINS
|
---|
640 | if (sp->sname[0] == '_' && strncmp(sp->sname, "__builtin_", 10) == 0)
|
---|
641 | return p; /* do not touch builtins here */
|
---|
642 |
|
---|
643 | #endif
|
---|
644 |
|
---|
645 | if (sp->sflags & STNODE) {
|
---|
646 | /* Generated for optimizer */
|
---|
647 | p->n_op = TEMP;
|
---|
648 | p->n_rval = sp->soffset;
|
---|
649 | }
|
---|
650 |
|
---|
651 | #ifdef GCC_COMPAT
|
---|
652 | /* Get a label name */
|
---|
653 | if (sp->sflags == SLBLNAME) {
|
---|
654 | p->n_type = VOID;
|
---|
655 | p->n_ap = MKAP(VOID);
|
---|
656 | }
|
---|
657 | #endif
|
---|
658 | if (sp->stype == UNDEF) {
|
---|
659 | uerror("%s undefined", sp->sname);
|
---|
660 | /* make p look reasonable */
|
---|
661 | p->n_type = INT;
|
---|
662 | p->n_ap = MKAP(INT);
|
---|
663 | p->n_df = NULL;
|
---|
664 | defid(p, SNULL);
|
---|
665 | }
|
---|
666 | if (sp->sclass == MOE) {
|
---|
667 | p->n_op = ICON;
|
---|
668 | p->n_lval = sp->soffset;
|
---|
669 | p->n_df = NULL;
|
---|
670 | p->n_sp = NULL;
|
---|
671 | }
|
---|
672 | return clocal(p);
|
---|
673 | }
|
---|
674 |
|
---|
675 | /*
|
---|
676 | * Cast a node to another type by inserting a cast.
|
---|
677 | * Just a nicer interface to buildtree.
|
---|
678 | * Returns the new tree.
|
---|
679 | */
|
---|
680 | NODE *
|
---|
681 | cast(NODE *p, TWORD t, TWORD u)
|
---|
682 | {
|
---|
683 | NODE *q;
|
---|
684 |
|
---|
685 | q = block(NAME, NIL, NIL, t, 0, MKAP(BTYPE(t)));
|
---|
686 | q->n_qual = u;
|
---|
687 | q = buildtree(CAST, q, p);
|
---|
688 | p = q->n_right;
|
---|
689 | nfree(q->n_left);
|
---|
690 | nfree(q);
|
---|
691 | return p;
|
---|
692 | }
|
---|
693 |
|
---|
694 | /*
|
---|
695 | * Cast and complain if necessary by not inserining a cast.
|
---|
696 | */
|
---|
697 | NODE *
|
---|
698 | ccast(NODE *p, TWORD t, TWORD u, union dimfun *df, struct attr *ap)
|
---|
699 | {
|
---|
700 | NODE *q;
|
---|
701 |
|
---|
702 | /* let buildtree do typechecking (and casting) */
|
---|
703 | q = block(NAME, NIL, NIL, t, df, ap);
|
---|
704 | p = buildtree(ASSIGN, q, p);
|
---|
705 | nfree(p->n_left);
|
---|
706 | q = optim(p->n_right);
|
---|
707 | nfree(p);
|
---|
708 | return q;
|
---|
709 | }
|
---|
710 |
|
---|
711 | /*
|
---|
712 | * Do a conditional branch.
|
---|
713 | */
|
---|
714 | void
|
---|
715 | cbranch(NODE *p, NODE *q)
|
---|
716 | {
|
---|
717 | p = buildtree(CBRANCH, p, q);
|
---|
718 | if (p->n_left->n_op == ICON) {
|
---|
719 | if (p->n_left->n_lval != 0) {
|
---|
720 | branch(q->n_lval); /* branch always */
|
---|
721 | reached = 0;
|
---|
722 | }
|
---|
723 | tfree(p);
|
---|
724 | tfree(q);
|
---|
725 | return;
|
---|
726 | }
|
---|
727 | ecomp(p);
|
---|
728 | }
|
---|
729 |
|
---|
730 | NODE *
|
---|
731 | strargs( p ) register NODE *p; { /* rewrite structure flavored arguments */
|
---|
732 |
|
---|
733 | if( p->n_op == CM ){
|
---|
734 | p->n_left = strargs( p->n_left );
|
---|
735 | p->n_right = strargs( p->n_right );
|
---|
736 | return( p );
|
---|
737 | }
|
---|
738 |
|
---|
739 | if( p->n_type == STRTY || p->n_type == UNIONTY ){
|
---|
740 | p = block(STARG, p, NIL, p->n_type, p->n_df, p->n_ap);
|
---|
741 | p->n_left = buildtree( ADDROF, p->n_left, NIL );
|
---|
742 | p = clocal(p);
|
---|
743 | }
|
---|
744 | return( p );
|
---|
745 | }
|
---|
746 |
|
---|
747 | /*
|
---|
748 | * apply the op o to the lval part of p; if binary, rhs is val
|
---|
749 | */
|
---|
750 | int
|
---|
751 | conval(NODE *p, int o, NODE *q)
|
---|
752 | {
|
---|
753 | TWORD tl = p->n_type, tr = q->n_type, td;
|
---|
754 | int i, u;
|
---|
755 | CONSZ val;
|
---|
756 | U_CONSZ v1, v2;
|
---|
757 |
|
---|
758 | val = q->n_lval;
|
---|
759 |
|
---|
760 | /* make both sides same type */
|
---|
761 | if (tl < BTMASK && tr < BTMASK) {
|
---|
762 | td = tl > tr ? tl : tr;
|
---|
763 | if (td < INT)
|
---|
764 | td = INT;
|
---|
765 | u = ISUNSIGNED(td);
|
---|
766 | if (tl != td)
|
---|
767 | p = makety(p, td, 0, 0, MKAP(td));
|
---|
768 | if (tr != td)
|
---|
769 | q = makety(q, td, 0, 0, MKAP(td));
|
---|
770 | } else
|
---|
771 | u = ISUNSIGNED(tl) || ISUNSIGNED(tr);
|
---|
772 | if( u && (o==LE||o==LT||o==GE||o==GT)) o += (UGE-GE);
|
---|
773 |
|
---|
774 | if (p->n_sp != NULL && q->n_sp != NULL)
|
---|
775 | return(0);
|
---|
776 | if (q->n_sp != NULL && o != PLUS)
|
---|
777 | return(0);
|
---|
778 | if (p->n_sp != NULL && o != PLUS && o != MINUS)
|
---|
779 | return(0);
|
---|
780 |
|
---|
781 | v1 = p->n_lval;
|
---|
782 | v2 = q->n_lval;
|
---|
783 | switch( o ){
|
---|
784 |
|
---|
785 | case PLUS:
|
---|
786 | p->n_lval += val;
|
---|
787 | if (p->n_sp == NULL) {
|
---|
788 | p->n_right = q->n_right;
|
---|
789 | p->n_type = q->n_type;
|
---|
790 | }
|
---|
791 | break;
|
---|
792 | case MINUS:
|
---|
793 | p->n_lval -= val;
|
---|
794 | break;
|
---|
795 | case MUL:
|
---|
796 | p->n_lval *= val;
|
---|
797 | break;
|
---|
798 | case DIV:
|
---|
799 | if (val == 0)
|
---|
800 | uerror("division by 0");
|
---|
801 | else {
|
---|
802 | if (u) {
|
---|
803 | v1 /= v2;
|
---|
804 | p->n_lval = v1;
|
---|
805 | } else
|
---|
806 | p->n_lval /= val;
|
---|
807 | }
|
---|
808 | break;
|
---|
809 | case MOD:
|
---|
810 | if (val == 0)
|
---|
811 | uerror("division by 0");
|
---|
812 | else {
|
---|
813 | if (u) {
|
---|
814 | v1 %= v2;
|
---|
815 | p->n_lval = v1;
|
---|
816 | } else
|
---|
817 | p->n_lval %= val;
|
---|
818 | }
|
---|
819 | break;
|
---|
820 | case AND:
|
---|
821 | p->n_lval &= val;
|
---|
822 | break;
|
---|
823 | case OR:
|
---|
824 | p->n_lval |= val;
|
---|
825 | break;
|
---|
826 | case ER:
|
---|
827 | p->n_lval ^= val;
|
---|
828 | break;
|
---|
829 | case LS:
|
---|
830 | i = (int)val;
|
---|
831 | p->n_lval = p->n_lval << i;
|
---|
832 | break;
|
---|
833 | case RS:
|
---|
834 | i = (int)val;
|
---|
835 | if (u) {
|
---|
836 | v1 = v1 >> i;
|
---|
837 | p->n_lval = v1;
|
---|
838 | } else
|
---|
839 | p->n_lval = p->n_lval >> i;
|
---|
840 | break;
|
---|
841 |
|
---|
842 | case UMINUS:
|
---|
843 | p->n_lval = - p->n_lval;
|
---|
844 | break;
|
---|
845 | case COMPL:
|
---|
846 | p->n_lval = ~p->n_lval;
|
---|
847 | break;
|
---|
848 | case NOT:
|
---|
849 | p->n_lval = !p->n_lval;
|
---|
850 | break;
|
---|
851 | case LT:
|
---|
852 | p->n_lval = p->n_lval < val;
|
---|
853 | break;
|
---|
854 | case LE:
|
---|
855 | p->n_lval = p->n_lval <= val;
|
---|
856 | break;
|
---|
857 | case GT:
|
---|
858 | p->n_lval = p->n_lval > val;
|
---|
859 | break;
|
---|
860 | case GE:
|
---|
861 | p->n_lval = p->n_lval >= val;
|
---|
862 | break;
|
---|
863 | case ULT:
|
---|
864 | p->n_lval = v1 < v2;
|
---|
865 | break;
|
---|
866 | case ULE:
|
---|
867 | p->n_lval = v1 <= v2;
|
---|
868 | break;
|
---|
869 | case UGT:
|
---|
870 | p->n_lval = v1 > v2;
|
---|
871 | break;
|
---|
872 | case UGE:
|
---|
873 | p->n_lval = v1 >= v2;
|
---|
874 | break;
|
---|
875 | case EQ:
|
---|
876 | p->n_lval = p->n_lval == val;
|
---|
877 | break;
|
---|
878 | case NE:
|
---|
879 | p->n_lval = p->n_lval != val;
|
---|
880 | break;
|
---|
881 | case ANDAND:
|
---|
882 | p->n_lval = p->n_lval && val;
|
---|
883 | break;
|
---|
884 | case OROR:
|
---|
885 | p->n_lval = p->n_lval || val;
|
---|
886 | break;
|
---|
887 | default:
|
---|
888 | return(0);
|
---|
889 | }
|
---|
890 | /* Do the best in making everything type correct after calc */
|
---|
891 | if (p->n_sp == NULL && q->n_sp == NULL)
|
---|
892 | p->n_lval = valcast(p->n_lval, p->n_type);
|
---|
893 | return(1);
|
---|
894 | }
|
---|
895 |
|
---|
896 | /*
|
---|
897 | * Ensure that v matches the type t; sign- or zero-extended
|
---|
898 | * as suitable to CONSZ.
|
---|
899 | * Only to be used for integer types.
|
---|
900 | */
|
---|
901 | CONSZ
|
---|
902 | valcast(CONSZ v, TWORD t)
|
---|
903 | {
|
---|
904 | CONSZ r;
|
---|
905 |
|
---|
906 | if (t < CHAR || t > ULONGLONG)
|
---|
907 | return v; /* cannot cast */
|
---|
908 |
|
---|
909 | if (t >= LONGLONG)
|
---|
910 | return v; /* already largest */
|
---|
911 |
|
---|
912 | #define M(x) ((((1ULL << ((x)-1)) - 1) << 1) + 1)
|
---|
913 | #define NOTM(x) (~M(x))
|
---|
914 | #define SBIT(x) (1ULL << ((x)-1))
|
---|
915 |
|
---|
916 | r = v & M(btattr[t].atypsz);
|
---|
917 | if (!ISUNSIGNED(t) && (SBIT(btattr[t].atypsz) & r))
|
---|
918 | r = r | NOTM(btattr[t].atypsz);
|
---|
919 | return r;
|
---|
920 | }
|
---|
921 |
|
---|
922 | /*
|
---|
923 | * Checks p for the existance of a pun. This is called when the op of p
|
---|
924 | * is ASSIGN, RETURN, CAST, COLON, or relational.
|
---|
925 | * One case is when enumerations are used: this applies only to lint.
|
---|
926 | * In the other case, one operand is a pointer, the other integer type
|
---|
927 | * we check that this integer is in fact a constant zero...
|
---|
928 | * in the case of ASSIGN, any assignment of pointer to integer is illegal
|
---|
929 | * this falls out, because the LHS is never 0.
|
---|
930 | * XXX - check for COMOPs in assignment RHS?
|
---|
931 | */
|
---|
932 | void
|
---|
933 | chkpun(NODE *p)
|
---|
934 | {
|
---|
935 | union dimfun *d1, *d2;
|
---|
936 | NODE *q;
|
---|
937 | int t1, t2;
|
---|
938 |
|
---|
939 | t1 = p->n_left->n_type;
|
---|
940 | t2 = p->n_right->n_type;
|
---|
941 |
|
---|
942 | switch (p->n_op) {
|
---|
943 | case RETURN:
|
---|
944 | /* return of void allowed but nothing else */
|
---|
945 | if (t1 == VOID && t2 == VOID)
|
---|
946 | return;
|
---|
947 | if (t1 == VOID) {
|
---|
948 | werror("returning value from void function");
|
---|
949 | return;
|
---|
950 | }
|
---|
951 | if (t2 == VOID) {
|
---|
952 | uerror("using void value");
|
---|
953 | return;
|
---|
954 | }
|
---|
955 | case COLON:
|
---|
956 | if (t1 == VOID && t2 == VOID)
|
---|
957 | return;
|
---|
958 | break;
|
---|
959 | default:
|
---|
960 | if ((t1 == VOID && t2 != VOID) || (t1 != VOID && t2 == VOID)) {
|
---|
961 | uerror("value of void expression used");
|
---|
962 | return;
|
---|
963 | }
|
---|
964 | break;
|
---|
965 | }
|
---|
966 |
|
---|
967 | /* allow void pointer assignments in any direction */
|
---|
968 | if (BTYPE(t1) == VOID && (t2 & TMASK))
|
---|
969 | return;
|
---|
970 | if (BTYPE(t2) == VOID && (t1 & TMASK))
|
---|
971 | return;
|
---|
972 |
|
---|
973 | /* boolean have special syntax */
|
---|
974 | if (t1 == BOOL) {
|
---|
975 | if (!ISARY(t2)) /* Anything scalar */
|
---|
976 | return;
|
---|
977 | }
|
---|
978 |
|
---|
979 | if (ISPTR(t1) || ISARY(t1))
|
---|
980 | q = p->n_right;
|
---|
981 | else
|
---|
982 | q = p->n_left;
|
---|
983 |
|
---|
984 | if (!ISPTR(q->n_type) && !ISARY(q->n_type)) {
|
---|
985 | if (q->n_op != ICON || q->n_lval != 0)
|
---|
986 | werror("illegal combination of pointer and integer");
|
---|
987 | } else {
|
---|
988 | if (t1 == t2) {
|
---|
989 | if (ISSOU(BTYPE(t1)) &&
|
---|
990 | !suemeq(p->n_left->n_ap, p->n_right->n_ap))
|
---|
991 | werror("illegal structure pointer combination");
|
---|
992 | return;
|
---|
993 | }
|
---|
994 | d1 = p->n_left->n_df;
|
---|
995 | d2 = p->n_right->n_df;
|
---|
996 | for (;;) {
|
---|
997 | if (ISARY(t1) || ISPTR(t1)) {
|
---|
998 | if (!ISARY(t2) && !ISPTR(t2))
|
---|
999 | break;
|
---|
1000 | if (ISARY(t1) && ISARY(t2) && d1->ddim != d2->ddim) {
|
---|
1001 | werror("illegal array size combination");
|
---|
1002 | return;
|
---|
1003 | }
|
---|
1004 | if (ISARY(t1))
|
---|
1005 | ++d1;
|
---|
1006 | if (ISARY(t2))
|
---|
1007 | ++d2;
|
---|
1008 | } else if (ISFTN(t1)) {
|
---|
1009 | if (chkftn(d1->dfun, d2->dfun)) {
|
---|
1010 | werror("illegal function "
|
---|
1011 | "pointer combination");
|
---|
1012 | return;
|
---|
1013 | }
|
---|
1014 | ++d1;
|
---|
1015 | ++d2;
|
---|
1016 | } else
|
---|
1017 | break;
|
---|
1018 | t1 = DECREF(t1);
|
---|
1019 | t2 = DECREF(t2);
|
---|
1020 | }
|
---|
1021 | if (DEUNSIGN(t1) != DEUNSIGN(t2))
|
---|
1022 | warner(Wpointer_sign, NULL);
|
---|
1023 | }
|
---|
1024 | }
|
---|
1025 |
|
---|
1026 | NODE *
|
---|
1027 | stref(NODE *p)
|
---|
1028 | {
|
---|
1029 | NODE *r;
|
---|
1030 | struct attr *ap;
|
---|
1031 | union dimfun *d;
|
---|
1032 | TWORD t, q;
|
---|
1033 | int dsc;
|
---|
1034 | OFFSZ off;
|
---|
1035 | struct symtab *s;
|
---|
1036 |
|
---|
1037 | /* make p->x */
|
---|
1038 | /* this is also used to reference automatic variables */
|
---|
1039 |
|
---|
1040 | s = p->n_right->n_sp;
|
---|
1041 | nfree(p->n_right);
|
---|
1042 | r = p->n_left;
|
---|
1043 | nfree(p);
|
---|
1044 | p = pconvert(r);
|
---|
1045 |
|
---|
1046 | /* make p look like ptr to x */
|
---|
1047 |
|
---|
1048 | if (!ISPTR(p->n_type))
|
---|
1049 | p->n_type = PTR+UNIONTY;
|
---|
1050 |
|
---|
1051 | t = INCREF(s->stype);
|
---|
1052 | q = INCQAL(s->squal);
|
---|
1053 | d = s->sdf;
|
---|
1054 | ap = s->sap;
|
---|
1055 |
|
---|
1056 | p = makety(p, t, q, d, ap);
|
---|
1057 |
|
---|
1058 | /* compute the offset to be added */
|
---|
1059 |
|
---|
1060 | off = s->soffset;
|
---|
1061 | dsc = s->sclass;
|
---|
1062 |
|
---|
1063 | #ifndef CAN_UNALIGN
|
---|
1064 | /*
|
---|
1065 | * If its a packed struct, and the target cannot do unaligned
|
---|
1066 | * accesses, then split it up in two bitfield operations.
|
---|
1067 | * LHS and RHS accesses are different, so must delay
|
---|
1068 | * it until we know. Do the bitfield construct here though.
|
---|
1069 | */
|
---|
1070 | if ((dsc & FIELD) == 0 && (off % talign(s->stype, s->sap))) {
|
---|
1071 | #if 0
|
---|
1072 | int sz = tsize(s->stype, s->sdf, s->sap);
|
---|
1073 | int al = talign(s->stype, s->sap);
|
---|
1074 | int sz1 = al - (off % al);
|
---|
1075 | #endif
|
---|
1076 | }
|
---|
1077 | #endif
|
---|
1078 |
|
---|
1079 | #if 0
|
---|
1080 | if (dsc & FIELD) { /* make fields look like ints */
|
---|
1081 | off = (off/ALINT)*ALINT;
|
---|
1082 | ap = MKAP(INT);
|
---|
1083 | }
|
---|
1084 | #endif
|
---|
1085 | if (off != 0) {
|
---|
1086 | p = block(PLUS, p, offcon(off, t, d, ap), t, d, ap);
|
---|
1087 | p->n_qual = q;
|
---|
1088 | p = optim(p);
|
---|
1089 | }
|
---|
1090 |
|
---|
1091 | p = buildtree(UMUL, p, NIL);
|
---|
1092 |
|
---|
1093 | /* if field, build field info */
|
---|
1094 |
|
---|
1095 | if (dsc & FIELD) {
|
---|
1096 | p = block(FLD, p, NIL, s->stype, 0, s->sap);
|
---|
1097 | p->n_qual = q;
|
---|
1098 | p->n_rval = PKFIELD(dsc&FLDSIZ, s->soffset%talign(s->stype, ap));
|
---|
1099 | }
|
---|
1100 |
|
---|
1101 | p = clocal(p);
|
---|
1102 | return p;
|
---|
1103 | }
|
---|
1104 |
|
---|
1105 | int
|
---|
1106 | notlval(p) register NODE *p; {
|
---|
1107 |
|
---|
1108 | /* return 0 if p an lvalue, 1 otherwise */
|
---|
1109 |
|
---|
1110 | again:
|
---|
1111 |
|
---|
1112 | switch( p->n_op ){
|
---|
1113 |
|
---|
1114 | case FLD:
|
---|
1115 | p = p->n_left;
|
---|
1116 | goto again;
|
---|
1117 |
|
---|
1118 | case NAME:
|
---|
1119 | case OREG:
|
---|
1120 | case UMUL:
|
---|
1121 | if( ISARY(p->n_type) || ISFTN(p->n_type) ) return(1);
|
---|
1122 | case TEMP:
|
---|
1123 | case REG:
|
---|
1124 | return(0);
|
---|
1125 |
|
---|
1126 | default:
|
---|
1127 | return(1);
|
---|
1128 |
|
---|
1129 | }
|
---|
1130 |
|
---|
1131 | }
|
---|
1132 | /* make a constant node with value i */
|
---|
1133 | NODE *
|
---|
1134 | bcon(int i)
|
---|
1135 | {
|
---|
1136 | return xbcon(i, NULL, INT);
|
---|
1137 | }
|
---|
1138 |
|
---|
1139 | NODE *
|
---|
1140 | xbcon(CONSZ val, struct symtab *sp, TWORD type)
|
---|
1141 | {
|
---|
1142 | NODE *p;
|
---|
1143 |
|
---|
1144 | p = block(ICON, NIL, NIL, type, 0, MKAP(type));
|
---|
1145 | p->n_lval = val;
|
---|
1146 | p->n_sp = sp;
|
---|
1147 | return clocal(p);
|
---|
1148 | }
|
---|
1149 |
|
---|
1150 | NODE *
|
---|
1151 | bpsize(NODE *p)
|
---|
1152 | {
|
---|
1153 | int isdyn(struct symtab *sp);
|
---|
1154 | struct attr *ap;
|
---|
1155 | struct symtab s;
|
---|
1156 | NODE *q, *r;
|
---|
1157 | TWORD t;
|
---|
1158 |
|
---|
1159 | s.stype = DECREF(p->n_type);
|
---|
1160 | s.sdf = p->n_df;
|
---|
1161 | if (isdyn(&s)) {
|
---|
1162 | q = bcon(1);
|
---|
1163 | for (t = s.stype; t > BTMASK; t = DECREF(t)) {
|
---|
1164 | if (ISPTR(t))
|
---|
1165 | return buildtree(MUL, q, bcon(SZPOINT(t)));
|
---|
1166 | if (ISARY(t)) {
|
---|
1167 | if (s.sdf->ddim < 0)
|
---|
1168 | r = tempnode(-s.sdf->ddim,
|
---|
1169 | INT, 0, MKAP(INT));
|
---|
1170 | else
|
---|
1171 | r = bcon(s.sdf->ddim/SZCHAR);
|
---|
1172 | q = buildtree(MUL, q, r);
|
---|
1173 | s.sdf++;
|
---|
1174 | }
|
---|
1175 | }
|
---|
1176 | ap = attr_find(p->n_ap, ATTR_BASETYP);
|
---|
1177 | p = buildtree(MUL, q, bcon(ap->atypsz/SZCHAR));
|
---|
1178 | } else
|
---|
1179 | p = (offcon(psize(p), p->n_type, p->n_df, p->n_ap));
|
---|
1180 | return p;
|
---|
1181 | }
|
---|
1182 |
|
---|
1183 | /*
|
---|
1184 | * p is a node of type pointer; psize returns the
|
---|
1185 | * size of the thing pointed to
|
---|
1186 | */
|
---|
1187 | OFFSZ
|
---|
1188 | psize(NODE *p)
|
---|
1189 | {
|
---|
1190 |
|
---|
1191 | if (!ISPTR(p->n_type)) {
|
---|
1192 | uerror("pointer required");
|
---|
1193 | return(SZINT);
|
---|
1194 | }
|
---|
1195 | /* note: no pointers to fields */
|
---|
1196 | return(tsize(DECREF(p->n_type), p->n_df, p->n_ap));
|
---|
1197 | }
|
---|
1198 |
|
---|
1199 | /*
|
---|
1200 | * convert an operand of p
|
---|
1201 | * f is either CVTL or CVTR
|
---|
1202 | * operand has type int, and is converted by the size of the other side
|
---|
1203 | * convert is called when an integer is to be added to a pointer, for
|
---|
1204 | * example in arrays or structures.
|
---|
1205 | */
|
---|
1206 | NODE *
|
---|
1207 | convert(NODE *p, int f)
|
---|
1208 | {
|
---|
1209 | union dimfun *df;
|
---|
1210 | TWORD ty, ty2;
|
---|
1211 | NODE *q, *r, *s, *rv;
|
---|
1212 |
|
---|
1213 | if (f == CVTL) {
|
---|
1214 | q = p->n_left;
|
---|
1215 | s = p->n_right;
|
---|
1216 | } else {
|
---|
1217 | q = p->n_right;
|
---|
1218 | s = p->n_left;
|
---|
1219 | }
|
---|
1220 | ty2 = ty = DECREF(s->n_type);
|
---|
1221 | while (ISARY(ty))
|
---|
1222 | ty = DECREF(ty);
|
---|
1223 |
|
---|
1224 | r = offcon(tsize(ty, s->n_df, s->n_ap), s->n_type, s->n_df, s->n_ap);
|
---|
1225 | ty = ty2;
|
---|
1226 | rv = bcon(1);
|
---|
1227 | df = s->n_df;
|
---|
1228 | while (ISARY(ty)) {
|
---|
1229 | rv = buildtree(MUL, rv, df->ddim >= 0 ? bcon(df->ddim) :
|
---|
1230 | tempnode(-df->ddim, INT, 0, MKAP(INT)));
|
---|
1231 | df++;
|
---|
1232 | ty = DECREF(ty);
|
---|
1233 | }
|
---|
1234 | rv = clocal(block(PMCONV, rv, r, INT, 0, MKAP(INT)));
|
---|
1235 | rv = optim(rv);
|
---|
1236 |
|
---|
1237 | r = block(PMCONV, q, rv, INT, 0, MKAP(INT));
|
---|
1238 | r = clocal(r);
|
---|
1239 | /*
|
---|
1240 | * Indexing is only allowed with integer arguments, so insert
|
---|
1241 | * SCONV here if arg is not an integer.
|
---|
1242 | * XXX - complain?
|
---|
1243 | */
|
---|
1244 | if (r->n_type != INTPTR)
|
---|
1245 | r = clocal(block(SCONV, r, NIL, INTPTR, 0, MKAP(INTPTR)));
|
---|
1246 | if (f == CVTL)
|
---|
1247 | p->n_left = r;
|
---|
1248 | else
|
---|
1249 | p->n_right = r;
|
---|
1250 | return(p);
|
---|
1251 | }
|
---|
1252 |
|
---|
1253 | NODE *
|
---|
1254 | pconvert( p ) register NODE *p; {
|
---|
1255 |
|
---|
1256 | /* if p should be changed into a pointer, do so */
|
---|
1257 |
|
---|
1258 | if( ISARY( p->n_type) ){
|
---|
1259 | p->n_type = DECREF( p->n_type );
|
---|
1260 | ++p->n_df;
|
---|
1261 | return( buildtree( ADDROF, p, NIL ) );
|
---|
1262 | }
|
---|
1263 | if( ISFTN( p->n_type) )
|
---|
1264 | return( buildtree( ADDROF, p, NIL ) );
|
---|
1265 |
|
---|
1266 | return( p );
|
---|
1267 | }
|
---|
1268 |
|
---|
1269 | NODE *
|
---|
1270 | oconvert(p) register NODE *p; {
|
---|
1271 | /* convert the result itself: used for pointer and unsigned */
|
---|
1272 |
|
---|
1273 | switch(p->n_op) {
|
---|
1274 |
|
---|
1275 | case LE:
|
---|
1276 | case LT:
|
---|
1277 | case GE:
|
---|
1278 | case GT:
|
---|
1279 | if(ISUNSIGNED(p->n_left->n_type) ||
|
---|
1280 | ISUNSIGNED(p->n_right->n_type) ||
|
---|
1281 | ISPTR(p->n_left->n_type) ||
|
---|
1282 | ISPTR(p->n_right->n_type))
|
---|
1283 | p->n_op += (ULE-LE);
|
---|
1284 | /* FALLTHROUGH */
|
---|
1285 | case EQ:
|
---|
1286 | case NE:
|
---|
1287 | return( p );
|
---|
1288 |
|
---|
1289 | case MINUS:
|
---|
1290 | p->n_type = INTPTR;
|
---|
1291 | p->n_ap = MKAP(INTPTR);
|
---|
1292 | return( clocal( block( PVCONV,
|
---|
1293 | p, bpsize(p->n_left), INT, 0, MKAP(INT))));
|
---|
1294 | }
|
---|
1295 |
|
---|
1296 | cerror( "illegal oconvert: %d", p->n_op );
|
---|
1297 |
|
---|
1298 | return(p);
|
---|
1299 | }
|
---|
1300 |
|
---|
1301 | /*
|
---|
1302 | * makes the operands of p agree; they are
|
---|
1303 | * either pointers or integers, by this time
|
---|
1304 | * with MINUS, the sizes must be the same
|
---|
1305 | * with COLON, the types must be the same
|
---|
1306 | */
|
---|
1307 | NODE *
|
---|
1308 | ptmatch(NODE *p)
|
---|
1309 | {
|
---|
1310 | struct attr *ap, *ap2;
|
---|
1311 | union dimfun *d, *d2;
|
---|
1312 | TWORD t1, t2, t, q1, q2, q;
|
---|
1313 | int o;
|
---|
1314 |
|
---|
1315 | o = p->n_op;
|
---|
1316 | t = t1 = p->n_left->n_type;
|
---|
1317 | q = q1 = p->n_left->n_qual;
|
---|
1318 | t2 = p->n_right->n_type;
|
---|
1319 | q2 = p->n_right->n_qual;
|
---|
1320 | d = p->n_left->n_df;
|
---|
1321 | d2 = p->n_right->n_df;
|
---|
1322 | ap = p->n_left->n_ap;
|
---|
1323 | ap2 = p->n_right->n_ap;
|
---|
1324 |
|
---|
1325 | switch( o ){
|
---|
1326 |
|
---|
1327 | case ASSIGN:
|
---|
1328 | case RETURN:
|
---|
1329 | case CAST:
|
---|
1330 | { break; }
|
---|
1331 |
|
---|
1332 | case MINUS: {
|
---|
1333 | int isdyn(struct symtab *sp);
|
---|
1334 | struct symtab s1, s2;
|
---|
1335 |
|
---|
1336 | s1.stype = DECREF(t);
|
---|
1337 | s1.sdf = d;
|
---|
1338 | s2.stype = DECREF(t2);
|
---|
1339 | s2.sdf = d2;
|
---|
1340 | if (isdyn(&s1) || isdyn(&s2))
|
---|
1341 | ; /* We don't know */
|
---|
1342 | else if (psize(p->n_left) != psize(p->n_right))
|
---|
1343 | uerror("illegal pointer subtraction");
|
---|
1344 | break;
|
---|
1345 | }
|
---|
1346 |
|
---|
1347 | case COLON:
|
---|
1348 | if (t1 != t2) {
|
---|
1349 | /*
|
---|
1350 | * Check for void pointer types. They are allowed
|
---|
1351 | * to cast to/from any pointers.
|
---|
1352 | */
|
---|
1353 | if (ISPTR(t1) && ISPTR(t2) &&
|
---|
1354 | (BTYPE(t1) == VOID || BTYPE(t2) == VOID))
|
---|
1355 | break;
|
---|
1356 | uerror("illegal types in :");
|
---|
1357 | }
|
---|
1358 | break;
|
---|
1359 |
|
---|
1360 | default: /* must work harder: relationals or comparisons */
|
---|
1361 |
|
---|
1362 | if( !ISPTR(t1) ){
|
---|
1363 | t = t2;
|
---|
1364 | q = q2;
|
---|
1365 | d = d2;
|
---|
1366 | ap = ap2;
|
---|
1367 | break;
|
---|
1368 | }
|
---|
1369 | if( !ISPTR(t2) ){
|
---|
1370 | break;
|
---|
1371 | }
|
---|
1372 |
|
---|
1373 | /* both are pointers */
|
---|
1374 | if( talign(t2,ap2) < talign(t,ap) ){
|
---|
1375 | t = t2;
|
---|
1376 | q = q2;
|
---|
1377 | ap = ap2;
|
---|
1378 | }
|
---|
1379 | break;
|
---|
1380 | }
|
---|
1381 |
|
---|
1382 | p->n_left = makety( p->n_left, t, q, d, ap );
|
---|
1383 | p->n_right = makety( p->n_right, t, q, d, ap );
|
---|
1384 | if( o!=MINUS && !clogop(o) ){
|
---|
1385 |
|
---|
1386 | p->n_type = t;
|
---|
1387 | p->n_qual = q;
|
---|
1388 | p->n_df = d;
|
---|
1389 | p->n_ap = ap;
|
---|
1390 | }
|
---|
1391 |
|
---|
1392 | return(clocal(p));
|
---|
1393 | }
|
---|
1394 |
|
---|
1395 | int tdebug = 0;
|
---|
1396 |
|
---|
1397 |
|
---|
1398 | /*
|
---|
1399 | * Satisfy the types of various arithmetic binary ops.
|
---|
1400 | *
|
---|
1401 | * rules are:
|
---|
1402 | * if assignment, type of LHS
|
---|
1403 | * if any doubles, make double
|
---|
1404 | * else if any float make float
|
---|
1405 | * else if any longlongs, make long long
|
---|
1406 | * else if any longs, make long
|
---|
1407 | * else etcetc.
|
---|
1408 | *
|
---|
1409 | * If the op with the highest rank is unsigned, this is the resulting type.
|
---|
1410 | * See: 6.3.1.1 rank order equal of signed and unsigned types
|
---|
1411 | * 6.3.1.8 Usual arithmetic conversions
|
---|
1412 | */
|
---|
1413 | NODE *
|
---|
1414 | tymatch(NODE *p)
|
---|
1415 | {
|
---|
1416 | TWORD tl, tr, t, tu;
|
---|
1417 | NODE *l, *r;
|
---|
1418 | int o, lu, ru;
|
---|
1419 |
|
---|
1420 | o = p->n_op;
|
---|
1421 | r = p->n_right;
|
---|
1422 | l = p->n_left;
|
---|
1423 |
|
---|
1424 | tl = l->n_type;
|
---|
1425 | tr = r->n_type;
|
---|
1426 |
|
---|
1427 | lu = ru = 0;
|
---|
1428 | if (ISUNSIGNED(tl)) {
|
---|
1429 | lu = 1;
|
---|
1430 | tl = DEUNSIGN(tl);
|
---|
1431 | }
|
---|
1432 | if (ISUNSIGNED(tr)) {
|
---|
1433 | ru = 1;
|
---|
1434 | tr = DEUNSIGN(tr);
|
---|
1435 | }
|
---|
1436 |
|
---|
1437 | if (clogop(o) && tl == tr && lu != ru &&
|
---|
1438 | l->n_op != ICON && r->n_op != ICON)
|
---|
1439 | warner(Wsign_compare, NULL);
|
---|
1440 |
|
---|
1441 | if (tl == LDOUBLE || tr == LDOUBLE)
|
---|
1442 | t = LDOUBLE;
|
---|
1443 | else if (tl == DOUBLE || tr == DOUBLE)
|
---|
1444 | t = DOUBLE;
|
---|
1445 | else if (tl == FLOAT || tr == FLOAT)
|
---|
1446 | t = FLOAT;
|
---|
1447 | else if (tl==LONGLONG || tr == LONGLONG)
|
---|
1448 | t = LONGLONG;
|
---|
1449 | else if (tl==LONG || tr==LONG)
|
---|
1450 | t = LONG;
|
---|
1451 | else /* everything else */
|
---|
1452 | t = INT;
|
---|
1453 |
|
---|
1454 | if (casgop(o)) {
|
---|
1455 | tu = l->n_type;
|
---|
1456 | t = tl;
|
---|
1457 | } else {
|
---|
1458 | /* Should result be unsigned? */
|
---|
1459 | /* This depends on ctype() being called correctly */
|
---|
1460 | tu = t;
|
---|
1461 | if (UNSIGNABLE(t) && (lu || ru)) {
|
---|
1462 | if (tl >= tr && lu)
|
---|
1463 | tu = ENUNSIGN(t);
|
---|
1464 | if (tr >= tl && ru)
|
---|
1465 | tu = ENUNSIGN(t);
|
---|
1466 | }
|
---|
1467 | }
|
---|
1468 |
|
---|
1469 | /* because expressions have values that are at least as wide
|
---|
1470 | as INT or UNSIGNED, the only conversions needed
|
---|
1471 | are those involving FLOAT/DOUBLE, and those
|
---|
1472 | from LONG to INT and ULONG to UNSIGNED */
|
---|
1473 |
|
---|
1474 | if (t != tl || (ru && !lu)) {
|
---|
1475 | if (o != CAST && r->n_op != ICON &&
|
---|
1476 | tsize(tl, 0, MKAP(tl)) > tsize(tu, 0, MKAP(tu)))
|
---|
1477 | warner(Wtruncate, tnames[tu], tnames[tl]);
|
---|
1478 | p->n_left = makety( p->n_left, tu, 0, 0, MKAP(tu));
|
---|
1479 | }
|
---|
1480 |
|
---|
1481 | if (t != tr || o==CAST || (lu && !ru)) {
|
---|
1482 | if (o != CAST && r->n_op != ICON &&
|
---|
1483 | tsize(tr, 0, MKAP(tr)) > tsize(tu, 0, MKAP(tu)))
|
---|
1484 | warner(Wtruncate, tnames[tu], tnames[tr]);
|
---|
1485 | p->n_right = makety(p->n_right, tu, 0, 0, MKAP(tu));
|
---|
1486 | }
|
---|
1487 |
|
---|
1488 | if( casgop(o) ){
|
---|
1489 | p->n_type = p->n_left->n_type;
|
---|
1490 | p->n_df = p->n_left->n_df;
|
---|
1491 | p->n_ap = p->n_left->n_ap;
|
---|
1492 | }
|
---|
1493 | else if( !clogop(o) ){
|
---|
1494 | p->n_type = tu;
|
---|
1495 | p->n_df = NULL;
|
---|
1496 | p->n_ap = MKAP(t);
|
---|
1497 | }
|
---|
1498 |
|
---|
1499 | #ifdef PCC_DEBUG
|
---|
1500 | if (tdebug) {
|
---|
1501 | printf("tymatch(%p): ", p);
|
---|
1502 | tprint(stdout, tl, 0);
|
---|
1503 | printf(" %s ", copst(o));
|
---|
1504 | tprint(stdout, tr, 0);
|
---|
1505 | printf(" => ");
|
---|
1506 | tprint(stdout, tu, 0);
|
---|
1507 | printf("\n");
|
---|
1508 | fwalk(p, eprint, 0);
|
---|
1509 | }
|
---|
1510 | #endif
|
---|
1511 |
|
---|
1512 | return(p);
|
---|
1513 | }
|
---|
1514 |
|
---|
1515 | /*
|
---|
1516 | * Create a float const node of zero.
|
---|
1517 | */
|
---|
1518 | static NODE *
|
---|
1519 | fzero(TWORD t)
|
---|
1520 | {
|
---|
1521 | NODE *p = block(FCON, NIL, NIL, t, 0, MKAP(t));
|
---|
1522 |
|
---|
1523 | p->n_dcon = FLOAT_CAST(0, INT);
|
---|
1524 | return p;
|
---|
1525 | }
|
---|
1526 |
|
---|
1527 | /*
|
---|
1528 | * make p into type t by inserting a conversion
|
---|
1529 | */
|
---|
1530 | NODE *
|
---|
1531 | makety(NODE *p, TWORD t, TWORD q, union dimfun *d, struct attr *ap)
|
---|
1532 | {
|
---|
1533 |
|
---|
1534 | if (t == p->n_type) {
|
---|
1535 | p->n_df = d;
|
---|
1536 | p->n_ap = ap;
|
---|
1537 | p->n_qual = q;
|
---|
1538 | return(p);
|
---|
1539 | }
|
---|
1540 |
|
---|
1541 | if (p->n_op == FCON && (t >= FLOAT && t <= LDOUBLE)) {
|
---|
1542 | if (t == FLOAT)
|
---|
1543 | p->n_dcon = (float)p->n_dcon;
|
---|
1544 | else if (t == DOUBLE)
|
---|
1545 | p->n_dcon = (double)p->n_dcon;
|
---|
1546 | else
|
---|
1547 | p->n_dcon = (long double)p->n_dcon;
|
---|
1548 | p->n_type = t;
|
---|
1549 | return p;
|
---|
1550 | }
|
---|
1551 |
|
---|
1552 | if (p->n_op == FCON) {
|
---|
1553 | int isf = ISFTY(t);
|
---|
1554 | NODE *r;
|
---|
1555 |
|
---|
1556 | if (isf||ISITY(t)) {
|
---|
1557 | if (isf == ISFTY(p->n_type)) {
|
---|
1558 | p->n_type = t;
|
---|
1559 | p->n_qual = q;
|
---|
1560 | p->n_df = d;
|
---|
1561 | p->n_ap = ap;
|
---|
1562 | return(p);
|
---|
1563 | } else if (isf == ISITY(p->n_type)) {
|
---|
1564 | /* will be zero */
|
---|
1565 | nfree(p);
|
---|
1566 | return fzero(t);
|
---|
1567 | } else if (ISCTY(p->n_type))
|
---|
1568 | cerror("complex constant");
|
---|
1569 | } else if (ISCTY(t)) {
|
---|
1570 | if (ISITY(p->n_type)) {
|
---|
1571 | /* convert to correct subtype */
|
---|
1572 | r = fzero(t - (COMPLEX-DOUBLE));
|
---|
1573 | p->n_type = t + (IMAG-COMPLEX);
|
---|
1574 | p->n_qual = q;
|
---|
1575 | p->n_df = d;
|
---|
1576 | p->n_ap = MKAP(p->n_type);
|
---|
1577 | return block(CM, r, p, t, 0, MKAP(t));
|
---|
1578 | } else if (ISFTY(p->n_type)) {
|
---|
1579 | /* convert to correct subtype */
|
---|
1580 | r = fzero(t + (IMAG-COMPLEX));
|
---|
1581 | p->n_type = t - (COMPLEX-DOUBLE);
|
---|
1582 | p->n_qual = q;
|
---|
1583 | p->n_df = d;
|
---|
1584 | p->n_ap = MKAP(p->n_type);
|
---|
1585 | return block(CM, p, r, t, 0, MKAP(t));
|
---|
1586 | } else if (ISCTY(p->n_type))
|
---|
1587 | cerror("complex constant2");
|
---|
1588 | }
|
---|
1589 | }
|
---|
1590 |
|
---|
1591 | if (t & TMASK) {
|
---|
1592 | /* non-simple type */
|
---|
1593 | p = block(PCONV, p, NIL, t, d, ap);
|
---|
1594 | p->n_qual = q;
|
---|
1595 | return clocal(p);
|
---|
1596 | }
|
---|
1597 |
|
---|
1598 | if (p->n_op == ICON) {
|
---|
1599 | if (ISFTY(t)) {
|
---|
1600 | p->n_op = FCON;
|
---|
1601 | p->n_dcon = FLOAT_CAST(p->n_lval, p->n_type);
|
---|
1602 | p->n_type = t;
|
---|
1603 | p->n_qual = q;
|
---|
1604 | p->n_ap = MKAP(t);
|
---|
1605 | return (clocal(p));
|
---|
1606 | } else if (ISCTY(t) || ISITY(t))
|
---|
1607 | cerror("complex constant3");
|
---|
1608 | }
|
---|
1609 |
|
---|
1610 | p = block(SCONV, p, NIL, t, d, ap);
|
---|
1611 | p->n_qual = q;
|
---|
1612 | return clocal(p);
|
---|
1613 |
|
---|
1614 | }
|
---|
1615 |
|
---|
1616 | NODE *
|
---|
1617 | block(int o, NODE *l, NODE *r, TWORD t, union dimfun *d, struct attr *ap)
|
---|
1618 | {
|
---|
1619 | register NODE *p;
|
---|
1620 |
|
---|
1621 | p = talloc();
|
---|
1622 | p->n_rval = 0;
|
---|
1623 | p->n_op = o;
|
---|
1624 | p->n_lval = 0; /* Protect against large lval */
|
---|
1625 | p->n_left = l;
|
---|
1626 | p->n_right = r;
|
---|
1627 | p->n_type = t;
|
---|
1628 | p->n_qual = 0;
|
---|
1629 | p->n_df = d;
|
---|
1630 | p->n_ap = ap;
|
---|
1631 | #if !defined(MULTIPASS)
|
---|
1632 | /* p->n_reg = */p->n_su = 0;
|
---|
1633 | p->n_regw = 0;
|
---|
1634 | #endif
|
---|
1635 | return(p);
|
---|
1636 | }
|
---|
1637 |
|
---|
1638 | /*
|
---|
1639 | * Return the constant value from an ICON.
|
---|
1640 | */
|
---|
1641 | CONSZ
|
---|
1642 | icons(NODE *p)
|
---|
1643 | {
|
---|
1644 | /* if p is an integer constant, return its value */
|
---|
1645 | CONSZ val;
|
---|
1646 |
|
---|
1647 | if (p->n_op != ICON || p->n_sp != NULL) {
|
---|
1648 | uerror( "constant expected");
|
---|
1649 | val = 1;
|
---|
1650 | } else
|
---|
1651 | val = p->n_lval;
|
---|
1652 | tfree(p);
|
---|
1653 | return(val);
|
---|
1654 | }
|
---|
1655 |
|
---|
1656 | /*
|
---|
1657 | * the intent of this table is to examine the
|
---|
1658 | * operators, and to check them for
|
---|
1659 | * correctness.
|
---|
1660 | *
|
---|
1661 | * The table is searched for the op and the
|
---|
1662 | * modified type (where this is one of the
|
---|
1663 | * types INT (includes char and short), LONG,
|
---|
1664 | * DOUBLE (includes FLOAT), and POINTER
|
---|
1665 | *
|
---|
1666 | * The default action is to make the node type integer
|
---|
1667 | *
|
---|
1668 | * The actions taken include:
|
---|
1669 | * PUN check for puns
|
---|
1670 | * CVTL convert the left operand
|
---|
1671 | * CVTR convert the right operand
|
---|
1672 | * TYPL the type is determined by the left operand
|
---|
1673 | * TYPR the type is determined by the right operand
|
---|
1674 | * TYMATCH force type of left and right to match,by inserting conversions
|
---|
1675 | * PTMATCH like TYMATCH, but for pointers
|
---|
1676 | * LVAL left operand must be lval
|
---|
1677 | * CVTO convert the op
|
---|
1678 | * NCVT do not convert the operands
|
---|
1679 | * OTHER handled by code
|
---|
1680 | * NCVTR convert the left operand, not the right...
|
---|
1681 | *
|
---|
1682 | */
|
---|
1683 |
|
---|
1684 | # define MINT 01 /* integer */
|
---|
1685 | # define MDBI 02 /* integer or double */
|
---|
1686 | # define MSTR 04 /* structure */
|
---|
1687 | # define MPTR 010 /* pointer */
|
---|
1688 | # define MPTI 020 /* pointer or integer */
|
---|
1689 |
|
---|
1690 | int
|
---|
1691 | opact(NODE *p)
|
---|
1692 | {
|
---|
1693 | int mt12, mt1, mt2, o;
|
---|
1694 |
|
---|
1695 | mt1 = mt2 = mt12 = 0;
|
---|
1696 |
|
---|
1697 | switch (coptype(o = p->n_op)) {
|
---|
1698 | case BITYPE:
|
---|
1699 | mt12=mt2 = moditype(p->n_right->n_type);
|
---|
1700 | case UTYPE:
|
---|
1701 | mt12 &= (mt1 = moditype(p->n_left->n_type));
|
---|
1702 | break;
|
---|
1703 | }
|
---|
1704 |
|
---|
1705 | switch( o ){
|
---|
1706 |
|
---|
1707 | case NAME :
|
---|
1708 | case ICON :
|
---|
1709 | case FCON :
|
---|
1710 | case CALL :
|
---|
1711 | case UCALL:
|
---|
1712 | case UMUL:
|
---|
1713 | { return( OTHER ); }
|
---|
1714 | case UMINUS:
|
---|
1715 | if( mt1 & MDBI ) return( TYPL );
|
---|
1716 | break;
|
---|
1717 |
|
---|
1718 | case COMPL:
|
---|
1719 | if( mt1 & MINT ) return( TYPL );
|
---|
1720 | break;
|
---|
1721 |
|
---|
1722 | case ADDROF:
|
---|
1723 | return( NCVT+OTHER );
|
---|
1724 | case NOT:
|
---|
1725 | /* case INIT: */
|
---|
1726 | case CM:
|
---|
1727 | case CBRANCH:
|
---|
1728 | case ANDAND:
|
---|
1729 | case OROR:
|
---|
1730 | return( 0 );
|
---|
1731 |
|
---|
1732 | case MUL:
|
---|
1733 | case DIV:
|
---|
1734 | if( mt12 & MDBI ) return( TYMATCH );
|
---|
1735 | break;
|
---|
1736 |
|
---|
1737 | case MOD:
|
---|
1738 | case AND:
|
---|
1739 | case OR:
|
---|
1740 | case ER:
|
---|
1741 | if( mt12 & MINT ) return( TYMATCH );
|
---|
1742 | break;
|
---|
1743 |
|
---|
1744 | case LS:
|
---|
1745 | case RS:
|
---|
1746 | if( mt12 & MINT ) return( TYPL+OTHER );
|
---|
1747 | break;
|
---|
1748 |
|
---|
1749 | case EQ:
|
---|
1750 | case NE:
|
---|
1751 | case LT:
|
---|
1752 | case LE:
|
---|
1753 | case GT:
|
---|
1754 | case GE:
|
---|
1755 | if( mt12 & MDBI ) return( TYMATCH+CVTO );
|
---|
1756 | else if( mt12 & MPTR ) return( PTMATCH+PUN+CVTO );
|
---|
1757 | else if( mt12 & MPTI ) return( PTMATCH+PUN );
|
---|
1758 | else break;
|
---|
1759 |
|
---|
1760 | case QUEST:
|
---|
1761 | return( TYPR+OTHER );
|
---|
1762 | case COMOP:
|
---|
1763 | return( TYPR );
|
---|
1764 |
|
---|
1765 | case STREF:
|
---|
1766 | return( NCVTR+OTHER );
|
---|
1767 |
|
---|
1768 | case FORCE:
|
---|
1769 | return( TYPL );
|
---|
1770 |
|
---|
1771 | case COLON:
|
---|
1772 | if( mt12 & MDBI ) return( TYMATCH );
|
---|
1773 | else if( mt12 & MPTR ) return( TYPL+PTMATCH+PUN );
|
---|
1774 | else if( (mt1&MINT) && (mt2&MPTR) ) return( TYPR+PUN );
|
---|
1775 | else if( (mt1&MPTR) && (mt2&MINT) ) return( TYPL+PUN );
|
---|
1776 | else if( mt12 & MSTR ) return( NCVT+TYPL+OTHER );
|
---|
1777 | break;
|
---|
1778 |
|
---|
1779 | case ASSIGN:
|
---|
1780 | case RETURN:
|
---|
1781 | if( mt12 & MSTR ) return( LVAL+NCVT+TYPL+OTHER );
|
---|
1782 | case CAST:
|
---|
1783 | if( mt12 & MDBI ) return( TYPL+LVAL+TYMATCH );
|
---|
1784 | else if( mt1 & MPTR) return( LVAL+PTMATCH+PUN );
|
---|
1785 | else if( mt12 & MPTI ) return( TYPL+LVAL+TYMATCH+PUN );
|
---|
1786 | break;
|
---|
1787 |
|
---|
1788 | case LSEQ:
|
---|
1789 | case RSEQ:
|
---|
1790 | if( mt12 & MINT ) return( TYPL+LVAL+OTHER );
|
---|
1791 | break;
|
---|
1792 |
|
---|
1793 | case MULEQ:
|
---|
1794 | case DIVEQ:
|
---|
1795 | if( mt12 & MDBI ) return( LVAL+TYMATCH );
|
---|
1796 | break;
|
---|
1797 |
|
---|
1798 | case MODEQ:
|
---|
1799 | case ANDEQ:
|
---|
1800 | case OREQ:
|
---|
1801 | case EREQ:
|
---|
1802 | if (mt12 & MINT)
|
---|
1803 | return(LVAL+TYMATCH);
|
---|
1804 | break;
|
---|
1805 |
|
---|
1806 | case PLUSEQ:
|
---|
1807 | case MINUSEQ:
|
---|
1808 | case INCR:
|
---|
1809 | case DECR:
|
---|
1810 | if (mt12 & MDBI)
|
---|
1811 | return(TYMATCH+LVAL);
|
---|
1812 | else if ((mt1&MPTR) && (mt2&MINT))
|
---|
1813 | return(TYPL+LVAL+CVTR);
|
---|
1814 | break;
|
---|
1815 |
|
---|
1816 | case MINUS:
|
---|
1817 | if (mt12 & MPTR)
|
---|
1818 | return(CVTO+PTMATCH+PUN);
|
---|
1819 | if (mt2 & MPTR)
|
---|
1820 | break;
|
---|
1821 | /* FALLTHROUGH */
|
---|
1822 | case PLUS:
|
---|
1823 | if (mt12 & MDBI)
|
---|
1824 | return(TYMATCH);
|
---|
1825 | else if ((mt1&MPTR) && (mt2&MINT))
|
---|
1826 | return(TYPL+CVTR);
|
---|
1827 | else if ((mt1&MINT) && (mt2&MPTR))
|
---|
1828 | return(TYPR+CVTL);
|
---|
1829 |
|
---|
1830 | }
|
---|
1831 | uerror("operands of %s have incompatible types", copst(o));
|
---|
1832 | return(NCVT);
|
---|
1833 | }
|
---|
1834 |
|
---|
1835 | int
|
---|
1836 | moditype(TWORD ty)
|
---|
1837 | {
|
---|
1838 | switch (ty) {
|
---|
1839 |
|
---|
1840 | case STRTY:
|
---|
1841 | case UNIONTY:
|
---|
1842 | return( MSTR );
|
---|
1843 |
|
---|
1844 | case BOOL:
|
---|
1845 | case CHAR:
|
---|
1846 | case SHORT:
|
---|
1847 | case UCHAR:
|
---|
1848 | case USHORT:
|
---|
1849 | case UNSIGNED:
|
---|
1850 | case ULONG:
|
---|
1851 | case ULONGLONG:
|
---|
1852 | case INT:
|
---|
1853 | case LONG:
|
---|
1854 | case LONGLONG:
|
---|
1855 | return( MINT|MDBI|MPTI );
|
---|
1856 | case FLOAT:
|
---|
1857 | case DOUBLE:
|
---|
1858 | case LDOUBLE:
|
---|
1859 | #ifndef NO_COMPLEX
|
---|
1860 | case FCOMPLEX:
|
---|
1861 | case COMPLEX:
|
---|
1862 | case LCOMPLEX:
|
---|
1863 | case FIMAG:
|
---|
1864 | case IMAG:
|
---|
1865 | case LIMAG:
|
---|
1866 | #endif
|
---|
1867 | return( MDBI );
|
---|
1868 | default:
|
---|
1869 | return( MPTR|MPTI );
|
---|
1870 |
|
---|
1871 | }
|
---|
1872 | }
|
---|
1873 |
|
---|
1874 | int tvaloff = MAXREGS+NPERMREG > 100 ? MAXREGS+NPERMREG + 100 : 100;
|
---|
1875 |
|
---|
1876 | /*
|
---|
1877 | * Returns a TEMP node with temp number nr.
|
---|
1878 | * If nr == 0, return a node with a new number.
|
---|
1879 | */
|
---|
1880 | NODE *
|
---|
1881 | tempnode(int nr, TWORD type, union dimfun *df, struct attr *ap)
|
---|
1882 | {
|
---|
1883 | NODE *r;
|
---|
1884 |
|
---|
1885 | if (tvaloff == -NOOFFSET)
|
---|
1886 | tvaloff++; /* Skip this for array indexing */
|
---|
1887 | r = block(TEMP, NIL, NIL, type, df, ap);
|
---|
1888 | regno(r) = nr ? nr : tvaloff;
|
---|
1889 | tvaloff += szty(type);
|
---|
1890 | return r;
|
---|
1891 | }
|
---|
1892 |
|
---|
1893 | /*
|
---|
1894 | * Do sizeof on p.
|
---|
1895 | */
|
---|
1896 | NODE *
|
---|
1897 | doszof(NODE *p)
|
---|
1898 | {
|
---|
1899 | extern NODE *arrstk[10];
|
---|
1900 | extern int arrstkp;
|
---|
1901 | union dimfun *df;
|
---|
1902 | TWORD ty;
|
---|
1903 | NODE *rv, *q;
|
---|
1904 | int astkp;
|
---|
1905 |
|
---|
1906 | if (p->n_op == FLD)
|
---|
1907 | uerror("can't apply sizeof to bit-field");
|
---|
1908 |
|
---|
1909 | /*
|
---|
1910 | * Arrays may be dynamic, may need to make computations.
|
---|
1911 | */
|
---|
1912 |
|
---|
1913 | rv = bcon(1);
|
---|
1914 | df = p->n_df;
|
---|
1915 | ty = p->n_type;
|
---|
1916 | astkp = 0;
|
---|
1917 | while (ISARY(ty)) {
|
---|
1918 | if (df->ddim == NOOFFSET)
|
---|
1919 | uerror("sizeof of incomplete type");
|
---|
1920 | if (df->ddim < 0) {
|
---|
1921 | if (arrstkp)
|
---|
1922 | q = arrstk[astkp++];
|
---|
1923 | else
|
---|
1924 | q = tempnode(-df->ddim, INT, 0, MKAP(INT));
|
---|
1925 | } else
|
---|
1926 | q = bcon(df->ddim);
|
---|
1927 | rv = buildtree(MUL, rv, q);
|
---|
1928 | df++;
|
---|
1929 | ty = DECREF(ty);
|
---|
1930 | }
|
---|
1931 | rv = buildtree(MUL, rv, bcon(tsize(ty, p->n_df, p->n_ap)/SZCHAR));
|
---|
1932 | tfree(p);
|
---|
1933 | arrstkp = 0; /* XXX - may this fail? */
|
---|
1934 | return rv;
|
---|
1935 | }
|
---|
1936 |
|
---|
1937 | #ifdef PCC_DEBUG
|
---|
1938 | void
|
---|
1939 | eprint(NODE *p, int down, int *a, int *b)
|
---|
1940 | {
|
---|
1941 | int ty;
|
---|
1942 |
|
---|
1943 | *a = *b = down+1;
|
---|
1944 | while( down > 1 ){
|
---|
1945 | printf( "\t" );
|
---|
1946 | down -= 2;
|
---|
1947 | }
|
---|
1948 | if( down ) printf( " " );
|
---|
1949 |
|
---|
1950 | ty = coptype( p->n_op );
|
---|
1951 |
|
---|
1952 | printf("%p) %s, ", p, copst(p->n_op));
|
---|
1953 | if (p->n_op == XARG || p->n_op == XASM)
|
---|
1954 | printf("id '%s', ", p->n_name);
|
---|
1955 | if (ty == LTYPE) {
|
---|
1956 | printf(CONFMT, p->n_lval);
|
---|
1957 | if (p->n_op == NAME || p->n_op == ICON)
|
---|
1958 | printf(", %p, ", p->n_sp);
|
---|
1959 | else
|
---|
1960 | printf(", %d, ", p->n_rval);
|
---|
1961 | }
|
---|
1962 | tprint(stdout, p->n_type, p->n_qual);
|
---|
1963 | printf( ", %p, ", p->n_df);
|
---|
1964 | dump_attr(p->n_ap);
|
---|
1965 | }
|
---|
1966 | # endif
|
---|
1967 |
|
---|
1968 | /*
|
---|
1969 | * Emit everything that should be emitted on the left side
|
---|
1970 | * of a comma operator, and remove the operator.
|
---|
1971 | * Do not traverse through QUEST, ANDAND and OROR.
|
---|
1972 | * Enable this for all targets when stable enough.
|
---|
1973 | */
|
---|
1974 | static void
|
---|
1975 | comops(NODE *p)
|
---|
1976 | {
|
---|
1977 | int o;
|
---|
1978 | NODE *q;
|
---|
1979 |
|
---|
1980 | while (p->n_op == COMOP) {
|
---|
1981 | /* XXX hack for GCC ({ }) ops */
|
---|
1982 | if (p->n_left->n_op == GOTO) {
|
---|
1983 | int v = (int)p->n_left->n_left->n_lval;
|
---|
1984 | ecomp(p->n_left);
|
---|
1985 | plabel(v+1);
|
---|
1986 | } else
|
---|
1987 | ecomp(p->n_left); /* will recurse if more COMOPs */
|
---|
1988 | q = p->n_right;
|
---|
1989 | *p = *q;
|
---|
1990 | nfree(q);
|
---|
1991 | }
|
---|
1992 | o = coptype(p->n_op);
|
---|
1993 | if (p->n_op == QUEST || p->n_op == ANDAND || p->n_op == OROR)
|
---|
1994 | o = UTYPE;
|
---|
1995 | if (o != LTYPE)
|
---|
1996 | comops(p->n_left);
|
---|
1997 | if (o == BITYPE)
|
---|
1998 | comops(p->n_right);
|
---|
1999 | }
|
---|
2000 |
|
---|
2001 | /*
|
---|
2002 | * Walk up through the tree from the leaves,
|
---|
2003 | * removing constant operators.
|
---|
2004 | */
|
---|
2005 | static void
|
---|
2006 | logwalk(NODE *p)
|
---|
2007 | {
|
---|
2008 | int o = coptype(p->n_op);
|
---|
2009 | NODE *l, *r;
|
---|
2010 |
|
---|
2011 | l = p->n_left;
|
---|
2012 | r = p->n_right;
|
---|
2013 | switch (o) {
|
---|
2014 | case LTYPE:
|
---|
2015 | return;
|
---|
2016 | case BITYPE:
|
---|
2017 | logwalk(r);
|
---|
2018 | case UTYPE:
|
---|
2019 | logwalk(l);
|
---|
2020 | }
|
---|
2021 | if (!clogop(p->n_op))
|
---|
2022 | return;
|
---|
2023 | if (p->n_op == NOT && l->n_op == ICON) {
|
---|
2024 | p->n_lval = l->n_lval == 0;
|
---|
2025 | nfree(l);
|
---|
2026 | p->n_op = ICON;
|
---|
2027 | }
|
---|
2028 | if (l->n_op == ICON && r->n_op == ICON) {
|
---|
2029 | if (conval(l, p->n_op, r) == 0) {
|
---|
2030 | /*
|
---|
2031 | * people sometimes tend to do really odd compares,
|
---|
2032 | * like "if ("abc" == "def")" etc.
|
---|
2033 | * do it runtime instead.
|
---|
2034 | */
|
---|
2035 | } else {
|
---|
2036 | p->n_lval = l->n_lval;
|
---|
2037 | p->n_op = ICON;
|
---|
2038 | nfree(l);
|
---|
2039 | nfree(r);
|
---|
2040 | }
|
---|
2041 | }
|
---|
2042 | }
|
---|
2043 |
|
---|
2044 | /*
|
---|
2045 | * Removes redundant logical operators for branch conditions.
|
---|
2046 | */
|
---|
2047 | static void
|
---|
2048 | fixbranch(NODE *p, int label)
|
---|
2049 | {
|
---|
2050 |
|
---|
2051 | logwalk(p);
|
---|
2052 |
|
---|
2053 | if (p->n_op == ICON) {
|
---|
2054 | if (p->n_lval != 0)
|
---|
2055 | branch(label);
|
---|
2056 | nfree(p);
|
---|
2057 | } else {
|
---|
2058 | if (!clogop(p->n_op)) /* Always conditional */
|
---|
2059 | p = buildtree(NE, p, bcon(0));
|
---|
2060 | ecode(buildtree(CBRANCH, p, bcon(label)));
|
---|
2061 | }
|
---|
2062 | }
|
---|
2063 |
|
---|
2064 | /*
|
---|
2065 | * Write out logical expressions as branches.
|
---|
2066 | */
|
---|
2067 | static void
|
---|
2068 | andorbr(NODE *p, int true, int false)
|
---|
2069 | {
|
---|
2070 | NODE *q;
|
---|
2071 | int o, lab;
|
---|
2072 |
|
---|
2073 | lab = -1;
|
---|
2074 | switch (o = p->n_op) {
|
---|
2075 | case EQ:
|
---|
2076 | case NE:
|
---|
2077 | /*
|
---|
2078 | * Remove redundant EQ/NE nodes.
|
---|
2079 | */
|
---|
2080 | while (((o = p->n_left->n_op) == EQ || o == NE) &&
|
---|
2081 | p->n_right->n_op == ICON) {
|
---|
2082 | o = p->n_op;
|
---|
2083 | q = p->n_left;
|
---|
2084 | if (p->n_right->n_lval == 0) {
|
---|
2085 | nfree(p->n_right);
|
---|
2086 | *p = *q;
|
---|
2087 | nfree(q);
|
---|
2088 | if (o == EQ)
|
---|
2089 | p->n_op = negrel[p->n_op - EQ];
|
---|
2090 | #if 0
|
---|
2091 | p->n_op = NE; /* toggla */
|
---|
2092 | #endif
|
---|
2093 | } else if (p->n_right->n_lval == 1) {
|
---|
2094 | nfree(p->n_right);
|
---|
2095 | *p = *q;
|
---|
2096 | nfree(q);
|
---|
2097 | if (o == NE)
|
---|
2098 | p->n_op = negrel[p->n_op - EQ];
|
---|
2099 | #if 0
|
---|
2100 | p->n_op = EQ; /* toggla */
|
---|
2101 | #endif
|
---|
2102 | } else
|
---|
2103 | break; /* XXX - should always be false */
|
---|
2104 |
|
---|
2105 | }
|
---|
2106 | /* FALLTHROUGH */
|
---|
2107 | case LE:
|
---|
2108 | case LT:
|
---|
2109 | case GE:
|
---|
2110 | case GT:
|
---|
2111 | calc: if (true < 0) {
|
---|
2112 | p->n_op = negrel[p->n_op - EQ];
|
---|
2113 | true = false;
|
---|
2114 | false = -1;
|
---|
2115 | }
|
---|
2116 |
|
---|
2117 | rmcops(p->n_left);
|
---|
2118 | rmcops(p->n_right);
|
---|
2119 | fixbranch(p, true);
|
---|
2120 | if (false >= 0)
|
---|
2121 | branch(false);
|
---|
2122 | break;
|
---|
2123 |
|
---|
2124 | case ULE:
|
---|
2125 | case UGT:
|
---|
2126 | /* Convert to friendlier ops */
|
---|
2127 | if (p->n_right->n_op == ICON && p->n_right->n_lval == 0)
|
---|
2128 | p->n_op = o == ULE ? EQ : NE;
|
---|
2129 | goto calc;
|
---|
2130 |
|
---|
2131 | case UGE:
|
---|
2132 | case ULT:
|
---|
2133 | /* Already true/false by definition */
|
---|
2134 | if (p->n_right->n_op == ICON && p->n_right->n_lval == 0) {
|
---|
2135 | if (true < 0) {
|
---|
2136 | o = o == ULT ? UGE : ULT;
|
---|
2137 | true = false;
|
---|
2138 | }
|
---|
2139 | rmcops(p->n_left);
|
---|
2140 | ecode(p->n_left);
|
---|
2141 | rmcops(p->n_right);
|
---|
2142 | ecode(p->n_right);
|
---|
2143 | nfree(p);
|
---|
2144 | if (o == UGE) /* true */
|
---|
2145 | branch(true);
|
---|
2146 | break;
|
---|
2147 | }
|
---|
2148 | goto calc;
|
---|
2149 |
|
---|
2150 | case ANDAND:
|
---|
2151 | lab = false<0 ? getlab() : false ;
|
---|
2152 | andorbr(p->n_left, -1, lab);
|
---|
2153 | comops(p->n_right);
|
---|
2154 | andorbr(p->n_right, true, false);
|
---|
2155 | if (false < 0)
|
---|
2156 | plabel( lab);
|
---|
2157 | nfree(p);
|
---|
2158 | break;
|
---|
2159 |
|
---|
2160 | case OROR:
|
---|
2161 | lab = true<0 ? getlab() : true;
|
---|
2162 | andorbr(p->n_left, lab, -1);
|
---|
2163 | comops(p->n_right);
|
---|
2164 | andorbr(p->n_right, true, false);
|
---|
2165 | if (true < 0)
|
---|
2166 | plabel( lab);
|
---|
2167 | nfree(p);
|
---|
2168 | break;
|
---|
2169 |
|
---|
2170 | case NOT:
|
---|
2171 | andorbr(p->n_left, false, true);
|
---|
2172 | nfree(p);
|
---|
2173 | break;
|
---|
2174 |
|
---|
2175 | default:
|
---|
2176 | rmcops(p);
|
---|
2177 | if (true >= 0)
|
---|
2178 | fixbranch(p, true);
|
---|
2179 | if (false >= 0) {
|
---|
2180 | if (true >= 0)
|
---|
2181 | branch(false);
|
---|
2182 | else
|
---|
2183 | fixbranch(buildtree(EQ, p, bcon(0)), false);
|
---|
2184 | }
|
---|
2185 | }
|
---|
2186 | }
|
---|
2187 |
|
---|
2188 | /*
|
---|
2189 | * Create a node for either TEMP or on-stack storage.
|
---|
2190 | */
|
---|
2191 | static NODE *
|
---|
2192 | cstknode(TWORD t, union dimfun *df, struct attr *ap)
|
---|
2193 | {
|
---|
2194 | struct symtab *sp;
|
---|
2195 |
|
---|
2196 | /* create a symtab entry suitable for this type */
|
---|
2197 | sp = getsymtab("0hej", STEMP);
|
---|
2198 | sp->stype = t;
|
---|
2199 | sp->sdf = df;
|
---|
2200 | sp->sap = ap;
|
---|
2201 | sp->sclass = AUTO;
|
---|
2202 | sp->soffset = NOOFFSET;
|
---|
2203 | oalloc(sp, &autooff);
|
---|
2204 | return nametree(sp);
|
---|
2205 |
|
---|
2206 | }
|
---|
2207 |
|
---|
2208 | /*
|
---|
2209 | * Massage the output trees to remove C-specific nodes:
|
---|
2210 | * COMOPs are split into separate statements.
|
---|
2211 | * QUEST/COLON are rewritten to branches.
|
---|
2212 | * ANDAND/OROR/NOT are rewritten to branches for lazy-evaluation.
|
---|
2213 | * CBRANCH conditions are rewritten for lazy-evaluation.
|
---|
2214 | */
|
---|
2215 | static void
|
---|
2216 | rmcops(NODE *p)
|
---|
2217 | {
|
---|
2218 | TWORD type;
|
---|
2219 | NODE *q, *r, *tval;
|
---|
2220 | int o, ty, lbl, lbl2;
|
---|
2221 |
|
---|
2222 | tval = NIL;
|
---|
2223 | o = p->n_op;
|
---|
2224 | ty = coptype(o);
|
---|
2225 | if (BTYPE(p->n_type) == ENUMTY) { /* fixup enum */
|
---|
2226 | struct symtab *sp = strmemb(p->n_ap);
|
---|
2227 | MODTYPE(p->n_type, sp->stype);
|
---|
2228 | /*
|
---|
2229 | * XXX may fail if these are true:
|
---|
2230 | * - variable-sized enums
|
---|
2231 | * - non-byte-addressed targets.
|
---|
2232 | */
|
---|
2233 | if (BTYPE(p->n_type) == ENUMTY && ISPTR(p->n_type))
|
---|
2234 | MODTYPE(p->n_type, INT); /* INT ok? */
|
---|
2235 | }
|
---|
2236 | switch (o) {
|
---|
2237 | case QUEST:
|
---|
2238 |
|
---|
2239 | /*
|
---|
2240 | * Create a branch node from ?:
|
---|
2241 | * || and && must be taken special care of.
|
---|
2242 | */
|
---|
2243 | type = p->n_type;
|
---|
2244 | andorbr(p->n_left, -1, lbl = getlab());
|
---|
2245 |
|
---|
2246 | /* Make ASSIGN node */
|
---|
2247 | /* Only if type is not void */
|
---|
2248 | q = p->n_right->n_left;
|
---|
2249 | comops(q);
|
---|
2250 | if (type != VOID) {
|
---|
2251 | tval = cstknode(q->n_type, q->n_df, q->n_ap);
|
---|
2252 | q = buildtree(ASSIGN, ccopy(tval), q);
|
---|
2253 | }
|
---|
2254 | rmcops(q);
|
---|
2255 | ecode(q); /* Done with assign */
|
---|
2256 | branch(lbl2 = getlab());
|
---|
2257 | plabel( lbl);
|
---|
2258 |
|
---|
2259 | q = p->n_right->n_right;
|
---|
2260 | comops(q);
|
---|
2261 | if (type != VOID) {
|
---|
2262 | q = buildtree(ASSIGN, ccopy(tval), q);
|
---|
2263 | }
|
---|
2264 | rmcops(q);
|
---|
2265 | ecode(q); /* Done with assign */
|
---|
2266 |
|
---|
2267 | plabel( lbl2);
|
---|
2268 |
|
---|
2269 | nfree(p->n_right);
|
---|
2270 | if (p->n_type != VOID) {
|
---|
2271 | *p = *tval;
|
---|
2272 | nfree(tval);
|
---|
2273 | } else {
|
---|
2274 | p->n_op = ICON;
|
---|
2275 | p->n_lval = 0;
|
---|
2276 | p->n_sp = NULL;
|
---|
2277 | }
|
---|
2278 | break;
|
---|
2279 |
|
---|
2280 | case ULE:
|
---|
2281 | case ULT:
|
---|
2282 | case UGE:
|
---|
2283 | case UGT:
|
---|
2284 | case EQ:
|
---|
2285 | case NE:
|
---|
2286 | case LE:
|
---|
2287 | case LT:
|
---|
2288 | case GE:
|
---|
2289 | case GT:
|
---|
2290 | case ANDAND:
|
---|
2291 | case OROR:
|
---|
2292 | case NOT:
|
---|
2293 | #ifdef SPECIAL_CCODES
|
---|
2294 | #error fix for private CCODES handling
|
---|
2295 | #else
|
---|
2296 | r = talloc();
|
---|
2297 | *r = *p;
|
---|
2298 | andorbr(r, -1, lbl = getlab());
|
---|
2299 |
|
---|
2300 | tval = cstknode(p->n_type, p->n_df, p->n_ap);
|
---|
2301 |
|
---|
2302 | ecode(buildtree(ASSIGN, ccopy(tval), bcon(1)));
|
---|
2303 | branch(lbl2 = getlab());
|
---|
2304 | plabel( lbl);
|
---|
2305 | ecode(buildtree(ASSIGN, ccopy(tval), bcon(0)));
|
---|
2306 | plabel( lbl2);
|
---|
2307 |
|
---|
2308 | *p = *tval;
|
---|
2309 | nfree(tval);
|
---|
2310 |
|
---|
2311 | #endif
|
---|
2312 | break;
|
---|
2313 | case CBRANCH:
|
---|
2314 | andorbr(p->n_left, p->n_right->n_lval, -1);
|
---|
2315 | nfree(p->n_right);
|
---|
2316 | p->n_op = ICON; p->n_type = VOID;
|
---|
2317 | break;
|
---|
2318 | case COMOP:
|
---|
2319 | cerror("COMOP error");
|
---|
2320 |
|
---|
2321 | default:
|
---|
2322 | if (ty == LTYPE)
|
---|
2323 | return;
|
---|
2324 | rmcops(p->n_left);
|
---|
2325 | if (ty == BITYPE)
|
---|
2326 | rmcops(p->n_right);
|
---|
2327 | }
|
---|
2328 | }
|
---|
2329 |
|
---|
2330 | /*
|
---|
2331 | * Return 1 if an assignment is found.
|
---|
2332 | */
|
---|
2333 | static int
|
---|
2334 | has_se(NODE *p)
|
---|
2335 | {
|
---|
2336 | if (cdope(p->n_op) & ASGFLG)
|
---|
2337 | return 1;
|
---|
2338 | if (coptype(p->n_op) == LTYPE)
|
---|
2339 | return 0;
|
---|
2340 | if (has_se(p->n_left))
|
---|
2341 | return 1;
|
---|
2342 | if (coptype(p->n_op) == BITYPE)
|
---|
2343 | return has_se(p->n_right);
|
---|
2344 | return 0;
|
---|
2345 | }
|
---|
2346 |
|
---|
2347 | /*
|
---|
2348 | * Find and convert asgop's to separate statements.
|
---|
2349 | * Be careful about side effects.
|
---|
2350 | * assign tells whether ASSIGN should be considered giving
|
---|
2351 | * side effects or not.
|
---|
2352 | */
|
---|
2353 | static NODE *
|
---|
2354 | delasgop(NODE *p)
|
---|
2355 | {
|
---|
2356 | NODE *q, *r;
|
---|
2357 | int tval;
|
---|
2358 |
|
---|
2359 | if (p->n_op == INCR || p->n_op == DECR) {
|
---|
2360 | /*
|
---|
2361 | * Rewrite x++ to (x += 1) -1; and deal with it further down.
|
---|
2362 | * Pass2 will remove -1 if unnecessary.
|
---|
2363 | */
|
---|
2364 | q = ccopy(p);
|
---|
2365 | tfree(p->n_left);
|
---|
2366 | q->n_op = (p->n_op==INCR)?PLUSEQ:MINUSEQ;
|
---|
2367 | p->n_op = (p->n_op==INCR)?MINUS:PLUS;
|
---|
2368 | p->n_left = delasgop(q);
|
---|
2369 |
|
---|
2370 | } else if ((cdope(p->n_op)&ASGOPFLG) &&
|
---|
2371 | p->n_op != RETURN && p->n_op != CAST) {
|
---|
2372 | NODE *l = p->n_left;
|
---|
2373 | NODE *ll = l->n_left;
|
---|
2374 |
|
---|
2375 | if (has_se(l)) {
|
---|
2376 | q = tempnode(0, ll->n_type, ll->n_df, ll->n_ap);
|
---|
2377 | tval = regno(q);
|
---|
2378 | r = tempnode(tval, ll->n_type, ll->n_df,ll->n_ap);
|
---|
2379 | l->n_left = q;
|
---|
2380 | /* Now the left side of node p has no side effects. */
|
---|
2381 | /* side effects on the right side must be obeyed */
|
---|
2382 | p = delasgop(p);
|
---|
2383 |
|
---|
2384 | r = buildtree(ASSIGN, r, ll);
|
---|
2385 | r = delasgop(r);
|
---|
2386 | ecode(r);
|
---|
2387 | } else {
|
---|
2388 | #if 0 /* Cannot call buildtree() here, it would invoke double add shifts */
|
---|
2389 | p->n_right = buildtree(UNASG p->n_op, ccopy(l),
|
---|
2390 | p->n_right);
|
---|
2391 | #else
|
---|
2392 | p->n_right = block(UNASG p->n_op, ccopy(l),
|
---|
2393 | p->n_right, p->n_type, p->n_df, p->n_ap);
|
---|
2394 | #endif
|
---|
2395 | p->n_op = ASSIGN;
|
---|
2396 | p->n_right = delasgop(p->n_right);
|
---|
2397 | p->n_right = clocal(p->n_right);
|
---|
2398 | }
|
---|
2399 |
|
---|
2400 | } else {
|
---|
2401 | if (coptype(p->n_op) == LTYPE)
|
---|
2402 | return p;
|
---|
2403 | p->n_left = delasgop(p->n_left);
|
---|
2404 | if (coptype(p->n_op) == BITYPE)
|
---|
2405 | p->n_right = delasgop(p->n_right);
|
---|
2406 | }
|
---|
2407 | return p;
|
---|
2408 | }
|
---|
2409 |
|
---|
2410 | int edebug = 0;
|
---|
2411 | void
|
---|
2412 | ecomp(NODE *p)
|
---|
2413 | {
|
---|
2414 |
|
---|
2415 | #ifdef PCC_DEBUG
|
---|
2416 | if (edebug)
|
---|
2417 | fwalk(p, eprint, 0);
|
---|
2418 | #endif
|
---|
2419 | if (!reached) {
|
---|
2420 | warner(Wunreachable_code, NULL);
|
---|
2421 | reached = 1;
|
---|
2422 | }
|
---|
2423 | p = optim(p);
|
---|
2424 | comops(p);
|
---|
2425 | rmcops(p);
|
---|
2426 | p = delasgop(p);
|
---|
2427 | if (p->n_op == ICON && p->n_type == VOID)
|
---|
2428 | tfree(p);
|
---|
2429 | else
|
---|
2430 | ecode(p);
|
---|
2431 | }
|
---|
2432 |
|
---|
2433 |
|
---|
2434 | #if defined(MULTIPASS)
|
---|
2435 | void
|
---|
2436 | p2tree(NODE *p)
|
---|
2437 | {
|
---|
2438 | struct symtab *q;
|
---|
2439 | int ty;
|
---|
2440 |
|
---|
2441 | myp2tree(p); /* local action can be taken here */
|
---|
2442 |
|
---|
2443 | ty = coptype(p->n_op);
|
---|
2444 |
|
---|
2445 | printf("%d\t", p->n_op);
|
---|
2446 |
|
---|
2447 | if (ty == LTYPE) {
|
---|
2448 | printf(CONFMT, p->n_lval);
|
---|
2449 | printf("\t");
|
---|
2450 | }
|
---|
2451 | if (ty != BITYPE) {
|
---|
2452 | if (p->n_op == NAME || p->n_op == ICON)
|
---|
2453 | printf("0\t");
|
---|
2454 | else
|
---|
2455 | printf("%d\t", p->n_rval);
|
---|
2456 | }
|
---|
2457 |
|
---|
2458 | printf("%o\t", p->n_type);
|
---|
2459 |
|
---|
2460 | /* handle special cases */
|
---|
2461 |
|
---|
2462 | switch (p->n_op) {
|
---|
2463 |
|
---|
2464 | case NAME:
|
---|
2465 | case ICON:
|
---|
2466 | /* print external name */
|
---|
2467 | if ((q = p->n_sp) != NULL) {
|
---|
2468 | if ((q->sclass == STATIC && q->slevel > 0)) {
|
---|
2469 | printf(LABFMT, q->soffset);
|
---|
2470 | } else
|
---|
2471 | printf("%s\n",
|
---|
2472 | q->soname ? q->soname : exname(q->sname));
|
---|
2473 | } else
|
---|
2474 | printf("\n");
|
---|
2475 | break;
|
---|
2476 |
|
---|
2477 | case STARG:
|
---|
2478 | case STASG:
|
---|
2479 | case STCALL:
|
---|
2480 | case USTCALL:
|
---|
2481 | /* print out size */
|
---|
2482 | /* use lhs size, in order to avoid hassles
|
---|
2483 | * with the structure `.' operator
|
---|
2484 | */
|
---|
2485 |
|
---|
2486 | /* note: p->left not a field... */
|
---|
2487 | printf(CONFMT, (CONSZ)tsize(STRTY, p->n_left->n_df,
|
---|
2488 | p->n_left->n_ap));
|
---|
2489 | printf("\t%d\t\n", talign(STRTY, p->n_left->n_ap));
|
---|
2490 | break;
|
---|
2491 |
|
---|
2492 | case XARG:
|
---|
2493 | case XASM:
|
---|
2494 | break;
|
---|
2495 |
|
---|
2496 | default:
|
---|
2497 | printf( "\n" );
|
---|
2498 | }
|
---|
2499 |
|
---|
2500 | if (ty != LTYPE)
|
---|
2501 | p2tree(p->n_left);
|
---|
2502 | if (ty == BITYPE)
|
---|
2503 | p2tree(p->n_right);
|
---|
2504 | }
|
---|
2505 | #else
|
---|
2506 | static char *
|
---|
2507 | sptostr(struct symtab *sp)
|
---|
2508 | {
|
---|
2509 | char *cp = inlalloc(32);
|
---|
2510 | int n = sp->soffset;
|
---|
2511 | if (n < 0)
|
---|
2512 | n = -n;
|
---|
2513 | snprintf(cp, 32, LABFMT, n);
|
---|
2514 | return cp;
|
---|
2515 | }
|
---|
2516 |
|
---|
2517 | void
|
---|
2518 | p2tree(NODE *p)
|
---|
2519 | {
|
---|
2520 | struct symtab *q;
|
---|
2521 | int ty;
|
---|
2522 |
|
---|
2523 | myp2tree(p); /* local action can be taken here */
|
---|
2524 |
|
---|
2525 | /* Fix left imaginary types */
|
---|
2526 | if (ISITY(BTYPE(p->n_type)))
|
---|
2527 | MODTYPE(p->n_type, p->n_type - (FIMAG-FLOAT));
|
---|
2528 |
|
---|
2529 | ty = coptype(p->n_op);
|
---|
2530 |
|
---|
2531 | switch( p->n_op ){
|
---|
2532 |
|
---|
2533 | case NAME:
|
---|
2534 | case ICON:
|
---|
2535 | if ((q = p->n_sp) != NULL) {
|
---|
2536 | if ((q->sclass == STATIC && q->slevel > 0)
|
---|
2537 | #ifdef GCC_COMPAT
|
---|
2538 | || q->sflags == SLBLNAME
|
---|
2539 | #endif
|
---|
2540 | ) {
|
---|
2541 | p->n_name = sptostr(q);
|
---|
2542 | } else {
|
---|
2543 | if ((p->n_name = q->soname) == NULL)
|
---|
2544 | p->n_name = addname(exname(q->sname));
|
---|
2545 | }
|
---|
2546 | } else
|
---|
2547 | p->n_name = "";
|
---|
2548 | break;
|
---|
2549 |
|
---|
2550 | case STASG:
|
---|
2551 | /* STASG used for stack array init */
|
---|
2552 | if (ISARY(p->n_type)) {
|
---|
2553 | int size1 = (int)tsize(p->n_type, p->n_left->n_df,
|
---|
2554 | p->n_left->n_ap)/SZCHAR;
|
---|
2555 | p->n_stsize = (int)tsize(p->n_type, p->n_right->n_df,
|
---|
2556 | p->n_right->n_ap)/SZCHAR;
|
---|
2557 | if (size1 < p->n_stsize)
|
---|
2558 | p->n_stsize = size1;
|
---|
2559 | p->n_stalign = talign(p->n_type,
|
---|
2560 | p->n_left->n_ap)/SZCHAR;
|
---|
2561 | break;
|
---|
2562 | }
|
---|
2563 | /* FALLTHROUGH */
|
---|
2564 | case STARG:
|
---|
2565 | case STCALL:
|
---|
2566 | case USTCALL:
|
---|
2567 | /* set up size parameters */
|
---|
2568 | p->n_stsize = (int)((tsize(STRTY, p->n_left->n_df,
|
---|
2569 | p->n_left->n_ap)+SZCHAR-1)/SZCHAR);
|
---|
2570 | p->n_stalign = talign(STRTY,p->n_left->n_ap)/SZCHAR;
|
---|
2571 | if (p->n_stalign == 0)
|
---|
2572 | p->n_stalign = 1; /* At least char for packed structs */
|
---|
2573 | break;
|
---|
2574 |
|
---|
2575 | case XARG:
|
---|
2576 | case XASM:
|
---|
2577 | break;
|
---|
2578 |
|
---|
2579 | default:
|
---|
2580 | p->n_name = "";
|
---|
2581 | }
|
---|
2582 |
|
---|
2583 | if( ty != LTYPE ) p2tree( p->n_left );
|
---|
2584 | if( ty == BITYPE ) p2tree( p->n_right );
|
---|
2585 | }
|
---|
2586 |
|
---|
2587 | #endif
|
---|
2588 |
|
---|
2589 | /*
|
---|
2590 | * Change void data types into char.
|
---|
2591 | */
|
---|
2592 | static void
|
---|
2593 | delvoid(NODE *p, void *arg)
|
---|
2594 | {
|
---|
2595 | /* Convert "PTR undef" (void *) to "PTR uchar" */
|
---|
2596 | if (BTYPE(p->n_type) == VOID)
|
---|
2597 | p->n_type = (p->n_type & ~BTMASK) | UCHAR;
|
---|
2598 | if (BTYPE(p->n_type) == BOOL) {
|
---|
2599 | if (p->n_op == SCONV && p->n_type == BOOL) {
|
---|
2600 | /* create a jump and a set */
|
---|
2601 | NODE *r;
|
---|
2602 | int l, l2;
|
---|
2603 |
|
---|
2604 | r = tempnode(0, BOOL_TYPE, NULL, MKAP(BOOL_TYPE));
|
---|
2605 | cbranch(buildtree(EQ, p->n_left, bcon(0)),
|
---|
2606 | bcon(l = getlab()));
|
---|
2607 | *p = *r;
|
---|
2608 | ecode(buildtree(ASSIGN, tcopy(r), bcon(1)));
|
---|
2609 | branch(l2 = getlab());
|
---|
2610 | plabel(l);
|
---|
2611 | ecode(buildtree(ASSIGN, r, bcon(0)));
|
---|
2612 | plabel(l2);
|
---|
2613 | } else
|
---|
2614 | p->n_type = (p->n_type & ~BTMASK) | BOOL_TYPE;
|
---|
2615 | }
|
---|
2616 |
|
---|
2617 | }
|
---|
2618 |
|
---|
2619 | void
|
---|
2620 | ecode(NODE *p)
|
---|
2621 | {
|
---|
2622 | /* walk the tree and write out the nodes.. */
|
---|
2623 |
|
---|
2624 | if (nerrors)
|
---|
2625 | return;
|
---|
2626 |
|
---|
2627 | #ifdef GCC_COMPAT
|
---|
2628 | {
|
---|
2629 | NODE *q = p;
|
---|
2630 |
|
---|
2631 | if (q->n_op == UMUL)
|
---|
2632 | q = p->n_left;
|
---|
2633 | if (cdope(q->n_op)&CALLFLG &&
|
---|
2634 | attr_find(q->n_ap, GCC_ATYP_WARN_UNUSED_RESULT))
|
---|
2635 | werror("return value ignored");
|
---|
2636 | }
|
---|
2637 | #endif
|
---|
2638 | p = optim(p);
|
---|
2639 | p = delasgop(p);
|
---|
2640 | walkf(p, delvoid, 0);
|
---|
2641 | #ifdef PCC_DEBUG
|
---|
2642 | if (xdebug) {
|
---|
2643 | printf("Fulltree:\n");
|
---|
2644 | fwalk(p, eprint, 0);
|
---|
2645 | }
|
---|
2646 | #endif
|
---|
2647 | p2tree(p);
|
---|
2648 | #if !defined(MULTIPASS)
|
---|
2649 | send_passt(IP_NODE, p);
|
---|
2650 | #endif
|
---|
2651 | }
|
---|
2652 |
|
---|
2653 | /*
|
---|
2654 | * Send something further on to the next pass.
|
---|
2655 | */
|
---|
2656 | void
|
---|
2657 | send_passt(int type, ...)
|
---|
2658 | {
|
---|
2659 | struct interpass *ip;
|
---|
2660 | struct interpass_prolog *ipp;
|
---|
2661 | extern int crslab;
|
---|
2662 | va_list ap;
|
---|
2663 | int sz;
|
---|
2664 |
|
---|
2665 | va_start(ap, type);
|
---|
2666 | if (cftnsp == NULL && type != IP_ASM) {
|
---|
2667 | #ifdef notyet
|
---|
2668 | cerror("no function");
|
---|
2669 | #endif
|
---|
2670 | if (type == IP_NODE)
|
---|
2671 | tfree(va_arg(ap, NODE *));
|
---|
2672 | return;
|
---|
2673 | }
|
---|
2674 | if (type == IP_PROLOG || type == IP_EPILOG)
|
---|
2675 | sz = sizeof(struct interpass_prolog);
|
---|
2676 | else
|
---|
2677 | sz = sizeof(struct interpass);
|
---|
2678 |
|
---|
2679 | ip = inlalloc(sz);
|
---|
2680 | ip->type = type;
|
---|
2681 | ip->lineno = lineno;
|
---|
2682 | switch (type) {
|
---|
2683 | case IP_NODE:
|
---|
2684 | ip->ip_node = va_arg(ap, NODE *);
|
---|
2685 | break;
|
---|
2686 | case IP_EPILOG:
|
---|
2687 | if (!isinlining)
|
---|
2688 | defloc(cftnsp);
|
---|
2689 | /* FALLTHROUGH */
|
---|
2690 | case IP_PROLOG:
|
---|
2691 | inftn = type == IP_PROLOG ? 1 : 0;
|
---|
2692 | ipp = (struct interpass_prolog *)ip;
|
---|
2693 | memset(ipp->ipp_regs, (type == IP_PROLOG)? -1 : 0,
|
---|
2694 | sizeof(ipp->ipp_regs));
|
---|
2695 | ipp->ipp_autos = va_arg(ap, int);
|
---|
2696 | ipp->ipp_name = va_arg(ap, char *);
|
---|
2697 | ipp->ipp_type = va_arg(ap, TWORD);
|
---|
2698 | ipp->ipp_vis = va_arg(ap, int);
|
---|
2699 | ip->ip_lbl = va_arg(ap, int);
|
---|
2700 | ipp->ip_tmpnum = va_arg(ap, int);
|
---|
2701 | ipp->ip_lblnum = crslab;
|
---|
2702 | if (type == IP_PROLOG)
|
---|
2703 | ipp->ip_lblnum--;
|
---|
2704 | break;
|
---|
2705 | case IP_DEFLAB:
|
---|
2706 | ip->ip_lbl = va_arg(ap, int);
|
---|
2707 | break;
|
---|
2708 | case IP_ASM:
|
---|
2709 | if (blevel == 0) { /* outside function */
|
---|
2710 | printf("\t");
|
---|
2711 | printf("%s", va_arg(ap, char *));
|
---|
2712 | printf("\n");
|
---|
2713 | va_end(ap);
|
---|
2714 | defloc(NULL);
|
---|
2715 | return;
|
---|
2716 | }
|
---|
2717 | ip->ip_asm = va_arg(ap, char *);
|
---|
2718 | break;
|
---|
2719 | default:
|
---|
2720 | cerror("bad send_passt type %d", type);
|
---|
2721 | }
|
---|
2722 | va_end(ap);
|
---|
2723 | pass1_lastchance(ip); /* target-specific info */
|
---|
2724 | if (isinlining)
|
---|
2725 | inline_addarg(ip);
|
---|
2726 | else
|
---|
2727 | pass2_compile(ip);
|
---|
2728 | }
|
---|
2729 |
|
---|
2730 | char *
|
---|
2731 | copst(int op)
|
---|
2732 | {
|
---|
2733 | if (op <= MAXOP)
|
---|
2734 | return opst[op];
|
---|
2735 | #define SNAM(x,y) case x: return #y;
|
---|
2736 | switch (op) {
|
---|
2737 | SNAM(QUALIFIER,QUALIFIER)
|
---|
2738 | SNAM(CLASS,CLASS)
|
---|
2739 | SNAM(RB,])
|
---|
2740 | SNAM(DOT,.)
|
---|
2741 | SNAM(ELLIPSIS,...)
|
---|
2742 | SNAM(LB,[)
|
---|
2743 | SNAM(TYPE,TYPE)
|
---|
2744 | SNAM(COMOP,COMOP)
|
---|
2745 | SNAM(QUEST,?)
|
---|
2746 | SNAM(COLON,:)
|
---|
2747 | SNAM(ANDAND,&&)
|
---|
2748 | SNAM(OROR,||)
|
---|
2749 | SNAM(NOT,!)
|
---|
2750 | SNAM(CAST,CAST)
|
---|
2751 | SNAM(PLUSEQ,+=)
|
---|
2752 | SNAM(MINUSEQ,-=)
|
---|
2753 | SNAM(MULEQ,*=)
|
---|
2754 | SNAM(DIVEQ,/=)
|
---|
2755 | SNAM(MODEQ,%=)
|
---|
2756 | SNAM(ANDEQ,&=)
|
---|
2757 | SNAM(OREQ,|=)
|
---|
2758 | SNAM(EREQ,^=)
|
---|
2759 | SNAM(LSEQ,<<=)
|
---|
2760 | SNAM(RSEQ,>>=)
|
---|
2761 | SNAM(INCR,++)
|
---|
2762 | SNAM(DECR,--)
|
---|
2763 | SNAM(STRING,STRING)
|
---|
2764 | SNAM(SZOF,SIZEOF)
|
---|
2765 | SNAM(ATTRIB,ATTRIBUTE)
|
---|
2766 | SNAM(TYMERGE,TYMERGE)
|
---|
2767 | #ifdef GCC_COMPAT
|
---|
2768 | SNAM(XREAL,__real__)
|
---|
2769 | SNAM(XIMAG,__imag__)
|
---|
2770 | #endif
|
---|
2771 | default:
|
---|
2772 | cerror("bad copst %d", op);
|
---|
2773 | }
|
---|
2774 | return 0; /* XXX gcc */
|
---|
2775 | }
|
---|
2776 |
|
---|
2777 | int
|
---|
2778 | cdope(int op)
|
---|
2779 | {
|
---|
2780 | if (op <= MAXOP)
|
---|
2781 | return dope[op];
|
---|
2782 | switch (op) {
|
---|
2783 | case CLOP:
|
---|
2784 | case STRING:
|
---|
2785 | case QUALIFIER:
|
---|
2786 | case CLASS:
|
---|
2787 | case RB:
|
---|
2788 | case ELLIPSIS:
|
---|
2789 | case TYPE:
|
---|
2790 | return LTYPE;
|
---|
2791 | case DOT:
|
---|
2792 | case SZOF:
|
---|
2793 | case COMOP:
|
---|
2794 | case QUEST:
|
---|
2795 | case COLON:
|
---|
2796 | case LB:
|
---|
2797 | case TYMERGE:
|
---|
2798 | return BITYPE;
|
---|
2799 | case XIMAG:
|
---|
2800 | case XREAL:
|
---|
2801 | case ATTRIB:
|
---|
2802 | return UTYPE;
|
---|
2803 | case ANDAND:
|
---|
2804 | case OROR:
|
---|
2805 | return BITYPE|LOGFLG;
|
---|
2806 | case NOT:
|
---|
2807 | return UTYPE|LOGFLG;
|
---|
2808 | case CAST:
|
---|
2809 | return BITYPE|ASGFLG|ASGOPFLG;
|
---|
2810 | case PLUSEQ:
|
---|
2811 | return BITYPE|ASGFLG|ASGOPFLG|FLOFLG|SIMPFLG|COMMFLG;
|
---|
2812 | case MINUSEQ:
|
---|
2813 | return BITYPE|FLOFLG|SIMPFLG|ASGFLG|ASGOPFLG;
|
---|
2814 | case MULEQ:
|
---|
2815 | return BITYPE|FLOFLG|MULFLG|ASGFLG|ASGOPFLG;
|
---|
2816 | case OREQ:
|
---|
2817 | case EREQ:
|
---|
2818 | case ANDEQ:
|
---|
2819 | return BITYPE|SIMPFLG|COMMFLG|ASGFLG|ASGOPFLG;
|
---|
2820 | case DIVEQ:
|
---|
2821 | return BITYPE|FLOFLG|MULFLG|DIVFLG|ASGFLG|ASGOPFLG;
|
---|
2822 | case MODEQ:
|
---|
2823 | return BITYPE|DIVFLG|ASGFLG|ASGOPFLG;
|
---|
2824 | case LSEQ:
|
---|
2825 | case RSEQ:
|
---|
2826 | return BITYPE|SHFFLG|ASGFLG|ASGOPFLG;
|
---|
2827 | case INCR:
|
---|
2828 | case DECR:
|
---|
2829 | return BITYPE|ASGFLG;
|
---|
2830 | }
|
---|
2831 | cerror("cdope missing op %d", op);
|
---|
2832 | return 0; /* XXX gcc */
|
---|
2833 | }
|
---|
2834 |
|
---|
2835 | /*
|
---|
2836 | * make a fresh copy of p
|
---|
2837 | */
|
---|
2838 | NODE *
|
---|
2839 | ccopy(NODE *p)
|
---|
2840 | {
|
---|
2841 | NODE *q;
|
---|
2842 |
|
---|
2843 | q = talloc();
|
---|
2844 | *q = *p;
|
---|
2845 |
|
---|
2846 | switch (coptype(q->n_op)) {
|
---|
2847 | case BITYPE:
|
---|
2848 | q->n_right = ccopy(p->n_right);
|
---|
2849 | case UTYPE:
|
---|
2850 | q->n_left = ccopy(p->n_left);
|
---|
2851 | }
|
---|
2852 |
|
---|
2853 | return(q);
|
---|
2854 | }
|
---|
2855 |
|
---|
2856 | /*
|
---|
2857 | * set PROG-seg label.
|
---|
2858 | */
|
---|
2859 | void
|
---|
2860 | plabel(int label)
|
---|
2861 | {
|
---|
2862 | reached = 1; /* Will this always be correct? */
|
---|
2863 | send_passt(IP_DEFLAB, label);
|
---|
2864 | }
|
---|
2865 |
|
---|
2866 | /*
|
---|
2867 | * Perform integer promotion on node n.
|
---|
2868 | */
|
---|
2869 | NODE *
|
---|
2870 | intprom(NODE *n)
|
---|
2871 | {
|
---|
2872 | if ((n->n_type >= CHAR && n->n_type < INT) || n->n_type == BOOL) {
|
---|
2873 | if ((n->n_type == UCHAR && MAX_UCHAR > MAX_INT) ||
|
---|
2874 | (n->n_type == USHORT && MAX_USHORT > MAX_INT))
|
---|
2875 | return makety(n, UNSIGNED, 0, 0, MKAP(UNSIGNED));
|
---|
2876 | return makety(n, INT, 0, 0, MKAP(INT));
|
---|
2877 | }
|
---|
2878 | return n;
|
---|
2879 | }
|
---|
2880 |
|
---|
2881 | /*
|
---|
2882 | * Return CON/VOL/0, whichever are active for the current type.
|
---|
2883 | */
|
---|
2884 | int
|
---|
2885 | cqual(TWORD t, TWORD q)
|
---|
2886 | {
|
---|
2887 | while (ISARY(t))
|
---|
2888 | t = DECREF(t), q = DECQAL(q);
|
---|
2889 | if (t <= BTMASK)
|
---|
2890 | q <<= TSHIFT;
|
---|
2891 | return q & (CON|VOL);
|
---|
2892 | }
|
---|
2893 |
|
---|
2894 | int crslab = 10;
|
---|
2895 | /*
|
---|
2896 | * Return a number for internal labels.
|
---|
2897 | */
|
---|
2898 | int
|
---|
2899 | getlab(void)
|
---|
2900 | {
|
---|
2901 | return crslab++;
|
---|
2902 | }
|
---|