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