source: mainline/uspace/app/pcc/cc/ccom/trees.c@ fae4d30

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since fae4d30 was 98a0fd3, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 14 years ago

Make C compiler build.

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