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