* add p cc
[mascara-docs.git] / compilers / pcc / pcc-1.0.0 / cc / ccom / trees.c
blobb029d00ea7ccbcaaea0b33d3062add8058b8f095
1 /* $Id: trees.c,v 1.272.2.1 2011/03/01 17:39:28 ragge Exp $ */
2 /*
3 * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
4 * All rights reserved.
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 void putjops(NODE *, void *);
81 static struct symtab *findmember(struct symtab *, char *);
82 int inftn; /* currently between epilog/prolog */
84 static char *tnames[] = {
85 "undef",
86 "farg",
87 "char",
88 "unsigned char",
89 "short",
90 "unsigned short",
91 "int",
92 "unsigned int",
93 "long",
94 "unsigned long",
95 "long long",
96 "unsigned long long",
97 "float",
98 "double",
99 "long double",
100 "strty",
101 "unionty",
102 "enumty",
103 "moety",
104 "void",
105 "signed", /* pass1 */
106 "bool", /* pass1 */
107 "fimag", /* pass1 */
108 "dimag", /* pass1 */
109 "limag", /* pass1 */
110 "fcomplex", /* pass1 */
111 "dcomplex", /* pass1 */
112 "lcomplex", /* pass1 */
113 "enumty", /* pass1 */
114 "?", "?"
117 /* some special actions, used in finding the type of nodes */
118 # define NCVT 01
119 # define PUN 02
120 # define TYPL 04
121 # define TYPR 010
122 # define TYMATCH 040
123 # define LVAL 0100
124 # define CVTO 0200
125 # define CVTL 0400
126 # define CVTR 01000
127 # define PTMATCH 02000
128 # define OTHER 04000
129 # define NCVTR 010000
131 /* node conventions:
133 NAME: rval>0 is stab index for external
134 rval<0 is -inlabel number
135 lval is offset in bits
136 ICON: lval has the value
137 rval has the STAB index, or - label number,
138 if a name whose address is in the constant
139 rval = NONAME means no name
140 REG: rval is reg. identification cookie
144 int bdebug = 0;
145 extern int negrel[];
147 NODE *
148 buildtree(int o, NODE *l, NODE *r)
150 NODE *p, *q;
151 int actions;
152 int opty;
153 struct symtab *sp = NULL; /* XXX gcc */
154 NODE *lr, *ll;
156 #ifdef PCC_DEBUG
157 if (bdebug) {
158 printf("buildtree(%s, %p, %p)\n", copst(o), l, r);
159 if (l) fwalk(l, eprint, 0);
160 if (r) fwalk(r, eprint, 0);
162 #endif
163 opty = coptype(o);
165 /* check for constants */
167 if (o == ANDAND || o == OROR || o == NOT) {
168 if (l->n_op == FCON) {
169 p = bcon(!FLOAT_ISZERO(l->n_dcon));
170 nfree(l);
171 l = p;
173 if (o != NOT && r->n_op == FCON) {
174 p = bcon(!FLOAT_ISZERO(r->n_dcon));
175 nfree(r);
176 r = p;
180 if( opty == UTYPE && l->n_op == ICON ){
182 switch( o ){
184 case NOT:
185 case UMINUS:
186 case COMPL:
187 if( conval( l, o, l ) ) return(l);
188 break;
190 } else if (o == NOT && l->n_op == FCON) {
191 l = clocal(block(SCONV, l, NIL, INT, 0, MKAP(INT)));
192 } else if( o == UMINUS && l->n_op == FCON ){
193 l->n_dcon = FLOAT_NEG(l->n_dcon);
194 return(l);
196 } else if( o==QUEST && l->n_op==ICON ) {
197 CONSZ c = l->n_lval;
198 nfree(l);
199 if (c) {
200 walkf(r->n_right, putjops, 0);
201 tfree(r->n_right);
202 l = r->n_left;
203 } else {
204 walkf(r->n_left, putjops, 0);
205 tfree(r->n_left);
206 l = r->n_right;
208 nfree(r);
209 return(l);
210 } else if( opty == BITYPE && l->n_op == ICON && r->n_op == ICON ){
212 switch( o ){
214 case PLUS:
215 case MINUS:
216 case MUL:
217 case DIV:
218 case MOD:
220 * Do type propagation for simple types here.
221 * The constant value is correct anyway.
222 * Maybe this op shortcut should be removed?
224 if (l->n_sp == NULL && r->n_sp == NULL &&
225 l->n_type < BTMASK && r->n_type < BTMASK) {
226 if (l->n_type > r->n_type)
227 r->n_type = l->n_type;
228 else
229 l->n_type = r->n_type;
231 /* FALLTHROUGH */
232 case ULT:
233 case UGT:
234 case ULE:
235 case UGE:
236 case LT:
237 case GT:
238 case LE:
239 case GE:
240 case EQ:
241 case NE:
242 case ANDAND:
243 case OROR:
244 case AND:
245 case OR:
246 case ER:
247 case LS:
248 case RS:
249 if (!ISPTR(l->n_type) && !ISPTR(r->n_type)) {
250 if( conval( l, o, r ) ) {
251 nfree(r);
252 return(l);
255 break;
257 } else if (opty == BITYPE && (l->n_op == FCON || l->n_op == ICON) &&
258 (r->n_op == FCON || r->n_op == ICON) && (o == PLUS || o == MINUS ||
259 o == MUL || o == DIV || (o >= EQ && o <= GT) )) {
260 TWORD t;
261 #ifndef CC_DIV_0
262 if (o == DIV &&
263 ((r->n_op == ICON && r->n_lval == 0) ||
264 (r->n_op == FCON && r->n_dcon == 0.0)))
265 goto runtime; /* HW dependent */
266 #endif
267 if (l->n_op == ICON)
268 l->n_dcon = FLOAT_CAST(l->n_lval, l->n_type);
269 if (r->n_op == ICON)
270 r->n_dcon = FLOAT_CAST(r->n_lval, r->n_type);
271 switch(o){
272 case PLUS:
273 case MINUS:
274 case MUL:
275 case DIV:
276 switch (o) {
277 case PLUS:
278 l->n_dcon = FLOAT_PLUS(l->n_dcon, r->n_dcon);
279 break;
280 case MINUS:
281 l->n_dcon = FLOAT_MINUS(l->n_dcon, r->n_dcon);
282 break;
283 case MUL:
284 l->n_dcon = FLOAT_MUL(l->n_dcon, r->n_dcon);
285 break;
286 case DIV:
287 l->n_dcon = FLOAT_DIV(l->n_dcon, r->n_dcon);
288 break;
290 t = (l->n_type > r->n_type ? l->n_type : r->n_type);
291 l->n_op = FCON;
292 l->n_type = t;
293 l->n_ap = MKAP(t);
294 nfree(r);
295 return(l);
296 case EQ:
297 case NE:
298 case LE:
299 case LT:
300 case GE:
301 case GT:
302 switch (o) {
303 case EQ:
304 l->n_lval = FLOAT_EQ(l->n_dcon, r->n_dcon);
305 break;
306 case NE:
307 l->n_lval = FLOAT_NE(l->n_dcon, r->n_dcon);
308 break;
309 case LE:
310 l->n_lval = FLOAT_LE(l->n_dcon, r->n_dcon);
311 break;
312 case LT:
313 l->n_lval = FLOAT_LT(l->n_dcon, r->n_dcon);
314 break;
315 case GE:
316 l->n_lval = FLOAT_GE(l->n_dcon, r->n_dcon);
317 break;
318 case GT:
319 l->n_lval = FLOAT_GT(l->n_dcon, r->n_dcon);
320 break;
322 nfree(r);
323 r = bcon(l->n_lval);
324 nfree(l);
325 return r;
328 #ifndef CC_DIV_0
329 runtime:
330 #endif
331 /* its real; we must make a new node */
333 p = block(o, l, r, INT, 0, MKAP(INT));
335 actions = opact(p);
337 if (actions & LVAL) { /* check left descendent */
338 if (notlval(p->n_left)) {
339 uerror("lvalue required");
340 nfree(p);
341 return l;
342 #ifdef notyet
343 } else {
344 if ((l->n_type > BTMASK && ISCON(l->n_qual)) ||
345 (l->n_type <= BTMASK && ISCON(l->n_qual << TSHIFT)))
346 if (blevel > 0)
347 uerror("lvalue is declared const");
348 #endif
352 if( actions & NCVTR ){
353 p->n_left = pconvert( p->n_left );
355 else if( !(actions & NCVT ) ){
356 switch( opty ){
358 case BITYPE:
359 p->n_right = pconvert( p->n_right );
360 case UTYPE:
361 p->n_left = pconvert( p->n_left );
366 if ((actions&PUN) && (o!=CAST))
367 chkpun(p);
369 if( actions & (TYPL|TYPR) ){
371 q = (actions&TYPL) ? p->n_left : p->n_right;
373 p->n_type = q->n_type;
374 p->n_qual = q->n_qual;
375 p->n_df = q->n_df;
376 p->n_ap = q->n_ap;
379 if( actions & CVTL ) p = convert( p, CVTL );
380 if( actions & CVTR ) p = convert( p, CVTR );
381 if( actions & TYMATCH ) p = tymatch(p);
382 if( actions & PTMATCH ) p = ptmatch(p);
384 if( actions & OTHER ){
385 struct symtab *sp1;
387 l = p->n_left;
388 r = p->n_right;
390 switch(o){
392 case NAME:
393 cerror("buildtree NAME");
395 case STREF:
396 /* p->x turned into *(p+offset) */
397 /* rhs must be a name; check correctness */
399 /* Find member symbol struct */
400 if (l->n_type != PTR+STRTY && l->n_type != PTR+UNIONTY){
401 uerror("struct or union required");
402 break;
405 if ((sp1 = strmemb(l->n_ap)) == NULL) {
406 uerror("undefined struct or union");
407 break;
410 if ((sp = findmember(sp1, r->n_name)) == NULL) {
411 uerror("member '%s' not declared", r->n_name);
412 break;
415 r->n_sp = sp;
416 p = stref(p);
417 break;
419 case UMUL:
420 if (l->n_op == ADDROF) {
421 nfree(p);
422 p = l->n_left;
423 nfree(l);
425 if( !ISPTR(l->n_type))uerror("illegal indirection");
426 p->n_type = DECREF(l->n_type);
427 p->n_qual = DECREF(l->n_qual);
428 p->n_df = l->n_df;
429 p->n_ap = l->n_ap;
430 break;
432 case ADDROF:
433 switch( l->n_op ){
435 case UMUL:
436 nfree(p);
437 p = l->n_left;
438 nfree(l);
439 case TEMP:
440 case NAME:
441 p->n_type = INCREF(l->n_type);
442 p->n_qual = INCQAL(l->n_qual);
443 p->n_df = l->n_df;
444 p->n_ap = l->n_ap;
445 break;
447 case COMOP:
448 nfree(p);
449 lr = buildtree(ADDROF, l->n_right, NIL);
450 p = buildtree( COMOP, l->n_left, lr );
451 nfree(l);
452 break;
454 case QUEST:
455 lr = buildtree( ADDROF, l->n_right->n_right, NIL );
456 ll = buildtree( ADDROF, l->n_right->n_left, NIL );
457 nfree(p); nfree(l->n_right);
458 p = buildtree( QUEST, l->n_left, buildtree( COLON, ll, lr ) );
459 nfree(l);
460 break;
462 default:
463 uerror("unacceptable operand of &: %d", l->n_op );
464 break;
466 break;
468 case LS:
469 case RS: /* must make type size at least int... */
470 if (p->n_type == CHAR || p->n_type == SHORT) {
471 p->n_left = makety(l, INT, 0, 0, MKAP(INT));
472 } else if (p->n_type == UCHAR || p->n_type == USHORT) {
473 p->n_left = makety(l, UNSIGNED, 0, 0,
474 MKAP(UNSIGNED));
476 l = p->n_left;
477 p->n_type = l->n_type;
478 p->n_qual = l->n_qual;
479 p->n_df = l->n_df;
480 p->n_ap = l->n_ap;
482 /* FALLTHROUGH */
483 case LSEQ:
484 case RSEQ: /* ...but not for assigned types */
485 if(tsize(r->n_type, r->n_df, r->n_ap) > SZINT)
486 p->n_right = makety(r, INT, 0, 0, MKAP(INT));
487 break;
489 case RETURN:
490 case ASSIGN:
491 case CAST:
492 /* structure assignment */
493 /* take the addresses of the two sides; then make an
494 * operator using STASG and
495 * the addresses of left and right */
497 if (strmemb(l->n_ap) != strmemb(r->n_ap))
498 uerror("assignment of different structures");
500 r = buildtree(ADDROF, r, NIL);
502 l = block(STASG, l, r, r->n_type, r->n_df, r->n_ap);
503 l = clocal(l);
505 if( o == RETURN ){
506 nfree(p);
507 p = l;
508 break;
511 p->n_op = UMUL;
512 p->n_left = l;
513 p->n_right = NIL;
514 break;
516 case QUEST: /* fixup types of : */
517 if (r->n_left->n_type != p->n_type)
518 r->n_left = makety(r->n_left, p->n_type,
519 p->n_qual, p->n_df, p->n_ap);
520 if (r->n_right->n_type != p->n_type)
521 r->n_right = makety(r->n_right, p->n_type,
522 p->n_qual, p->n_df, p->n_ap);
523 break;
525 case COLON:
526 /* structure colon */
528 if (strmemb(l->n_ap) != strmemb(r->n_ap))
529 uerror( "type clash in conditional" );
530 break;
532 case CALL:
533 p->n_right = r = strargs(p->n_right);
534 p = funcode(p);
535 /* FALLTHROUGH */
536 case UCALL:
537 if (!ISPTR(l->n_type))
538 uerror("illegal function");
539 p->n_type = DECREF(l->n_type);
540 if (!ISFTN(p->n_type))
541 uerror("illegal function");
542 p->n_type = DECREF(p->n_type);
543 p->n_df = l->n_df+1; /* add one for prototypes */
544 p->n_ap = l->n_ap;
545 if (p->n_type == STRTY || p->n_type == UNIONTY) {
546 /* function returning structure */
547 /* make function really return ptr to str., with * */
549 p->n_op += STCALL-CALL;
550 p->n_type = INCREF(p->n_type);
551 p = clocal(p); /* before recursing */
552 p = buildtree(UMUL, p, NIL);
555 break;
557 default:
558 cerror( "other code %d", o );
564 * Allow (void)0 casts.
565 * XXX - anything on the right side must be possible to cast.
566 * XXX - remove void types further on.
568 if (p->n_op == CAST && p->n_type == VOID &&
569 p->n_right->n_op == ICON)
570 p->n_right->n_type = VOID;
572 if (actions & CVTO)
573 p = oconvert(p);
574 p = clocal(p);
576 #ifdef PCC_DEBUG
577 if (bdebug) {
578 printf("End of buildtree:\n");
579 fwalk(p, eprint, 0);
581 #endif
583 return(p);
587 /* Find a member in a struct or union. May be an unnamed member */
588 static struct symtab *
589 findmember(struct symtab *sp, char *s)
591 struct symtab *sp2, *sp3;
593 for (; sp != NULL; sp = sp->snext) {
594 if (sp->sname[0] == '*') {
595 /* unnamed member, recurse down */
596 if ((sp2 = findmember(strmemb(sp->sap), s))) {
597 sp3 = tmpalloc(sizeof (struct symtab));
598 *sp3 = *sp2;
599 sp3->soffset += sp->soffset;
600 return sp3;
602 } else if (sp->sname == s)
603 return sp;
605 return NULL;
610 * Check if there will be a lost label destination inside of a ?:
611 * It cannot be reached so just print it out.
613 void
614 putjops(NODE *p, void *arg)
616 if (p->n_op == COMOP && p->n_left->n_op == GOTO)
617 plabel(p->n_left->n_left->n_lval+1);
621 * Build a name node based on a symtab entry.
622 * broken out from buildtree().
624 NODE *
625 nametree(struct symtab *sp)
627 NODE *p;
629 p = block(NAME, NIL, NIL, sp->stype, sp->sdf, sp->sap);
630 p->n_qual = sp->squal;
631 p->n_sp = sp;
633 #ifndef NO_C_BUILTINS
634 if (sp->sname[0] == '_' && strncmp(sp->sname, "__builtin_", 10) == 0)
635 return p; /* do not touch builtins here */
637 #endif
639 if (sp->sflags & STNODE) {
640 /* Generated for optimizer */
641 p->n_op = TEMP;
642 p->n_rval = sp->soffset;
645 #ifdef GCC_COMPAT
646 /* Get a label name */
647 if (sp->sflags == SLBLNAME) {
648 p->n_type = VOID;
649 p->n_ap = MKAP(VOID);
651 #endif
652 if (sp->stype == UNDEF) {
653 uerror("%s undefined", sp->sname);
654 /* make p look reasonable */
655 p->n_type = INT;
656 p->n_ap = MKAP(INT);
657 p->n_df = NULL;
658 defid(p, SNULL);
660 if (sp->sclass == MOE) {
661 p->n_op = ICON;
662 p->n_lval = sp->soffset;
663 p->n_df = NULL;
664 p->n_sp = NULL;
666 return clocal(p);
670 * Cast a node to another type by inserting a cast.
671 * Just a nicer interface to buildtree.
672 * Returns the new tree.
674 NODE *
675 cast(NODE *p, TWORD t, TWORD u)
677 NODE *q;
679 q = block(NAME, NIL, NIL, t, 0, MKAP(BTYPE(t)));
680 q->n_qual = u;
681 q = buildtree(CAST, q, p);
682 p = q->n_right;
683 nfree(q->n_left);
684 nfree(q);
685 return p;
689 * Cast and complain if necessary by not inserining a cast.
691 NODE *
692 ccast(NODE *p, TWORD t, TWORD u, union dimfun *df, struct attr *ap)
694 NODE *q;
696 /* let buildtree do typechecking (and casting) */
697 q = block(NAME, NIL, NIL, t, df, ap);
698 p = buildtree(ASSIGN, q, p);
699 nfree(p->n_left);
700 q = optim(p->n_right);
701 nfree(p);
702 return q;
706 * Do a conditional branch.
708 void
709 cbranch(NODE *p, NODE *q)
711 p = buildtree(CBRANCH, p, q);
712 if (p->n_left->n_op == ICON) {
713 if (p->n_left->n_lval != 0) {
714 branch(q->n_lval); /* branch always */
715 reached = 0;
717 tfree(p);
718 tfree(q);
719 return;
721 ecomp(p);
724 NODE *
725 strargs( p ) register NODE *p; { /* rewrite structure flavored arguments */
727 if( p->n_op == CM ){
728 p->n_left = strargs( p->n_left );
729 p->n_right = strargs( p->n_right );
730 return( p );
733 if( p->n_type == STRTY || p->n_type == UNIONTY ){
734 p = block(STARG, p, NIL, p->n_type, p->n_df, p->n_ap);
735 p->n_left = buildtree( ADDROF, p->n_left, NIL );
736 p = clocal(p);
738 return( p );
742 * apply the op o to the lval part of p; if binary, rhs is val
745 conval(NODE *p, int o, NODE *q)
747 TWORD tl = p->n_type, tr = q->n_type, td;
748 int i, u;
749 CONSZ val;
750 U_CONSZ v1, v2;
752 val = q->n_lval;
754 /* make both sides same type */
755 if (tl < BTMASK && tr < BTMASK) {
756 td = tl > tr ? tl : tr;
757 if (td < INT)
758 td = INT;
759 u = ISUNSIGNED(td);
760 if (tl != td)
761 p = makety(p, td, 0, 0, MKAP(td));
762 if (tr != td)
763 q = makety(q, td, 0, 0, MKAP(td));
764 } else
765 u = ISUNSIGNED(tl) || ISUNSIGNED(tr);
766 if( u && (o==LE||o==LT||o==GE||o==GT)) o += (UGE-GE);
768 if (p->n_sp != NULL && q->n_sp != NULL)
769 return(0);
770 if (q->n_sp != NULL && o != PLUS)
771 return(0);
772 if (p->n_sp != NULL && o != PLUS && o != MINUS)
773 return(0);
775 v1 = p->n_lval;
776 v2 = q->n_lval;
777 switch( o ){
779 case PLUS:
780 p->n_lval += val;
781 if (p->n_sp == NULL) {
782 p->n_right = q->n_right;
783 p->n_type = q->n_type;
785 break;
786 case MINUS:
787 p->n_lval -= val;
788 break;
789 case MUL:
790 p->n_lval *= val;
791 break;
792 case DIV:
793 if (val == 0)
794 uerror("division by 0");
795 else {
796 if (u) {
797 v1 /= v2;
798 p->n_lval = v1;
799 } else
800 p->n_lval /= val;
802 break;
803 case MOD:
804 if (val == 0)
805 uerror("division by 0");
806 else {
807 if (u) {
808 v1 %= v2;
809 p->n_lval = v1;
810 } else
811 p->n_lval %= val;
813 break;
814 case AND:
815 p->n_lval &= val;
816 break;
817 case OR:
818 p->n_lval |= val;
819 break;
820 case ER:
821 p->n_lval ^= val;
822 break;
823 case LS:
824 i = (int)val;
825 p->n_lval = p->n_lval << i;
826 break;
827 case RS:
828 i = (int)val;
829 if (u) {
830 v1 = v1 >> i;
831 p->n_lval = v1;
832 } else
833 p->n_lval = p->n_lval >> i;
834 break;
836 case UMINUS:
837 p->n_lval = - p->n_lval;
838 break;
839 case COMPL:
840 p->n_lval = ~p->n_lval;
841 break;
842 case NOT:
843 p->n_lval = !p->n_lval;
844 break;
845 case LT:
846 p->n_lval = p->n_lval < val;
847 break;
848 case LE:
849 p->n_lval = p->n_lval <= val;
850 break;
851 case GT:
852 p->n_lval = p->n_lval > val;
853 break;
854 case GE:
855 p->n_lval = p->n_lval >= val;
856 break;
857 case ULT:
858 p->n_lval = v1 < v2;
859 break;
860 case ULE:
861 p->n_lval = v1 <= v2;
862 break;
863 case UGT:
864 p->n_lval = v1 > v2;
865 break;
866 case UGE:
867 p->n_lval = v1 >= v2;
868 break;
869 case EQ:
870 p->n_lval = p->n_lval == val;
871 break;
872 case NE:
873 p->n_lval = p->n_lval != val;
874 break;
875 case ANDAND:
876 p->n_lval = p->n_lval && val;
877 break;
878 case OROR:
879 p->n_lval = p->n_lval || val;
880 break;
881 default:
882 return(0);
884 /* Do the best in making everything type correct after calc */
885 if (p->n_sp == NULL && q->n_sp == NULL)
886 p->n_lval = valcast(p->n_lval, p->n_type);
887 return(1);
891 * Ensure that v matches the type t; sign- or zero-extended
892 * as suitable to CONSZ.
893 * Only to be used for integer types.
895 CONSZ
896 valcast(CONSZ v, TWORD t)
898 CONSZ r;
900 if (t < CHAR || t > ULONGLONG)
901 return v; /* cannot cast */
903 if (t >= LONGLONG)
904 return v; /* already largest */
906 #define M(x) ((((1ULL << ((x)-1)) - 1) << 1) + 1)
907 #define NOTM(x) (~M(x))
908 #define SBIT(x) (1ULL << ((x)-1))
910 r = v & M(btattr[t].atypsz);
911 if (!ISUNSIGNED(t) && (SBIT(btattr[t].atypsz) & r))
912 r = r | NOTM(btattr[t].atypsz);
913 return r;
917 * Checks p for the existance of a pun. This is called when the op of p
918 * is ASSIGN, RETURN, CAST, COLON, or relational.
919 * One case is when enumerations are used: this applies only to lint.
920 * In the other case, one operand is a pointer, the other integer type
921 * we check that this integer is in fact a constant zero...
922 * in the case of ASSIGN, any assignment of pointer to integer is illegal
923 * this falls out, because the LHS is never 0.
924 * XXX - check for COMOPs in assignment RHS?
926 void
927 chkpun(NODE *p)
929 union dimfun *d1, *d2;
930 NODE *q;
931 int t1, t2;
933 t1 = p->n_left->n_type;
934 t2 = p->n_right->n_type;
936 switch (p->n_op) {
937 case RETURN:
938 /* return of void allowed but nothing else */
939 if (t1 == VOID && t2 == VOID)
940 return;
941 if (t1 == VOID) {
942 werror("returning value from void function");
943 return;
945 if (t2 == VOID) {
946 uerror("using void value");
947 return;
949 case COLON:
950 if (t1 == VOID && t2 == VOID)
951 return;
952 break;
953 default:
954 if ((t1 == VOID && t2 != VOID) || (t1 != VOID && t2 == VOID)) {
955 uerror("value of void expression used");
956 return;
958 break;
961 /* allow void pointer assignments in any direction */
962 if (BTYPE(t1) == VOID && (t2 & TMASK))
963 return;
964 if (BTYPE(t2) == VOID && (t1 & TMASK))
965 return;
967 /* boolean have special syntax */
968 if (t1 == BOOL) {
969 if (!ISARY(t2)) /* Anything scalar */
970 return;
973 if (ISPTR(t1) || ISARY(t1))
974 q = p->n_right;
975 else
976 q = p->n_left;
978 if (!ISPTR(q->n_type) && !ISARY(q->n_type)) {
979 if (q->n_op != ICON || q->n_lval != 0)
980 werror("illegal combination of pointer and integer");
981 } else {
982 if (t1 == t2) {
983 if (ISSOU(BTYPE(t1)) &&
984 !suemeq(p->n_left->n_ap, p->n_right->n_ap))
985 werror("illegal structure pointer combination");
986 return;
988 d1 = p->n_left->n_df;
989 d2 = p->n_right->n_df;
990 for (;;) {
991 if (ISARY(t1) || ISPTR(t1)) {
992 if (!ISARY(t2) && !ISPTR(t2))
993 break;
994 if (ISARY(t1) && ISARY(t2) && d1->ddim != d2->ddim) {
995 werror("illegal array size combination");
996 return;
998 if (ISARY(t1))
999 ++d1;
1000 if (ISARY(t2))
1001 ++d2;
1002 } else if (ISFTN(t1)) {
1003 if (chkftn(d1->dfun, d2->dfun)) {
1004 werror("illegal function "
1005 "pointer combination");
1006 return;
1008 ++d1;
1009 ++d2;
1010 } else
1011 break;
1012 t1 = DECREF(t1);
1013 t2 = DECREF(t2);
1015 if (DEUNSIGN(t1) != DEUNSIGN(t2))
1016 warner(Wpointer_sign, NULL);
1020 NODE *
1021 stref(NODE *p)
1023 NODE *r;
1024 struct attr *ap;
1025 union dimfun *d;
1026 TWORD t, q;
1027 int dsc;
1028 OFFSZ off;
1029 struct symtab *s;
1031 /* make p->x */
1032 /* this is also used to reference automatic variables */
1034 s = p->n_right->n_sp;
1035 nfree(p->n_right);
1036 r = p->n_left;
1037 nfree(p);
1038 p = pconvert(r);
1040 /* make p look like ptr to x */
1042 if (!ISPTR(p->n_type))
1043 p->n_type = PTR+UNIONTY;
1045 t = INCREF(s->stype);
1046 q = INCQAL(s->squal);
1047 d = s->sdf;
1048 ap = s->sap;
1050 p = makety(p, t, q, d, ap);
1052 /* compute the offset to be added */
1054 off = s->soffset;
1055 dsc = s->sclass;
1057 #ifndef CAN_UNALIGN
1059 * If its a packed struct, and the target cannot do unaligned
1060 * accesses, then split it up in two bitfield operations.
1061 * LHS and RHS accesses are different, so must delay
1062 * it until we know. Do the bitfield construct here though.
1064 if ((dsc & FIELD) == 0 && (off % talign(s->stype, s->sap))) {
1065 #if 0
1066 int sz = tsize(s->stype, s->sdf, s->sap);
1067 int al = talign(s->stype, s->sap);
1068 int sz1 = al - (off % al);
1069 #endif
1071 #endif
1073 #if 0
1074 if (dsc & FIELD) { /* make fields look like ints */
1075 off = (off/ALINT)*ALINT;
1076 ap = MKAP(INT);
1078 #endif
1079 if (off != 0) {
1080 p = block(PLUS, p, offcon(off, t, d, ap), t, d, ap);
1081 p->n_qual = q;
1082 p = optim(p);
1085 p = buildtree(UMUL, p, NIL);
1087 /* if field, build field info */
1089 if (dsc & FIELD) {
1090 p = block(FLD, p, NIL, s->stype, 0, s->sap);
1091 p->n_qual = q;
1092 p->n_rval = PKFIELD(dsc&FLDSIZ, s->soffset%talign(s->stype, ap));
1095 p = clocal(p);
1096 return p;
1100 notlval(p) register NODE *p; {
1102 /* return 0 if p an lvalue, 1 otherwise */
1104 again:
1106 switch( p->n_op ){
1108 case FLD:
1109 p = p->n_left;
1110 goto again;
1112 case NAME:
1113 case OREG:
1114 case UMUL:
1115 if( ISARY(p->n_type) || ISFTN(p->n_type) ) return(1);
1116 case TEMP:
1117 case REG:
1118 return(0);
1120 default:
1121 return(1);
1126 /* make a constant node with value i */
1127 NODE *
1128 bcon(int i)
1130 return xbcon(i, NULL, INT);
1133 NODE *
1134 xbcon(CONSZ val, struct symtab *sp, TWORD type)
1136 NODE *p;
1138 p = block(ICON, NIL, NIL, type, 0, MKAP(type));
1139 p->n_lval = val;
1140 p->n_sp = sp;
1141 return clocal(p);
1144 NODE *
1145 bpsize(NODE *p)
1147 int isdyn(struct symtab *sp);
1148 struct attr *ap;
1149 struct symtab s;
1150 NODE *q, *r;
1151 TWORD t;
1153 s.stype = DECREF(p->n_type);
1154 s.sdf = p->n_df;
1155 if (isdyn(&s)) {
1156 q = bcon(1);
1157 for (t = s.stype; t > BTMASK; t = DECREF(t)) {
1158 if (ISPTR(t))
1159 return buildtree(MUL, q, bcon(SZPOINT(t)));
1160 if (ISARY(t)) {
1161 if (s.sdf->ddim < 0)
1162 r = tempnode(-s.sdf->ddim,
1163 INT, 0, MKAP(INT));
1164 else
1165 r = bcon(s.sdf->ddim/SZCHAR);
1166 q = buildtree(MUL, q, r);
1167 s.sdf++;
1170 ap = attr_find(p->n_ap, ATTR_BASETYP);
1171 p = buildtree(MUL, q, bcon(ap->atypsz/SZCHAR));
1172 } else
1173 p = (offcon(psize(p), p->n_type, p->n_df, p->n_ap));
1174 return p;
1178 * p is a node of type pointer; psize returns the
1179 * size of the thing pointed to
1181 OFFSZ
1182 psize(NODE *p)
1185 if (!ISPTR(p->n_type)) {
1186 uerror("pointer required");
1187 return(SZINT);
1189 /* note: no pointers to fields */
1190 return(tsize(DECREF(p->n_type), p->n_df, p->n_ap));
1194 * convert an operand of p
1195 * f is either CVTL or CVTR
1196 * operand has type int, and is converted by the size of the other side
1197 * convert is called when an integer is to be added to a pointer, for
1198 * example in arrays or structures.
1200 NODE *
1201 convert(NODE *p, int f)
1203 union dimfun *df;
1204 TWORD ty, ty2;
1205 NODE *q, *r, *s, *rv;
1207 if (f == CVTL) {
1208 q = p->n_left;
1209 s = p->n_right;
1210 } else {
1211 q = p->n_right;
1212 s = p->n_left;
1214 ty2 = ty = DECREF(s->n_type);
1215 while (ISARY(ty))
1216 ty = DECREF(ty);
1218 r = offcon(tsize(ty, s->n_df, s->n_ap), s->n_type, s->n_df, s->n_ap);
1219 ty = ty2;
1220 rv = bcon(1);
1221 df = s->n_df;
1222 while (ISARY(ty)) {
1223 rv = buildtree(MUL, rv, df->ddim >= 0 ? bcon(df->ddim) :
1224 tempnode(-df->ddim, INT, 0, MKAP(INT)));
1225 df++;
1226 ty = DECREF(ty);
1228 rv = clocal(block(PMCONV, rv, r, INT, 0, MKAP(INT)));
1229 rv = optim(rv);
1231 r = block(PMCONV, q, rv, INT, 0, MKAP(INT));
1232 r = clocal(r);
1234 * Indexing is only allowed with integer arguments, so insert
1235 * SCONV here if arg is not an integer.
1236 * XXX - complain?
1238 if (r->n_type != INTPTR)
1239 r = clocal(block(SCONV, r, NIL, INTPTR, 0, MKAP(INTPTR)));
1240 if (f == CVTL)
1241 p->n_left = r;
1242 else
1243 p->n_right = r;
1244 return(p);
1247 NODE *
1248 pconvert( p ) register NODE *p; {
1250 /* if p should be changed into a pointer, do so */
1252 if( ISARY( p->n_type) ){
1253 p->n_type = DECREF( p->n_type );
1254 ++p->n_df;
1255 return( buildtree( ADDROF, p, NIL ) );
1257 if( ISFTN( p->n_type) )
1258 return( buildtree( ADDROF, p, NIL ) );
1260 return( p );
1263 NODE *
1264 oconvert(p) register NODE *p; {
1265 /* convert the result itself: used for pointer and unsigned */
1267 switch(p->n_op) {
1269 case LE:
1270 case LT:
1271 case GE:
1272 case GT:
1273 if(ISUNSIGNED(p->n_left->n_type) ||
1274 ISUNSIGNED(p->n_right->n_type) ||
1275 ISPTR(p->n_left->n_type) ||
1276 ISPTR(p->n_right->n_type))
1277 p->n_op += (ULE-LE);
1278 /* FALLTHROUGH */
1279 case EQ:
1280 case NE:
1281 return( p );
1283 case MINUS:
1284 p->n_type = INTPTR;
1285 p->n_ap = MKAP(INTPTR);
1286 return( clocal( block( PVCONV,
1287 p, bpsize(p->n_left), INT, 0, MKAP(INT))));
1290 cerror( "illegal oconvert: %d", p->n_op );
1292 return(p);
1296 * makes the operands of p agree; they are
1297 * either pointers or integers, by this time
1298 * with MINUS, the sizes must be the same
1299 * with COLON, the types must be the same
1301 NODE *
1302 ptmatch(NODE *p)
1304 struct attr *ap, *ap2;
1305 union dimfun *d, *d2;
1306 TWORD t1, t2, t, q1, q2, q;
1307 int o;
1309 o = p->n_op;
1310 t = t1 = p->n_left->n_type;
1311 q = q1 = p->n_left->n_qual;
1312 t2 = p->n_right->n_type;
1313 q2 = p->n_right->n_qual;
1314 d = p->n_left->n_df;
1315 d2 = p->n_right->n_df;
1316 ap = p->n_left->n_ap;
1317 ap2 = p->n_right->n_ap;
1319 switch( o ){
1321 case ASSIGN:
1322 case RETURN:
1323 case CAST:
1324 { break; }
1326 case MINUS: {
1327 int isdyn(struct symtab *sp);
1328 struct symtab s1, s2;
1330 s1.stype = DECREF(t);
1331 s1.sdf = d;
1332 s2.stype = DECREF(t2);
1333 s2.sdf = d2;
1334 if (isdyn(&s1) || isdyn(&s2))
1335 ; /* We don't know */
1336 else if (psize(p->n_left) != psize(p->n_right))
1337 uerror("illegal pointer subtraction");
1338 break;
1341 case COLON:
1342 if (t1 != t2) {
1344 * Check for void pointer types. They are allowed
1345 * to cast to/from any pointers.
1347 if (ISPTR(t1) && ISPTR(t2) &&
1348 (BTYPE(t1) == VOID || BTYPE(t2) == VOID))
1349 break;
1350 uerror("illegal types in :");
1352 break;
1354 default: /* must work harder: relationals or comparisons */
1356 if( !ISPTR(t1) ){
1357 t = t2;
1358 q = q2;
1359 d = d2;
1360 ap = ap2;
1361 break;
1363 if( !ISPTR(t2) ){
1364 break;
1367 /* both are pointers */
1368 if( talign(t2,ap2) < talign(t,ap) ){
1369 t = t2;
1370 q = q2;
1371 ap = ap2;
1373 break;
1376 p->n_left = makety( p->n_left, t, q, d, ap );
1377 p->n_right = makety( p->n_right, t, q, d, ap );
1378 if( o!=MINUS && !clogop(o) ){
1380 p->n_type = t;
1381 p->n_qual = q;
1382 p->n_df = d;
1383 p->n_ap = ap;
1386 return(clocal(p));
1389 int tdebug = 0;
1393 * Satisfy the types of various arithmetic binary ops.
1395 * rules are:
1396 * if assignment, type of LHS
1397 * if any doubles, make double
1398 * else if any float make float
1399 * else if any longlongs, make long long
1400 * else if any longs, make long
1401 * else etcetc.
1403 * If the op with the highest rank is unsigned, this is the resulting type.
1404 * See: 6.3.1.1 rank order equal of signed and unsigned types
1405 * 6.3.1.8 Usual arithmetic conversions
1407 NODE *
1408 tymatch(NODE *p)
1410 TWORD tl, tr, t, tu;
1411 NODE *l, *r;
1412 int o, lu, ru;
1414 o = p->n_op;
1415 r = p->n_right;
1416 l = p->n_left;
1418 tl = l->n_type;
1419 tr = r->n_type;
1421 lu = ru = 0;
1422 if (ISUNSIGNED(tl)) {
1423 lu = 1;
1424 tl = DEUNSIGN(tl);
1426 if (ISUNSIGNED(tr)) {
1427 ru = 1;
1428 tr = DEUNSIGN(tr);
1431 if (clogop(o) && tl == tr && lu != ru &&
1432 l->n_op != ICON && r->n_op != ICON)
1433 warner(Wsign_compare, NULL);
1435 if (tl == LDOUBLE || tr == LDOUBLE)
1436 t = LDOUBLE;
1437 else if (tl == DOUBLE || tr == DOUBLE)
1438 t = DOUBLE;
1439 else if (tl == FLOAT || tr == FLOAT)
1440 t = FLOAT;
1441 else if (tl==LONGLONG || tr == LONGLONG)
1442 t = LONGLONG;
1443 else if (tl==LONG || tr==LONG)
1444 t = LONG;
1445 else /* everything else */
1446 t = INT;
1448 if (casgop(o)) {
1449 tu = l->n_type;
1450 t = tl;
1451 } else {
1452 /* Should result be unsigned? */
1453 /* This depends on ctype() being called correctly */
1454 tu = t;
1455 if (UNSIGNABLE(t) && (lu || ru)) {
1456 if (tl >= tr && lu)
1457 tu = ENUNSIGN(t);
1458 if (tr >= tl && ru)
1459 tu = ENUNSIGN(t);
1463 /* because expressions have values that are at least as wide
1464 as INT or UNSIGNED, the only conversions needed
1465 are those involving FLOAT/DOUBLE, and those
1466 from LONG to INT and ULONG to UNSIGNED */
1468 if (t != tl || (ru && !lu)) {
1469 if (o != CAST && r->n_op != ICON &&
1470 tsize(tl, 0, MKAP(tl)) > tsize(tu, 0, MKAP(tu)))
1471 warner(Wtruncate, tnames[tu], tnames[tl]);
1472 p->n_left = makety( p->n_left, tu, 0, 0, MKAP(tu));
1475 if (t != tr || o==CAST || (lu && !ru)) {
1476 if (o != CAST && r->n_op != ICON &&
1477 tsize(tr, 0, MKAP(tr)) > tsize(tu, 0, MKAP(tu)))
1478 warner(Wtruncate, tnames[tu], tnames[tr]);
1479 p->n_right = makety(p->n_right, tu, 0, 0, MKAP(tu));
1482 if( casgop(o) ){
1483 p->n_type = p->n_left->n_type;
1484 p->n_df = p->n_left->n_df;
1485 p->n_ap = p->n_left->n_ap;
1487 else if( !clogop(o) ){
1488 p->n_type = tu;
1489 p->n_df = NULL;
1490 p->n_ap = MKAP(t);
1493 #ifdef PCC_DEBUG
1494 if (tdebug) {
1495 printf("tymatch(%p): ", p);
1496 tprint(stdout, tl, 0);
1497 printf(" %s ", copst(o));
1498 tprint(stdout, tr, 0);
1499 printf(" => ");
1500 tprint(stdout, tu, 0);
1501 printf("\n");
1502 fwalk(p, eprint, 0);
1504 #endif
1506 return(p);
1510 * Create a float const node of zero.
1512 static NODE *
1513 fzero(TWORD t)
1515 NODE *p = block(FCON, NIL, NIL, t, 0, MKAP(t));
1517 p->n_dcon = FLOAT_CAST(0, INT);
1518 return p;
1522 * make p into type t by inserting a conversion
1524 NODE *
1525 makety(NODE *p, TWORD t, TWORD q, union dimfun *d, struct attr *ap)
1528 if (t == p->n_type) {
1529 p->n_df = d;
1530 p->n_ap = ap;
1531 p->n_qual = q;
1532 return(p);
1535 if (p->n_op == FCON && (t >= FLOAT && t <= LDOUBLE)) {
1536 if (t == FLOAT)
1537 p->n_dcon = (float)p->n_dcon;
1538 else if (t == DOUBLE)
1539 p->n_dcon = (double)p->n_dcon;
1540 else
1541 p->n_dcon = (long double)p->n_dcon;
1542 p->n_type = t;
1543 return p;
1546 if (p->n_op == FCON) {
1547 int isf = ISFTY(t);
1548 NODE *r;
1550 if (isf||ISITY(t)) {
1551 if (isf == ISFTY(p->n_type)) {
1552 p->n_type = t;
1553 p->n_qual = q;
1554 p->n_df = d;
1555 p->n_ap = ap;
1556 return(p);
1557 } else if (isf == ISITY(p->n_type)) {
1558 /* will be zero */
1559 nfree(p);
1560 return fzero(t);
1561 } else if (ISCTY(p->n_type))
1562 cerror("complex constant");
1563 } else if (ISCTY(t)) {
1564 if (ISITY(p->n_type)) {
1565 /* convert to correct subtype */
1566 r = fzero(t - (COMPLEX-DOUBLE));
1567 p->n_type = t + (IMAG-COMPLEX);
1568 p->n_qual = q;
1569 p->n_df = d;
1570 p->n_ap = MKAP(p->n_type);
1571 return block(CM, r, p, t, 0, MKAP(t));
1572 } else if (ISFTY(p->n_type)) {
1573 /* convert to correct subtype */
1574 r = fzero(t + (IMAG-COMPLEX));
1575 p->n_type = t - (COMPLEX-DOUBLE);
1576 p->n_qual = q;
1577 p->n_df = d;
1578 p->n_ap = MKAP(p->n_type);
1579 return block(CM, p, r, t, 0, MKAP(t));
1580 } else if (ISCTY(p->n_type))
1581 cerror("complex constant2");
1585 if (t & TMASK) {
1586 /* non-simple type */
1587 p = block(PCONV, p, NIL, t, d, ap);
1588 p->n_qual = q;
1589 return clocal(p);
1592 if (p->n_op == ICON) {
1593 if (ISFTY(t)) {
1594 p->n_op = FCON;
1595 p->n_dcon = FLOAT_CAST(p->n_lval, p->n_type);
1596 p->n_type = t;
1597 p->n_qual = q;
1598 p->n_ap = MKAP(t);
1599 return (clocal(p));
1600 } else if (ISCTY(t) || ISITY(t))
1601 cerror("complex constant3");
1604 p = block(SCONV, p, NIL, t, d, ap);
1605 p->n_qual = q;
1606 return clocal(p);
1610 NODE *
1611 block(int o, NODE *l, NODE *r, TWORD t, union dimfun *d, struct attr *ap)
1613 register NODE *p;
1615 p = talloc();
1616 p->n_rval = 0;
1617 p->n_op = o;
1618 p->n_lval = 0; /* Protect against large lval */
1619 p->n_left = l;
1620 p->n_right = r;
1621 p->n_type = t;
1622 p->n_qual = 0;
1623 p->n_df = d;
1624 p->n_ap = ap;
1625 #if !defined(MULTIPASS)
1626 /* p->n_reg = */p->n_su = 0;
1627 p->n_regw = 0;
1628 #endif
1629 return(p);
1633 * Return the constant value from an ICON.
1635 CONSZ
1636 icons(NODE *p)
1638 /* if p is an integer constant, return its value */
1639 CONSZ val;
1641 if (p->n_op != ICON || p->n_sp != NULL) {
1642 uerror( "constant expected");
1643 val = 1;
1644 } else
1645 val = p->n_lval;
1646 tfree(p);
1647 return(val);
1651 * the intent of this table is to examine the
1652 * operators, and to check them for
1653 * correctness.
1655 * The table is searched for the op and the
1656 * modified type (where this is one of the
1657 * types INT (includes char and short), LONG,
1658 * DOUBLE (includes FLOAT), and POINTER
1660 * The default action is to make the node type integer
1662 * The actions taken include:
1663 * PUN check for puns
1664 * CVTL convert the left operand
1665 * CVTR convert the right operand
1666 * TYPL the type is determined by the left operand
1667 * TYPR the type is determined by the right operand
1668 * TYMATCH force type of left and right to match,by inserting conversions
1669 * PTMATCH like TYMATCH, but for pointers
1670 * LVAL left operand must be lval
1671 * CVTO convert the op
1672 * NCVT do not convert the operands
1673 * OTHER handled by code
1674 * NCVTR convert the left operand, not the right...
1678 # define MINT 01 /* integer */
1679 # define MDBI 02 /* integer or double */
1680 # define MSTR 04 /* structure */
1681 # define MPTR 010 /* pointer */
1682 # define MPTI 020 /* pointer or integer */
1685 opact(NODE *p)
1687 int mt12, mt1, mt2, o;
1689 mt1 = mt2 = mt12 = 0;
1691 switch (coptype(o = p->n_op)) {
1692 case BITYPE:
1693 mt12=mt2 = moditype(p->n_right->n_type);
1694 case UTYPE:
1695 mt12 &= (mt1 = moditype(p->n_left->n_type));
1696 break;
1699 switch( o ){
1701 case NAME :
1702 case ICON :
1703 case FCON :
1704 case CALL :
1705 case UCALL:
1706 case UMUL:
1707 { return( OTHER ); }
1708 case UMINUS:
1709 if( mt1 & MDBI ) return( TYPL );
1710 break;
1712 case COMPL:
1713 if( mt1 & MINT ) return( TYPL );
1714 break;
1716 case ADDROF:
1717 return( NCVT+OTHER );
1718 case NOT:
1719 /* case INIT: */
1720 case CM:
1721 case CBRANCH:
1722 case ANDAND:
1723 case OROR:
1724 return( 0 );
1726 case MUL:
1727 case DIV:
1728 if( mt12 & MDBI ) return( TYMATCH );
1729 break;
1731 case MOD:
1732 case AND:
1733 case OR:
1734 case ER:
1735 if( mt12 & MINT ) return( TYMATCH );
1736 break;
1738 case LS:
1739 case RS:
1740 if( mt12 & MINT ) return( TYPL+OTHER );
1741 break;
1743 case EQ:
1744 case NE:
1745 case LT:
1746 case LE:
1747 case GT:
1748 case GE:
1749 if( mt12 & MDBI ) return( TYMATCH+CVTO );
1750 else if( mt12 & MPTR ) return( PTMATCH+PUN+CVTO );
1751 else if( mt12 & MPTI ) return( PTMATCH+PUN );
1752 else break;
1754 case QUEST:
1755 return( TYPR+OTHER );
1756 case COMOP:
1757 return( TYPR );
1759 case STREF:
1760 return( NCVTR+OTHER );
1762 case FORCE:
1763 return( TYPL );
1765 case COLON:
1766 if( mt12 & MDBI ) return( TYMATCH );
1767 else if( mt12 & MPTR ) return( TYPL+PTMATCH+PUN );
1768 else if( (mt1&MINT) && (mt2&MPTR) ) return( TYPR+PUN );
1769 else if( (mt1&MPTR) && (mt2&MINT) ) return( TYPL+PUN );
1770 else if( mt12 & MSTR ) return( NCVT+TYPL+OTHER );
1771 break;
1773 case ASSIGN:
1774 case RETURN:
1775 if( mt12 & MSTR ) return( LVAL+NCVT+TYPL+OTHER );
1776 case CAST:
1777 if( mt12 & MDBI ) return( TYPL+LVAL+TYMATCH );
1778 else if( mt1 & MPTR) return( LVAL+PTMATCH+PUN );
1779 else if( mt12 & MPTI ) return( TYPL+LVAL+TYMATCH+PUN );
1780 break;
1782 case LSEQ:
1783 case RSEQ:
1784 if( mt12 & MINT ) return( TYPL+LVAL+OTHER );
1785 break;
1787 case MULEQ:
1788 case DIVEQ:
1789 if( mt12 & MDBI ) return( LVAL+TYMATCH );
1790 break;
1792 case MODEQ:
1793 case ANDEQ:
1794 case OREQ:
1795 case EREQ:
1796 if (mt12 & MINT)
1797 return(LVAL+TYMATCH);
1798 break;
1800 case PLUSEQ:
1801 case MINUSEQ:
1802 case INCR:
1803 case DECR:
1804 if (mt12 & MDBI)
1805 return(TYMATCH+LVAL);
1806 else if ((mt1&MPTR) && (mt2&MINT))
1807 return(TYPL+LVAL+CVTR);
1808 break;
1810 case MINUS:
1811 if (mt12 & MPTR)
1812 return(CVTO+PTMATCH+PUN);
1813 if (mt2 & MPTR)
1814 break;
1815 /* FALLTHROUGH */
1816 case PLUS:
1817 if (mt12 & MDBI)
1818 return(TYMATCH);
1819 else if ((mt1&MPTR) && (mt2&MINT))
1820 return(TYPL+CVTR);
1821 else if ((mt1&MINT) && (mt2&MPTR))
1822 return(TYPR+CVTL);
1825 uerror("operands of %s have incompatible types", copst(o));
1826 return(NCVT);
1830 moditype(TWORD ty)
1832 switch (ty) {
1834 case STRTY:
1835 case UNIONTY:
1836 return( MSTR );
1838 case BOOL:
1839 case CHAR:
1840 case SHORT:
1841 case UCHAR:
1842 case USHORT:
1843 case UNSIGNED:
1844 case ULONG:
1845 case ULONGLONG:
1846 case INT:
1847 case LONG:
1848 case LONGLONG:
1849 return( MINT|MDBI|MPTI );
1850 case FLOAT:
1851 case DOUBLE:
1852 case LDOUBLE:
1853 #ifndef NO_COMPLEX
1854 case FCOMPLEX:
1855 case COMPLEX:
1856 case LCOMPLEX:
1857 case FIMAG:
1858 case IMAG:
1859 case LIMAG:
1860 #endif
1861 return( MDBI );
1862 default:
1863 return( MPTR|MPTI );
1868 int tvaloff = MAXREGS+NPERMREG > 100 ? MAXREGS+NPERMREG + 100 : 100;
1871 * Returns a TEMP node with temp number nr.
1872 * If nr == 0, return a node with a new number.
1874 NODE *
1875 tempnode(int nr, TWORD type, union dimfun *df, struct attr *ap)
1877 NODE *r;
1879 if (tvaloff == -NOOFFSET)
1880 tvaloff++; /* Skip this for array indexing */
1881 r = block(TEMP, NIL, NIL, type, df, ap);
1882 regno(r) = nr ? nr : tvaloff;
1883 tvaloff += szty(type);
1884 return r;
1888 * Do sizeof on p.
1890 NODE *
1891 doszof(NODE *p)
1893 extern NODE *arrstk[10];
1894 extern int arrstkp;
1895 union dimfun *df;
1896 TWORD ty;
1897 NODE *rv, *q;
1898 int astkp;
1900 if (p->n_op == FLD)
1901 uerror("can't apply sizeof to bit-field");
1904 * Arrays may be dynamic, may need to make computations.
1907 rv = bcon(1);
1908 df = p->n_df;
1909 ty = p->n_type;
1910 astkp = 0;
1911 while (ISARY(ty)) {
1912 if (df->ddim == NOOFFSET)
1913 uerror("sizeof of incomplete type");
1914 if (df->ddim < 0) {
1915 if (arrstkp)
1916 q = arrstk[astkp++];
1917 else
1918 q = tempnode(-df->ddim, INT, 0, MKAP(INT));
1919 } else
1920 q = bcon(df->ddim);
1921 rv = buildtree(MUL, rv, q);
1922 df++;
1923 ty = DECREF(ty);
1925 rv = buildtree(MUL, rv, bcon(tsize(ty, p->n_df, p->n_ap)/SZCHAR));
1926 tfree(p);
1927 arrstkp = 0; /* XXX - may this fail? */
1928 return rv;
1931 #ifdef PCC_DEBUG
1932 void
1933 eprint(NODE *p, int down, int *a, int *b)
1935 int ty;
1937 *a = *b = down+1;
1938 while( down > 1 ){
1939 printf( "\t" );
1940 down -= 2;
1942 if( down ) printf( " " );
1944 ty = coptype( p->n_op );
1946 printf("%p) %s, ", p, copst(p->n_op));
1947 if (p->n_op == XARG || p->n_op == XASM)
1948 printf("id '%s', ", p->n_name);
1949 if (ty == LTYPE) {
1950 printf(CONFMT, p->n_lval);
1951 if (p->n_op == NAME || p->n_op == ICON)
1952 printf(", %p, ", p->n_sp);
1953 else
1954 printf(", %d, ", p->n_rval);
1956 tprint(stdout, p->n_type, p->n_qual);
1957 printf( ", %p, ", p->n_df);
1958 dump_attr(p->n_ap);
1960 # endif
1963 * Emit everything that should be emitted on the left side
1964 * of a comma operator, and remove the operator.
1965 * Do not traverse through QUEST, ANDAND and OROR.
1966 * Enable this for all targets when stable enough.
1968 static void
1969 comops(NODE *p)
1971 int o;
1972 NODE *q;
1974 while (p->n_op == COMOP) {
1975 /* XXX hack for GCC ({ }) ops */
1976 if (p->n_left->n_op == GOTO) {
1977 int v = (int)p->n_left->n_left->n_lval;
1978 ecomp(p->n_left);
1979 plabel(v+1);
1980 } else
1981 ecomp(p->n_left); /* will recurse if more COMOPs */
1982 q = p->n_right;
1983 *p = *q;
1984 nfree(q);
1986 o = coptype(p->n_op);
1987 if (p->n_op == QUEST || p->n_op == ANDAND || p->n_op == OROR)
1988 o = UTYPE;
1989 if (o != LTYPE)
1990 comops(p->n_left);
1991 if (o == BITYPE)
1992 comops(p->n_right);
1996 * Walk up through the tree from the leaves,
1997 * removing constant operators.
1999 static void
2000 logwalk(NODE *p)
2002 int o = coptype(p->n_op);
2003 NODE *l, *r;
2005 l = p->n_left;
2006 r = p->n_right;
2007 switch (o) {
2008 case LTYPE:
2009 return;
2010 case BITYPE:
2011 logwalk(r);
2012 case UTYPE:
2013 logwalk(l);
2015 if (!clogop(p->n_op))
2016 return;
2017 if (p->n_op == NOT && l->n_op == ICON) {
2018 p->n_lval = l->n_lval == 0;
2019 nfree(l);
2020 p->n_op = ICON;
2022 if (l->n_op == ICON && r->n_op == ICON) {
2023 if (conval(l, p->n_op, r) == 0) {
2025 * people sometimes tend to do really odd compares,
2026 * like "if ("abc" == "def")" etc.
2027 * do it runtime instead.
2029 } else {
2030 p->n_lval = l->n_lval;
2031 p->n_op = ICON;
2032 nfree(l);
2033 nfree(r);
2039 * Removes redundant logical operators for branch conditions.
2041 static void
2042 fixbranch(NODE *p, int label)
2045 logwalk(p);
2047 if (p->n_op == ICON) {
2048 if (p->n_lval != 0)
2049 branch(label);
2050 nfree(p);
2051 } else {
2052 if (!clogop(p->n_op)) /* Always conditional */
2053 p = buildtree(NE, p, bcon(0));
2054 ecode(buildtree(CBRANCH, p, bcon(label)));
2059 * Write out logical expressions as branches.
2061 static void
2062 andorbr(NODE *p, int true, int false)
2064 NODE *q;
2065 int o, lab;
2067 lab = -1;
2068 switch (o = p->n_op) {
2069 case EQ:
2070 case NE:
2072 * Remove redundant EQ/NE nodes.
2074 while (((o = p->n_left->n_op) == EQ || o == NE) &&
2075 p->n_right->n_op == ICON) {
2076 o = p->n_op;
2077 q = p->n_left;
2078 if (p->n_right->n_lval == 0) {
2079 nfree(p->n_right);
2080 *p = *q;
2081 nfree(q);
2082 if (o == EQ)
2083 p->n_op = negrel[p->n_op - EQ];
2084 #if 0
2085 p->n_op = NE; /* toggla */
2086 #endif
2087 } else if (p->n_right->n_lval == 1) {
2088 nfree(p->n_right);
2089 *p = *q;
2090 nfree(q);
2091 if (o == NE)
2092 p->n_op = negrel[p->n_op - EQ];
2093 #if 0
2094 p->n_op = EQ; /* toggla */
2095 #endif
2096 } else
2097 break; /* XXX - should always be false */
2100 /* FALLTHROUGH */
2101 case LE:
2102 case LT:
2103 case GE:
2104 case GT:
2105 calc: if (true < 0) {
2106 p->n_op = negrel[p->n_op - EQ];
2107 true = false;
2108 false = -1;
2111 rmcops(p->n_left);
2112 rmcops(p->n_right);
2113 fixbranch(p, true);
2114 if (false >= 0)
2115 branch(false);
2116 break;
2118 case ULE:
2119 case UGT:
2120 /* Convert to friendlier ops */
2121 if (p->n_right->n_op == ICON && p->n_right->n_lval == 0)
2122 p->n_op = o == ULE ? EQ : NE;
2123 goto calc;
2125 case UGE:
2126 case ULT:
2127 /* Already true/false by definition */
2128 if (p->n_right->n_op == ICON && p->n_right->n_lval == 0) {
2129 if (true < 0) {
2130 o = o == ULT ? UGE : ULT;
2131 true = false;
2133 rmcops(p->n_left);
2134 ecode(p->n_left);
2135 rmcops(p->n_right);
2136 ecode(p->n_right);
2137 nfree(p);
2138 if (o == UGE) /* true */
2139 branch(true);
2140 break;
2142 goto calc;
2144 case ANDAND:
2145 lab = false<0 ? getlab() : false ;
2146 andorbr(p->n_left, -1, lab);
2147 comops(p->n_right);
2148 andorbr(p->n_right, true, false);
2149 if (false < 0)
2150 plabel( lab);
2151 nfree(p);
2152 break;
2154 case OROR:
2155 lab = true<0 ? getlab() : true;
2156 andorbr(p->n_left, lab, -1);
2157 comops(p->n_right);
2158 andorbr(p->n_right, true, false);
2159 if (true < 0)
2160 plabel( lab);
2161 nfree(p);
2162 break;
2164 case NOT:
2165 andorbr(p->n_left, false, true);
2166 nfree(p);
2167 break;
2169 default:
2170 rmcops(p);
2171 if (true >= 0)
2172 fixbranch(p, true);
2173 if (false >= 0) {
2174 if (true >= 0)
2175 branch(false);
2176 else
2177 fixbranch(buildtree(EQ, p, bcon(0)), false);
2183 * Create a node for either TEMP or on-stack storage.
2185 static NODE *
2186 cstknode(TWORD t, union dimfun *df, struct attr *ap)
2188 struct symtab *sp;
2190 /* create a symtab entry suitable for this type */
2191 sp = getsymtab("0hej", STEMP);
2192 sp->stype = t;
2193 sp->sdf = df;
2194 sp->sap = ap;
2195 sp->sclass = AUTO;
2196 sp->soffset = NOOFFSET;
2197 oalloc(sp, &autooff);
2198 return nametree(sp);
2203 * Massage the output trees to remove C-specific nodes:
2204 * COMOPs are split into separate statements.
2205 * QUEST/COLON are rewritten to branches.
2206 * ANDAND/OROR/NOT are rewritten to branches for lazy-evaluation.
2207 * CBRANCH conditions are rewritten for lazy-evaluation.
2209 static void
2210 rmcops(NODE *p)
2212 TWORD type;
2213 NODE *q, *r, *tval;
2214 int o, ty, lbl, lbl2;
2216 tval = NIL;
2217 o = p->n_op;
2218 ty = coptype(o);
2219 if (BTYPE(p->n_type) == ENUMTY) { /* fixup enum */
2220 struct symtab *sp = strmemb(p->n_ap);
2221 MODTYPE(p->n_type, sp->stype);
2223 * XXX may fail if these are true:
2224 * - variable-sized enums
2225 * - non-byte-addressed targets.
2227 if (BTYPE(p->n_type) == ENUMTY && ISPTR(p->n_type))
2228 MODTYPE(p->n_type, INT); /* INT ok? */
2230 switch (o) {
2231 case QUEST:
2234 * Create a branch node from ?:
2235 * || and && must be taken special care of.
2237 type = p->n_type;
2238 andorbr(p->n_left, -1, lbl = getlab());
2240 /* Make ASSIGN node */
2241 /* Only if type is not void */
2242 q = p->n_right->n_left;
2243 comops(q);
2244 if (type != VOID) {
2245 tval = cstknode(q->n_type, q->n_df, q->n_ap);
2246 q = buildtree(ASSIGN, ccopy(tval), q);
2248 rmcops(q);
2249 ecode(q); /* Done with assign */
2250 branch(lbl2 = getlab());
2251 plabel( lbl);
2253 q = p->n_right->n_right;
2254 comops(q);
2255 if (type != VOID) {
2256 q = buildtree(ASSIGN, ccopy(tval), q);
2258 rmcops(q);
2259 ecode(q); /* Done with assign */
2261 plabel( lbl2);
2263 nfree(p->n_right);
2264 if (p->n_type != VOID) {
2265 *p = *tval;
2266 nfree(tval);
2267 } else {
2268 p->n_op = ICON;
2269 p->n_lval = 0;
2270 p->n_sp = NULL;
2272 break;
2274 case ULE:
2275 case ULT:
2276 case UGE:
2277 case UGT:
2278 case EQ:
2279 case NE:
2280 case LE:
2281 case LT:
2282 case GE:
2283 case GT:
2284 case ANDAND:
2285 case OROR:
2286 case NOT:
2287 #ifdef SPECIAL_CCODES
2288 #error fix for private CCODES handling
2289 #else
2290 r = talloc();
2291 *r = *p;
2292 andorbr(r, -1, lbl = getlab());
2294 tval = cstknode(p->n_type, p->n_df, p->n_ap);
2296 ecode(buildtree(ASSIGN, ccopy(tval), bcon(1)));
2297 branch(lbl2 = getlab());
2298 plabel( lbl);
2299 ecode(buildtree(ASSIGN, ccopy(tval), bcon(0)));
2300 plabel( lbl2);
2302 *p = *tval;
2303 nfree(tval);
2305 #endif
2306 break;
2307 case CBRANCH:
2308 andorbr(p->n_left, p->n_right->n_lval, -1);
2309 nfree(p->n_right);
2310 p->n_op = ICON; p->n_type = VOID;
2311 break;
2312 case COMOP:
2313 cerror("COMOP error");
2315 default:
2316 if (ty == LTYPE)
2317 return;
2318 rmcops(p->n_left);
2319 if (ty == BITYPE)
2320 rmcops(p->n_right);
2325 * Return 1 if an assignment is found.
2327 static int
2328 has_se(NODE *p)
2330 if (cdope(p->n_op) & ASGFLG)
2331 return 1;
2332 if (coptype(p->n_op) == LTYPE)
2333 return 0;
2334 if (has_se(p->n_left))
2335 return 1;
2336 if (coptype(p->n_op) == BITYPE)
2337 return has_se(p->n_right);
2338 return 0;
2342 * Find and convert asgop's to separate statements.
2343 * Be careful about side effects.
2344 * assign tells whether ASSIGN should be considered giving
2345 * side effects or not.
2347 static NODE *
2348 delasgop(NODE *p)
2350 NODE *q, *r;
2351 int tval;
2353 if (p->n_op == INCR || p->n_op == DECR) {
2355 * Rewrite x++ to (x += 1) -1; and deal with it further down.
2356 * Pass2 will remove -1 if unnecessary.
2358 q = ccopy(p);
2359 tfree(p->n_left);
2360 q->n_op = (p->n_op==INCR)?PLUSEQ:MINUSEQ;
2361 p->n_op = (p->n_op==INCR)?MINUS:PLUS;
2362 p->n_left = delasgop(q);
2364 } else if ((cdope(p->n_op)&ASGOPFLG) &&
2365 p->n_op != RETURN && p->n_op != CAST) {
2366 NODE *l = p->n_left;
2367 NODE *ll = l->n_left;
2369 if (has_se(l)) {
2370 q = tempnode(0, ll->n_type, ll->n_df, ll->n_ap);
2371 tval = regno(q);
2372 r = tempnode(tval, ll->n_type, ll->n_df,ll->n_ap);
2373 l->n_left = q;
2374 /* Now the left side of node p has no side effects. */
2375 /* side effects on the right side must be obeyed */
2376 p = delasgop(p);
2378 r = buildtree(ASSIGN, r, ll);
2379 r = delasgop(r);
2380 ecode(r);
2381 } else {
2382 #if 0 /* Cannot call buildtree() here, it would invoke double add shifts */
2383 p->n_right = buildtree(UNASG p->n_op, ccopy(l),
2384 p->n_right);
2385 #else
2386 p->n_right = block(UNASG p->n_op, ccopy(l),
2387 p->n_right, p->n_type, p->n_df, p->n_ap);
2388 #endif
2389 p->n_op = ASSIGN;
2390 p->n_right = delasgop(p->n_right);
2391 p->n_right = clocal(p->n_right);
2394 } else {
2395 if (coptype(p->n_op) == LTYPE)
2396 return p;
2397 p->n_left = delasgop(p->n_left);
2398 if (coptype(p->n_op) == BITYPE)
2399 p->n_right = delasgop(p->n_right);
2401 return p;
2404 int edebug = 0;
2405 void
2406 ecomp(NODE *p)
2409 #ifdef PCC_DEBUG
2410 if (edebug)
2411 fwalk(p, eprint, 0);
2412 #endif
2413 if (!reached) {
2414 warner(Wunreachable_code, NULL);
2415 reached = 1;
2417 p = optim(p);
2418 comops(p);
2419 rmcops(p);
2420 p = delasgop(p);
2421 if (p->n_op == ICON && p->n_type == VOID)
2422 tfree(p);
2423 else
2424 ecode(p);
2428 #if defined(MULTIPASS)
2429 void
2430 p2tree(NODE *p)
2432 struct symtab *q;
2433 int ty;
2435 myp2tree(p); /* local action can be taken here */
2437 ty = coptype(p->n_op);
2439 printf("%d\t", p->n_op);
2441 if (ty == LTYPE) {
2442 printf(CONFMT, p->n_lval);
2443 printf("\t");
2445 if (ty != BITYPE) {
2446 if (p->n_op == NAME || p->n_op == ICON)
2447 printf("0\t");
2448 else
2449 printf("%d\t", p->n_rval);
2452 printf("%o\t", p->n_type);
2454 /* handle special cases */
2456 switch (p->n_op) {
2458 case NAME:
2459 case ICON:
2460 /* print external name */
2461 if ((q = p->n_sp) != NULL) {
2462 if ((q->sclass == STATIC && q->slevel > 0)) {
2463 printf(LABFMT, q->soffset);
2464 } else
2465 printf("%s\n",
2466 q->soname ? q->soname : exname(q->sname));
2467 } else
2468 printf("\n");
2469 break;
2471 case STARG:
2472 case STASG:
2473 case STCALL:
2474 case USTCALL:
2475 /* print out size */
2476 /* use lhs size, in order to avoid hassles
2477 * with the structure `.' operator
2480 /* note: p->left not a field... */
2481 printf(CONFMT, (CONSZ)tsize(STRTY, p->n_left->n_df,
2482 p->n_left->n_ap));
2483 printf("\t%d\t\n", talign(STRTY, p->n_left->n_ap));
2484 break;
2486 case XARG:
2487 case XASM:
2488 break;
2490 default:
2491 printf( "\n" );
2494 if (ty != LTYPE)
2495 p2tree(p->n_left);
2496 if (ty == BITYPE)
2497 p2tree(p->n_right);
2499 #else
2500 static char *
2501 sptostr(struct symtab *sp)
2503 char *cp = inlalloc(32);
2504 int n = sp->soffset;
2505 if (n < 0)
2506 n = -n;
2507 snprintf(cp, 32, LABFMT, n);
2508 return cp;
2511 void
2512 p2tree(NODE *p)
2514 struct symtab *q;
2515 int ty;
2517 myp2tree(p); /* local action can be taken here */
2519 /* Fix left imaginary types */
2520 if (ISITY(BTYPE(p->n_type)))
2521 MODTYPE(p->n_type, p->n_type - (FIMAG-FLOAT));
2523 ty = coptype(p->n_op);
2525 switch( p->n_op ){
2527 case NAME:
2528 case ICON:
2529 if ((q = p->n_sp) != NULL) {
2530 if ((q->sclass == STATIC && q->slevel > 0)
2531 #ifdef GCC_COMPAT
2532 || q->sflags == SLBLNAME
2533 #endif
2535 p->n_name = sptostr(q);
2536 } else {
2537 if ((p->n_name = q->soname) == NULL)
2538 p->n_name = addname(exname(q->sname));
2540 } else
2541 p->n_name = "";
2542 break;
2544 case STASG:
2545 /* STASG used for stack array init */
2546 if (ISARY(p->n_type)) {
2547 int size1 = (int)tsize(p->n_type, p->n_left->n_df,
2548 p->n_left->n_ap)/SZCHAR;
2549 p->n_stsize = (int)tsize(p->n_type, p->n_right->n_df,
2550 p->n_right->n_ap)/SZCHAR;
2551 if (size1 < p->n_stsize)
2552 p->n_stsize = size1;
2553 p->n_stalign = talign(p->n_type,
2554 p->n_left->n_ap)/SZCHAR;
2555 break;
2557 /* FALLTHROUGH */
2558 case STARG:
2559 case STCALL:
2560 case USTCALL:
2561 /* set up size parameters */
2562 p->n_stsize = (int)((tsize(STRTY, p->n_left->n_df,
2563 p->n_left->n_ap)+SZCHAR-1)/SZCHAR);
2564 p->n_stalign = talign(STRTY,p->n_left->n_ap)/SZCHAR;
2565 if (p->n_stalign == 0)
2566 p->n_stalign = 1; /* At least char for packed structs */
2567 break;
2569 case XARG:
2570 case XASM:
2571 break;
2573 default:
2574 p->n_name = "";
2577 if( ty != LTYPE ) p2tree( p->n_left );
2578 if( ty == BITYPE ) p2tree( p->n_right );
2581 #endif
2584 * Change void data types into char.
2586 static void
2587 delvoid(NODE *p, void *arg)
2589 /* Convert "PTR undef" (void *) to "PTR uchar" */
2590 if (BTYPE(p->n_type) == VOID)
2591 p->n_type = (p->n_type & ~BTMASK) | UCHAR;
2592 if (BTYPE(p->n_type) == BOOL) {
2593 if (p->n_op == SCONV && p->n_type == BOOL) {
2594 /* create a jump and a set */
2595 NODE *r;
2596 int l, l2;
2598 r = tempnode(0, BOOL_TYPE, NULL, MKAP(BOOL_TYPE));
2599 cbranch(buildtree(EQ, p->n_left, bcon(0)),
2600 bcon(l = getlab()));
2601 *p = *r;
2602 ecode(buildtree(ASSIGN, tcopy(r), bcon(1)));
2603 branch(l2 = getlab());
2604 plabel(l);
2605 ecode(buildtree(ASSIGN, r, bcon(0)));
2606 plabel(l2);
2607 } else
2608 p->n_type = (p->n_type & ~BTMASK) | BOOL_TYPE;
2613 void
2614 ecode(NODE *p)
2616 /* walk the tree and write out the nodes.. */
2618 if (nerrors)
2619 return;
2621 #ifdef GCC_COMPAT
2623 NODE *q = p;
2625 if (q->n_op == UMUL)
2626 q = p->n_left;
2627 if (cdope(q->n_op)&CALLFLG &&
2628 attr_find(q->n_ap, GCC_ATYP_WARN_UNUSED_RESULT))
2629 werror("return value ignored");
2631 #endif
2632 p = optim(p);
2633 p = delasgop(p);
2634 walkf(p, delvoid, 0);
2635 #ifdef PCC_DEBUG
2636 if (xdebug) {
2637 printf("Fulltree:\n");
2638 fwalk(p, eprint, 0);
2640 #endif
2641 p2tree(p);
2642 #if !defined(MULTIPASS)
2643 send_passt(IP_NODE, p);
2644 #endif
2648 * Send something further on to the next pass.
2650 void
2651 send_passt(int type, ...)
2653 struct interpass *ip;
2654 struct interpass_prolog *ipp;
2655 extern int crslab;
2656 va_list ap;
2657 int sz;
2659 va_start(ap, type);
2660 if (cftnsp == NULL && type != IP_ASM) {
2661 #ifdef notyet
2662 cerror("no function");
2663 #endif
2664 if (type == IP_NODE)
2665 tfree(va_arg(ap, NODE *));
2666 return;
2668 if (type == IP_PROLOG || type == IP_EPILOG)
2669 sz = sizeof(struct interpass_prolog);
2670 else
2671 sz = sizeof(struct interpass);
2673 ip = inlalloc(sz);
2674 ip->type = type;
2675 ip->lineno = lineno;
2676 switch (type) {
2677 case IP_NODE:
2678 ip->ip_node = va_arg(ap, NODE *);
2679 break;
2680 case IP_EPILOG:
2681 if (!isinlining)
2682 defloc(cftnsp);
2683 /* FALLTHROUGH */
2684 case IP_PROLOG:
2685 inftn = type == IP_PROLOG ? 1 : 0;
2686 ipp = (struct interpass_prolog *)ip;
2687 memset(ipp->ipp_regs, (type == IP_PROLOG)? -1 : 0,
2688 sizeof(ipp->ipp_regs));
2689 ipp->ipp_autos = va_arg(ap, int);
2690 ipp->ipp_name = va_arg(ap, char *);
2691 ipp->ipp_type = va_arg(ap, TWORD);
2692 ipp->ipp_vis = va_arg(ap, int);
2693 ip->ip_lbl = va_arg(ap, int);
2694 ipp->ip_tmpnum = va_arg(ap, int);
2695 ipp->ip_lblnum = crslab;
2696 if (type == IP_PROLOG)
2697 ipp->ip_lblnum--;
2698 break;
2699 case IP_DEFLAB:
2700 ip->ip_lbl = va_arg(ap, int);
2701 break;
2702 case IP_ASM:
2703 if (blevel == 0) { /* outside function */
2704 printf("\t");
2705 printf("%s", va_arg(ap, char *));
2706 printf("\n");
2707 va_end(ap);
2708 defloc(NULL);
2709 return;
2711 ip->ip_asm = va_arg(ap, char *);
2712 break;
2713 default:
2714 cerror("bad send_passt type %d", type);
2716 va_end(ap);
2717 pass1_lastchance(ip); /* target-specific info */
2718 if (isinlining)
2719 inline_addarg(ip);
2720 else
2721 pass2_compile(ip);
2724 char *
2725 copst(int op)
2727 if (op <= MAXOP)
2728 return opst[op];
2729 #define SNAM(x,y) case x: return #y;
2730 switch (op) {
2731 SNAM(QUALIFIER,QUALIFIER)
2732 SNAM(CLASS,CLASS)
2733 SNAM(RB,])
2734 SNAM(DOT,.)
2735 SNAM(ELLIPSIS,...)
2736 SNAM(LB,[)
2737 SNAM(TYPE,TYPE)
2738 SNAM(COMOP,COMOP)
2739 SNAM(QUEST,?)
2740 SNAM(COLON,:)
2741 SNAM(ANDAND,&&)
2742 SNAM(OROR,||)
2743 SNAM(NOT,!)
2744 SNAM(CAST,CAST)
2745 SNAM(PLUSEQ,+=)
2746 SNAM(MINUSEQ,-=)
2747 SNAM(MULEQ,*=)
2748 SNAM(DIVEQ,/=)
2749 SNAM(MODEQ,%=)
2750 SNAM(ANDEQ,&=)
2751 SNAM(OREQ,|=)
2752 SNAM(EREQ,^=)
2753 SNAM(LSEQ,<<=)
2754 SNAM(RSEQ,>>=)
2755 SNAM(INCR,++)
2756 SNAM(DECR,--)
2757 SNAM(STRING,STRING)
2758 SNAM(SZOF,SIZEOF)
2759 SNAM(ATTRIB,ATTRIBUTE)
2760 SNAM(TYMERGE,TYMERGE)
2761 #ifdef GCC_COMPAT
2762 SNAM(XREAL,__real__)
2763 SNAM(XIMAG,__imag__)
2764 #endif
2765 default:
2766 cerror("bad copst %d", op);
2768 return 0; /* XXX gcc */
2772 cdope(int op)
2774 if (op <= MAXOP)
2775 return dope[op];
2776 switch (op) {
2777 case CLOP:
2778 case STRING:
2779 case QUALIFIER:
2780 case CLASS:
2781 case RB:
2782 case ELLIPSIS:
2783 case TYPE:
2784 return LTYPE;
2785 case DOT:
2786 case SZOF:
2787 case COMOP:
2788 case QUEST:
2789 case COLON:
2790 case LB:
2791 case TYMERGE:
2792 return BITYPE;
2793 case XIMAG:
2794 case XREAL:
2795 case ATTRIB:
2796 return UTYPE;
2797 case ANDAND:
2798 case OROR:
2799 return BITYPE|LOGFLG;
2800 case NOT:
2801 return UTYPE|LOGFLG;
2802 case CAST:
2803 return BITYPE|ASGFLG|ASGOPFLG;
2804 case PLUSEQ:
2805 return BITYPE|ASGFLG|ASGOPFLG|FLOFLG|SIMPFLG|COMMFLG;
2806 case MINUSEQ:
2807 return BITYPE|FLOFLG|SIMPFLG|ASGFLG|ASGOPFLG;
2808 case MULEQ:
2809 return BITYPE|FLOFLG|MULFLG|ASGFLG|ASGOPFLG;
2810 case OREQ:
2811 case EREQ:
2812 case ANDEQ:
2813 return BITYPE|SIMPFLG|COMMFLG|ASGFLG|ASGOPFLG;
2814 case DIVEQ:
2815 return BITYPE|FLOFLG|MULFLG|DIVFLG|ASGFLG|ASGOPFLG;
2816 case MODEQ:
2817 return BITYPE|DIVFLG|ASGFLG|ASGOPFLG;
2818 case LSEQ:
2819 case RSEQ:
2820 return BITYPE|SHFFLG|ASGFLG|ASGOPFLG;
2821 case INCR:
2822 case DECR:
2823 return BITYPE|ASGFLG;
2825 cerror("cdope missing op %d", op);
2826 return 0; /* XXX gcc */
2830 * make a fresh copy of p
2832 NODE *
2833 ccopy(NODE *p)
2835 NODE *q;
2837 q = talloc();
2838 *q = *p;
2840 switch (coptype(q->n_op)) {
2841 case BITYPE:
2842 q->n_right = ccopy(p->n_right);
2843 case UTYPE:
2844 q->n_left = ccopy(p->n_left);
2847 return(q);
2851 * set PROG-seg label.
2853 void
2854 plabel(int label)
2856 reached = 1; /* Will this always be correct? */
2857 send_passt(IP_DEFLAB, label);
2861 * Perform integer promotion on node n.
2863 NODE *
2864 intprom(NODE *n)
2866 if ((n->n_type >= CHAR && n->n_type < INT) || n->n_type == BOOL) {
2867 if ((n->n_type == UCHAR && MAX_UCHAR > MAX_INT) ||
2868 (n->n_type == USHORT && MAX_USHORT > MAX_INT))
2869 return makety(n, UNSIGNED, 0, 0, MKAP(UNSIGNED));
2870 return makety(n, INT, 0, 0, MKAP(INT));
2872 return n;
2876 * Return CON/VOL/0, whichever are active for the current type.
2879 cqual(TWORD t, TWORD q)
2881 while (ISARY(t))
2882 t = DECREF(t), q = DECQAL(q);
2883 if (t <= BTMASK)
2884 q <<= TSHIFT;
2885 return q & (CON|VOL);
2888 int crslab = 10;
2890 * Return a number for internal labels.
2893 getlab(void)
2895 return crslab++;