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