1 /* $Id: trees.c,v 1.272.2.1 2011/03/01 17:39:28 ragge Exp $ */
3 * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
32 * Redistribution and use in source and binary forms, with or without
33 * modification, are permitted provided that the following conditions
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
45 * Neither the name of Caldera International, Inc. nor the names of other
46 * contributors may be used to endorse or promote products derived from
47 * this software without specific prior written permission.
49 * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
50 * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
51 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
52 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
53 * DISCLAIMED. IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE
54 * FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
55 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
56 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
57 * HOWEVER CAUSED AND ON ANY THEORY OFLIABILITY, WHETHER IN CONTRACT,
58 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
59 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
60 * POSSIBILITY OF SUCH DAMAGE.
63 * Some of the changes from 32V include:
64 * - Understand "void" as type.
65 * - Handle enums as ints everywhere.
66 * - Convert some C-specific ops into branches.
75 static void chkpun(NODE
*p
);
76 static int opact(NODE
*p
);
77 static int moditype(TWORD
);
78 static NODE
*strargs(NODE
*);
79 static void rmcops(NODE
*p
);
80 void putjops(NODE
*, void *);
81 static struct symtab
*findmember(struct symtab
*, char *);
82 int inftn
; /* currently between epilog/prolog */
84 static char *tnames
[] = {
105 "signed", /* pass1 */
110 "fcomplex", /* pass1 */
111 "dcomplex", /* pass1 */
112 "lcomplex", /* pass1 */
113 "enumty", /* pass1 */
117 /* some special actions, used in finding the type of nodes */
127 # define PTMATCH 02000
129 # define NCVTR 010000
133 NAME: rval>0 is stab index for external
134 rval<0 is -inlabel number
135 lval is offset in bits
136 ICON: lval has the value
137 rval has the STAB index, or - label number,
138 if a name whose address is in the constant
139 rval = NONAME means no name
140 REG: rval is reg. identification cookie
148 buildtree(int o
, NODE
*l
, NODE
*r
)
153 struct symtab
*sp
= NULL
; /* XXX gcc */
158 printf("buildtree(%s, %p, %p)\n", copst(o
), l
, r
);
159 if (l
) fwalk(l
, eprint
, 0);
160 if (r
) fwalk(r
, eprint
, 0);
165 /* check for constants */
167 if (o
== ANDAND
|| o
== OROR
|| o
== NOT
) {
168 if (l
->n_op
== FCON
) {
169 p
= bcon(!FLOAT_ISZERO(l
->n_dcon
));
173 if (o
!= NOT
&& r
->n_op
== FCON
) {
174 p
= bcon(!FLOAT_ISZERO(r
->n_dcon
));
180 if( opty
== UTYPE
&& l
->n_op
== ICON
){
187 if( conval( l
, o
, l
) ) return(l
);
190 } else if (o
== NOT
&& l
->n_op
== FCON
) {
191 l
= clocal(block(SCONV
, l
, NIL
, INT
, 0, MKAP(INT
)));
192 } else if( o
== UMINUS
&& l
->n_op
== FCON
){
193 l
->n_dcon
= FLOAT_NEG(l
->n_dcon
);
196 } else if( o
==QUEST
&& l
->n_op
==ICON
) {
200 walkf(r
->n_right
, putjops
, 0);
204 walkf(r
->n_left
, putjops
, 0);
210 } else if( opty
== BITYPE
&& l
->n_op
== ICON
&& r
->n_op
== ICON
){
220 * Do type propagation for simple types here.
221 * The constant value is correct anyway.
222 * Maybe this op shortcut should be removed?
224 if (l
->n_sp
== NULL
&& r
->n_sp
== NULL
&&
225 l
->n_type
< BTMASK
&& r
->n_type
< BTMASK
) {
226 if (l
->n_type
> r
->n_type
)
227 r
->n_type
= l
->n_type
;
229 l
->n_type
= r
->n_type
;
249 if (!ISPTR(l
->n_type
) && !ISPTR(r
->n_type
)) {
250 if( conval( l
, o
, r
) ) {
257 } else if (opty
== BITYPE
&& (l
->n_op
== FCON
|| l
->n_op
== ICON
) &&
258 (r
->n_op
== FCON
|| r
->n_op
== ICON
) && (o
== PLUS
|| o
== MINUS
||
259 o
== MUL
|| o
== DIV
|| (o
>= EQ
&& o
<= GT
) )) {
263 ((r
->n_op
== ICON
&& r
->n_lval
== 0) ||
264 (r
->n_op
== FCON
&& r
->n_dcon
== 0.0)))
265 goto runtime
; /* HW dependent */
268 l
->n_dcon
= FLOAT_CAST(l
->n_lval
, l
->n_type
);
270 r
->n_dcon
= FLOAT_CAST(r
->n_lval
, r
->n_type
);
278 l
->n_dcon
= FLOAT_PLUS(l
->n_dcon
, r
->n_dcon
);
281 l
->n_dcon
= FLOAT_MINUS(l
->n_dcon
, r
->n_dcon
);
284 l
->n_dcon
= FLOAT_MUL(l
->n_dcon
, r
->n_dcon
);
287 l
->n_dcon
= FLOAT_DIV(l
->n_dcon
, r
->n_dcon
);
290 t
= (l
->n_type
> r
->n_type
? l
->n_type
: r
->n_type
);
304 l
->n_lval
= FLOAT_EQ(l
->n_dcon
, r
->n_dcon
);
307 l
->n_lval
= FLOAT_NE(l
->n_dcon
, r
->n_dcon
);
310 l
->n_lval
= FLOAT_LE(l
->n_dcon
, r
->n_dcon
);
313 l
->n_lval
= FLOAT_LT(l
->n_dcon
, r
->n_dcon
);
316 l
->n_lval
= FLOAT_GE(l
->n_dcon
, r
->n_dcon
);
319 l
->n_lval
= FLOAT_GT(l
->n_dcon
, r
->n_dcon
);
331 /* its real; we must make a new node */
333 p
= block(o
, l
, r
, INT
, 0, MKAP(INT
));
337 if (actions
& LVAL
) { /* check left descendent */
338 if (notlval(p
->n_left
)) {
339 uerror("lvalue required");
344 if ((l
->n_type
> BTMASK
&& ISCON(l
->n_qual
)) ||
345 (l
->n_type
<= BTMASK
&& ISCON(l
->n_qual
<< TSHIFT
)))
347 uerror("lvalue is declared const");
352 if( actions
& NCVTR
){
353 p
->n_left
= pconvert( p
->n_left
);
355 else if( !(actions
& NCVT
) ){
359 p
->n_right
= pconvert( p
->n_right
);
361 p
->n_left
= pconvert( p
->n_left
);
366 if ((actions
&PUN
) && (o
!=CAST
))
369 if( actions
& (TYPL
|TYPR
) ){
371 q
= (actions
&TYPL
) ? p
->n_left
: p
->n_right
;
373 p
->n_type
= q
->n_type
;
374 p
->n_qual
= q
->n_qual
;
379 if( actions
& CVTL
) p
= convert( p
, CVTL
);
380 if( actions
& CVTR
) p
= convert( p
, CVTR
);
381 if( actions
& TYMATCH
) p
= tymatch(p
);
382 if( actions
& PTMATCH
) p
= ptmatch(p
);
384 if( actions
& OTHER
){
393 cerror("buildtree NAME");
396 /* p->x turned into *(p+offset) */
397 /* rhs must be a name; check correctness */
399 /* Find member symbol struct */
400 if (l
->n_type
!= PTR
+STRTY
&& l
->n_type
!= PTR
+UNIONTY
){
401 uerror("struct or union required");
405 if ((sp1
= strmemb(l
->n_ap
)) == NULL
) {
406 uerror("undefined struct or union");
410 if ((sp
= findmember(sp1
, r
->n_name
)) == NULL
) {
411 uerror("member '%s' not declared", r
->n_name
);
420 if (l
->n_op
== ADDROF
) {
425 if( !ISPTR(l
->n_type
))uerror("illegal indirection");
426 p
->n_type
= DECREF(l
->n_type
);
427 p
->n_qual
= DECREF(l
->n_qual
);
441 p
->n_type
= INCREF(l
->n_type
);
442 p
->n_qual
= INCQAL(l
->n_qual
);
449 lr
= buildtree(ADDROF
, l
->n_right
, NIL
);
450 p
= buildtree( COMOP
, l
->n_left
, lr
);
455 lr
= buildtree( ADDROF
, l
->n_right
->n_right
, NIL
);
456 ll
= buildtree( ADDROF
, l
->n_right
->n_left
, NIL
);
457 nfree(p
); nfree(l
->n_right
);
458 p
= buildtree( QUEST
, l
->n_left
, buildtree( COLON
, ll
, lr
) );
463 uerror("unacceptable operand of &: %d", l
->n_op
);
469 case RS
: /* must make type size at least int... */
470 if (p
->n_type
== CHAR
|| p
->n_type
== SHORT
) {
471 p
->n_left
= makety(l
, INT
, 0, 0, MKAP(INT
));
472 } else if (p
->n_type
== UCHAR
|| p
->n_type
== USHORT
) {
473 p
->n_left
= makety(l
, UNSIGNED
, 0, 0,
477 p
->n_type
= l
->n_type
;
478 p
->n_qual
= l
->n_qual
;
484 case RSEQ
: /* ...but not for assigned types */
485 if(tsize(r
->n_type
, r
->n_df
, r
->n_ap
) > SZINT
)
486 p
->n_right
= makety(r
, INT
, 0, 0, MKAP(INT
));
492 /* structure assignment */
493 /* take the addresses of the two sides; then make an
494 * operator using STASG and
495 * the addresses of left and right */
497 if (strmemb(l
->n_ap
) != strmemb(r
->n_ap
))
498 uerror("assignment of different structures");
500 r
= buildtree(ADDROF
, r
, NIL
);
502 l
= block(STASG
, l
, r
, r
->n_type
, r
->n_df
, r
->n_ap
);
516 case QUEST
: /* fixup types of : */
517 if (r
->n_left
->n_type
!= p
->n_type
)
518 r
->n_left
= makety(r
->n_left
, p
->n_type
,
519 p
->n_qual
, p
->n_df
, p
->n_ap
);
520 if (r
->n_right
->n_type
!= p
->n_type
)
521 r
->n_right
= makety(r
->n_right
, p
->n_type
,
522 p
->n_qual
, p
->n_df
, p
->n_ap
);
526 /* structure colon */
528 if (strmemb(l
->n_ap
) != strmemb(r
->n_ap
))
529 uerror( "type clash in conditional" );
533 p
->n_right
= r
= strargs(p
->n_right
);
537 if (!ISPTR(l
->n_type
))
538 uerror("illegal function");
539 p
->n_type
= DECREF(l
->n_type
);
540 if (!ISFTN(p
->n_type
))
541 uerror("illegal function");
542 p
->n_type
= DECREF(p
->n_type
);
543 p
->n_df
= l
->n_df
+1; /* add one for prototypes */
545 if (p
->n_type
== STRTY
|| p
->n_type
== UNIONTY
) {
546 /* function returning structure */
547 /* make function really return ptr to str., with * */
549 p
->n_op
+= STCALL
-CALL
;
550 p
->n_type
= INCREF(p
->n_type
);
551 p
= clocal(p
); /* before recursing */
552 p
= buildtree(UMUL
, p
, NIL
);
558 cerror( "other code %d", o
);
564 * Allow (void)0 casts.
565 * XXX - anything on the right side must be possible to cast.
566 * XXX - remove void types further on.
568 if (p
->n_op
== CAST
&& p
->n_type
== VOID
&&
569 p
->n_right
->n_op
== ICON
)
570 p
->n_right
->n_type
= VOID
;
578 printf("End of buildtree:\n");
587 /* Find a member in a struct or union. May be an unnamed member */
588 static struct symtab
*
589 findmember(struct symtab
*sp
, char *s
)
591 struct symtab
*sp2
, *sp3
;
593 for (; sp
!= NULL
; sp
= sp
->snext
) {
594 if (sp
->sname
[0] == '*') {
595 /* unnamed member, recurse down */
596 if ((sp2
= findmember(strmemb(sp
->sap
), s
))) {
597 sp3
= tmpalloc(sizeof (struct symtab
));
599 sp3
->soffset
+= sp
->soffset
;
602 } else if (sp
->sname
== s
)
610 * Check if there will be a lost label destination inside of a ?:
611 * It cannot be reached so just print it out.
614 putjops(NODE
*p
, void *arg
)
616 if (p
->n_op
== COMOP
&& p
->n_left
->n_op
== GOTO
)
617 plabel(p
->n_left
->n_left
->n_lval
+1);
621 * Build a name node based on a symtab entry.
622 * broken out from buildtree().
625 nametree(struct symtab
*sp
)
629 p
= block(NAME
, NIL
, NIL
, sp
->stype
, sp
->sdf
, sp
->sap
);
630 p
->n_qual
= sp
->squal
;
633 #ifndef NO_C_BUILTINS
634 if (sp
->sname
[0] == '_' && strncmp(sp
->sname
, "__builtin_", 10) == 0)
635 return p
; /* do not touch builtins here */
639 if (sp
->sflags
& STNODE
) {
640 /* Generated for optimizer */
642 p
->n_rval
= sp
->soffset
;
646 /* Get a label name */
647 if (sp
->sflags
== SLBLNAME
) {
649 p
->n_ap
= MKAP(VOID
);
652 if (sp
->stype
== UNDEF
) {
653 uerror("%s undefined", sp
->sname
);
654 /* make p look reasonable */
660 if (sp
->sclass
== MOE
) {
662 p
->n_lval
= sp
->soffset
;
670 * Cast a node to another type by inserting a cast.
671 * Just a nicer interface to buildtree.
672 * Returns the new tree.
675 cast(NODE
*p
, TWORD t
, TWORD u
)
679 q
= block(NAME
, NIL
, NIL
, t
, 0, MKAP(BTYPE(t
)));
681 q
= buildtree(CAST
, q
, p
);
689 * Cast and complain if necessary by not inserining a cast.
692 ccast(NODE
*p
, TWORD t
, TWORD u
, union dimfun
*df
, struct attr
*ap
)
696 /* let buildtree do typechecking (and casting) */
697 q
= block(NAME
, NIL
, NIL
, t
, df
, ap
);
698 p
= buildtree(ASSIGN
, q
, p
);
700 q
= optim(p
->n_right
);
706 * Do a conditional branch.
709 cbranch(NODE
*p
, NODE
*q
)
711 p
= buildtree(CBRANCH
, p
, q
);
712 if (p
->n_left
->n_op
== ICON
) {
713 if (p
->n_left
->n_lval
!= 0) {
714 branch(q
->n_lval
); /* branch always */
725 strargs( p
) register NODE
*p
; { /* rewrite structure flavored arguments */
728 p
->n_left
= strargs( p
->n_left
);
729 p
->n_right
= strargs( p
->n_right
);
733 if( p
->n_type
== STRTY
|| p
->n_type
== UNIONTY
){
734 p
= block(STARG
, p
, NIL
, p
->n_type
, p
->n_df
, p
->n_ap
);
735 p
->n_left
= buildtree( ADDROF
, p
->n_left
, NIL
);
742 * apply the op o to the lval part of p; if binary, rhs is val
745 conval(NODE
*p
, int o
, NODE
*q
)
747 TWORD tl
= p
->n_type
, tr
= q
->n_type
, td
;
754 /* make both sides same type */
755 if (tl
< BTMASK
&& tr
< BTMASK
) {
756 td
= tl
> tr
? tl
: tr
;
761 p
= makety(p
, td
, 0, 0, MKAP(td
));
763 q
= makety(q
, td
, 0, 0, MKAP(td
));
765 u
= ISUNSIGNED(tl
) || ISUNSIGNED(tr
);
766 if( u
&& (o
==LE
||o
==LT
||o
==GE
||o
==GT
)) o
+= (UGE
-GE
);
768 if (p
->n_sp
!= NULL
&& q
->n_sp
!= NULL
)
770 if (q
->n_sp
!= NULL
&& o
!= PLUS
)
772 if (p
->n_sp
!= NULL
&& o
!= PLUS
&& o
!= MINUS
)
781 if (p
->n_sp
== NULL
) {
782 p
->n_right
= q
->n_right
;
783 p
->n_type
= q
->n_type
;
794 uerror("division by 0");
805 uerror("division by 0");
825 p
->n_lval
= p
->n_lval
<< i
;
833 p
->n_lval
= p
->n_lval
>> i
;
837 p
->n_lval
= - p
->n_lval
;
840 p
->n_lval
= ~p
->n_lval
;
843 p
->n_lval
= !p
->n_lval
;
846 p
->n_lval
= p
->n_lval
< val
;
849 p
->n_lval
= p
->n_lval
<= val
;
852 p
->n_lval
= p
->n_lval
> val
;
855 p
->n_lval
= p
->n_lval
>= val
;
861 p
->n_lval
= v1
<= v2
;
867 p
->n_lval
= v1
>= v2
;
870 p
->n_lval
= p
->n_lval
== val
;
873 p
->n_lval
= p
->n_lval
!= val
;
876 p
->n_lval
= p
->n_lval
&& val
;
879 p
->n_lval
= p
->n_lval
|| val
;
884 /* Do the best in making everything type correct after calc */
885 if (p
->n_sp
== NULL
&& q
->n_sp
== NULL
)
886 p
->n_lval
= valcast(p
->n_lval
, p
->n_type
);
891 * Ensure that v matches the type t; sign- or zero-extended
892 * as suitable to CONSZ.
893 * Only to be used for integer types.
896 valcast(CONSZ v
, TWORD t
)
900 if (t
< CHAR
|| t
> ULONGLONG
)
901 return v
; /* cannot cast */
904 return v
; /* already largest */
906 #define M(x) ((((1ULL << ((x)-1)) - 1) << 1) + 1)
907 #define NOTM(x) (~M(x))
908 #define SBIT(x) (1ULL << ((x)-1))
910 r
= v
& M(btattr
[t
].atypsz
);
911 if (!ISUNSIGNED(t
) && (SBIT(btattr
[t
].atypsz
) & r
))
912 r
= r
| NOTM(btattr
[t
].atypsz
);
917 * Checks p for the existance of a pun. This is called when the op of p
918 * is ASSIGN, RETURN, CAST, COLON, or relational.
919 * One case is when enumerations are used: this applies only to lint.
920 * In the other case, one operand is a pointer, the other integer type
921 * we check that this integer is in fact a constant zero...
922 * in the case of ASSIGN, any assignment of pointer to integer is illegal
923 * this falls out, because the LHS is never 0.
924 * XXX - check for COMOPs in assignment RHS?
929 union dimfun
*d1
, *d2
;
933 t1
= p
->n_left
->n_type
;
934 t2
= p
->n_right
->n_type
;
938 /* return of void allowed but nothing else */
939 if (t1
== VOID
&& t2
== VOID
)
942 werror("returning value from void function");
946 uerror("using void value");
950 if (t1
== VOID
&& t2
== VOID
)
954 if ((t1
== VOID
&& t2
!= VOID
) || (t1
!= VOID
&& t2
== VOID
)) {
955 uerror("value of void expression used");
961 /* allow void pointer assignments in any direction */
962 if (BTYPE(t1
) == VOID
&& (t2
& TMASK
))
964 if (BTYPE(t2
) == VOID
&& (t1
& TMASK
))
967 /* boolean have special syntax */
969 if (!ISARY(t2
)) /* Anything scalar */
973 if (ISPTR(t1
) || ISARY(t1
))
978 if (!ISPTR(q
->n_type
) && !ISARY(q
->n_type
)) {
979 if (q
->n_op
!= ICON
|| q
->n_lval
!= 0)
980 werror("illegal combination of pointer and integer");
983 if (ISSOU(BTYPE(t1
)) &&
984 !suemeq(p
->n_left
->n_ap
, p
->n_right
->n_ap
))
985 werror("illegal structure pointer combination");
988 d1
= p
->n_left
->n_df
;
989 d2
= p
->n_right
->n_df
;
991 if (ISARY(t1
) || ISPTR(t1
)) {
992 if (!ISARY(t2
) && !ISPTR(t2
))
994 if (ISARY(t1
) && ISARY(t2
) && d1
->ddim
!= d2
->ddim
) {
995 werror("illegal array size combination");
1002 } else if (ISFTN(t1
)) {
1003 if (chkftn(d1
->dfun
, d2
->dfun
)) {
1004 werror("illegal function "
1005 "pointer combination");
1015 if (DEUNSIGN(t1
) != DEUNSIGN(t2
))
1016 warner(Wpointer_sign
, NULL
);
1032 /* this is also used to reference automatic variables */
1034 s
= p
->n_right
->n_sp
;
1040 /* make p look like ptr to x */
1042 if (!ISPTR(p
->n_type
))
1043 p
->n_type
= PTR
+UNIONTY
;
1045 t
= INCREF(s
->stype
);
1046 q
= INCQAL(s
->squal
);
1050 p
= makety(p
, t
, q
, d
, ap
);
1052 /* compute the offset to be added */
1059 * If its a packed struct, and the target cannot do unaligned
1060 * accesses, then split it up in two bitfield operations.
1061 * LHS and RHS accesses are different, so must delay
1062 * it until we know. Do the bitfield construct here though.
1064 if ((dsc
& FIELD
) == 0 && (off
% talign(s
->stype
, s
->sap
))) {
1066 int sz
= tsize(s
->stype
, s
->sdf
, s
->sap
);
1067 int al
= talign(s
->stype
, s
->sap
);
1068 int sz1
= al
- (off
% al
);
1074 if (dsc
& FIELD
) { /* make fields look like ints */
1075 off
= (off
/ALINT
)*ALINT
;
1080 p
= block(PLUS
, p
, offcon(off
, t
, d
, ap
), t
, d
, ap
);
1085 p
= buildtree(UMUL
, p
, NIL
);
1087 /* if field, build field info */
1090 p
= block(FLD
, p
, NIL
, s
->stype
, 0, s
->sap
);
1092 p
->n_rval
= PKFIELD(dsc
&FLDSIZ
, s
->soffset
%talign(s
->stype
, ap
));
1100 notlval(p
) register NODE
*p
; {
1102 /* return 0 if p an lvalue, 1 otherwise */
1115 if( ISARY(p
->n_type
) || ISFTN(p
->n_type
) ) return(1);
1126 /* make a constant node with value i */
1130 return xbcon(i
, NULL
, INT
);
1134 xbcon(CONSZ val
, struct symtab
*sp
, TWORD type
)
1138 p
= block(ICON
, NIL
, NIL
, type
, 0, MKAP(type
));
1147 int isdyn(struct symtab
*sp
);
1153 s
.stype
= DECREF(p
->n_type
);
1157 for (t
= s
.stype
; t
> BTMASK
; t
= DECREF(t
)) {
1159 return buildtree(MUL
, q
, bcon(SZPOINT(t
)));
1161 if (s
.sdf
->ddim
< 0)
1162 r
= tempnode(-s
.sdf
->ddim
,
1165 r
= bcon(s
.sdf
->ddim
/SZCHAR
);
1166 q
= buildtree(MUL
, q
, r
);
1170 ap
= attr_find(p
->n_ap
, ATTR_BASETYP
);
1171 p
= buildtree(MUL
, q
, bcon(ap
->atypsz
/SZCHAR
));
1173 p
= (offcon(psize(p
), p
->n_type
, p
->n_df
, p
->n_ap
));
1178 * p is a node of type pointer; psize returns the
1179 * size of the thing pointed to
1185 if (!ISPTR(p
->n_type
)) {
1186 uerror("pointer required");
1189 /* note: no pointers to fields */
1190 return(tsize(DECREF(p
->n_type
), p
->n_df
, p
->n_ap
));
1194 * convert an operand of p
1195 * f is either CVTL or CVTR
1196 * operand has type int, and is converted by the size of the other side
1197 * convert is called when an integer is to be added to a pointer, for
1198 * example in arrays or structures.
1201 convert(NODE
*p
, int f
)
1205 NODE
*q
, *r
, *s
, *rv
;
1214 ty2
= ty
= DECREF(s
->n_type
);
1218 r
= offcon(tsize(ty
, s
->n_df
, s
->n_ap
), s
->n_type
, s
->n_df
, s
->n_ap
);
1223 rv
= buildtree(MUL
, rv
, df
->ddim
>= 0 ? bcon(df
->ddim
) :
1224 tempnode(-df
->ddim
, INT
, 0, MKAP(INT
)));
1228 rv
= clocal(block(PMCONV
, rv
, r
, INT
, 0, MKAP(INT
)));
1231 r
= block(PMCONV
, q
, rv
, INT
, 0, MKAP(INT
));
1234 * Indexing is only allowed with integer arguments, so insert
1235 * SCONV here if arg is not an integer.
1238 if (r
->n_type
!= INTPTR
)
1239 r
= clocal(block(SCONV
, r
, NIL
, INTPTR
, 0, MKAP(INTPTR
)));
1248 pconvert( p
) register NODE
*p
; {
1250 /* if p should be changed into a pointer, do so */
1252 if( ISARY( p
->n_type
) ){
1253 p
->n_type
= DECREF( p
->n_type
);
1255 return( buildtree( ADDROF
, p
, NIL
) );
1257 if( ISFTN( p
->n_type
) )
1258 return( buildtree( ADDROF
, p
, NIL
) );
1264 oconvert(p
) register NODE
*p
; {
1265 /* convert the result itself: used for pointer and unsigned */
1273 if(ISUNSIGNED(p
->n_left
->n_type
) ||
1274 ISUNSIGNED(p
->n_right
->n_type
) ||
1275 ISPTR(p
->n_left
->n_type
) ||
1276 ISPTR(p
->n_right
->n_type
))
1277 p
->n_op
+= (ULE
-LE
);
1285 p
->n_ap
= MKAP(INTPTR
);
1286 return( clocal( block( PVCONV
,
1287 p
, bpsize(p
->n_left
), INT
, 0, MKAP(INT
))));
1290 cerror( "illegal oconvert: %d", p
->n_op
);
1296 * makes the operands of p agree; they are
1297 * either pointers or integers, by this time
1298 * with MINUS, the sizes must be the same
1299 * with COLON, the types must be the same
1304 struct attr
*ap
, *ap2
;
1305 union dimfun
*d
, *d2
;
1306 TWORD t1
, t2
, t
, q1
, q2
, q
;
1310 t
= t1
= p
->n_left
->n_type
;
1311 q
= q1
= p
->n_left
->n_qual
;
1312 t2
= p
->n_right
->n_type
;
1313 q2
= p
->n_right
->n_qual
;
1314 d
= p
->n_left
->n_df
;
1315 d2
= p
->n_right
->n_df
;
1316 ap
= p
->n_left
->n_ap
;
1317 ap2
= p
->n_right
->n_ap
;
1327 int isdyn(struct symtab
*sp
);
1328 struct symtab s1
, s2
;
1330 s1
.stype
= DECREF(t
);
1332 s2
.stype
= DECREF(t2
);
1334 if (isdyn(&s1
) || isdyn(&s2
))
1335 ; /* We don't know */
1336 else if (psize(p
->n_left
) != psize(p
->n_right
))
1337 uerror("illegal pointer subtraction");
1344 * Check for void pointer types. They are allowed
1345 * to cast to/from any pointers.
1347 if (ISPTR(t1
) && ISPTR(t2
) &&
1348 (BTYPE(t1
) == VOID
|| BTYPE(t2
) == VOID
))
1350 uerror("illegal types in :");
1354 default: /* must work harder: relationals or comparisons */
1367 /* both are pointers */
1368 if( talign(t2
,ap2
) < talign(t
,ap
) ){
1376 p
->n_left
= makety( p
->n_left
, t
, q
, d
, ap
);
1377 p
->n_right
= makety( p
->n_right
, t
, q
, d
, ap
);
1378 if( o
!=MINUS
&& !clogop(o
) ){
1393 * Satisfy the types of various arithmetic binary ops.
1396 * if assignment, type of LHS
1397 * if any doubles, make double
1398 * else if any float make float
1399 * else if any longlongs, make long long
1400 * else if any longs, make long
1403 * If the op with the highest rank is unsigned, this is the resulting type.
1404 * See: 6.3.1.1 rank order equal of signed and unsigned types
1405 * 6.3.1.8 Usual arithmetic conversions
1410 TWORD tl
, tr
, t
, tu
;
1422 if (ISUNSIGNED(tl
)) {
1426 if (ISUNSIGNED(tr
)) {
1431 if (clogop(o
) && tl
== tr
&& lu
!= ru
&&
1432 l
->n_op
!= ICON
&& r
->n_op
!= ICON
)
1433 warner(Wsign_compare
, NULL
);
1435 if (tl
== LDOUBLE
|| tr
== LDOUBLE
)
1437 else if (tl
== DOUBLE
|| tr
== DOUBLE
)
1439 else if (tl
== FLOAT
|| tr
== FLOAT
)
1441 else if (tl
==LONGLONG
|| tr
== LONGLONG
)
1443 else if (tl
==LONG
|| tr
==LONG
)
1445 else /* everything else */
1452 /* Should result be unsigned? */
1453 /* This depends on ctype() being called correctly */
1455 if (UNSIGNABLE(t
) && (lu
|| ru
)) {
1463 /* because expressions have values that are at least as wide
1464 as INT or UNSIGNED, the only conversions needed
1465 are those involving FLOAT/DOUBLE, and those
1466 from LONG to INT and ULONG to UNSIGNED */
1468 if (t
!= tl
|| (ru
&& !lu
)) {
1469 if (o
!= CAST
&& r
->n_op
!= ICON
&&
1470 tsize(tl
, 0, MKAP(tl
)) > tsize(tu
, 0, MKAP(tu
)))
1471 warner(Wtruncate
, tnames
[tu
], tnames
[tl
]);
1472 p
->n_left
= makety( p
->n_left
, tu
, 0, 0, MKAP(tu
));
1475 if (t
!= tr
|| o
==CAST
|| (lu
&& !ru
)) {
1476 if (o
!= CAST
&& r
->n_op
!= ICON
&&
1477 tsize(tr
, 0, MKAP(tr
)) > tsize(tu
, 0, MKAP(tu
)))
1478 warner(Wtruncate
, tnames
[tu
], tnames
[tr
]);
1479 p
->n_right
= makety(p
->n_right
, tu
, 0, 0, MKAP(tu
));
1483 p
->n_type
= p
->n_left
->n_type
;
1484 p
->n_df
= p
->n_left
->n_df
;
1485 p
->n_ap
= p
->n_left
->n_ap
;
1487 else if( !clogop(o
) ){
1495 printf("tymatch(%p): ", p
);
1496 tprint(stdout
, tl
, 0);
1497 printf(" %s ", copst(o
));
1498 tprint(stdout
, tr
, 0);
1500 tprint(stdout
, tu
, 0);
1502 fwalk(p
, eprint
, 0);
1510 * Create a float const node of zero.
1515 NODE
*p
= block(FCON
, NIL
, NIL
, t
, 0, MKAP(t
));
1517 p
->n_dcon
= FLOAT_CAST(0, INT
);
1522 * make p into type t by inserting a conversion
1525 makety(NODE
*p
, TWORD t
, TWORD q
, union dimfun
*d
, struct attr
*ap
)
1528 if (t
== p
->n_type
) {
1535 if (p
->n_op
== FCON
&& (t
>= FLOAT
&& t
<= LDOUBLE
)) {
1537 p
->n_dcon
= (float)p
->n_dcon
;
1538 else if (t
== DOUBLE
)
1539 p
->n_dcon
= (double)p
->n_dcon
;
1541 p
->n_dcon
= (long double)p
->n_dcon
;
1546 if (p
->n_op
== FCON
) {
1550 if (isf
||ISITY(t
)) {
1551 if (isf
== ISFTY(p
->n_type
)) {
1557 } else if (isf
== ISITY(p
->n_type
)) {
1561 } else if (ISCTY(p
->n_type
))
1562 cerror("complex constant");
1563 } else if (ISCTY(t
)) {
1564 if (ISITY(p
->n_type
)) {
1565 /* convert to correct subtype */
1566 r
= fzero(t
- (COMPLEX
-DOUBLE
));
1567 p
->n_type
= t
+ (IMAG
-COMPLEX
);
1570 p
->n_ap
= MKAP(p
->n_type
);
1571 return block(CM
, r
, p
, t
, 0, MKAP(t
));
1572 } else if (ISFTY(p
->n_type
)) {
1573 /* convert to correct subtype */
1574 r
= fzero(t
+ (IMAG
-COMPLEX
));
1575 p
->n_type
= t
- (COMPLEX
-DOUBLE
);
1578 p
->n_ap
= MKAP(p
->n_type
);
1579 return block(CM
, p
, r
, t
, 0, MKAP(t
));
1580 } else if (ISCTY(p
->n_type
))
1581 cerror("complex constant2");
1586 /* non-simple type */
1587 p
= block(PCONV
, p
, NIL
, t
, d
, ap
);
1592 if (p
->n_op
== ICON
) {
1595 p
->n_dcon
= FLOAT_CAST(p
->n_lval
, p
->n_type
);
1600 } else if (ISCTY(t
) || ISITY(t
))
1601 cerror("complex constant3");
1604 p
= block(SCONV
, p
, NIL
, t
, d
, ap
);
1611 block(int o
, NODE
*l
, NODE
*r
, TWORD t
, union dimfun
*d
, struct attr
*ap
)
1618 p
->n_lval
= 0; /* Protect against large lval */
1625 #if !defined(MULTIPASS)
1626 /* p->n_reg = */p
->n_su
= 0;
1633 * Return the constant value from an ICON.
1638 /* if p is an integer constant, return its value */
1641 if (p
->n_op
!= ICON
|| p
->n_sp
!= NULL
) {
1642 uerror( "constant expected");
1651 * the intent of this table is to examine the
1652 * operators, and to check them for
1655 * The table is searched for the op and the
1656 * modified type (where this is one of the
1657 * types INT (includes char and short), LONG,
1658 * DOUBLE (includes FLOAT), and POINTER
1660 * The default action is to make the node type integer
1662 * The actions taken include:
1663 * PUN check for puns
1664 * CVTL convert the left operand
1665 * CVTR convert the right operand
1666 * TYPL the type is determined by the left operand
1667 * TYPR the type is determined by the right operand
1668 * TYMATCH force type of left and right to match,by inserting conversions
1669 * PTMATCH like TYMATCH, but for pointers
1670 * LVAL left operand must be lval
1671 * CVTO convert the op
1672 * NCVT do not convert the operands
1673 * OTHER handled by code
1674 * NCVTR convert the left operand, not the right...
1678 # define MINT 01 /* integer */
1679 # define MDBI 02 /* integer or double */
1680 # define MSTR 04 /* structure */
1681 # define MPTR 010 /* pointer */
1682 # define MPTI 020 /* pointer or integer */
1687 int mt12
, mt1
, mt2
, o
;
1689 mt1
= mt2
= mt12
= 0;
1691 switch (coptype(o
= p
->n_op
)) {
1693 mt12
=mt2
= moditype(p
->n_right
->n_type
);
1695 mt12
&= (mt1
= moditype(p
->n_left
->n_type
));
1707 { return( OTHER
); }
1709 if( mt1
& MDBI
) return( TYPL
);
1713 if( mt1
& MINT
) return( TYPL
);
1717 return( NCVT
+OTHER
);
1728 if( mt12
& MDBI
) return( TYMATCH
);
1735 if( mt12
& MINT
) return( TYMATCH
);
1740 if( mt12
& MINT
) return( TYPL
+OTHER
);
1749 if( mt12
& MDBI
) return( TYMATCH
+CVTO
);
1750 else if( mt12
& MPTR
) return( PTMATCH
+PUN
+CVTO
);
1751 else if( mt12
& MPTI
) return( PTMATCH
+PUN
);
1755 return( TYPR
+OTHER
);
1760 return( NCVTR
+OTHER
);
1766 if( mt12
& MDBI
) return( TYMATCH
);
1767 else if( mt12
& MPTR
) return( TYPL
+PTMATCH
+PUN
);
1768 else if( (mt1
&MINT
) && (mt2
&MPTR
) ) return( TYPR
+PUN
);
1769 else if( (mt1
&MPTR
) && (mt2
&MINT
) ) return( TYPL
+PUN
);
1770 else if( mt12
& MSTR
) return( NCVT
+TYPL
+OTHER
);
1775 if( mt12
& MSTR
) return( LVAL
+NCVT
+TYPL
+OTHER
);
1777 if( mt12
& MDBI
) return( TYPL
+LVAL
+TYMATCH
);
1778 else if( mt1
& MPTR
) return( LVAL
+PTMATCH
+PUN
);
1779 else if( mt12
& MPTI
) return( TYPL
+LVAL
+TYMATCH
+PUN
);
1784 if( mt12
& MINT
) return( TYPL
+LVAL
+OTHER
);
1789 if( mt12
& MDBI
) return( LVAL
+TYMATCH
);
1797 return(LVAL
+TYMATCH
);
1805 return(TYMATCH
+LVAL
);
1806 else if ((mt1
&MPTR
) && (mt2
&MINT
))
1807 return(TYPL
+LVAL
+CVTR
);
1812 return(CVTO
+PTMATCH
+PUN
);
1819 else if ((mt1
&MPTR
) && (mt2
&MINT
))
1821 else if ((mt1
&MINT
) && (mt2
&MPTR
))
1825 uerror("operands of %s have incompatible types", copst(o
));
1849 return( MINT
|MDBI
|MPTI
);
1863 return( MPTR
|MPTI
);
1868 int tvaloff
= MAXREGS
+NPERMREG
> 100 ? MAXREGS
+NPERMREG
+ 100 : 100;
1871 * Returns a TEMP node with temp number nr.
1872 * If nr == 0, return a node with a new number.
1875 tempnode(int nr
, TWORD type
, union dimfun
*df
, struct attr
*ap
)
1879 if (tvaloff
== -NOOFFSET
)
1880 tvaloff
++; /* Skip this for array indexing */
1881 r
= block(TEMP
, NIL
, NIL
, type
, df
, ap
);
1882 regno(r
) = nr
? nr
: tvaloff
;
1883 tvaloff
+= szty(type
);
1893 extern NODE
*arrstk
[10];
1901 uerror("can't apply sizeof to bit-field");
1904 * Arrays may be dynamic, may need to make computations.
1912 if (df
->ddim
== NOOFFSET
)
1913 uerror("sizeof of incomplete type");
1916 q
= arrstk
[astkp
++];
1918 q
= tempnode(-df
->ddim
, INT
, 0, MKAP(INT
));
1921 rv
= buildtree(MUL
, rv
, q
);
1925 rv
= buildtree(MUL
, rv
, bcon(tsize(ty
, p
->n_df
, p
->n_ap
)/SZCHAR
));
1927 arrstkp
= 0; /* XXX - may this fail? */
1933 eprint(NODE
*p
, int down
, int *a
, int *b
)
1942 if( down
) printf( " " );
1944 ty
= coptype( p
->n_op
);
1946 printf("%p) %s, ", p
, copst(p
->n_op
));
1947 if (p
->n_op
== XARG
|| p
->n_op
== XASM
)
1948 printf("id '%s', ", p
->n_name
);
1950 printf(CONFMT
, p
->n_lval
);
1951 if (p
->n_op
== NAME
|| p
->n_op
== ICON
)
1952 printf(", %p, ", p
->n_sp
);
1954 printf(", %d, ", p
->n_rval
);
1956 tprint(stdout
, p
->n_type
, p
->n_qual
);
1957 printf( ", %p, ", p
->n_df
);
1963 * Emit everything that should be emitted on the left side
1964 * of a comma operator, and remove the operator.
1965 * Do not traverse through QUEST, ANDAND and OROR.
1966 * Enable this for all targets when stable enough.
1974 while (p
->n_op
== COMOP
) {
1975 /* XXX hack for GCC ({ }) ops */
1976 if (p
->n_left
->n_op
== GOTO
) {
1977 int v
= (int)p
->n_left
->n_left
->n_lval
;
1981 ecomp(p
->n_left
); /* will recurse if more COMOPs */
1986 o
= coptype(p
->n_op
);
1987 if (p
->n_op
== QUEST
|| p
->n_op
== ANDAND
|| p
->n_op
== OROR
)
1996 * Walk up through the tree from the leaves,
1997 * removing constant operators.
2002 int o
= coptype(p
->n_op
);
2015 if (!clogop(p
->n_op
))
2017 if (p
->n_op
== NOT
&& l
->n_op
== ICON
) {
2018 p
->n_lval
= l
->n_lval
== 0;
2022 if (l
->n_op
== ICON
&& r
->n_op
== ICON
) {
2023 if (conval(l
, p
->n_op
, r
) == 0) {
2025 * people sometimes tend to do really odd compares,
2026 * like "if ("abc" == "def")" etc.
2027 * do it runtime instead.
2030 p
->n_lval
= l
->n_lval
;
2039 * Removes redundant logical operators for branch conditions.
2042 fixbranch(NODE
*p
, int label
)
2047 if (p
->n_op
== ICON
) {
2052 if (!clogop(p
->n_op
)) /* Always conditional */
2053 p
= buildtree(NE
, p
, bcon(0));
2054 ecode(buildtree(CBRANCH
, p
, bcon(label
)));
2059 * Write out logical expressions as branches.
2062 andorbr(NODE
*p
, int true, int false)
2068 switch (o
= p
->n_op
) {
2072 * Remove redundant EQ/NE nodes.
2074 while (((o
= p
->n_left
->n_op
) == EQ
|| o
== NE
) &&
2075 p
->n_right
->n_op
== ICON
) {
2078 if (p
->n_right
->n_lval
== 0) {
2083 p
->n_op
= negrel
[p
->n_op
- EQ
];
2085 p
->n_op
= NE
; /* toggla */
2087 } else if (p
->n_right
->n_lval
== 1) {
2092 p
->n_op
= negrel
[p
->n_op
- EQ
];
2094 p
->n_op
= EQ
; /* toggla */
2097 break; /* XXX - should always be false */
2105 calc
: if (true < 0) {
2106 p
->n_op
= negrel
[p
->n_op
- EQ
];
2120 /* Convert to friendlier ops */
2121 if (p
->n_right
->n_op
== ICON
&& p
->n_right
->n_lval
== 0)
2122 p
->n_op
= o
== ULE
? EQ
: NE
;
2127 /* Already true/false by definition */
2128 if (p
->n_right
->n_op
== ICON
&& p
->n_right
->n_lval
== 0) {
2130 o
= o
== ULT
? UGE
: ULT
;
2138 if (o
== UGE
) /* true */
2145 lab
= false<0 ? getlab() : false ;
2146 andorbr(p
->n_left
, -1, lab
);
2148 andorbr(p
->n_right
, true, false);
2155 lab
= true<0 ? getlab() : true;
2156 andorbr(p
->n_left
, lab
, -1);
2158 andorbr(p
->n_right
, true, false);
2165 andorbr(p
->n_left
, false, true);
2177 fixbranch(buildtree(EQ
, p
, bcon(0)), false);
2183 * Create a node for either TEMP or on-stack storage.
2186 cstknode(TWORD t
, union dimfun
*df
, struct attr
*ap
)
2190 /* create a symtab entry suitable for this type */
2191 sp
= getsymtab("0hej", STEMP
);
2196 sp
->soffset
= NOOFFSET
;
2197 oalloc(sp
, &autooff
);
2198 return nametree(sp
);
2203 * Massage the output trees to remove C-specific nodes:
2204 * COMOPs are split into separate statements.
2205 * QUEST/COLON are rewritten to branches.
2206 * ANDAND/OROR/NOT are rewritten to branches for lazy-evaluation.
2207 * CBRANCH conditions are rewritten for lazy-evaluation.
2214 int o
, ty
, lbl
, lbl2
;
2219 if (BTYPE(p
->n_type
) == ENUMTY
) { /* fixup enum */
2220 struct symtab
*sp
= strmemb(p
->n_ap
);
2221 MODTYPE(p
->n_type
, sp
->stype
);
2223 * XXX may fail if these are true:
2224 * - variable-sized enums
2225 * - non-byte-addressed targets.
2227 if (BTYPE(p
->n_type
) == ENUMTY
&& ISPTR(p
->n_type
))
2228 MODTYPE(p
->n_type
, INT
); /* INT ok? */
2234 * Create a branch node from ?:
2235 * || and && must be taken special care of.
2238 andorbr(p
->n_left
, -1, lbl
= getlab());
2240 /* Make ASSIGN node */
2241 /* Only if type is not void */
2242 q
= p
->n_right
->n_left
;
2245 tval
= cstknode(q
->n_type
, q
->n_df
, q
->n_ap
);
2246 q
= buildtree(ASSIGN
, ccopy(tval
), q
);
2249 ecode(q
); /* Done with assign */
2250 branch(lbl2
= getlab());
2253 q
= p
->n_right
->n_right
;
2256 q
= buildtree(ASSIGN
, ccopy(tval
), q
);
2259 ecode(q
); /* Done with assign */
2264 if (p
->n_type
!= VOID
) {
2287 #ifdef SPECIAL_CCODES
2288 #error fix for private CCODES handling
2292 andorbr(r
, -1, lbl
= getlab());
2294 tval
= cstknode(p
->n_type
, p
->n_df
, p
->n_ap
);
2296 ecode(buildtree(ASSIGN
, ccopy(tval
), bcon(1)));
2297 branch(lbl2
= getlab());
2299 ecode(buildtree(ASSIGN
, ccopy(tval
), bcon(0)));
2308 andorbr(p
->n_left
, p
->n_right
->n_lval
, -1);
2310 p
->n_op
= ICON
; p
->n_type
= VOID
;
2313 cerror("COMOP error");
2325 * Return 1 if an assignment is found.
2330 if (cdope(p
->n_op
) & ASGFLG
)
2332 if (coptype(p
->n_op
) == LTYPE
)
2334 if (has_se(p
->n_left
))
2336 if (coptype(p
->n_op
) == BITYPE
)
2337 return has_se(p
->n_right
);
2342 * Find and convert asgop's to separate statements.
2343 * Be careful about side effects.
2344 * assign tells whether ASSIGN should be considered giving
2345 * side effects or not.
2353 if (p
->n_op
== INCR
|| p
->n_op
== DECR
) {
2355 * Rewrite x++ to (x += 1) -1; and deal with it further down.
2356 * Pass2 will remove -1 if unnecessary.
2360 q
->n_op
= (p
->n_op
==INCR
)?PLUSEQ
:MINUSEQ
;
2361 p
->n_op
= (p
->n_op
==INCR
)?MINUS
:PLUS
;
2362 p
->n_left
= delasgop(q
);
2364 } else if ((cdope(p
->n_op
)&ASGOPFLG
) &&
2365 p
->n_op
!= RETURN
&& p
->n_op
!= CAST
) {
2366 NODE
*l
= p
->n_left
;
2367 NODE
*ll
= l
->n_left
;
2370 q
= tempnode(0, ll
->n_type
, ll
->n_df
, ll
->n_ap
);
2372 r
= tempnode(tval
, ll
->n_type
, ll
->n_df
,ll
->n_ap
);
2374 /* Now the left side of node p has no side effects. */
2375 /* side effects on the right side must be obeyed */
2378 r
= buildtree(ASSIGN
, r
, ll
);
2382 #if 0 /* Cannot call buildtree() here, it would invoke double add shifts */
2383 p
->n_right
= buildtree(UNASG p
->n_op
, ccopy(l
),
2386 p
->n_right
= block(UNASG p
->n_op
, ccopy(l
),
2387 p
->n_right
, p
->n_type
, p
->n_df
, p
->n_ap
);
2390 p
->n_right
= delasgop(p
->n_right
);
2391 p
->n_right
= clocal(p
->n_right
);
2395 if (coptype(p
->n_op
) == LTYPE
)
2397 p
->n_left
= delasgop(p
->n_left
);
2398 if (coptype(p
->n_op
) == BITYPE
)
2399 p
->n_right
= delasgop(p
->n_right
);
2411 fwalk(p
, eprint
, 0);
2414 warner(Wunreachable_code
, NULL
);
2421 if (p
->n_op
== ICON
&& p
->n_type
== VOID
)
2428 #if defined(MULTIPASS)
2435 myp2tree(p
); /* local action can be taken here */
2437 ty
= coptype(p
->n_op
);
2439 printf("%d\t", p
->n_op
);
2442 printf(CONFMT
, p
->n_lval
);
2446 if (p
->n_op
== NAME
|| p
->n_op
== ICON
)
2449 printf("%d\t", p
->n_rval
);
2452 printf("%o\t", p
->n_type
);
2454 /* handle special cases */
2460 /* print external name */
2461 if ((q
= p
->n_sp
) != NULL
) {
2462 if ((q
->sclass
== STATIC
&& q
->slevel
> 0)) {
2463 printf(LABFMT
, q
->soffset
);
2466 q
->soname
? q
->soname
: exname(q
->sname
));
2475 /* print out size */
2476 /* use lhs size, in order to avoid hassles
2477 * with the structure `.' operator
2480 /* note: p->left not a field... */
2481 printf(CONFMT
, (CONSZ
)tsize(STRTY
, p
->n_left
->n_df
,
2483 printf("\t%d\t\n", talign(STRTY
, p
->n_left
->n_ap
));
2501 sptostr(struct symtab
*sp
)
2503 char *cp
= inlalloc(32);
2504 int n
= sp
->soffset
;
2507 snprintf(cp
, 32, LABFMT
, n
);
2517 myp2tree(p
); /* local action can be taken here */
2519 /* Fix left imaginary types */
2520 if (ISITY(BTYPE(p
->n_type
)))
2521 MODTYPE(p
->n_type
, p
->n_type
- (FIMAG
-FLOAT
));
2523 ty
= coptype(p
->n_op
);
2529 if ((q
= p
->n_sp
) != NULL
) {
2530 if ((q
->sclass
== STATIC
&& q
->slevel
> 0)
2532 || q
->sflags
== SLBLNAME
2535 p
->n_name
= sptostr(q
);
2537 if ((p
->n_name
= q
->soname
) == NULL
)
2538 p
->n_name
= addname(exname(q
->sname
));
2545 /* STASG used for stack array init */
2546 if (ISARY(p
->n_type
)) {
2547 int size1
= (int)tsize(p
->n_type
, p
->n_left
->n_df
,
2548 p
->n_left
->n_ap
)/SZCHAR
;
2549 p
->n_stsize
= (int)tsize(p
->n_type
, p
->n_right
->n_df
,
2550 p
->n_right
->n_ap
)/SZCHAR
;
2551 if (size1
< p
->n_stsize
)
2552 p
->n_stsize
= size1
;
2553 p
->n_stalign
= talign(p
->n_type
,
2554 p
->n_left
->n_ap
)/SZCHAR
;
2561 /* set up size parameters */
2562 p
->n_stsize
= (int)((tsize(STRTY
, p
->n_left
->n_df
,
2563 p
->n_left
->n_ap
)+SZCHAR
-1)/SZCHAR
);
2564 p
->n_stalign
= talign(STRTY
,p
->n_left
->n_ap
)/SZCHAR
;
2565 if (p
->n_stalign
== 0)
2566 p
->n_stalign
= 1; /* At least char for packed structs */
2577 if( ty
!= LTYPE
) p2tree( p
->n_left
);
2578 if( ty
== BITYPE
) p2tree( p
->n_right
);
2584 * Change void data types into char.
2587 delvoid(NODE
*p
, void *arg
)
2589 /* Convert "PTR undef" (void *) to "PTR uchar" */
2590 if (BTYPE(p
->n_type
) == VOID
)
2591 p
->n_type
= (p
->n_type
& ~BTMASK
) | UCHAR
;
2592 if (BTYPE(p
->n_type
) == BOOL
) {
2593 if (p
->n_op
== SCONV
&& p
->n_type
== BOOL
) {
2594 /* create a jump and a set */
2598 r
= tempnode(0, BOOL_TYPE
, NULL
, MKAP(BOOL_TYPE
));
2599 cbranch(buildtree(EQ
, p
->n_left
, bcon(0)),
2600 bcon(l
= getlab()));
2602 ecode(buildtree(ASSIGN
, tcopy(r
), bcon(1)));
2603 branch(l2
= getlab());
2605 ecode(buildtree(ASSIGN
, r
, bcon(0)));
2608 p
->n_type
= (p
->n_type
& ~BTMASK
) | BOOL_TYPE
;
2616 /* walk the tree and write out the nodes.. */
2625 if (q
->n_op
== UMUL
)
2627 if (cdope(q
->n_op
)&CALLFLG
&&
2628 attr_find(q
->n_ap
, GCC_ATYP_WARN_UNUSED_RESULT
))
2629 werror("return value ignored");
2634 walkf(p
, delvoid
, 0);
2637 printf("Fulltree:\n");
2638 fwalk(p
, eprint
, 0);
2642 #if !defined(MULTIPASS)
2643 send_passt(IP_NODE
, p
);
2648 * Send something further on to the next pass.
2651 send_passt(int type
, ...)
2653 struct interpass
*ip
;
2654 struct interpass_prolog
*ipp
;
2660 if (cftnsp
== NULL
&& type
!= IP_ASM
) {
2662 cerror("no function");
2664 if (type
== IP_NODE
)
2665 tfree(va_arg(ap
, NODE
*));
2668 if (type
== IP_PROLOG
|| type
== IP_EPILOG
)
2669 sz
= sizeof(struct interpass_prolog
);
2671 sz
= sizeof(struct interpass
);
2675 ip
->lineno
= lineno
;
2678 ip
->ip_node
= va_arg(ap
, NODE
*);
2685 inftn
= type
== IP_PROLOG
? 1 : 0;
2686 ipp
= (struct interpass_prolog
*)ip
;
2687 memset(ipp
->ipp_regs
, (type
== IP_PROLOG
)? -1 : 0,
2688 sizeof(ipp
->ipp_regs
));
2689 ipp
->ipp_autos
= va_arg(ap
, int);
2690 ipp
->ipp_name
= va_arg(ap
, char *);
2691 ipp
->ipp_type
= va_arg(ap
, TWORD
);
2692 ipp
->ipp_vis
= va_arg(ap
, int);
2693 ip
->ip_lbl
= va_arg(ap
, int);
2694 ipp
->ip_tmpnum
= va_arg(ap
, int);
2695 ipp
->ip_lblnum
= crslab
;
2696 if (type
== IP_PROLOG
)
2700 ip
->ip_lbl
= va_arg(ap
, int);
2703 if (blevel
== 0) { /* outside function */
2705 printf("%s", va_arg(ap
, char *));
2711 ip
->ip_asm
= va_arg(ap
, char *);
2714 cerror("bad send_passt type %d", type
);
2717 pass1_lastchance(ip
); /* target-specific info */
2729 #define SNAM(x,y) case x: return #y;
2731 SNAM(QUALIFIER
,QUALIFIER
)
2759 SNAM(ATTRIB
,ATTRIBUTE
)
2760 SNAM(TYMERGE
,TYMERGE
)
2762 SNAM(XREAL
,__real__
)
2763 SNAM(XIMAG
,__imag__
)
2766 cerror("bad copst %d", op
);
2768 return 0; /* XXX gcc */
2799 return BITYPE
|LOGFLG
;
2801 return UTYPE
|LOGFLG
;
2803 return BITYPE
|ASGFLG
|ASGOPFLG
;
2805 return BITYPE
|ASGFLG
|ASGOPFLG
|FLOFLG
|SIMPFLG
|COMMFLG
;
2807 return BITYPE
|FLOFLG
|SIMPFLG
|ASGFLG
|ASGOPFLG
;
2809 return BITYPE
|FLOFLG
|MULFLG
|ASGFLG
|ASGOPFLG
;
2813 return BITYPE
|SIMPFLG
|COMMFLG
|ASGFLG
|ASGOPFLG
;
2815 return BITYPE
|FLOFLG
|MULFLG
|DIVFLG
|ASGFLG
|ASGOPFLG
;
2817 return BITYPE
|DIVFLG
|ASGFLG
|ASGOPFLG
;
2820 return BITYPE
|SHFFLG
|ASGFLG
|ASGOPFLG
;
2823 return BITYPE
|ASGFLG
;
2825 cerror("cdope missing op %d", op
);
2826 return 0; /* XXX gcc */
2830 * make a fresh copy of p
2840 switch (coptype(q
->n_op
)) {
2842 q
->n_right
= ccopy(p
->n_right
);
2844 q
->n_left
= ccopy(p
->n_left
);
2851 * set PROG-seg label.
2856 reached
= 1; /* Will this always be correct? */
2857 send_passt(IP_DEFLAB
, label
);
2861 * Perform integer promotion on node n.
2866 if ((n
->n_type
>= CHAR
&& n
->n_type
< INT
) || n
->n_type
== BOOL
) {
2867 if ((n
->n_type
== UCHAR
&& MAX_UCHAR
> MAX_INT
) ||
2868 (n
->n_type
== USHORT
&& MAX_USHORT
> MAX_INT
))
2869 return makety(n
, UNSIGNED
, 0, 0, MKAP(UNSIGNED
));
2870 return makety(n
, INT
, 0, 0, MKAP(INT
));
2876 * Return CON/VOL/0, whichever are active for the current type.
2879 cqual(TWORD t
, TWORD q
)
2882 t
= DECREF(t
), q
= DECQAL(q
);
2885 return q
& (CON
|VOL
);
2890 * Return a number for internal labels.