new date 20231021
[pcc.git] / cc / cxxcom / trees.c
blob8b95aa4d88c690eeb0b162d6472338a3a90ac60b
1 /* $Id: trees.c,v 1.23 2016/09/26 16:45:43 ragge Exp $ */
2 /*
3 * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
4 * All rights reserved.
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
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.
30 * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
32 * Redistribution and use in source and binary forms, with or without
33 * modification, are permitted provided that the following conditions
34 * are met:
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.
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.
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.
69 # include "pass1.h"
70 # include "pass2.h"
72 # include <stdarg.h>
73 # include <string.h>
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 void putjops(NODE *, void *);
82 static void p2tree(NODE *);
83 static struct symtab *findmember(struct symtab *, char *);
84 int inftn; /* currently between epilog/prolog */
86 static char *tnames[] = {
87 "undef",
88 "farg",
89 "char",
90 "unsigned char",
91 "short",
92 "unsigned short",
93 "int",
94 "unsigned int",
95 "long",
96 "unsigned long",
97 "long long",
98 "unsigned long long",
99 "float",
100 "double",
101 "long double",
102 "strty",
103 "unionty",
104 "enumty",
105 "moety",
106 "void",
107 "signed", /* pass1 */
108 "bool", /* pass1 */
109 "fimag", /* pass1 */
110 "dimag", /* pass1 */
111 "limag", /* pass1 */
112 "fcomplex", /* pass1 */
113 "dcomplex", /* pass1 */
114 "lcomplex", /* pass1 */
115 "enumty", /* pass1 */
116 "?", "?"
119 /* some special actions, used in finding the type of nodes */
120 # define NCVT 01
121 # define PUN 02
122 # define TYPL 04
123 # define TYPR 010
124 # define TYMATCH 040
125 # define LVAL 0100
126 # define CVTO 0200
127 # define CVTL 0400
128 # define CVTR 01000
129 # define PTMATCH 02000
130 # define OTHER 04000
131 # define NCVTR 010000
132 # define PROML 020000 /* promote left operand */
134 /* node conventions:
136 NAME: rval>0 is stab index for external
137 rval<0 is -inlabel number
138 lval is offset in bits
139 ICON: lval has the value
140 rval has the STAB index, or - label number,
141 if a name whose address is in the constant
142 rval = NONAME means no name
143 REG: rval is reg. identification cookie
147 extern int negrel[];
149 /* Have some defaults for most common targets */
150 #ifndef WORD_ADDRESSED
151 #define offcon(o,t,d,ap) xbcon((o/SZCHAR), NULL, INTPTR)
152 #define VBLOCK(p,b,t,d,a) buildtree(DIV, p, b)
153 #define MBLOCK(p,b,t,d,a) buildtree(MUL, p, b)
154 #else
155 #define VBLOCK(p,b,t,d,a) block(PVCONV, p, b, t, d, a)
156 #define MBLOCK(p,b,t,d,a) block(PMCONV, p, b, t, d, a)
157 #endif
159 NODE *
160 buildtree(int o, NODE *l, NODE *r)
162 NODE *p, *q;
163 int actions;
164 int opty, n;
165 struct symtab *sp = NULL; /* XXX gcc */
166 NODE *lr, *ll;
168 #ifdef PCC_DEBUG
169 if (bdebug) {
170 printf("buildtree(%s, %p, %p)\n", copst(o), l, r);
171 if (l) fwalk(l, eprint, 0);
172 if (r) fwalk(r, eprint, 0);
174 #endif
175 opty = coptype(o);
177 /* check for constants */
179 if (o == ANDAND || o == OROR || o == NOT) {
180 if (l->n_op == FCON) {
181 p = bcon(!FLOAT_ISZERO(FCAST(l->n_dcon)));
182 nfree(l);
183 l = p;
185 if (o != NOT && r->n_op == FCON) {
186 p = bcon(!FLOAT_ISZERO(FCAST(r->n_dcon)));
187 nfree(r);
188 r = p;
192 if( opty == UTYPE && l->n_op == ICON ){
194 switch( o ){
196 case NOT:
197 case UMINUS:
198 case COMPL:
199 if( conval( l, o, l ) ) return(l);
200 break;
202 } else if (o == NOT && l->n_op == FCON) {
203 l = clocal(block(SCONV, l, NIL, INT, 0, 0));
204 } else if( o == UMINUS && l->n_op == FCON ){
205 FLOAT_NEG(FCAST(l->n_dcon));
206 return(l);
208 } else if( o==QUEST &&
209 (l->n_op==ICON || (l->n_op==NAME && ISARY(l->n_type)))) {
210 CONSZ c = glval(l);
211 if (l->n_op==NAME)
212 c = 1; /* will become constant later */
213 nfree(l);
214 if (c) {
215 walkf(r->n_right, putjops, 0);
216 tfree(r->n_right);
217 l = r->n_left;
218 } else {
219 walkf(r->n_left, putjops, 0);
220 tfree(r->n_left);
221 l = r->n_right;
223 nfree(r);
224 return(l);
225 } else if( opty == BITYPE && l->n_op == ICON && r->n_op == ICON ){
227 switch( o ){
229 case PLUS:
230 case MINUS:
231 case MUL:
232 case DIV:
233 case MOD:
235 * Do type propagation for simple types here.
236 * The constant value is correct anyway.
237 * Maybe this op shortcut should be removed?
239 if (l->n_sp == NULL && r->n_sp == NULL &&
240 l->n_type < BTMASK && r->n_type < BTMASK) {
241 if (l->n_type > r->n_type)
242 r->n_type = l->n_type;
243 else
244 l->n_type = r->n_type;
246 /* FALLTHROUGH */
247 case ULT:
248 case UGT:
249 case ULE:
250 case UGE:
251 case LT:
252 case GT:
253 case LE:
254 case GE:
255 case EQ:
256 case NE:
257 case ANDAND:
258 case OROR:
259 case AND:
260 case OR:
261 case ER:
262 case LS:
263 case RS:
264 if (!ISPTR(l->n_type) && !ISPTR(r->n_type)) {
265 if( conval( l, o, r ) ) {
266 nfree(r);
267 return(l);
270 break;
272 } else if (opty == BITYPE && (l->n_op == FCON || l->n_op == ICON) &&
273 (r->n_op == FCON || r->n_op == ICON) && (o == PLUS || o == MINUS ||
274 o == MUL || o == DIV || (o >= EQ && o <= GT) )) {
275 #define D(x) ((FLT *)x)
276 #ifndef CC_DIV_0
277 if (o == DIV &&
278 ((r->n_op == ICON && glval(r) == 0) ||
279 (r->n_op == FCON && FLOAT_EQ(D(r->n_dcon), FLOAT_ZERO))))
280 goto runtime; /* HW dependent */
281 #endif
282 if (l->n_op == ICON) {
283 if (!concast(l, r->n_type))
284 cerror("fail cast const");
285 } else if (r->n_op == ICON) {
286 if (!concast(r, l->n_type))
287 cerror("fail cast const");
290 switch(o){
291 case PLUS:
292 case MINUS:
293 case MUL:
294 case DIV:
295 switch (o) {
296 case PLUS:
297 FLOAT_PLUS(l, r);
298 break;
299 case MINUS:
300 FLOAT_MINUS(l, r);
301 break;
302 case MUL:
303 FLOAT_MUL(l, r);
304 break;
305 case DIV:
306 FLOAT_DIV(l, r);
307 break;
309 nfree(r);
310 return(l);
311 case EQ:
312 case NE:
313 case LE:
314 case LT:
315 case GE:
316 case GT:
317 switch (o) {
318 case EQ:
319 n = FLOAT_EQ(D(l->n_dcon), D(r->n_dcon));
320 break;
321 case NE:
322 n = FLOAT_NE(D(l->n_dcon), D(r->n_dcon));
323 break;
324 case LE:
325 n = FLOAT_LE(D(l->n_dcon), D(r->n_dcon));
326 break;
327 case LT:
328 n = FLOAT_LT(D(l->n_dcon), D(r->n_dcon));
329 break;
330 case GE:
331 n = FLOAT_GE(D(l->n_dcon), D(r->n_dcon));
332 break;
333 case GT:
334 n = FLOAT_GT(D(l->n_dcon), D(r->n_dcon));
335 break;
336 default:
337 n = 0; /* XXX flow analysis */
339 nfree(r);
340 nfree(l);
341 return bcon(n);
344 #ifndef CC_DIV_0
345 runtime:
346 #endif
347 /* its real; we must make a new node */
349 p = block(o, l, r, INT, 0, 0);
351 actions = opact(p);
353 if (actions & PROML)
354 p->n_left = intprom(p->n_left);
356 if (actions & LVAL) { /* check left descendent */
357 if (notlval(p->n_left)) {
358 uerror("lvalue required");
359 nfree(p);
360 return l;
361 #ifdef notyet
362 } else {
363 if ((l->n_type > BTMASK && ISCON(l->n_qual)) ||
364 (l->n_type <= BTMASK && ISCON(l->n_qual << TSHIFT)))
365 if (blevel > 0)
366 uerror("lvalue is declared const");
367 #endif
371 if( actions & NCVTR ){
372 p->n_left = pconvert( p->n_left );
374 else if( !(actions & NCVT ) ){
375 switch( opty ){
377 case BITYPE:
378 p->n_right = pconvert( p->n_right );
379 /* FALLTHROUGH */
380 case UTYPE:
381 p->n_left = pconvert( p->n_left );
386 if ((actions&PUN) && (o!=CAST))
387 chkpun(p);
389 if( actions & (TYPL|TYPR) ){
391 q = (actions&TYPL) ? p->n_left : p->n_right;
393 p->n_type = q->n_type;
394 p->n_qual = q->n_qual;
395 p->n_df = q->n_df;
396 p->n_ap = q->n_ap;
399 if( actions & CVTL ) p = convert( p, CVTL );
400 if( actions & CVTR ) p = convert( p, CVTR );
401 if( actions & TYMATCH ) p = tymatch(p);
402 if( actions & PTMATCH ) p = ptmatch(p);
404 if( actions & OTHER ){
405 struct symtab *sp1;
407 l = p->n_left;
408 r = p->n_right;
410 switch(o){
412 case NAME:
413 cerror("buildtree NAME");
415 case STREF:
416 /* p->x turned into *(p+offset) */
417 /* rhs must be a name; check correctness */
419 /* Find member symbol struct */
420 if (l->n_type != PTR+STRTY && l->n_type != PTR+UNIONTY){
421 uerror("struct or union required");
422 break;
425 if ((sp1 = strmemb(l->n_ap)) == NULL) {
426 uerror("undefined struct or union");
427 break;
430 if ((sp = findmember(sp1, r->n_name)) == NULL) {
431 uerror("member '%s' not declared", r->n_name);
432 break;
435 r->n_sp = sp;
436 p = stref(p);
437 break;
439 case UMUL:
440 if (l->n_op == ADDROF) {
441 nfree(p);
442 p = nfree(l);
444 if( !ISPTR(l->n_type))uerror("illegal indirection");
445 p->n_type = DECREF(l->n_type);
446 p->n_qual = DECREF(l->n_qual);
447 p->n_df = l->n_df;
448 p->n_ap = l->n_ap;
449 break;
451 case ADDROF:
452 switch( l->n_op ){
454 case UMUL:
455 nfree(p);
456 p = nfree(l);
457 /* FALLTHROUGH */
458 case TEMP:
459 case NAME:
460 p->n_type = INCREF(l->n_type);
461 p->n_qual = INCQAL(l->n_qual);
462 p->n_df = l->n_df;
463 p->n_ap = l->n_ap;
464 break;
466 case COMOP:
467 nfree(p);
468 lr = buildtree(ADDROF, l->n_right, NIL);
469 p = buildtree( COMOP, l->n_left, lr );
470 nfree(l);
471 break;
473 case QUEST:
474 lr = buildtree( ADDROF, l->n_right->n_right, NIL );
475 ll = buildtree( ADDROF, l->n_right->n_left, NIL );
476 nfree(p); nfree(l->n_right);
477 p = buildtree( QUEST, l->n_left, buildtree( COLON, ll, lr ) );
478 nfree(l);
479 break;
481 default:
482 uerror("unacceptable operand of &: %d", l->n_op );
483 break;
485 break;
487 case LS:
488 case RS: /* must make type size at least int... */
489 if (p->n_type == CHAR || p->n_type == SHORT) {
490 p->n_left = makety(l, INT, 0, 0, 0);
491 } else if (p->n_type == UCHAR || p->n_type == USHORT) {
492 p->n_left = makety(l, UNSIGNED, 0, 0, 0);
494 l = p->n_left;
495 p->n_type = l->n_type;
496 p->n_qual = l->n_qual;
497 p->n_df = l->n_df;
498 p->n_ap = l->n_ap;
500 /* FALLTHROUGH */
501 case LSEQ:
502 case RSEQ: /* ...but not for assigned types */
503 if(tsize(r->n_type, r->n_df, r->n_ap) > SZINT)
504 p->n_right = makety(r, INT, 0, 0, 0);
505 break;
507 case RETURN:
508 case ASSIGN:
509 case CAST:
510 /* structure assignment */
511 /* take the addresses of the two sides; then make an
512 * operator using STASG and
513 * the addresses of left and right */
515 if (strmemb(l->n_ap) != strmemb(r->n_ap))
516 uerror("assignment of different structures");
518 r = buildtree(ADDROF, r, NIL);
520 l = block(STASG, l, r, r->n_type, r->n_df, r->n_ap);
521 l = clocal(l);
523 if( o == RETURN ){
524 nfree(p);
525 p = l;
526 break;
529 p->n_op = UMUL;
530 p->n_left = l;
531 p->n_right = NIL;
532 break;
534 case QUEST: /* fixup types of : */
535 if (r->n_left->n_type != p->n_type)
536 r->n_left = makety(r->n_left, p->n_type,
537 p->n_qual, p->n_df, p->n_ap);
538 if (r->n_right->n_type != p->n_type)
539 r->n_right = makety(r->n_right, p->n_type,
540 p->n_qual, p->n_df, p->n_ap);
541 break;
543 case COLON:
544 /* structure colon */
546 if (strmemb(l->n_ap) != strmemb(r->n_ap))
547 uerror( "type clash in conditional" );
548 break;
550 case CALL:
551 p->n_right = r = strargs(p->n_right);
552 p = funcode(p);
553 /* FALLTHROUGH */
554 case UCALL:
555 if (!ISPTR(l->n_type))
556 uerror("illegal function");
557 p->n_type = DECREF(l->n_type);
558 if (!ISFTN(p->n_type))
559 uerror("illegal function");
560 p->n_type = DECREF(p->n_type);
561 p->n_df = l->n_df+1; /* add one for prototypes */
562 p->n_ap = l->n_ap;
563 if (p->n_type == STRTY || p->n_type == UNIONTY) {
564 /* function returning structure */
565 /* make function really return ptr to str., with * */
567 p->n_op += STCALL-CALL;
568 p->n_type = INCREF(p->n_type);
569 p = clocal(p); /* before recursing */
570 p = buildtree(UMUL, p, NIL);
573 break;
575 default:
576 cerror( "other code %d", o );
582 * Allow (void)0 casts.
583 * XXX - anything on the right side must be possible to cast.
584 * XXX - remove void types further on.
586 if (p->n_op == CAST && p->n_type == VOID &&
587 p->n_right->n_op == ICON)
588 p->n_right->n_type = VOID;
590 if (actions & CVTO)
591 p = oconvert(p);
592 p = clocal(p);
594 #ifdef PCC_DEBUG
595 if (bdebug) {
596 printf("End of buildtree:\n");
597 fwalk(p, eprint, 0);
599 #endif
601 return(p);
605 /* Find a member in a struct or union. May be an unnamed member */
606 static struct symtab *
607 findmember(struct symtab *sp, char *s)
609 struct symtab *sp2, *sp3;
611 for (; sp != NULL; sp = sp->snext) {
612 if (sp->sname[0] == '*') {
613 /* unnamed member, recurse down */
614 if ((sp2 = findmember(strmemb(sp->sap), s))) {
615 sp3 = tmpalloc(sizeof (struct symtab));
616 *sp3 = *sp2;
617 sp3->soffset += sp->soffset;
618 return sp3;
620 } else if (sp->sname == s)
621 return sp;
623 return NULL;
628 * Check if there will be a lost label destination inside of a ?:
629 * It cannot be reached so just print it out.
631 void
632 putjops(NODE *p, void *arg)
634 if (p->n_op == COMOP && p->n_left->n_op == GOTO)
635 plabel((int)glval(p->n_left->n_left)+1);
639 * Build a name node based on a symtab entry.
640 * broken out from buildtree().
642 NODE *
643 nametree(struct symtab *sp)
645 NODE *p;
647 p = block(NAME, NIL, NIL, sp->stype, sp->sdf, sp->sap);
648 p->n_qual = sp->squal;
649 p->n_sp = sp;
651 #ifndef NO_C_BUILTINS
652 if (sp->sname[0] == '_' && strncmp(sp->sname, "__builtin_", 10) == 0)
653 return p; /* do not touch builtins here */
655 #endif
657 if (sp->sflags & STNODE) {
658 /* Generated for optimizer */
659 p->n_op = TEMP;
660 p->n_rval = sp->soffset;
663 #ifdef GCC_COMPAT
664 /* Get a label name */
665 if (sp->sflags == SLBLNAME) {
666 p->n_type = VOID;
668 #endif
669 if (sp->stype == UNDEF) {
670 uerror("%s undefined", sp->sname);
671 /* make p look reasonable */
672 p->n_type = INT;
673 p->n_df = NULL;
674 defid(p, SNULL);
676 if (sp->sclass == MOE) {
677 p->n_op = ICON;
678 glval(p) = sp->soffset;
679 p->n_df = NULL;
680 p->n_sp = NULL;
682 return clocal(p);
686 * Cast a node to another type by inserting a cast.
687 * Just a nicer interface to buildtree.
688 * Returns the new tree.
690 NODE *
691 cast(NODE *p, TWORD t, TWORD u)
693 NODE *q;
695 q = block(NAME, NIL, NIL, t, 0, 0);
696 q->n_qual = u;
697 q = buildtree(CAST, q, p);
698 p = q->n_right;
699 nfree(q->n_left);
700 nfree(q);
701 return p;
705 * Cast and complain if necessary by not inserining a cast.
707 NODE *
708 ccast(NODE *p, TWORD t, TWORD u, union dimfun *df, struct attr *ap)
710 NODE *q;
712 /* let buildtree do typechecking (and casting) */
713 q = block(NAME, NIL, NIL, t, df, ap);
714 p = buildtree(ASSIGN, q, p);
715 nfree(p->n_left);
716 q = optim(p->n_right);
717 nfree(p);
718 return q;
722 * Do an actual cast of a constant (if possible).
723 * Routine assumes 2-complement (is there anything else today?)
724 * Returns 1 if handled, 0 otherwise.
727 concast(NODE *p, TWORD t)
729 extern short sztable[];
730 CONSZ val;
732 if (p->n_op != ICON && p->n_op != FCON) /* only constants */
733 return 0;
734 if (p->n_op == ICON && p->n_sp != NULL) { /* no addresses */
735 if (t == BOOL) {
736 glval(p) = 1, p->n_type = BOOL, p->n_sp = NULL;
737 return 1;
739 return 0;
741 if ((p->n_type & TMASK) || (t & TMASK)) /* no cast of pointers */
742 return 0;
744 //printf("concast till %d\n", t);
745 //fwalk(p, eprint, 0);
747 #define TYPMSK(y) ((((1LL << (y-1))-1) << 1) | 1)
748 if (p->n_op == ICON) {
749 val = glval(p);
751 if (t == BOOL) {
752 if (val)
753 glval(p) = 1;
754 } else if (t <= ULONGLONG) {
755 glval(p) = val & TYPMSK(sztable[t]);
756 if (!ISUNSIGNED(t)) {
757 if (val & (1LL << (sztable[t]-1)))
758 glval(p) |= ~TYPMSK(sztable[t]);
760 } else if (t <= LDOUBLE) {
761 p->n_op = FCON;
762 FLOAT_INT2FP(D(p->n_dcon), val, p->n_type);
764 } else { /* p->n_op == FCON */
765 if (t == BOOL) {
766 p->n_op = ICON;
767 glval(p) = FLOAT_NE(D(p->n_dcon),FLOAT_ZERO);
768 p->n_sp = NULL;
769 } else if (t <= ULONGLONG) {
770 p->n_op = ICON;
771 glval(p) = ISUNSIGNED(t) ? /* XXX FIXME */
772 ((U_CONSZ)D(p->n_dcon)->fp) : D(p->n_dcon)->fp;
773 p->n_sp = NULL;
774 } else {
775 D(p->n_dcon)->fp = t == FLOAT ? (float)D(p->n_dcon)->fp :
776 t == DOUBLE ? (double)D(p->n_dcon)->fp : D(p->n_dcon)->fp;
779 p->n_type = t;
780 //fwalk(p, eprint, 0);
781 return 1;
785 * Do a conditional branch.
787 void
788 cbranch(NODE *p, NODE *q)
790 p = buildtree(CBRANCH, p, q);
791 if (p->n_left->n_op == ICON) {
792 if (glval(p->n_left) != 0) {
793 branch((int)glval(q)); /* branch always */
794 reached = 0;
796 tfree(p);
797 tfree(q);
798 return;
800 ecomp(p);
803 NODE *
804 strargs(register NODE *p)
806 /* rewrite structure flavored arguments */
808 if( p->n_op == CM ){
809 p->n_left = strargs( p->n_left );
810 p->n_right = strargs( p->n_right );
811 return( p );
814 if( p->n_type == STRTY || p->n_type == UNIONTY ){
815 p = block(STARG, p, NIL, p->n_type, p->n_df, p->n_ap);
816 p->n_left = buildtree( ADDROF, p->n_left, NIL );
817 p = clocal(p);
819 return( p );
823 * apply the op o to the lval part of p; if binary, rhs is val
826 conval(NODE *p, int o, NODE *q)
828 TWORD tl = p->n_type, tr = q->n_type, td;
829 int i, u;
830 CONSZ val;
831 U_CONSZ v1, v2;
833 val = glval(q);
835 /* make both sides same type */
836 if (tl < BTMASK && tr < BTMASK) {
837 td = tl > tr ? tl : tr;
838 if (td < INT)
839 td = INT;
840 u = ISUNSIGNED(td);
841 if (tl != td)
842 p = makety(p, td, 0, 0, 0);
843 if (tr != td)
844 q = makety(q, td, 0, 0, 0);
845 } else
846 u = ISUNSIGNED(tl) || ISUNSIGNED(tr);
847 if( u && (o==LE||o==LT||o==GE||o==GT)) o += (UGE-GE);
849 if (p->n_sp != NULL && q->n_sp != NULL)
850 return(0);
851 if (q->n_sp != NULL && o != PLUS)
852 return(0);
853 if (p->n_sp != NULL && o != PLUS && o != MINUS)
854 return(0);
856 v1 = glval(p);
857 v2 = glval(q);
858 if (v2 == 0 && (cdope(o) & DIVFLG))
859 return 0; /* leave division by zero to runtime */
860 switch( o ){
862 case PLUS:
863 glval(p) += val;
864 if (p->n_sp == NULL) {
865 p->n_right = q->n_right;
866 p->n_type = q->n_type;
868 break;
869 case MINUS:
870 glval(p) -= val;
871 break;
872 case MUL:
873 glval(p) *= val;
874 break;
875 case DIV:
876 if (u) {
877 v1 /= v2;
878 glval(p) = v1;
879 } else
880 glval(p) /= val;
881 break;
882 case MOD:
883 if (u) {
884 v1 %= v2;
885 glval(p) = v1;
886 } else
887 glval(p) %= val;
888 break;
889 case AND:
890 glval(p) &= val;
891 break;
892 case OR:
893 glval(p) |= val;
894 break;
895 case ER:
896 glval(p) ^= val;
897 break;
898 case LS:
899 i = (int)val;
900 glval(p) = glval(p) << i;
901 break;
902 case RS:
903 i = (int)val;
904 if (u) {
905 v1 = v1 >> i;
906 glval(p) = v1;
907 } else
908 glval(p) = glval(p) >> i;
909 break;
911 case UMINUS:
912 glval(p) = - glval(p);
913 break;
914 case COMPL:
915 glval(p) = ~glval(p);
916 break;
917 case NOT:
918 glval(p) = !glval(p);
919 break;
920 case LT:
921 glval(p) = glval(p) < val;
922 break;
923 case LE:
924 glval(p) = glval(p) <= val;
925 break;
926 case GT:
927 glval(p) = glval(p) > val;
928 break;
929 case GE:
930 glval(p) = glval(p) >= val;
931 break;
932 case ULT:
933 glval(p) = v1 < v2;
934 break;
935 case ULE:
936 glval(p) = v1 <= v2;
937 break;
938 case UGT:
939 glval(p) = v1 > v2;
940 break;
941 case UGE:
942 glval(p) = v1 >= v2;
943 break;
944 case EQ:
945 glval(p) = glval(p) == val;
946 break;
947 case NE:
948 glval(p) = glval(p) != val;
949 break;
950 case ANDAND:
951 glval(p) = glval(p) && val;
952 break;
953 case OROR:
954 glval(p) = glval(p) || val;
955 break;
956 default:
957 return(0);
959 /* Do the best in making everything type correct after calc */
960 if (p->n_sp == NULL && q->n_sp == NULL)
961 glval(p) = valcast(glval(p), p->n_type);
962 return(1);
966 * Ensure that v matches the type t; sign- or zero-extended
967 * as suitable to CONSZ.
968 * Only to be used for integer types.
970 CONSZ
971 valcast(CONSZ v, TWORD t)
973 CONSZ r;
974 int sz;
976 if (t < CHAR || t > ULONGLONG)
977 return v; /* cannot cast */
979 if (t >= LONGLONG)
980 return v; /* already largest */
982 #define M(x) ((((1ULL << ((x)-1)) - 1) << 1) + 1)
983 #define NOTM(x) (~M(x))
984 #define SBIT(x) (1ULL << ((x)-1))
986 sz = (int)tsize(t, NULL, NULL);
987 r = v & M(sz);
988 if (!ISUNSIGNED(t) && (SBIT(sz) & r))
989 r = r | NOTM(sz);
990 return r;
994 * Checks p for the existence of a pun. This is called when the op of p
995 * is ASSIGN, RETURN, CAST, COLON, or relational.
996 * One case is when enumerations are used: this applies only to lint.
997 * In the other case, one operand is a pointer, the other integer type
998 * we check that this integer is in fact a constant zero...
999 * in the case of ASSIGN, any assignment of pointer to integer is illegal
1000 * this falls out, because the LHS is never 0.
1001 * XXX - check for COMOPs in assignment RHS?
1003 void
1004 chkpun(NODE *p)
1006 union dimfun *d1, *d2;
1007 NODE *q;
1008 int t1, t2;
1010 t1 = p->n_left->n_type;
1011 t2 = p->n_right->n_type;
1013 switch (p->n_op) {
1014 case RETURN:
1015 /* return of void allowed but nothing else */
1016 if (t1 == VOID && t2 == VOID)
1017 return;
1018 if (t1 == VOID) {
1019 werror("returning value from void function");
1020 return;
1022 if (t2 == VOID) {
1023 uerror("using void value");
1024 return;
1026 break;
1027 case COLON:
1028 if (t1 == VOID && t2 == VOID)
1029 return;
1030 break;
1031 default:
1032 if ((t1 == VOID && t2 != VOID) || (t1 != VOID && t2 == VOID)) {
1033 uerror("value of void expression used");
1034 return;
1036 break;
1039 /* allow void pointer assignments in any direction */
1040 if (BTYPE(t1) == VOID && (t2 & TMASK))
1041 return;
1042 if (BTYPE(t2) == VOID && (t1 & TMASK))
1043 return;
1045 /* boolean have special syntax */
1046 if (t1 == BOOL) {
1047 if (!ISARY(t2)) /* Anything scalar */
1048 return;
1051 if (ISPTR(t1) || ISARY(t1))
1052 q = p->n_right;
1053 else
1054 q = p->n_left;
1056 if (!ISPTR(q->n_type) && !ISARY(q->n_type)) {
1057 if (q->n_op != ICON || glval(q) != 0)
1058 werror("illegal combination of pointer and integer");
1059 } else {
1060 if (t1 == t2) {
1061 if (ISSOU(BTYPE(t1)) &&
1062 !suemeq(p->n_left->n_ap, p->n_right->n_ap))
1063 werror("illegal structure pointer combination");
1064 return;
1066 d1 = p->n_left->n_df;
1067 d2 = p->n_right->n_df;
1068 for (;;) {
1069 if (ISARY(t1) || ISPTR(t1)) {
1070 if (!ISARY(t2) && !ISPTR(t2))
1071 break;
1072 if (ISARY(t1) && ISARY(t2) && d1->ddim != d2->ddim) {
1073 werror("illegal array size combination");
1074 return;
1076 if (ISARY(t1))
1077 ++d1;
1078 if (ISARY(t2))
1079 ++d2;
1080 } else if (ISFTN(t1)) {
1081 if (chkftn(d1->dfun, d2->dfun)) {
1082 werror("illegal function "
1083 "pointer combination");
1084 return;
1086 ++d1;
1087 ++d2;
1088 } else
1089 break;
1090 t1 = DECREF(t1);
1091 t2 = DECREF(t2);
1093 if (DEUNSIGN(t1) != DEUNSIGN(t2))
1094 warner(Wpointer_sign);
1098 static NODE *
1099 offplus(NODE *p, int off, TWORD t, TWORD q, union dimfun *d, struct attr *ap) {
1100 if (off != 0) {
1101 p = block(PLUS, p, offcon(off, t, d, ap), t, d, ap);
1102 p->n_qual = q;
1103 p = optim(p);
1106 return buildtree(UMUL, p, NIL);
1109 NODE *
1110 stref(NODE *p)
1112 NODE *r;
1113 struct attr *ap, *xap, *yap;
1114 union dimfun *d;
1115 TWORD t, q;
1116 int dsc;
1117 OFFSZ off;
1118 struct symtab *s;
1120 /* make p->x */
1121 /* this is also used to reference automatic variables */
1123 s = p->n_right->n_sp;
1124 nfree(p->n_right);
1125 r = nfree(p);
1126 #ifdef GCC_COMPAT
1127 xap = attr_find(r->n_ap, GCC_ATYP_PACKED);
1128 #endif
1130 p = pconvert(r);
1132 /* make p look like ptr to x */
1134 if (!ISPTR(p->n_type))
1135 p->n_type = PTR+UNIONTY;
1137 t = INCREF(s->stype);
1138 q = INCQAL(s->squal);
1139 d = s->sdf;
1140 ap = s->sap;
1141 #ifdef GCC_COMPAT
1142 if ((yap = attr_find(ap, GCC_ATYP_PACKED)) != NULL)
1143 xap = yap;
1144 else if (xap != NULL)
1145 ap = attr_add(ap, attr_dup(xap));
1146 #else
1147 xap = yap = NULL;
1148 #endif
1149 /* xap set if packed struct */
1151 p = makety(p, t, q, d, ap);
1152 if (ISFTN(s->stype)) {
1153 /* direct class call */
1154 p = block(NMLIST, p, nametree(s), INT, 0, 0);
1155 return p;
1158 /* compute the offset to be added */
1160 off = s->soffset;
1161 dsc = s->sclass;
1163 if (dsc & FIELD) {
1164 TWORD ftyp = s->stype;
1165 int fal = talign(ftyp, ap);
1166 off = (off/fal)*fal;
1167 p = offplus(p, off, t, q, d, ap);
1168 p = block(FLD, p, NIL, ftyp, 0, ap);
1169 p->n_qual = q;
1170 p->n_rval = PKFIELD(dsc&FLDSIZ, s->soffset%fal);
1171 } else {
1172 p = offplus(p, off, t, q, d, ap);
1173 #ifndef CAN_UNALIGN
1174 /* if target cannot handle unaligned addresses, fix here */
1175 #endif
1178 p = clocal(p);
1179 return p;
1183 notlval(register NODE *p)
1185 /* return 0 if p an lvalue, 1 otherwise */
1187 again:
1189 switch( p->n_op ){
1191 case FLD:
1192 p = p->n_left;
1193 goto again;
1195 case NAME:
1196 case OREG:
1197 case UMUL:
1198 if( ISARY(p->n_type) || ISFTN(p->n_type) ) return(1);
1199 case TEMP:
1200 case REG:
1201 return(0);
1203 default:
1204 return(1);
1208 /* make a constant node with value i */
1209 NODE *
1210 bcon(int i)
1212 return xbcon(i, NULL, INT);
1215 NODE *
1216 xbcon(CONSZ val, struct symtab *sp, TWORD type)
1218 NODE *p;
1220 p = block(ICON, NIL, NIL, type, 0, 0);
1221 glval(p) = val;
1222 p->n_sp = sp;
1223 return clocal(p);
1226 NODE *
1227 bpsize(NODE *p)
1229 int isdyn(struct symtab *sp);
1230 struct symtab s;
1231 NODE *q, *r;
1232 TWORD t;
1233 int sz;
1235 s.stype = DECREF(p->n_type);
1236 s.sdf = p->n_df;
1237 if (isdyn(&s)) {
1238 q = bcon(1);
1239 for (t = s.stype; t > BTMASK; t = DECREF(t)) {
1240 if (ISPTR(t))
1241 return buildtree(MUL, q, bcon(SZPOINT(t)));
1242 if (ISARY(t)) {
1243 if (s.sdf->ddim < 0)
1244 r = tempnode(-s.sdf->ddim, INT, 0, 0);
1245 else
1246 r = bcon(s.sdf->ddim/SZCHAR);
1247 q = buildtree(MUL, q, r);
1248 s.sdf++;
1251 sz = (int)tsize(p->n_type, p->n_df, p->n_ap);
1252 p = buildtree(MUL, q, bcon(sz/SZCHAR));
1253 } else
1254 p = (offcon(psize(p), p->n_type, p->n_df, p->n_ap));
1255 return p;
1259 * p is a node of type pointer; psize returns the
1260 * size of the thing pointed to
1262 OFFSZ
1263 psize(NODE *p)
1266 if (!ISPTR(p->n_type)) {
1267 uerror("pointer required");
1268 return(SZINT);
1270 /* note: no pointers to fields */
1271 return(tsize(DECREF(p->n_type), p->n_df, p->n_ap));
1275 * convert an operand of p
1276 * f is either CVTL or CVTR
1277 * operand has type int, and is converted by the size of the other side
1278 * convert is called when an integer is to be added to a pointer, for
1279 * example in arrays or structures.
1281 NODE *
1282 convert(NODE *p, int f)
1284 union dimfun *df;
1285 TWORD ty, ty2;
1286 NODE *q, *r, *s, *rv;
1288 if (f == CVTL) {
1289 q = p->n_left;
1290 s = p->n_right;
1291 } else {
1292 q = p->n_right;
1293 s = p->n_left;
1295 ty2 = ty = DECREF(s->n_type);
1296 while (ISARY(ty))
1297 ty = DECREF(ty);
1299 r = offcon(tsize(ty, s->n_df, s->n_ap), s->n_type, s->n_df, s->n_ap);
1300 ty = ty2;
1301 rv = bcon(1);
1302 df = s->n_df;
1303 while (ISARY(ty)) {
1304 rv = buildtree(MUL, rv, df->ddim >= 0 ? bcon(df->ddim) :
1305 tempnode(-df->ddim, INT, 0, 0));
1306 df++;
1307 ty = DECREF(ty);
1309 rv = clocal(MBLOCK(rv, r, INT, 0, 0));
1310 rv = optim(rv);
1312 r = MBLOCK(q, rv, INT, 0, 0);
1313 r = clocal(r);
1315 * Indexing is only allowed with integer arguments, so insert
1316 * SCONV here if arg is not an integer.
1317 * XXX - complain?
1319 if (r->n_type != INTPTR)
1320 r = clocal(makety(r, INTPTR, 0, 0, 0));
1321 if (f == CVTL)
1322 p->n_left = r;
1323 else
1324 p->n_right = r;
1325 return(p);
1328 NODE *
1329 pconvert(register NODE *p)
1331 /* if p should be changed into a pointer, do so */
1333 if( ISARY( p->n_type) ){
1334 p->n_type = DECREF( p->n_type );
1335 ++p->n_df;
1336 return( buildtree( ADDROF, p, NIL ) );
1338 if( ISFTN( p->n_type) )
1339 return( buildtree( ADDROF, p, NIL ) );
1341 return( p );
1344 NODE *
1345 oconvert(register NODE *p)
1347 /* convert the result itself: used for pointer and unsigned */
1349 switch(p->n_op) {
1351 case LE:
1352 case LT:
1353 case GE:
1354 case GT:
1355 if(ISUNSIGNED(p->n_left->n_type) ||
1356 ISUNSIGNED(p->n_right->n_type) ||
1357 ISPTR(p->n_left->n_type) ||
1358 ISPTR(p->n_right->n_type))
1359 p->n_op += (ULE-LE);
1360 /* FALLTHROUGH */
1361 case EQ:
1362 case NE:
1363 return( p );
1365 case MINUS:
1366 p->n_type = INTPTR;
1367 p->n_ap = NULL;
1368 return(clocal(VBLOCK(p, bpsize(p->n_left), INT, 0, 0)));
1371 cerror( "illegal oconvert: %d", p->n_op );
1373 return(p);
1377 * makes the operands of p agree; they are
1378 * either pointers or integers, by this time
1379 * with MINUS, the sizes must be the same
1380 * with COLON, the types must be the same
1382 NODE *
1383 ptmatch(NODE *p)
1385 struct attr *ap, *ap2;
1386 union dimfun *d, *d2;
1387 TWORD t1, t2, t, q1, q2, q;
1388 int o;
1390 o = p->n_op;
1391 t = t1 = p->n_left->n_type;
1392 q = q1 = p->n_left->n_qual;
1393 t2 = p->n_right->n_type;
1394 q2 = p->n_right->n_qual;
1395 d = p->n_left->n_df;
1396 d2 = p->n_right->n_df;
1397 ap = p->n_left->n_ap;
1398 ap2 = p->n_right->n_ap;
1400 switch( o ){
1402 case ASSIGN:
1403 case RETURN:
1404 { break; }
1406 case CAST:
1407 if (t == VOID) {
1408 /* just paint over */
1409 p->n_right = block(SCONV, p->n_right, NIL, VOID, 0, 0);
1410 return p;
1412 break;
1414 case MINUS: {
1415 int isdyn(struct symtab *sp);
1416 struct symtab s1, s2;
1418 s1.stype = DECREF(t);
1419 s1.sdf = d;
1420 s2.stype = DECREF(t2);
1421 s2.sdf = d2;
1422 if (isdyn(&s1) || isdyn(&s2))
1423 ; /* We don't know */
1424 else if (psize(p->n_left) != psize(p->n_right))
1425 uerror("illegal pointer subtraction");
1426 break;
1429 case COLON:
1430 if (t1 != t2) {
1432 * Check for void pointer types. They are allowed
1433 * to cast to/from any pointers.
1435 if (ISPTR(t1) && ISPTR(t2) &&
1436 (BTYPE(t1) == VOID || BTYPE(t2) == VOID))
1437 break;
1438 uerror("illegal types in :");
1440 break;
1442 default: /* must work harder: relationals or comparisons */
1444 if( !ISPTR(t1) ){
1445 t = t2;
1446 q = q2;
1447 d = d2;
1448 ap = ap2;
1449 break;
1451 if( !ISPTR(t2) ){
1452 break;
1455 /* both are pointers */
1456 if( talign(t2,ap2) < talign(t,ap) ){
1457 t = t2;
1458 q = q2;
1459 ap = ap2;
1461 break;
1464 p->n_left = makety( p->n_left, t, q, d, ap );
1465 p->n_right = makety( p->n_right, t, q, d, ap );
1466 if( o!=MINUS && !clogop(o) ){
1468 p->n_type = t;
1469 p->n_qual = q;
1470 p->n_df = d;
1471 p->n_ap = ap;
1474 return(clocal(p));
1478 * Satisfy the types of various arithmetic binary ops.
1480 * rules are:
1481 * if assignment, type of LHS
1482 * if any doubles, make double
1483 * else if any float make float
1484 * else if any longlongs, make long long
1485 * else if any longs, make long
1486 * else etcetc.
1488 * If the op with the highest rank is unsigned, this is the resulting type.
1489 * See: 6.3.1.1 rank order equal of signed and unsigned types
1490 * 6.3.1.8 Usual arithmetic conversions
1492 static NODE *
1493 tymatch(NODE *p)
1495 TWORD tl, tr, t;
1496 NODE *l, *r;
1497 int o;
1499 o = p->n_op;
1500 r = p->n_right;
1501 l = p->n_left;
1503 tl = l->n_type;
1504 tr = r->n_type;
1506 if (tl == BOOL) tl = BOOL_TYPE;
1507 if (tr == BOOL) tr = BOOL_TYPE;
1509 if (casgop(o)) {
1510 if (r->n_op != ICON && tl < FLOAT && tr < FLOAT &&
1511 DEUNSIGN(tl) < DEUNSIGN(tr) && o != CAST)
1512 warner(Wtruncate, tnames[tr], tnames[tl]);
1513 p->n_right = makety(p->n_right, l->n_type, 0, 0, 0);
1514 t = p->n_type = l->n_type;
1515 p->n_ap = l->n_ap;
1516 } else {
1517 t = tl > tr ? tl : tr; /* MAX */
1518 /* This depends on ctype() called early */
1519 if (o != COLON && t < INT)
1520 t = INT;
1521 if (tl != t) p->n_left = makety(p->n_left, t, 0, 0, 0);
1522 if (tr != t) p->n_right = makety(p->n_right, t, 0, 0, 0);
1523 if (o == COLON && l->n_type == BOOL && r->n_type == BOOL)
1524 t = p->n_type = BOOL;
1525 else if (!clogop(o))
1526 p->n_type = t;
1528 #ifdef PCC_DEBUG
1529 if (tdebug) {
1530 printf("tymatch(%p): ", p);
1531 tprint(tl, 0);
1532 printf(" %s ", copst(o));
1533 tprint(tr, 0);
1534 printf(" => ");
1535 tprint(t, 0);
1536 printf("\n");
1537 fwalk(p, eprint, 0);
1539 #endif
1540 return p;
1544 * make p into type t by inserting a conversion
1546 NODE *
1547 makety(NODE *p, TWORD t, TWORD q, union dimfun *d, struct attr *ap)
1550 if (t == p->n_type) {
1551 p->n_df = d;
1552 p->n_ap = ap;
1553 p->n_qual = q;
1554 return(p);
1557 if (ISITY(t) || ISCTY(t) || ISITY(p->n_type) || ISCTY(p->n_type))
1558 cerror("makety");
1560 if (concast(p, t))
1561 return clocal(p);
1563 p = block(t & TMASK ? PCONV : SCONV, p, NIL, t, d, ap);
1564 p->n_qual = q;
1565 return clocal(p);
1568 NODE *
1569 block(int o, NODE *l, NODE *r, TWORD t, union dimfun *d, struct attr *ap)
1571 register NODE *p;
1573 p = talloc();
1574 p->n_rval = 0;
1575 p->n_op = o;
1576 glval(p) = 0; /* Protect against large lval */
1577 p->n_left = l;
1578 p->n_right = r;
1579 p->n_type = t;
1580 p->n_qual = 0;
1581 p->n_df = d;
1582 p->n_ap = ap;
1583 #if !defined(MULTIPASS)
1584 /* p->n_reg = */p->n_su = 0;
1585 p->n_regw = 0;
1586 #endif
1587 return(p);
1591 * Return the constant value from an ICON.
1593 CONSZ
1594 icons(NODE *p)
1596 /* if p is an integer constant, return its value */
1597 CONSZ val;
1599 if (p->n_op != ICON || p->n_sp != NULL) {
1600 uerror( "constant expected");
1601 val = 1;
1602 } else
1603 val = glval(p);
1604 tfree(p);
1605 return(val);
1609 * the intent of this table is to examine the
1610 * operators, and to check them for
1611 * correctness.
1613 * The table is searched for the op and the
1614 * modified type (where this is one of the
1615 * types INT (includes char and short), LONG,
1616 * DOUBLE (includes FLOAT), and POINTER
1618 * The default action is to make the node type integer
1620 * The actions taken include:
1621 * PUN check for puns
1622 * CVTL convert the left operand
1623 * CVTR convert the right operand
1624 * TYPL the type is determined by the left operand
1625 * TYPR the type is determined by the right operand
1626 * TYMATCH force type of left and right to match,by inserting conversions
1627 * PTMATCH like TYMATCH, but for pointers
1628 * LVAL left operand must be lval
1629 * CVTO convert the op
1630 * NCVT do not convert the operands
1631 * OTHER handled by code
1632 * NCVTR convert the left operand, not the right...
1636 # define MINT 01 /* integer */
1637 # define MDBI 02 /* integer or double */
1638 # define MSTR 04 /* structure */
1639 # define MPTR 010 /* pointer */
1640 # define MPTI 020 /* pointer or integer */
1643 opact(NODE *p)
1645 int mt12, mt1, mt2, o;
1647 mt1 = mt2 = mt12 = 0;
1649 switch (coptype(o = p->n_op)) {
1650 case BITYPE:
1651 mt12=mt2 = moditype(p->n_right->n_type);
1652 /* FALLTHROUGH */
1653 case UTYPE:
1654 mt12 &= (mt1 = moditype(p->n_left->n_type));
1655 break;
1658 switch( o ){
1660 case NAME :
1661 case ICON :
1662 case FCON :
1663 case CALL :
1664 case UCALL:
1665 case UMUL:
1666 { return( OTHER ); }
1667 case UMINUS:
1668 if( mt1 & MDBI ) return( TYPL+PROML );
1669 break;
1671 case COMPL:
1672 if( mt1 & MINT ) return( TYPL+PROML );
1673 break;
1675 case ADDROF:
1676 return( NCVT+OTHER );
1677 case NOT:
1678 return( PROML );
1680 /* case INIT: */
1681 case CM:
1682 case CBRANCH:
1683 case ANDAND:
1684 case OROR:
1685 return( 0 );
1687 case MUL:
1688 case DIV:
1689 if( mt12 & MDBI ) return( TYMATCH );
1690 break;
1692 case MOD:
1693 case AND:
1694 case OR:
1695 case ER:
1696 if( mt12 & MINT ) return( TYMATCH );
1697 break;
1699 case LS:
1700 case RS:
1701 if( mt12 & MINT ) return( TYPL+OTHER );
1702 break;
1704 case EQ:
1705 case NE:
1706 case LT:
1707 case LE:
1708 case GT:
1709 case GE:
1710 if( mt12 & MDBI ) return( TYMATCH+CVTO );
1711 else if( mt12 & MPTR ) return( PTMATCH+PUN+CVTO );
1712 else if( mt12 & MPTI ) return( PTMATCH+PUN );
1713 else break;
1715 case QUEST:
1716 return( TYPR+OTHER );
1717 case COMOP:
1718 return( TYPR );
1720 case STREF:
1721 return( NCVTR+OTHER );
1723 case FORCE:
1724 return( TYPL );
1726 case COLON:
1727 if( mt12 & MDBI ) return( TYMATCH );
1728 else if( mt12 & MPTR ) return( TYPL+PTMATCH+PUN );
1729 else if( (mt1&MINT) && (mt2&MPTR) ) return( TYPR+PUN );
1730 else if( (mt1&MPTR) && (mt2&MINT) ) return( TYPL+PUN );
1731 else if( mt12 & MSTR ) return( NCVT+TYPL+OTHER );
1732 break;
1734 case ASSIGN:
1735 case RETURN:
1736 if( mt12 & MSTR ) return( LVAL+NCVT+TYPL+OTHER );
1737 case CAST:
1738 if( mt12 & MDBI ) return( TYPL+LVAL+TYMATCH );
1739 else if( mt1 & MPTR) return( LVAL+PTMATCH+PUN );
1740 else if( mt12 & MPTI ) return( TYPL+LVAL+TYMATCH+PUN );
1741 break;
1743 case LSEQ:
1744 case RSEQ:
1745 if( mt12 & MINT ) return( TYPL+LVAL+OTHER );
1746 break;
1748 case MULEQ:
1749 case DIVEQ:
1750 if( mt12 & MDBI ) return( LVAL+TYMATCH );
1751 break;
1753 case MODEQ:
1754 case ANDEQ:
1755 case OREQ:
1756 case EREQ:
1757 if (mt12 & MINT)
1758 return(LVAL+TYMATCH);
1759 break;
1761 case PLUSEQ:
1762 case MINUSEQ:
1763 case INCR:
1764 case DECR:
1765 if (mt12 & MDBI)
1766 return(TYMATCH+LVAL);
1767 else if ((mt1&MPTR) && (mt2&MINT))
1768 return(TYPL+LVAL+CVTR);
1769 break;
1771 case MINUS:
1772 if (mt12 & MPTR)
1773 return(CVTO+PTMATCH+PUN);
1774 if (mt2 & MPTR)
1775 break;
1776 /* FALLTHROUGH */
1777 case PLUS:
1778 if (mt12 & MDBI)
1779 return(TYMATCH);
1780 else if ((mt1&MPTR) && (mt2&MINT))
1781 return(TYPL+CVTR);
1782 else if ((mt1&MINT) && (mt2&MPTR))
1783 return(TYPR+CVTL);
1786 uerror("operands of %s have incompatible types", copst(o));
1787 return(NCVT);
1791 moditype(TWORD ty)
1793 switch (ty) {
1795 case STRTY:
1796 case UNIONTY:
1797 return( MSTR );
1799 case BOOL:
1800 case CHAR:
1801 case SHORT:
1802 case UCHAR:
1803 case USHORT:
1804 case UNSIGNED:
1805 case ULONG:
1806 case ULONGLONG:
1807 case INT:
1808 case LONG:
1809 case LONGLONG:
1810 return( MINT|MDBI|MPTI );
1811 case FLOAT:
1812 case DOUBLE:
1813 case LDOUBLE:
1814 #ifndef NO_COMPLEX
1815 case FCOMPLEX:
1816 case COMPLEX:
1817 case LCOMPLEX:
1818 case FIMAG:
1819 case IMAG:
1820 case LIMAG:
1821 #endif
1822 return( MDBI );
1823 default:
1824 return( MPTR|MPTI );
1829 int tvaloff = MAXREGS+NPERMREG > 100 ? MAXREGS+NPERMREG + 100 : 100;
1832 * Returns a TEMP node with temp number nr.
1833 * If nr == 0, return a node with a new number.
1835 NODE *
1836 tempnode(int nr, TWORD type, union dimfun *df, struct attr *ap)
1838 NODE *r;
1840 if (tvaloff == -NOOFFSET)
1841 tvaloff++; /* Skip this for array indexing */
1842 r = block(TEMP, NIL, NIL, type, df, ap);
1843 regno(r) = nr ? nr : tvaloff;
1844 tvaloff += szty(type);
1845 return r;
1849 * Do sizeof on p.
1851 NODE *
1852 doszof(NODE *p)
1854 extern NODE *arrstk[10];
1855 extern int arrstkp;
1856 union dimfun *df;
1857 TWORD ty;
1858 NODE *rv, *q;
1859 int astkp;
1861 if (p->n_op == FLD)
1862 uerror("can't apply sizeof to bit-field");
1865 * Arrays may be dynamic, may need to make computations.
1868 rv = bcon(1);
1869 df = p->n_df;
1870 ty = p->n_type;
1871 astkp = 0;
1872 while (ISARY(ty)) {
1873 if (df->ddim == NOOFFSET)
1874 uerror("sizeof of incomplete type");
1875 if (df->ddim < 0) {
1876 if (arrstkp)
1877 q = arrstk[astkp++];
1878 else
1879 q = tempnode(-df->ddim, INT, 0, 0);
1880 } else
1881 q = bcon(df->ddim);
1882 rv = buildtree(MUL, rv, q);
1883 df++;
1884 ty = DECREF(ty);
1886 rv = buildtree(MUL, rv,
1887 xbcon(tsize(ty, p->n_df, p->n_ap)/SZCHAR, NULL, INTPTR));
1888 tfree(p);
1889 arrstkp = 0; /* XXX - may this fail? */
1890 return rv;
1893 #ifdef PCC_DEBUG
1894 void
1895 eprint(NODE *p, int down, int *a, int *b)
1897 int ty;
1899 *a = *b = down+1;
1900 while( down > 1 ){
1901 printf( "\t" );
1902 down -= 2;
1904 if( down ) printf( " " );
1906 ty = coptype( p->n_op );
1908 printf("%p) %s, ", p, copst(p->n_op));
1909 if (p->n_op == XARG || p->n_op == XASM)
1910 printf("id '%s', ", p->n_name);
1911 if (ty == LTYPE) {
1912 printf(CONFMT, glval(p));
1913 if (p->n_op == NAME || p->n_op == ICON)
1914 printf(", %p, ", p->n_sp);
1915 else
1916 printf(", %d, ", p->n_rval);
1918 tprint(p->n_type, p->n_qual);
1919 printf( ", %p, ", p->n_df);
1920 #ifdef GCC_COMPAT
1921 dump_attr(p->n_ap);
1922 #endif
1924 # endif
1927 * Emit everything that should be emitted on the left side
1928 * of a comma operator, and remove the operator.
1929 * Do not traverse through QUEST, ANDAND and OROR.
1930 * Enable this for all targets when stable enough.
1932 static void
1933 comops(NODE *p)
1935 int o;
1936 NODE *q;
1938 while (p->n_op == COMOP) {
1939 /* XXX hack for GCC ({ }) ops */
1940 if (p->n_left->n_op == GOTO) {
1941 int v = (int)glval(p->n_left->n_left);
1942 ecomp(p->n_left);
1943 plabel(v+1);
1944 } else
1945 ecomp(p->n_left); /* will recurse if more COMOPs */
1946 q = p->n_right;
1947 *p = *q;
1948 nfree(q);
1950 o = coptype(p->n_op);
1951 if (p->n_op == QUEST || p->n_op == ANDAND || p->n_op == OROR)
1952 o = UTYPE;
1953 if (o != LTYPE)
1954 comops(p->n_left);
1955 if (o == BITYPE)
1956 comops(p->n_right);
1960 * Walk up through the tree from the leaves,
1961 * removing constant operators.
1963 static void
1964 logwalk(NODE *p)
1966 int o = coptype(p->n_op);
1967 NODE *l, *r;
1969 l = p->n_left;
1970 r = p->n_right;
1971 switch (o) {
1972 case LTYPE:
1973 return;
1974 case BITYPE:
1975 logwalk(r);
1976 /* FALLTHROUGH */
1977 case UTYPE:
1978 logwalk(l);
1980 if (!clogop(p->n_op))
1981 return;
1982 if (p->n_op == NOT && l->n_op == ICON) {
1983 glval(p) = glval(l) == 0;
1984 nfree(l);
1985 p->n_op = ICON;
1987 if (l->n_op == ICON && r->n_op == ICON) {
1988 if (conval(l, p->n_op, r) == 0) {
1990 * people sometimes tend to do really odd compares,
1991 * like "if ("abc" == "def")" etc.
1992 * do it runtime instead.
1994 } else {
1995 glval(p) = glval(l);
1996 p->n_op = ICON;
1997 nfree(l);
1998 nfree(r);
2004 * Removes redundant logical operators for branch conditions.
2006 static void
2007 fixbranch(NODE *p, int label)
2010 logwalk(p);
2012 if (p->n_op == ICON) {
2013 if (glval(p) != 0)
2014 branch(label);
2015 nfree(p);
2016 } else {
2017 if (!clogop(p->n_op)) /* Always conditional */
2018 p = buildtree(NE, p, bcon(0));
2019 ecode(buildtree(CBRANCH, p, bcon(label)));
2024 * Write out logical expressions as branches.
2026 static void
2027 andorbr(NODE *p, int true, int false)
2029 NODE *q;
2030 int o, lab;
2032 lab = -1;
2033 switch (o = p->n_op) {
2034 case EQ:
2035 case NE:
2037 * Remove redundant EQ/NE nodes.
2039 while (((o = p->n_left->n_op) == EQ || o == NE) &&
2040 p->n_right->n_op == ICON) {
2041 o = p->n_op;
2042 q = p->n_left;
2043 if (glval(p->n_right) == 0) {
2044 nfree(p->n_right);
2045 *p = *q;
2046 nfree(q);
2047 if (o == EQ)
2048 p->n_op = negrel[p->n_op - EQ];
2049 #if 0
2050 p->n_op = NE; /* toggla */
2051 #endif
2052 } else if (glval(p->n_right) == 1) {
2053 nfree(p->n_right);
2054 *p = *q;
2055 nfree(q);
2056 if (o == NE)
2057 p->n_op = negrel[p->n_op - EQ];
2058 #if 0
2059 p->n_op = EQ; /* toggla */
2060 #endif
2061 } else
2062 break; /* XXX - should always be false */
2065 /* FALLTHROUGH */
2066 case LE:
2067 case LT:
2068 case GE:
2069 case GT:
2070 calc: if (true < 0) {
2071 p->n_op = negrel[p->n_op - EQ];
2072 true = false;
2073 false = -1;
2076 rmcops(p->n_left);
2077 rmcops(p->n_right);
2078 fixbranch(p, true);
2079 if (false >= 0)
2080 branch(false);
2081 break;
2083 case ULE:
2084 case UGT:
2085 /* Convert to friendlier ops */
2086 if (nncon(p->n_right) && glval(p->n_right) == 0)
2087 p->n_op = o == ULE ? EQ : NE;
2088 goto calc;
2090 case UGE:
2091 case ULT:
2092 /* Already true/false by definition */
2093 if (nncon(p->n_right) && glval(p->n_right) == 0) {
2094 if (true < 0) {
2095 o = o == ULT ? UGE : ULT;
2096 true = false;
2098 rmcops(p->n_left);
2099 ecode(p->n_left);
2100 rmcops(p->n_right);
2101 ecode(p->n_right);
2102 nfree(p);
2103 if (o == UGE) /* true */
2104 branch(true);
2105 break;
2107 goto calc;
2109 case ANDAND:
2110 lab = false<0 ? getlab() : false ;
2111 andorbr(p->n_left, -1, lab);
2112 comops(p->n_right);
2113 andorbr(p->n_right, true, false);
2114 if (false < 0)
2115 plabel( lab);
2116 nfree(p);
2117 break;
2119 case OROR:
2120 lab = true<0 ? getlab() : true;
2121 andorbr(p->n_left, lab, -1);
2122 comops(p->n_right);
2123 andorbr(p->n_right, true, false);
2124 if (true < 0)
2125 plabel( lab);
2126 nfree(p);
2127 break;
2129 case NOT:
2130 andorbr(p->n_left, false, true);
2131 nfree(p);
2132 break;
2134 default:
2135 rmcops(p);
2136 if (true >= 0)
2137 fixbranch(p, true);
2138 if (false >= 0) {
2139 if (true >= 0)
2140 branch(false);
2141 else
2142 fixbranch(buildtree(EQ, p, bcon(0)), false);
2148 * Create a node for either TEMP or on-stack storage.
2150 NODE *
2151 cstknode(TWORD t, union dimfun *df, struct attr *ap)
2153 struct symtab *sp;
2155 /* create a symtab entry suitable for this type */
2156 sp = getsymtab("0hej", STEMP);
2157 sp->stype = t;
2158 sp->sdf = df;
2159 sp->sap = ap;
2160 sp->sclass = AUTO;
2161 sp->soffset = NOOFFSET;
2162 oalloc(sp, &autooff);
2163 return nametree(sp);
2168 * Massage the output trees to remove C-specific nodes:
2169 * COMOPs are split into separate statements.
2170 * QUEST/COLON are rewritten to branches.
2171 * ANDAND/OROR/NOT are rewritten to branches for lazy-evaluation.
2172 * CBRANCH conditions are rewritten for lazy-evaluation.
2174 static void
2175 rmcops(NODE *p)
2177 TWORD type;
2178 NODE *q, *r, *tval;
2179 int o, ty, lbl, lbl2;
2181 tval = NIL;
2182 o = p->n_op;
2183 ty = coptype(o);
2184 if (BTYPE(p->n_type) == ENUMTY) { /* fixup enum */
2185 struct symtab *sp = strmemb(p->n_ap);
2186 MODTYPE(p->n_type, sp->stype);
2188 * XXX may fail if these are true:
2189 * - variable-sized enums
2190 * - non-byte-addressed targets.
2192 if (BTYPE(p->n_type) == ENUMTY && ISPTR(p->n_type))
2193 MODTYPE(p->n_type, INT); /* INT ok? */
2195 switch (o) {
2196 case QUEST:
2199 * Create a branch node from ?:
2200 * || and && must be taken special care of.
2202 type = p->n_type;
2203 andorbr(p->n_left, -1, lbl = getlab());
2205 /* Make ASSIGN node */
2206 /* Only if type is not void */
2207 q = p->n_right->n_left;
2208 comops(q);
2209 if (type != VOID) {
2210 tval = cstknode(q->n_type, q->n_df, q->n_ap);
2211 q = buildtree(ASSIGN, ccopy(tval), q);
2213 rmcops(q);
2214 ecode(q); /* Done with assign */
2215 branch(lbl2 = getlab());
2216 plabel( lbl);
2218 q = p->n_right->n_right;
2219 comops(q);
2220 if (type != VOID) {
2221 q = buildtree(ASSIGN, ccopy(tval), q);
2223 rmcops(q);
2224 ecode(q); /* Done with assign */
2226 plabel( lbl2);
2228 nfree(p->n_right);
2229 if (p->n_type != VOID) {
2230 *p = *tval;
2231 nfree(tval);
2232 } else {
2233 p->n_op = ICON;
2234 glval(p) = 0;
2235 p->n_sp = NULL;
2237 break;
2239 case ULE:
2240 case ULT:
2241 case UGE:
2242 case UGT:
2243 case EQ:
2244 case NE:
2245 case LE:
2246 case LT:
2247 case GE:
2248 case GT:
2249 case ANDAND:
2250 case OROR:
2251 case NOT:
2252 #ifdef SPECIAL_CCODES
2253 #error fix for private CCODES handling
2254 #else
2255 r = talloc();
2256 *r = *p;
2257 andorbr(r, -1, lbl = getlab());
2259 tval = cstknode(p->n_type, p->n_df, p->n_ap);
2261 ecode(buildtree(ASSIGN, ccopy(tval), bcon(1)));
2262 branch(lbl2 = getlab());
2263 plabel( lbl);
2264 ecode(buildtree(ASSIGN, ccopy(tval), bcon(0)));
2265 plabel( lbl2);
2267 *p = *tval;
2268 nfree(tval);
2270 #endif
2271 break;
2272 case CBRANCH:
2273 andorbr(p->n_left, glval(p->n_right), -1);
2274 nfree(p->n_right);
2275 p->n_op = ICON; p->n_type = VOID;
2276 break;
2277 case COMOP:
2278 cerror("COMOP error");
2280 default:
2281 if (ty == LTYPE)
2282 return;
2283 rmcops(p->n_left);
2284 if (ty == BITYPE)
2285 rmcops(p->n_right);
2290 * Return 1 if an assignment is found.
2292 static int
2293 has_se(NODE *p)
2295 if (cdope(p->n_op) & ASGFLG)
2296 return 1;
2297 if (coptype(p->n_op) == LTYPE)
2298 return 0;
2299 if (has_se(p->n_left))
2300 return 1;
2301 if (coptype(p->n_op) == BITYPE)
2302 return has_se(p->n_right);
2303 return 0;
2307 * Find and convert asgop's to separate statements.
2308 * Be careful about side effects.
2309 * assign tells whether ASSIGN should be considered giving
2310 * side effects or not.
2312 static NODE *
2313 delasgop(NODE *p)
2315 NODE *q, *r;
2316 int tval;
2318 if (p->n_op == INCR || p->n_op == DECR) {
2320 * Rewrite x++ to (x += 1) -1; and deal with it further down.
2321 * Pass2 will remove -1 if unnecessary.
2323 q = ccopy(p);
2324 tfree(p->n_left);
2325 q->n_op = (p->n_op==INCR)?PLUSEQ:MINUSEQ;
2326 p->n_op = (p->n_op==INCR)?MINUS:PLUS;
2327 p->n_left = delasgop(q);
2329 } else if ((cdope(p->n_op)&ASGOPFLG) &&
2330 p->n_op != RETURN && p->n_op != CAST) {
2331 NODE *l = p->n_left;
2332 NODE *ll = l->n_left;
2334 if (has_se(l)) {
2335 q = tempnode(0, ll->n_type, ll->n_df, ll->n_ap);
2336 tval = regno(q);
2337 r = tempnode(tval, ll->n_type, ll->n_df,ll->n_ap);
2338 l->n_left = q;
2339 /* Now the left side of node p has no side effects. */
2340 /* side effects on the right side must be obeyed */
2341 p = delasgop(p);
2343 r = buildtree(ASSIGN, r, ll);
2344 r = delasgop(r);
2345 ecode(r);
2346 } else {
2347 #if 0 /* Cannot call buildtree() here, it would invoke double add shifts */
2348 p->n_right = buildtree(UNASG p->n_op, ccopy(l),
2349 p->n_right);
2350 #else
2351 p->n_right = block(UNASG p->n_op, ccopy(l),
2352 p->n_right, p->n_type, p->n_df, p->n_ap);
2353 #endif
2354 p->n_op = ASSIGN;
2355 p->n_right = delasgop(p->n_right);
2356 p->n_right = clocal(p->n_right);
2359 } else {
2360 if (coptype(p->n_op) == LTYPE)
2361 return p;
2362 p->n_left = delasgop(p->n_left);
2363 if (coptype(p->n_op) == BITYPE)
2364 p->n_right = delasgop(p->n_right);
2366 return p;
2369 #ifndef FIELDOPS
2371 /* avoid promotion to int */
2372 #define TYPMOD(o, p, n, t) clocal(block(o, p, n, t, 0, 0))
2373 #define TYPLS(p, n, t) TYPMOD(LS, p, n, t)
2374 #define TYPRS(p, n, t) TYPMOD(RS, p, n, t)
2375 #define TYPOR(p, q, t) TYPMOD(OR, p, q, t)
2376 #define TYPAND(p, q, t) TYPMOD(AND, p, q, t)
2379 * Read an unaligned bitfield from position pointed to by p starting at
2380 * off and size fsz and return a tree of type t with resulting data.
2382 static NODE *
2383 rdualfld(NODE *p, TWORD t, TWORD ct, int off, int fsz)
2385 int t2f, inbits, tsz, ctsz;
2386 NODE *q, *r;
2388 ct = ENUNSIGN(ct);
2389 ctsz = (int)tsize(ct, 0, 0);
2391 /* traverse until first data byte */
2392 for (t2f = 0; off > ctsz; t2f++, off -= ctsz)
2394 #ifdef UNALIGNED_ACCESS
2395 /* try to squeeze it into an int */
2396 if (off + fsz > ctsz && off + fsz <= SZINT) {
2397 ct = UNSIGNED;
2398 ctsz = SZINT;
2400 #endif
2401 p = makety(p, PTR|ct, 0, 0, 0);
2402 if (off + fsz <= ctsz) {
2403 /* only one operation needed */
2404 q = buildtree(UMUL, buildtree(PLUS, p, bcon(t2f)), 0);
2405 if (!ISUNSIGNED(t)) {
2406 ct = DEUNSIGN(ct);
2407 q = makety(q, ct, 0, 0, 0);
2409 q = TYPLS(q, bcon(ctsz-fsz-off), ct);
2410 q = TYPRS(q, bcon(ctsz-fsz), ct);
2411 q = makety(q, t, 0, 0, 0);
2412 } else {
2413 q = buildtree(UMUL, buildtree(PLUS, ccopy(p), bcon(t2f)), 0);
2414 q = makety(TYPRS(q, bcon(off), ct), t, 0, 0, 0);
2415 inbits = ctsz - off;
2416 t2f++;
2418 while (fsz > inbits) {
2419 r = buildtree(UMUL,
2420 buildtree(PLUS, ccopy(p), bcon(t2f)), 0);
2421 r = makety(r, t, 0, 0, 0);
2422 r = TYPLS(r, bcon(inbits), t);
2423 q = TYPOR(q, r, t);
2424 inbits += ctsz;
2425 t2f++;
2427 /* sign/zero extend XXX - RS must sign extend */
2428 tsz = (int)tsize(t, 0, 0);
2429 if (!ISUNSIGNED(t)) {
2430 t = DEUNSIGN(t);
2431 q = makety(q, t, 0, 0, 0);
2433 q = TYPLS(q, bcon(tsz-fsz), t);
2434 q = TYPRS(q, bcon(tsz-fsz), t);
2435 tfree(p);
2438 return q;
2442 * Write val to a (unaligned) bitfield with length fsz positioned off bits
2443 * from d. Bitfield type is t, and type to use when writing is ct.
2444 * neither f nor d should have any side effects if copied.
2445 * Multiples of ct are supposed to be written without problems.
2446 * Both val and d are free'd after use.
2448 static NODE *
2449 wrualfld(NODE *val, NODE *d, TWORD t, TWORD ct, int off, int fsz)
2451 NODE *p, *q, *r, *rn, *s;
2452 int ctsz, t2f, inbits;
2454 ctsz = (int)tsize(ct, 0, 0);
2456 ct = ENUNSIGN(ct);
2457 d = makety(d, PTR|ct, 0, 0, 0);
2459 for (t2f = 0; off > ctsz; t2f++, off -= ctsz)
2462 if (off + fsz <= ctsz) {
2463 r = tempnode(0, ct, 0, 0);
2465 /* only one operation needed */
2466 d = buildtree(UMUL, buildtree(PLUS, d, bcon(t2f)), 0);
2467 p = ccopy(d);
2468 p = TYPAND(p, xbcon(~(SZMASK(fsz) << off), 0, ct), ct);
2470 val = makety(val, ct, 0, 0, 0);
2471 q = TYPAND(val, xbcon(SZMASK(fsz), 0, ct), ct);
2472 q = buildtree(ASSIGN, ccopy(r), q);
2474 q = TYPLS(q, bcon(off), ct);
2475 p = TYPOR(p, q, ct);
2476 p = makety(p, t, 0, 0, 0);
2477 rn = buildtree(ASSIGN, d, p);
2478 rn = buildtree(COMOP, rn, makety(r, t, 0, 0, 0));
2479 } else {
2480 s = makety(ccopy(val), t, 0, 0, 0);
2481 s = TYPAND(s, xbcon(SZMASK(fsz), 0, t), t);
2483 r = buildtree(UMUL, buildtree(PLUS, ccopy(d), bcon(t2f)), 0);
2484 p = ccopy(r);
2485 p = TYPAND(p, xbcon(SZMASK(off), 0, ct), ct);
2486 q = ccopy(val);
2487 q = TYPLS(q, bcon(off), t);
2488 q = makety(q, ct, 0, 0, 0);
2489 p = TYPOR(p, q, ct);
2490 rn = buildtree(ASSIGN, r, p);
2491 inbits = ctsz - off;
2492 t2f++;
2494 while (fsz > inbits+ctsz) {
2495 r = buildtree(UMUL,
2496 buildtree(PLUS, ccopy(d), bcon(t2f)), 0);
2497 q = ccopy(val);
2498 q = TYPRS(q, bcon(inbits), t);
2499 q = makety(q, ct, 0, 0, 0);
2500 rn = buildtree(COMOP, rn, buildtree(ASSIGN, r, q));
2501 t2f++;
2502 inbits += ctsz;
2505 r = buildtree(UMUL, buildtree(PLUS, d, bcon(t2f)), 0);
2506 p = ccopy(r);
2507 p = TYPAND(p, makety(xbcon(~SZMASK(fsz-inbits), 0, ct),
2508 ct, 0, 0, 0), ct);
2509 q = TYPRS(val, bcon(inbits), t);
2510 q = TYPAND(q, xbcon(SZMASK(fsz-inbits), 0, t), t);
2511 q = makety(q, ct, 0, 0, 0);
2512 p = TYPOR(p, q, ct);
2513 rn = buildtree(COMOP, rn, buildtree(ASSIGN, r, p));
2514 rn = buildtree(COMOP, rn, s);
2516 return rn;
2520 * Rewrite bitfield operations to shifts.
2522 static NODE *
2523 rmfldops(NODE *p)
2525 TWORD t, ct;
2526 NODE *q, *r, *t1, *t2, *bt, *t3, *t4;
2527 int fsz, foff;
2529 if (p->n_op == FLD) {
2530 /* Rewrite a field read operation */
2531 fsz = UPKFSZ(p->n_rval);
2532 foff = UPKFOFF(p->n_rval);
2533 q = buildtree(ADDROF, p->n_left, NIL);
2535 ct = t = p->n_type;
2536 #ifdef GCC_COMPAT
2537 if (attr_find(p->n_ap, GCC_ATYP_PACKED) &&
2538 coptype(q->n_op) != LTYPE) {
2539 t1 = tempnode(0, q->n_type, 0, 0);
2540 bt = buildtree(ASSIGN, ccopy(t1), q);
2541 q = t1;
2542 #ifndef UNALIGNED_ACCESS
2543 ct = UCHAR;
2544 #endif
2545 } else
2546 #endif
2547 bt = bcon(0);
2548 q = rdualfld(q, t, ct, foff, fsz);
2549 p->n_left = bt;
2550 p->n_right = q;
2551 p->n_op = COMOP;
2552 } else if (((cdope(p->n_op)&ASGOPFLG) || p->n_op == ASSIGN ||
2553 p->n_op == INCR || p->n_op == DECR) && p->n_left->n_op == FLD) {
2555 * Rewrite a field write operation
2556 * More difficult than a read op since we must care
2557 * about side effects.
2559 q = p->n_left;
2560 fsz = UPKFSZ(q->n_rval);
2561 foff = UPKFOFF(q->n_rval);
2562 t = q->n_left->n_type;
2563 #if TARGET_ENDIAN == TARGET_BE
2564 foff = (int)tsize(t, 0, 0) - fsz - foff;
2565 #endif
2566 bt = NULL;
2567 if (p->n_right->n_op != ICON && p->n_right->n_op != NAME) {
2568 t2 = tempnode(0, p->n_right->n_type, 0, 0);
2569 bt = buildtree(ASSIGN, ccopy(t2), p->n_right);
2570 } else
2571 t2 = p->n_right;
2573 ct = t;
2574 #ifdef GCC_COMPAT
2575 #ifndef UNALIGNED_ACCESS
2576 if (attr_find(q->n_ap, GCC_ATYP_PACKED))
2577 ct = UCHAR;
2578 #endif
2579 #endif
2580 /* t2 is what we have to write (RHS of ASSIGN) */
2581 /* bt is (eventually) something that must be written */
2584 if (q->n_left->n_op == UMUL) {
2585 /* LHS of assignment may have side effects */
2586 q = q->n_left;
2587 t1 = tempnode(0, q->n_left->n_type, 0, 0);
2588 r = buildtree(ASSIGN, ccopy(t1), q->n_left);
2590 bt = bt ? block(COMOP, bt, r, INT, 0, 0) : r;
2591 q->n_left = t1;
2593 t1 = buildtree(ADDROF, p->n_left->n_left, 0);
2595 /* t1 is lval where to write (and read) */
2597 if (p->n_op == ASSIGN) {
2598 q = wrualfld(t2, t1, t, ct, foff, fsz);
2599 if (bt)
2600 q = block(COMOP, bt, q, t, 0, 0);
2601 nfree(p->n_left);
2602 p->n_left = bcon(0);
2603 p->n_right = q;
2604 p->n_op = COMOP;
2605 } else if ((cdope(p->n_op)&ASGOPFLG)) {
2606 /* And here is the asgop-specific code */
2607 t3 = tempnode(0, t, 0, 0);
2608 q = rdualfld(ccopy(t1), t, ct, foff, fsz);
2609 q = buildtree(UNASG p->n_op, q, t2);
2610 q = buildtree(ASSIGN, ccopy(t3), q);
2611 r = wrualfld(ccopy(t3), t1, t, ct, foff, fsz);
2612 q = buildtree(COMOP, q, r);
2613 q = buildtree(COMOP, q, t3);
2615 nfree(p->n_left);
2616 p->n_left = bt ? bt : bcon(0);
2617 p->n_right = q;
2618 p->n_op = COMOP;
2619 } else {
2620 t3 = tempnode(0, t, 0, 0);
2621 t4 = tempnode(0, t, 0, 0);
2623 q = rdualfld(ccopy(t1), t, ct, foff, fsz);
2624 q = buildtree(ASSIGN, ccopy(t3), q);
2625 r = buildtree(p->n_op==INCR?PLUS:MINUS, ccopy(t3), t2);
2626 r = buildtree(ASSIGN, ccopy(t4), r);
2627 q = buildtree(COMOP, q, r);
2628 r = wrualfld(t4, t1, t, ct, foff, fsz);
2629 q = buildtree(COMOP, q, r);
2631 if (bt)
2632 q = block(COMOP, bt, q, t, 0, 0);
2633 nfree(p->n_left);
2634 p->n_left = q;
2635 p->n_right = t3;
2636 p->n_op = COMOP;
2639 if (coptype(p->n_op) != LTYPE)
2640 p->n_left = rmfldops(p->n_left);
2641 if (coptype(p->n_op) == BITYPE)
2642 p->n_right = rmfldops(p->n_right);
2643 return p;
2645 #endif
2647 void
2648 ecomp(NODE *p)
2651 #ifdef PCC_DEBUG
2652 if (edebug)
2653 fwalk(p, eprint, 0);
2654 #endif
2655 if (!reached) {
2656 warner(Wunreachable_code);
2657 reached = 1;
2659 p = optim(p);
2660 #ifndef FIELDOPS
2661 p = rmfldops(p);
2662 #endif
2663 comops(p);
2664 rmcops(p);
2665 p = delasgop(p);
2666 if (p->n_op == ICON && p->n_type == VOID)
2667 tfree(p);
2668 else
2669 ecode(p);
2673 #if defined(MULTIPASS)
2674 void
2675 p2tree(NODE *p)
2677 struct symtab *q;
2678 int ty;
2680 myp2tree(p); /* local action can be taken here */
2682 ty = coptype(p->n_op);
2684 printf("%d\t", p->n_op);
2686 if (ty == LTYPE) {
2687 printf(CONFMT, glval(p));
2688 printf("\t");
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);
2697 printf("%o\t", p->n_type);
2699 /* handle special cases */
2701 switch (p->n_op) {
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;
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
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;
2731 case XARG:
2732 case XASM:
2733 break;
2735 default:
2736 printf( "\n" );
2739 if (ty != LTYPE)
2740 p2tree(p->n_left);
2741 if (ty == BITYPE)
2742 p2tree(p->n_right);
2744 #else
2745 static char *
2746 sptostr(struct symtab *sp)
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;
2756 void
2757 p2tree(NODE *p)
2759 struct attr *oap, *ap;
2760 struct symtab *q;
2761 int ty;
2763 myp2tree(p); /* local action can be taken here */
2765 /* Fix left imaginary types */
2766 if (ISITY(BTYPE(p->n_type)))
2767 MODTYPE(p->n_type, p->n_type - (FIMAG-FLOAT));
2769 /* cleanup attributes.
2770 * copy those that are supposed to go into pass2 */
2771 oap = p->n_ap;
2772 p->n_ap = NULL;
2773 for (ap = oap; ap; ap = ap->next)
2774 if (ap->atype < ATTR_MI_MAX)
2775 p->n_ap = attr_add(p->n_ap, attr_dup(ap));
2776 /* XXX store size of attr in itself */
2778 ty = coptype(p->n_op);
2780 switch( p->n_op ){
2782 case NAME:
2783 case ICON:
2784 if ((q = p->n_sp) != NULL) {
2785 if ((q->sclass == STATIC && q->slevel > 0)
2786 #ifdef GCC_COMPAT
2787 || q->sflags == SLBLNAME
2788 #endif
2790 p->n_name = sptostr(q);
2791 } else {
2792 if ((p->n_name = q->soname) == NULL)
2793 p->n_name = addname(exname(q->sname));
2795 } else
2796 p->n_name = "";
2797 break;
2799 case STASG:
2800 case STARG:
2801 case STCALL:
2802 case USTCALL:
2803 /* STASG used for stack array init */
2804 if (p->n_op == STASG && ISARY(p->n_type)) {
2805 int size1 = (int)tsize(p->n_type, p->n_left->n_df,
2806 p->n_left->n_ap)/SZCHAR;
2807 ap->iarg(0) = (int)tsize(p->n_type, p->n_right->n_df,
2808 p->n_right->n_ap)/SZCHAR;
2809 if (size1 < ap->iarg(0))
2810 ap->iarg(0) = size1;
2811 ap->iarg(1) = talign(p->n_type,
2812 p->n_left->n_ap)/SZCHAR;
2813 break;
2815 /* set up size parameters */
2816 ap->iarg(0) = (int)((tsize(STRTY, p->n_left->n_df,
2817 p->n_left->n_ap)+SZCHAR-1)/SZCHAR);
2818 ap->iarg(1) = talign(STRTY,p->n_left->n_ap)/SZCHAR;
2819 if (ap->iarg(1) == 0)
2820 ap->iarg(1) = 1; /* At least char for packed structs */
2821 break;
2823 case XARG:
2824 case XASM:
2825 break;
2827 default:
2828 p->n_name = "";
2831 if( ty != LTYPE ) p2tree( p->n_left );
2832 if( ty == BITYPE ) p2tree( p->n_right );
2835 #endif
2838 * Change void data types into char.
2840 static void
2841 delvoid(NODE *p, void *arg)
2843 /* Convert "PTR undef" (void *) to "PTR uchar" */
2844 if (BTYPE(p->n_type) == VOID)
2845 p->n_type = (p->n_type & ~BTMASK) | UCHAR;
2846 if (BTYPE(p->n_type) == BOOL) {
2847 if (p->n_op == SCONV && p->n_type == BOOL) {
2848 /* create a jump and a set */
2849 NODE *r;
2850 int l, l2;
2852 r = tempnode(0, BOOL_TYPE, NULL, 0);
2853 cbranch(buildtree(EQ, p->n_left, bcon(0)),
2854 bcon(l = getlab()));
2855 *p = *r;
2856 ecode(buildtree(ASSIGN, tcopy(r), bcon(1)));
2857 branch(l2 = getlab());
2858 plabel(l);
2859 ecode(buildtree(ASSIGN, r, bcon(0)));
2860 plabel(l2);
2861 } else
2862 p->n_type = (p->n_type & ~BTMASK) | BOOL_TYPE;
2868 * Change calls inside calls to separate statement.
2870 static NODE *
2871 deldcall(NODE *p, int split)
2873 NODE *q, *r;
2874 int o = p->n_op;
2876 if (cdope(o) & CALLFLG) {
2877 if (split) {
2878 q = cstknode(p->n_type, p->n_df, p->n_ap);
2879 r = ccopy(q);
2880 q = block(ASSIGN, q, p, p->n_type, p->n_df, p->n_ap);
2881 ecode(q);
2882 return r;
2884 split++;
2886 if (coptype(o) == BITYPE)
2887 p->n_right = deldcall(p->n_right, split);
2888 if (coptype(o) != LTYPE)
2889 p->n_left = deldcall(p->n_left, split);
2890 return p;
2893 #ifndef WORD_ADDRESSED
2895 static NODE *
2896 pprop(NODE *p, TWORD t, struct attr *ap)
2898 int o = p->n_op;
2899 TWORD t2;
2901 #ifdef PCC_DEBUG
2902 if (p->n_op == TEMP && p->n_type != t &&
2903 !(ISPTR(p->n_type) && ISPTR(t))) {
2904 cerror("TEMP type change: %x -> %x", p->n_type, t);
2906 #endif
2908 p->n_type = t;
2909 p->n_ap = ap;
2910 switch (o) {
2911 case UMUL:
2912 t = INCREF(t);
2913 break;
2914 case ADDROF:
2915 t2 = p->n_left->n_type;
2916 if (p->n_left->n_op == TEMP) {
2917 /* Will be converted to memory in pass2 */
2918 if (!ISPTR(t2) && DECREF(t) != t2)
2919 ; /* XXX cannot convert this */
2920 else
2921 p->n_left->n_type = DECREF(t);
2922 return p;
2924 if (ISPTR(t2) && !ISPTR(DECREF(t)))
2925 break; /* not quite correct */
2926 t = DECREF(t);
2927 break;
2928 case PCONV:
2929 return p;
2931 case PLUSEQ:
2932 case PLUS:
2933 case INCR:
2934 case DECR:
2935 if (!ISPTR(p->n_left->n_type)) {
2936 if (!ISPTR(p->n_right->n_type))
2937 cerror("no * in PLUS");
2938 p->n_right = pprop(p->n_right, t, ap);
2939 } else
2940 p->n_left = pprop(p->n_left, t, ap);
2941 return p;
2943 case MINUSEQ:
2944 case MINUS:
2945 if (ISPTR(p->n_left->n_type)) {
2946 if (ISPTR(p->n_right->n_type))
2947 break; /* change both */
2948 p->n_left = pprop(p->n_left, t, ap);
2949 } else
2950 p->n_right = pprop(p->n_right, t, ap);
2951 return p;
2953 case CALL:
2954 case UCALL:
2955 case STCALL: /* may end up here if struct passed in regs */
2956 case USTCALL:
2957 return p;
2959 case STASG: /* if struct is cast to pointer */
2960 return p;
2962 case ASSIGN:
2963 break;
2965 default:
2966 if (coptype(o) == LTYPE)
2967 break;
2969 #ifdef PCC_DEBUG
2970 fwalk(p, eprint, 0);
2971 #endif
2972 cerror("pprop op error %d\n", o);
2974 if (coptype(o) == BITYPE)
2975 p->n_right = pprop(p->n_right, t, ap);
2976 if (coptype(o) != LTYPE)
2977 p->n_left = pprop(p->n_left, t, ap);
2978 return p;
2982 * Search for PCONV's that can be removed while still keeping
2983 * the type correctness.
2985 NODE *
2986 rmpconv(NODE *p)
2988 struct symtab *sp;
2989 int o = p->n_op;
2990 int ot = coptype(o);
2991 NODE *q, *l;
2993 if (ot != LTYPE)
2994 p->n_left = rmpconv(p->n_left);
2995 if (ot == BITYPE)
2996 p->n_right = rmpconv(p->n_right);
2997 if (o != PCONV)
2998 return p;
2999 l = p->n_left;
3000 if (nncon(l) || (cdope(l->n_op) & CALLFLG))
3001 ; /* Let any nonamed constant be cast to pointer directly */
3002 else if (l->n_type >= INTPTR && l->n_op == ICON) {
3003 /* named constants only if >= pointer size */
3004 /* create INTPTR type */
3005 sp = l->n_sp;
3006 l->n_sp = NULL;
3007 concast(l, INTPTR);
3008 l->n_sp = sp;
3009 } else if (!ISPTR(l->n_type))
3010 return p;
3011 q = pprop(p->n_left, p->n_type, p->n_ap);
3012 nfree(p);
3013 return q;
3015 #endif
3017 void
3018 ecode(NODE *p)
3020 /* walk the tree and write out the nodes.. */
3022 if (nerrors)
3023 return;
3025 #ifdef GCC_COMPAT
3027 NODE *q = p;
3029 if (q->n_op == UMUL)
3030 q = p->n_left;
3031 if (cdope(q->n_op)&CALLFLG &&
3032 attr_find(q->n_ap, GCC_ATYP_WARN_UNUSED_RESULT))
3033 werror("return value ignored");
3035 #endif
3036 #ifndef WORD_ADDRESSED
3037 p = rmpconv(p);
3038 #endif
3039 p = optim(p);
3040 p = delasgop(p);
3041 p = deldcall(p, 0);
3042 walkf(p, delvoid, 0);
3043 #ifdef PCC_DEBUG
3044 if (xdebug) {
3045 printf("Fulltree:\n");
3046 fwalk(p, eprint, 0);
3048 #endif
3049 p2tree(p);
3050 #if !defined(MULTIPASS)
3051 send_passt(IP_NODE, p);
3052 #endif
3056 * Send something further on to the next pass.
3058 void
3059 send_passt(int type, ...)
3061 struct interpass *ip;
3062 struct interpass_prolog *ipp;
3063 extern int crslab;
3064 va_list ap;
3065 int sz;
3067 va_start(ap, type);
3068 if (cftnsp == NULL && type != IP_ASM) {
3069 #ifdef notyet
3070 cerror("no function");
3071 #endif
3072 if (type == IP_NODE)
3073 tfree(va_arg(ap, NODE *));
3074 return;
3076 if (type == IP_PROLOG || type == IP_EPILOG)
3077 sz = sizeof(struct interpass_prolog);
3078 else
3079 sz = sizeof(struct interpass);
3081 ip = inlalloc(sz);
3082 ip->type = type;
3083 ip->lineno = lineno;
3084 switch (type) {
3085 case IP_NODE:
3086 ip->ip_node = va_arg(ap, NODE *);
3087 if (ip->ip_node->n_op == LABEL) {
3088 NODE *p = ip->ip_node;
3089 ip->ip_lbl = (int)glval(p->n_left);
3090 ip->type = IP_DEFLAB;
3091 nfree(nfree(p));
3093 break;
3094 case IP_EPILOG:
3095 if (!isinlining) {
3096 locctr(PROG, cftnsp);
3097 defloc(cftnsp);
3099 /* FALLTHROUGH */
3100 case IP_PROLOG:
3101 inftn = type == IP_PROLOG ? 1 : 0;
3102 ipp = (struct interpass_prolog *)ip;
3103 ipp->ipp_autos = va_arg(ap, int);
3104 ipp->ipp_name = va_arg(ap, char *);
3105 ipp->ipp_type = va_arg(ap, TWORD);
3106 ipp->ipp_vis = va_arg(ap, int);
3107 ip->ip_lbl = va_arg(ap, int);
3108 ipp->ip_tmpnum = va_arg(ap, int);
3109 ipp->ip_lblnum = crslab;
3110 if (type == IP_PROLOG)
3111 ipp->ip_lblnum--;
3112 break;
3113 case IP_DEFLAB:
3114 ip->ip_lbl = va_arg(ap, int);
3115 break;
3116 case IP_ASM:
3117 if (blevel == 0) { /* outside function */
3118 printf("%s", va_arg(ap, char *));
3119 va_end(ap);
3120 locctr(NOSEG, NULL);
3121 return;
3123 ip->ip_asm = va_arg(ap, char *);
3124 break;
3125 default:
3126 cerror("bad send_passt type %d", type);
3128 va_end(ap);
3129 pass1_lastchance(ip); /* target-specific info */
3130 if (isinlining)
3131 inline_addarg(ip);
3132 else
3133 pass2_compile(ip);
3136 char *
3137 copst(int op)
3139 if (op <= MAXOP)
3140 return opst[op];
3141 #define SNAM(x,y) case x: return #y;
3142 switch (op) {
3143 SNAM(QUALIFIER,QUALIFIER)
3144 SNAM(CLASS,CLASS)
3145 SNAM(RB,])
3146 SNAM(DOT,.)
3147 SNAM(ELLIPSIS,...)
3148 SNAM(LB,[)
3149 SNAM(TYPE,TYPE)
3150 SNAM(COMOP,COMOP)
3151 SNAM(QUEST,?)
3152 SNAM(COLON,:)
3153 SNAM(ANDAND,&&)
3154 SNAM(OROR,||)
3155 SNAM(NOT,!)
3156 SNAM(CAST,CAST)
3157 SNAM(PLUSEQ,+=)
3158 SNAM(MINUSEQ,-=)
3159 SNAM(MULEQ,*=)
3160 SNAM(DIVEQ,/=)
3161 SNAM(MODEQ,%=)
3162 SNAM(ANDEQ,&=)
3163 SNAM(OREQ,|=)
3164 SNAM(EREQ,^=)
3165 SNAM(LSEQ,<<=)
3166 SNAM(RSEQ,>>=)
3167 SNAM(INCR,++)
3168 SNAM(DECR,--)
3169 SNAM(STRING,STRING)
3170 SNAM(SZOF,SIZEOF)
3171 SNAM(ATTRIB,ATTRIBUTE)
3172 SNAM(TYMERGE,TYMERGE)
3173 SNAM(LABEL,LABEL)
3174 SNAM(NEWKW,NEW)
3175 SNAM(NMLIST,::)
3176 #ifdef GCC_COMPAT
3177 SNAM(XREAL,__real__)
3178 SNAM(XIMAG,__imag__)
3179 #endif
3180 default:
3181 cerror("bad copst %d", op);
3183 return 0; /* XXX gcc */
3187 cdope(int op)
3189 if (op <= MAXOP)
3190 return dope[op];
3191 switch (op) {
3192 case CLOP:
3193 case STRING:
3194 case QUALIFIER:
3195 case CLASS:
3196 case RB:
3197 case ELLIPSIS:
3198 case TYPE:
3199 return LTYPE;
3200 case DOT:
3201 case SZOF:
3202 case COMOP:
3203 case QUEST:
3204 case COLON:
3205 case LB:
3206 case TYMERGE:
3207 case NEWKW:
3208 case NMLIST:
3209 return BITYPE;
3210 case XIMAG:
3211 case XREAL:
3212 case ATTRIB:
3213 case LABEL:
3214 return UTYPE;
3215 case ANDAND:
3216 case OROR:
3217 return BITYPE|LOGFLG;
3218 case NOT:
3219 return UTYPE|LOGFLG;
3220 case CAST:
3221 return BITYPE|ASGFLG|ASGOPFLG;
3222 case PLUSEQ:
3223 return BITYPE|ASGFLG|ASGOPFLG|FLOFLG|SIMPFLG|COMMFLG;
3224 case MINUSEQ:
3225 return BITYPE|FLOFLG|SIMPFLG|ASGFLG|ASGOPFLG;
3226 case MULEQ:
3227 return BITYPE|FLOFLG|MULFLG|ASGFLG|ASGOPFLG;
3228 case OREQ:
3229 case EREQ:
3230 case ANDEQ:
3231 return BITYPE|SIMPFLG|COMMFLG|ASGFLG|ASGOPFLG;
3232 case DIVEQ:
3233 return BITYPE|FLOFLG|MULFLG|DIVFLG|ASGFLG|ASGOPFLG;
3234 case MODEQ:
3235 return BITYPE|DIVFLG|ASGFLG|ASGOPFLG;
3236 case LSEQ:
3237 case RSEQ:
3238 return BITYPE|SHFFLG|ASGFLG|ASGOPFLG;
3239 case INCR:
3240 case DECR:
3241 return BITYPE|ASGFLG;
3243 cerror("cdope missing op %d", op);
3244 return 0; /* XXX gcc */
3248 * make a fresh copy of p
3250 NODE *
3251 ccopy(NODE *p)
3253 NODE *q;
3255 q = talloc();
3256 *q = *p;
3258 switch (coptype(q->n_op)) {
3259 case BITYPE:
3260 q->n_right = ccopy(p->n_right);
3261 case UTYPE:
3262 q->n_left = ccopy(p->n_left);
3265 return(q);
3268 NODE *
3269 nlabel(int label)
3271 return block(LABEL, bcon(label), NIL, 0, 0, 0);
3275 * set PROG-seg label.
3277 void
3278 plabel(int label)
3280 reached = 1; /* Will this always be correct? */
3281 send_passt(IP_NODE, nlabel(label));
3285 * Perform integer promotion on node n.
3287 NODE *
3288 intprom(NODE *n)
3290 if ((n->n_type >= CHAR && n->n_type < INT) || n->n_type == BOOL) {
3291 if ((n->n_type == UCHAR && MAX_UCHAR > MAX_INT) ||
3292 (n->n_type == USHORT && MAX_USHORT > MAX_INT))
3293 return makety(n, UNSIGNED, 0, 0, 0);
3294 return makety(n, INT, 0, 0, 0);
3296 return n;
3300 * Return CON/VOL/0, whichever are active for the current type.
3303 cqual(TWORD t, TWORD q)
3305 while (ISARY(t))
3306 t = DECREF(t), q = DECQAL(q);
3307 if (t <= BTMASK)
3308 q <<= TSHIFT;
3309 return q & (CON|VOL);
3312 int crslab = 10;
3314 * Return a number for internal labels.
3317 getlab(void)
3319 return crslab++;