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