Quick Search:

Mode

Context

Displaying the whole file. None | Less | More | Full

Other Diffs

Ignore

Blank Lines Whitespace: Expand:

Diff

1.6
 
1.7
 
MAIN:plunky:20121022091852
 
trees.c
_>11 /*      $Id$    */
 22 /*
 33  * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
 44  * All rights reserved.
 55  *
 66  * Redistribution and use in source and binary forms, with or without
 77  * modification, are permitted provided that the following conditions
 88  * are met:
 99  * 1. Redistributions of source code must retain the above copyright
 1010  *    notice, this list of conditions and the following disclaimer.
 1111  * 2. Redistributions in binary form must reproduce the above copyright
 1212  *    notice, this list of conditions and the following disclaimer in the
 1313  *    documentation and/or other materials provided with the distribution.
 1414  * 3. The name of the author may not be used to endorse or promote products
 1515  *    derived from this software without specific prior written permission
 1616  *
 1717  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 1818  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 1919  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 2020  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 2121  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 2222  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 2323  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 2424  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 2525  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 2626  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 2727  */
 2828 
 2929 /*
 3030  * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
 3131  *
 3232  * Redistribution and use in source and binary forms, with or without
 3333  * modification, are permitted provided that the following conditions
 3434  * are met:
 3535  *
 3636  * Redistributions of source code and documentation must retain the above
 3737  * copyright notice, this list of conditions and the following disclaimer.
 3838  * Redistributions in binary form must reproduce the above copyright
 3939  * notice, this list of conditionsand the following disclaimer in the
 4040  * documentation and/or other materials provided with the distribution.
 4141  * All advertising materials mentioning features or use of this software
 4242  * must display the following acknowledgement:
 4343  *      This product includes software developed or owned by Caldera
 4444  *      International, Inc.
 4545  * Neither the name of Caldera International, Inc. nor the names of other
 4646  * contributors may be used to endorse or promote products derived from
 4747  * this software without specific prior written permission.
 4848  *
 4949  * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
 5050  * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
 5151  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 5252  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 5353  * DISCLAIMED.  IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE
 5454  * FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 5555  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 5656  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 5757  * HOWEVER CAUSED AND ON ANY THEORY OFLIABILITY, WHETHER IN CONTRACT,
 5858  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 5959  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 6060  * POSSIBILITY OF SUCH DAMAGE.
 6161  */
 6262 /*
 6363  * Some of the changes from 32V include:
 6464  * - Understand "void" as type.
 6565  * - Handle enums as ints everywhere.
 6666  * - Convert some C-specific ops into branches.
 6767  */
 6868 
 6969 # include "pass1.h"
 7070 # include "pass2.h"
 7171 
 7272 # include <stdarg.h>
 7373 # include <string.h>
 7474 
 7575 static void chkpun(NODE *p);
 7676 static int opact(NODE *p);
 7777 static int moditype(TWORD);
 7878 static NODE *strargs(NODE *);
 7979 static void rmcops(NODE *p);
 8080 static NODE *tymatch(NODE *p);
 8181 void putjops(NODE *, void *);
 8282 static struct symtab *findmember(struct symtab *, char *);
 8383 int inftn; /* currently between epilog/prolog */
 8484 
 8585 static char *tnames[] = {
 8686         "undef",
 8787         "farg",
 8888         "char",
 8989         "unsigned char",
 9090         "short",
 9191         "unsigned short",
 9292         "int",
 9393         "unsigned int",
 9494         "long",
 9595         "unsigned long",
 9696         "long long",
 9797         "unsigned long long",
 9898         "float",
 9999         "double",
 100100         "long double",
 101101         "strty",
 102102         "unionty",
 103103         "enumty",
 104104         "moety",
 105105         "void",
 106106         "signed", /* pass1 */
 107107         "bool", /* pass1 */
 108108         "fimag", /* pass1 */
 109109         "dimag", /* pass1 */
 110110         "limag", /* pass1 */
 111111         "fcomplex", /* pass1 */
 112112         "dcomplex", /* pass1 */
 113113         "lcomplex", /* pass1 */
 114114         "enumty", /* pass1 */
 115115         "?", "?"
 116116 };
 117117 
 118118 /*      some special actions, used in finding the type of nodes */
 119119 # define NCVT 01
 120120 # define PUN 02
 121121 # define TYPL 04
 122122 # define TYPR 010
 123123 # define TYMATCH 040
 124124 # define LVAL 0100
 125125 # define CVTO 0200
 126126 # define CVTL 0400
 127127 # define CVTR 01000
 128128 # define PTMATCH 02000
 129129 # define OTHER 04000
 130130 # define NCVTR 010000
 131131 # define PROML 020000   /* promote left operand */
 132132 
 133133 /* node conventions:
 134134 
 135135         NAME:   rval>0 is stab index for external
 136136                 rval<0 is -inlabel number
 137137                 lval is offset in bits
 138138         ICON:   lval has the value
 139139                 rval has the STAB index, or - label number,
 140140                         if a name whose address is in the constant
 141141                 rval = NONAME means no name
 142142         REG:    rval is reg. identification cookie
 143143 
 144144         */
 145145 
 146146 extern int negrel[];
 147147 
 148148 /* Have some defaults for most common targets */
 149149 #ifndef WORD_ADDRESSED
 150150 #define offcon(o,t,d,ap) xbcon((o/SZCHAR), NULL, INTPTR)
 151151 #define VBLOCK(p,b,t,d,a) buildtree(DIV, p, b)
 152152 #define MBLOCK(p,b,t,d,a) buildtree(MUL, p, b)
 153153 #else
 154154 #define VBLOCK(p,b,t,d,a) block(PVCONV, p, b, t, d, a)
 155155 #define MBLOCK(p,b,t,d,a) block(PMCONV, p, b, t, d, a)
 156156 #endif
 157157 
 158158 NODE *
 159159 buildtree(int o, NODE *l, NODE *r)
 160160 {
 161161         NODE *p, *q;
 162162         int actions;
 163163         int opty, n;
 164164         struct symtab *sp = NULL; /* XXX gcc */
 165165         NODE *lr, *ll;
 166166 
 167167 #ifdef PCC_DEBUG
 168168         if (bdebug) {
 169169                 printf("buildtree(%s, %p, %p)\n", copst(o), l, r);
 170170                 if (l) fwalk(l, eprint, 0);
 171171                 if (r) fwalk(r, eprint, 0);
 172172         }
 173173 #endif
 174174         opty = coptype(o);
 175175 
 176176         /* check for constants */
 177177 
 178178         if (o == ANDAND || o == OROR || o == NOT) {
 179179                 if (l->n_op == FCON) {
 180180                         p = bcon(!FLOAT_ISZERO(l->n_dcon));
 181181                         nfree(l);
 182182                         l = p;
 183183                 }
 184184                 if (o != NOT && r->n_op == FCON) {
 185185                         p = bcon(!FLOAT_ISZERO(r->n_dcon));
 186186                         nfree(r);
 187187                         r = p;
 188188                 }
 189189         }
 190190 
 191191         if( opty == UTYPE && l->n_op == ICON ){
 192192 
 193193                 switch( o ){
 194194 
 195195                 case NOT:
 196196                 case UMINUS:
 197197                 case COMPL:
 198198                         if( conval( l, o, l ) ) return(l);
 199199                         break;
 200200                 }
 201201         } else if (o == NOT && l->n_op == FCON) {
 202202                 l = clocal(block(SCONV, l, NIL, INT, 0, 0));
 203203         } else if( o == UMINUS && l->n_op == FCON ){
 204204                         l->n_dcon = FLOAT_NEG(l->n_dcon);
 205205                         return(l);
 206206 
 207207         } else if( o==QUEST &&
 208208             (l->n_op==ICON || (l->n_op==NAME && ISARY(l->n_type)))) {
 209209                 CONSZ c = l->n_lval;
 210210                 if (l->n_op==NAME)
 211211                         c = 1; /* will become constant later */
 212212                 nfree(l);
 213213                 if (c) {
 214214                         walkf(r->n_right, putjops, 0);
 215215                         tfree(r->n_right);
 216216                         l = r->n_left;
 217217                 } else {
 218218                         walkf(r->n_left, putjops, 0);
 219219                         tfree(r->n_left);
 220220                         l = r->n_right;
 221221                 }
 222222                 nfree(r);
 223223                 return(l);
 224224         } else if( opty == BITYPE && l->n_op == ICON && r->n_op == ICON ){
 225225 
 226226                 switch( o ){
 227227 
 228228                 case PLUS:
 229229                 case MINUS:
 230230                 case MUL:
 231231                 case DIV:
 232232                 case MOD:
 233233                         /*
 234234                          * Do type propagation for simple types here.
 235235                          * The constant value is correct anyway.
 236236                          * Maybe this op shortcut should be removed?
 237237                          */
 238238                         if (l->n_sp == NULL && r->n_sp == NULL &&
 239239                             l->n_type < BTMASK && r->n_type < BTMASK) {
 240240                                 if (l->n_type > r->n_type)
 241241                                         r->n_type = l->n_type;
 242242                                 else
 243243                                         l->n_type = r->n_type;
 244244                         }
 245245                         /* FALLTHROUGH */
 246246                 case ULT:
 247247                 case UGT:
 248248                 case ULE:
 249249                 case UGE:
 250250                 case LT:
 251251                 case GT:
 252252                 case LE:
 253253                 case GE:
 254254                 case EQ:
 255255                 case NE:
 256256                 case ANDAND:
 257257                 case OROR:
 258258                 case AND:
 259259                 case OR:
 260260                 case ER:
 261261                 case LS:
 262262                 case RS:
 263263                         if (!ISPTR(l->n_type) && !ISPTR(r->n_type)) {
 264264                                 if( conval( l, o, r ) ) {
 265265                                         nfree(r);
 266266                                         return(l);
 267267                                 }
 268268                         }
 269269                         break;
 270270                 }
 271271         } else if (opty == BITYPE && (l->n_op == FCON || l->n_op == ICON) &&
 272272             (r->n_op == FCON || r->n_op == ICON) && (o == PLUS || o == MINUS ||
 273273             o == MUL || o == DIV || (o >= EQ && o <= GT) )) {
 274274                 TWORD t;
 275275 #ifndef CC_DIV_0
 276276                 if (o == DIV &&
 277277                     ((r->n_op == ICON && r->n_lval == 0) ||
 278278                      (r->n_op == FCON && r->n_dcon == 0.0)))
 279279                                 goto runtime; /* HW dependent */
 280280 #endif
 281281                 if (l->n_op == ICON)
 282282                         l->n_dcon = FLOAT_CAST(l->n_lval, l->n_type);
 283283                 if (r->n_op == ICON)
 284284                         r->n_dcon = FLOAT_CAST(r->n_lval, r->n_type);
 285285                 switch(o){
 286286                 case PLUS:
 287287                 case MINUS:
 288288                 case MUL:
 289289                 case DIV:
 290290                         switch (o) {
 291291                         case PLUS:
 292292                                 l->n_dcon = FLOAT_PLUS(l->n_dcon, r->n_dcon);
 293293                                 break;
 294294                         case MINUS:
 295295                                 l->n_dcon = FLOAT_MINUS(l->n_dcon, r->n_dcon);
 296296                                 break;
 297297                         case MUL:
 298298                                 l->n_dcon = FLOAT_MUL(l->n_dcon, r->n_dcon);
 299299                                 break;
 300300                         case DIV:
 301301                                 l->n_dcon = FLOAT_DIV(l->n_dcon, r->n_dcon);
 302302                                 break;
 303303                         }
 304304                         t = (l->n_type > r->n_type ? l->n_type : r->n_type);
 305305                         l->n_op = FCON;
 306306                         l->n_type = t;
 307307                         nfree(r);
 308308                         return(l);
 309309                 case EQ:
 310310                 case NE:
 311311                 case LE:
 312312                 case LT:
 313313                 case GE:
 314314                 case GT:
 315315                         switch (o) {
 316316                         case EQ:
 317317                                 n = FLOAT_EQ(l->n_dcon, r->n_dcon);
 318318                                 break;
 319319                         case NE:
 320320                                 n = FLOAT_NE(l->n_dcon, r->n_dcon);
 321321                                 break;
 322322                         case LE:
 323323                                 n = FLOAT_LE(l->n_dcon, r->n_dcon);
 324324                                 break;
 325325                         case LT:
 326326                                 n = FLOAT_LT(l->n_dcon, r->n_dcon);
 327327                                 break;
 328328                         case GE:
 329329                                 n = FLOAT_GE(l->n_dcon, r->n_dcon);
 330330                                 break;
 331331                         case GT:
 332332                                 n = FLOAT_GT(l->n_dcon, r->n_dcon);
 333333                                 break;
 334334                         default:
 335335                                 n = 0; /* XXX flow analysis */
 336336                         }
 337337                         nfree(r);
 338338                         nfree(l);
 339339                         return bcon(n);
 340340                 }
 341341         }
 342342 #ifndef CC_DIV_0
 343343 runtime:
 344344 #endif
 345345         /* its real; we must make a new node */
 346346 
 347347         p = block(o, l, r, INT, 0, 0);
 348348 
 349349         actions = opact(p);
 350350 
 351351         if (actions & PROML)
 352352                 p->n_left = intprom(p->n_left);
 353353 
 354354         if (actions & LVAL) { /* check left descendent */
 355355                 if (notlval(p->n_left)) {
 356356                         uerror("lvalue required");
 357357                         nfree(p);
 358358                         return l;
 359359 #ifdef notyet
 360360                 } else {
 361361                         if ((l->n_type > BTMASK && ISCON(l->n_qual)) ||
 362362                             (l->n_type <= BTMASK && ISCON(l->n_qual << TSHIFT)))
 363363                                 if (blevel > 0)
 364364                                         uerror("lvalue is declared const");
 365365 #endif
 366366                 }
 367367         }
 368368 
 369369         if( actions & NCVTR ){
 370370                 p->n_left = pconvert( p->n_left );
 371371                 }
 372372         else if( !(actions & NCVT ) ){
 373373                 switch( opty ){
 374374 
 375375                 case BITYPE:
 376376                         p->n_right = pconvert( p->n_right );
<> 377+                        /* FALLTHROUGH */
377378                 case UTYPE:
 378379                         p->n_left = pconvert( p->n_left );
 379380 
 380381                         }
 381382                 }
 382383 
 383384         if ((actions&PUN) && (o!=CAST))
 384385                 chkpun(p);
 385386 
 386387         if( actions & (TYPL|TYPR) ){
 387388 
 388389                 q = (actions&TYPL) ? p->n_left : p->n_right;
 389390 
 390391                 p->n_type = q->n_type;
 391392                 p->n_qual = q->n_qual;
 392393                 p->n_df = q->n_df;
 393394                 p->n_ap = q->n_ap;
 394395                 }
 395396 
 396397         if( actions & CVTL ) p = convert( p, CVTL );
 397398         if( actions & CVTR ) p = convert( p, CVTR );
 398399         if( actions & TYMATCH ) p = tymatch(p);
 399400         if( actions & PTMATCH ) p = ptmatch(p);
 400401 
 401402         if( actions & OTHER ){
 402403                 struct symtab *sp1;
 403404 
 404405                 l = p->n_left;
 405406                 r = p->n_right;
 406407 
 407408                 switch(o){
 408409 
 409410                 case NAME:
 410411                         cerror("buildtree NAME");
 411412 
 412413                 case STREF:
 413414                         /* p->x turned into *(p+offset) */
 414415                         /* rhs must be a name; check correctness */
 415416 
 416417                         /* Find member symbol struct */
 417418                         if (l->n_type != PTR+STRTY && l->n_type != PTR+UNIONTY){
 418419                                 uerror("struct or union required");
 419420                                 break;
 420421                         }
 421422 
 422423                         if ((sp1 = strmemb(l->n_ap)) == NULL) {
 423424                                 uerror("undefined struct or union");
 424425                                 break;
 425426                         }
 426427 
 427428                         if ((sp = findmember(sp1, r->n_name)) == NULL) {
 428429                                 uerror("member '%s' not declared", r->n_name);
 429430                                 break;
 430431                         }
 431432 
 432433                         r->n_sp = sp;
 433434                         p = stref(p);
 434435                         break;
 435436 
 436437                 case UMUL:
 437438                         if (l->n_op == ADDROF) {
 438439                                 nfree(p);
 439440                                 p = nfree(l);
 440441                         }
 441442                         if( !ISPTR(l->n_type))uerror("illegal indirection");
 442443                         p->n_type = DECREF(l->n_type);
 443444                         p->n_qual = DECREF(l->n_qual);
 444445                         p->n_df = l->n_df;
 445446                         p->n_ap = l->n_ap;
 446447                         break;
 447448 
 448449                 case ADDROF:
 449450                         switch( l->n_op ){
 450451 
 451452                         case UMUL:
 452453                                 nfree(p);
 453454                                 p = nfree(l);
 454455                                 /* FALLTHROUGH */
 455456                         case TEMP:
 456457                         case NAME:
 457458                                 p->n_type = INCREF(l->n_type);
 458459                                 p->n_qual = INCQAL(l->n_qual);
 459460                                 p->n_df = l->n_df;
 460461                                 p->n_ap = l->n_ap;
 461462                                 break;
 462463 
 463464                         case COMOP:
 464465                                 nfree(p);
 465466                                 lr = buildtree(ADDROF, l->n_right, NIL);
 466467                                 p = buildtree( COMOP, l->n_left, lr );
 467468                                 nfree(l);
 468469                                 break;
 469470 
 470471                         case QUEST:
 471472                                 lr = buildtree( ADDROF, l->n_right->n_right, NIL );
 472473                                 ll = buildtree( ADDROF, l->n_right->n_left, NIL );
 473474                                 nfree(p); nfree(l->n_right);
 474475                                 p = buildtree( QUEST, l->n_left, buildtree( COLON, ll, lr ) );
 475476                                 nfree(l);
 476477                                 break;
 477478 
 478479                         default:
 479480                                 uerror("unacceptable operand of &: %d", l->n_op );
 480481                                 break;
 481482                                 }
 482483                         break;
 483484 
 484485                 case LS:
 485486                 case RS: /* must make type size at least int... */
 486487                         if (p->n_type == CHAR || p->n_type == SHORT) {
 487488                                 p->n_left = makety(l, INT, 0, 0, 0);
 488489                         } else if (p->n_type == UCHAR || p->n_type == USHORT) {
 489490                                 p->n_left = makety(l, UNSIGNED, 0, 0, 0);
 490491                         }
 491492                         l = p->n_left;
 492493                         p->n_type = l->n_type;
 493494                         p->n_qual = l->n_qual;
 494495                         p->n_df = l->n_df;
 495496                         p->n_ap = l->n_ap;
 496497 
 497498                         /* FALLTHROUGH */
 498499                 case LSEQ:
 499500                 case RSEQ: /* ...but not for assigned types */
 500501                         if(tsize(r->n_type, r->n_df, r->n_ap) > SZINT)
 501502                                 p->n_right = makety(r, INT, 0, 0, 0);
 502503                         break;
 503504 
 504505                 case RETURN:
 505506                 case ASSIGN:
 506507                 case CAST:
 507508                         /* structure assignment */
 508509                         /* take the addresses of the two sides; then make an
 509510                          * operator using STASG and
 510511                          * the addresses of left and right */
 511512 
 512513                         if (strmemb(l->n_ap) != strmemb(r->n_ap))
 513514                                 uerror("assignment of different structures");
 514515 
 515516                         r = buildtree(ADDROF, r, NIL);
 516517 
 517518                         l = block(STASG, l, r, r->n_type, r->n_df, r->n_ap);
 518519                         l = clocal(l);
 519520 
 520521                         if( o == RETURN ){
 521522                                 nfree(p);
 522523                                 p = l;
 523524                                 break;
 524525                         }
 525526 
 526527                         p->n_op = UMUL;
 527528                         p->n_left = l;
 528529                         p->n_right = NIL;
 529530                         break;
 530531 
 531532                 case QUEST: /* fixup types of : */
 532533                         if (r->n_left->n_type != p->n_type)
 533534                                 r->n_left = makety(r->n_left, p->n_type,
 534535                                     p->n_qual, p->n_df, p->n_ap);
 535536                         if (r->n_right->n_type != p->n_type)
 536537                                 r->n_right = makety(r->n_right, p->n_type,
 537538                                     p->n_qual, p->n_df, p->n_ap);
 538539                         break;
 539540 
 540541                 case COLON:
 541542                         /* structure colon */
 542543 
 543544                         if (strmemb(l->n_ap) != strmemb(r->n_ap))
 544545                                 uerror( "type clash in conditional" );
 545546                         break;
 546547 
 547548                 case CALL:
 548549                         p->n_right = r = strargs(p->n_right);
 549550                         p = funcode(p);
 550551                         /* FALLTHROUGH */
 551552                 case UCALL:
 552553                         if (!ISPTR(l->n_type))
 553554                                 uerror("illegal function");
 554555                         p->n_type = DECREF(l->n_type);
 555556                         if (!ISFTN(p->n_type))
 556557                                 uerror("illegal function");
 557558                         p->n_type = DECREF(p->n_type);
 558559                         p->n_df = l->n_df+1; /* add one for prototypes */
 559560                         p->n_ap = l->n_ap;
 560561                         if (p->n_type == STRTY || p->n_type == UNIONTY) {
 561562                                 /* function returning structure */
 562563                                 /*  make function really return ptr to str., with * */
 563564 
 564565                                 p->n_op += STCALL-CALL;
 565566                                 p->n_type = INCREF(p->n_type);
 566567                                 p = clocal(p); /* before recursing */
 567568                                 p = buildtree(UMUL, p, NIL);
 568569 
 569570                                 }
 570571                         break;
 571572 
 572573                 default:
 573574                         cerror( "other code %d", o );
 574575                         }
 575576 
 576577                 }
 577578 
 578579         /*
 579580          * Allow (void)0 casts.
 580581          * XXX - anything on the right side must be possible to cast.
 581582          * XXX - remove void types further on.
 582583          */
 583584         if (p->n_op == CAST && p->n_type == VOID &&
 584585             p->n_right->n_op == ICON)
 585586                 p->n_right->n_type = VOID;
 586587 
 587588         if (actions & CVTO)
 588589                 p = oconvert(p);
 589590         p = clocal(p);
 590591 
 591592 #ifdef PCC_DEBUG
 592593         if (bdebug) {
 593594                 printf("End of buildtree:\n");
 594595                 fwalk(p, eprint, 0);
 595596         }
 596597 #endif
 597598 
 598599         return(p);
 599600 
 600601         }
 601602 
 602603 /* Find a member in a struct or union.  May be an unnamed member */
 603604 static struct symtab *
 604605 findmember(struct symtab *sp, char *s)
 605606 {
 606607         struct symtab *sp2, *sp3;
 607608 
 608609         for (; sp != NULL; sp = sp->snext) {
 609610                 if (sp->sname[0] == '*') {
 610611                         /* unnamed member, recurse down */
 611612                         if ((sp2 = findmember(strmemb(sp->sap), s))) {
 612613                                 sp3 = tmpalloc(sizeof (struct symtab));
 613614                                 *sp3 = *sp2;
 614615                                 sp3->soffset += sp->soffset;
 615616                                 return sp3;
 616617                         }
 617618                 } else if (sp->sname == s)
 618619                         return sp;
 619620         }
 620621         return NULL;
 621622 }
 622623 
 623624 
 624625 /*
 625626  * Check if there will be a lost label destination inside of a ?:
 626627  * It cannot be reached so just print it out.
 627628  */
 628629 void
 629630 putjops(NODE *p, void *arg)
 630631 {
 631632         if (p->n_op == COMOP && p->n_left->n_op == GOTO)
 632633                 plabel((int)p->n_left->n_left->n_lval+1);
 633634 }
 634635 
 635636 /*
 636637  * Build a name node based on a symtab entry.
 637638  * broken out from buildtree().
 638639  */
 639640 NODE *
 640641 nametree(struct symtab *sp)
 641642 {
 642643         NODE *p;
 643644 
 644645         p = block(NAME, NIL, NIL, sp->stype, sp->sdf, sp->sap);
 645646         p->n_qual = sp->squal;
 646647         p->n_sp = sp;
 647648 
 648649 #ifndef NO_C_BUILTINS
 649650         if (sp->sname[0] == '_' && strncmp(sp->sname, "__builtin_", 10) == 0)
 650651                 return p/* do not touch builtins here */
 651652         
 652653 #endif
 653654 
 654655         if (sp->sflags & STNODE) {
 655656                 /* Generated for optimizer */
 656657                 p->n_op = TEMP;
 657658                 p->n_rval = sp->soffset;
 658659         }
 659660 
 660661 #ifdef GCC_COMPAT
 661662         /* Get a label name */
 662663         if (sp->sflags == SLBLNAME) {
 663664                 p->n_type = VOID;
 664665         }
 665666 #endif
 666667         if (sp->stype == UNDEF) {
 667668                 uerror("%s undefined", sp->sname);
 668669                 /* make p look reasonable */
 669670                 p->n_type = INT;
 670671                 p->n_df = NULL;
 671672                 defid(p, SNULL);
 672673         }
 673674         if (sp->sclass == MOE) {
 674675                 p->n_op = ICON;
 675676                 p->n_lval = sp->soffset;
 676677                 p->n_df = NULL;
 677678                 p->n_sp = NULL;
 678679         }
 679680         return clocal(p);
 680681 }
 681682 
 682683 /*
 683684  * Cast a node to another type by inserting a cast.
 684685  * Just a nicer interface to buildtree.
 685686  * Returns the new tree.
 686687  */
 687688 NODE *
 688689 cast(NODE *p, TWORD t, TWORD u)
 689690 {
 690691         NODE *q;
 691692 
 692693         q = block(NAME, NIL, NIL, t, 0, 0);
 693694         q->n_qual = u;
 694695         q = buildtree(CAST, q, p);
 695696         p = q->n_right;
 696697         nfree(q->n_left);
 697698         nfree(q);
 698699         return p;
 699700 }
 700701 
 701702 /*
 702703  * Cast and complain if necessary by not inserining a cast.
 703704  */
 704705 NODE *
 705706 ccast(NODE *p, TWORD t, TWORD u, union dimfun *df, struct attr *ap)
 706707 {
 707708         NODE *q;
 708709 
 709710         /* let buildtree do typechecking (and casting) */
 710711         q = block(NAME, NIL, NIL, t, df, ap);
 711712         p = buildtree(ASSIGN, q, p);
 712713         nfree(p->n_left);
 713714         q = optim(p->n_right);
 714715         nfree(p);
 715716         return q;
 716717 }
 717718 
 718719 /*
 719720  * Do an actual cast of a constant (if possible).
 720721  * Routine assumes 2-complement (is there anything else today?)
 721722  * Returns 1 if handled, 0 otherwise.
 722723  */
 723724 int
 724725 concast(NODE *p, TWORD t)
 725726 {
 726727         extern short sztable[];
 727728         CONSZ val;
 728729 
 729730         if (p->n_op != ICON && p->n_op != FCON) /* only constants */
 730731                 return 0;
 731732         if (p->n_op == ICON && p->n_sp != NULL) { /* no addresses */
 732733                 if (t == BOOL) {
 733734                         p->n_lval = 1, p->n_type = BOOL, p->n_sp = NULL;
 734735                         return 1;
 735736                 }
 736737                 return 0;
 737738         }
 738739         if ((p->n_type & TMASK) || (t & TMASK)) /* no cast of pointers */
 739740                 return 0;
 740741 
 741742 //printf("concast till %d\n", t);
 742743 //fwalk(p, eprint, 0);
 743744 
 744745 #define TYPMSK(y) ((((1LL << (y-1))-1) << 1) | 1)
 745746         if (p->n_op == ICON) {
 746747                 val = p->n_lval;
 747748 
 748749                 if (t == BOOL) {
 749750                         if (val)
 750751                                 p->n_lval = 1;
 751752                 } else if (t <= ULONGLONG) {
 752753                         p->n_lval = val & TYPMSK(sztable[t]);
 753754                         if (!ISUNSIGNED(t)) {
 754755                                 if (val & (1LL << (sztable[t]-1)))
 755756                                         p->n_lval |= ~TYPMSK(sztable[t]);
 756757                         }
 757758                 } else if (t <= LDOUBLE) {
 758759                         p->n_op = FCON;
 759760                         p->n_dcon = FLOAT_CAST(val, p->n_type);
 760761                 }
 761762         } else { /* p->n_op == FCON */
 762763                 if (t == BOOL) {
 763764                         p->n_op = ICON;
 764765                         p->n_lval = FLOAT_NE(p->n_dcon,0.0);
 765766                         p->n_sp = NULL;
 766767                 } else if (t <= ULONGLONG) {
 767768                         p->n_op = ICON;
 768769                         p->n_lval = ISUNSIGNED(t) ? /* XXX FIXME */
 769770                             ((U_CONSZ)p->n_dcon) : p->n_dcon;
 770771                         p->n_sp = NULL;
 771772                 } else {
 772773                         p->n_dcon = t == FLOAT ? (float)p->n_dcon :
 773774                             t == DOUBLE ? (double)p->n_dcon : p->n_dcon;
 774775                 }
 775776         }
 776777         p->n_type = t;
 777778 //fwalk(p, eprint, 0);
 778779         return 1;
 779780 }
 780781 
 781782 /*
 782783  * Do a conditional branch.
 783784  */
 784785 void
 785786 cbranch(NODE *p, NODE *q)
 786787 {
 787788         p = buildtree(CBRANCH, p, q);
 788789         if (p->n_left->n_op == ICON) {
 789790                 if (p->n_left->n_lval != 0) {
 790791                         branch((int)q->n_lval); /* branch always */
 791792                         reached = 0;
 792793                 }
 793794                 tfree(p);
 794795                 tfree(q);
 795796                 return;
 796797         }
 797798         ecomp(p);
 798799 }
 799800 
 800801 NODE *
 801802 strargs(register NODE *p)
 802803 {
 803804         /* rewrite structure flavored arguments */
 804805 
 805806         if( p->n_op == CM ){
 806807                 p->n_left = strargs( p->n_left );
 807808                 p->n_right = strargs( p->n_right );
 808809                 return( p );
 809810                 }
 810811 
 811812         if( p->n_type == STRTY || p->n_type == UNIONTY ){
 812813                 p = block(STARG, p, NIL, p->n_type, p->n_df, p->n_ap);
 813814                 p->n_left = buildtree( ADDROF, p->n_left, NIL );
 814815                 p = clocal(p);
 815816                 }
 816817         return( p );
 817818 }
 818819 
 819820 /*
 820821  * apply the op o to the lval part of p; if binary, rhs is val
 821822  */
 822823 int
 823824 conval(NODE *p, int o, NODE *q)
 824825 {
 825826         TWORD tl = p->n_type, tr = q->n_type, td;
 826827         int i, u;
 827828         CONSZ val;
 828829         U_CONSZ v1, v2;
 829830 
 830831         val = q->n_lval;
 831832 
 832833         /* make both sides same type */
 833834         if (tl < BTMASK && tr < BTMASK) {
 834835                 td = tl > tr ? tl : tr;
 835836                 if (td < INT)
 836837                         td = INT;
 837838                 u = ISUNSIGNED(td);
 838839                 if (tl != td)
 839840                         p = makety(p, td, 0, 0, 0);
 840841                 if (tr != td)
 841842                         q = makety(q, td, 0, 0, 0);
 842843         } else
 843844                 u = ISUNSIGNED(tl) || ISUNSIGNED(tr);
 844845         if( u && (o==LE||o==LT||o==GE||o==GT)) o += (UGE-GE);
 845846 
 846847         if (p->n_sp != NULL && q->n_sp != NULL)
 847848                 return(0);
 848849         if (q->n_sp != NULL && o != PLUS)
 849850                 return(0);
 850851         if (p->n_sp != NULL && o != PLUS && o != MINUS)
 851852                 return(0);
 852853 
 853854         v1 = p->n_lval;
 854855         v2 = q->n_lval;
 855856         if (v2 == 0 && (cdope(o) & DIVFLG))
 856857                 return 0; /* leave division by zero to runtime */
 857858         switch( o ){
 858859 
 859860         case PLUS:
 860861                 p->n_lval += val;
 861862                 if (p->n_sp == NULL) {
 862863                         p->n_right = q->n_right;
 863864                         p->n_type = q->n_type;
 864865                 }
 865866                 break;
 866867         case MINUS:
 867868                 p->n_lval -= val;
 868869                 break;
 869870         case MUL:
 870871                 p->n_lval *= val;
 871872                 break;
 872873         case DIV:
 873874                 if (u) {
 874875                         v1 /= v2;
 875876                         p->n_lval = v1;
 876877                 } else
 877878                         p->n_lval /= val;
 878879                 break;
 879880         case MOD:
 880881                 if (u) {
 881882                         v1 %= v2;
 882883                         p->n_lval = v1;
 883884                 } else
 884885                         p->n_lval %= val;
 885886                 break;
 886887         case AND:
 887888                 p->n_lval &= val;
 888889                 break;
 889890         case OR:
 890891                 p->n_lval |= val;
 891892                 break;
 892893         case ER:
 893894                 p->n_lval ^= val;
 894895                 break;
 895896         case LS:
 896897                 i = (int)val;
 897898                 p->n_lval = p->n_lval << i;
 898899                 break;
 899900         case RS:
 900901                 i = (int)val;
 901902                 if (u) {
 902903                         v1 = v1 >> i;
 903904                         p->n_lval = v1;
 904905                 } else
 905906                         p->n_lval = p->n_lval >> i;
 906907                 break;
 907908 
 908909         case UMINUS:
 909910                 p->n_lval = - p->n_lval;
 910911                 break;
 911912         case COMPL:
 912913                 p->n_lval = ~p->n_lval;
 913914                 break;
 914915         case NOT:
 915916                 p->n_lval = !p->n_lval;
 916917                 break;
 917918         case LT:
 918919                 p->n_lval = p->n_lval < val;
 919920                 break;
 920921         case LE:
 921922                 p->n_lval = p->n_lval <= val;
 922923                 break;
 923924         case GT:
 924925                 p->n_lval = p->n_lval > val;
 925926                 break;
 926927         case GE:
 927928                 p->n_lval = p->n_lval >= val;
 928929                 break;
 929930         case ULT:
 930931                 p->n_lval = v1 < v2;
 931932                 break;
 932933         case ULE:
 933934                 p->n_lval = v1 <= v2;
 934935                 break;
 935936         case UGT:
 936937                 p->n_lval = v1 > v2;
 937938                 break;
 938939         case UGE:
 939940                 p->n_lval = v1 >= v2;
 940941                 break;
 941942         case EQ:
 942943                 p->n_lval = p->n_lval == val;
 943944                 break;
 944945         case NE:
 945946                 p->n_lval = p->n_lval != val;
 946947                 break;
 947948         case ANDAND:
 948949                 p->n_lval = p->n_lval && val;
 949950                 break;
 950951         case OROR:
 951952                 p->n_lval = p->n_lval || val;
 952953                 break;
 953954         default:
 954955                 return(0);
 955956                 }
 956957         /* Do the best in making everything type correct after calc */
 957958         if (p->n_sp == NULL && q->n_sp == NULL)
 958959                 p->n_lval = valcast(p->n_lval, p->n_type);
 959960         return(1);
 960961         }
 961962 
 962963 /*
 963964  * Ensure that v matches the type t; sign- or zero-extended
 964965  * as suitable to CONSZ.
 965966  * Only to be used for integer types.
 966967  */
 967968 CONSZ
 968969 valcast(CONSZ v, TWORD t)
 969970 {
 970971         CONSZ r;
 971972         int sz;
 972973 
 973974         if (t < CHAR || t > ULONGLONG)
 974975                 return v; /* cannot cast */
 975976 
 976977         if (t >= LONGLONG)
 977978                 return v; /* already largest */
 978979 
 979980 #define M(x)    ((((1ULL << ((x)-1)) - 1) << 1) + 1)
 980981 #define NOTM(x) (~M(x))
 981982 #define SBIT(x) (1ULL << ((x)-1))
 982983 
 983984         sz = (int)tsize(t, NULL, NULL);
 984985         r = v & M(sz);
 985986         if (!ISUNSIGNED(t) && (SBIT(sz) & r))
 986987                 r = r | NOTM(sz);
 987988         return r;
 988989 }
 989990 
 990991 /*
 991992  * Checks p for the existance of a pun.  This is called when the op of p
 992993  * is ASSIGN, RETURN, CAST, COLON, or relational.
 993994  * One case is when enumerations are used: this applies only to lint.
 994995  * In the other case, one operand is a pointer, the other integer type
 995996  * we check that this integer is in fact a constant zero...
 996997  * in the case of ASSIGN, any assignment of pointer to integer is illegal
 997998  * this falls out, because the LHS is never 0.
 998999  * XXX - check for COMOPs in assignment RHS?
 9991000  */
 10001001 void
 10011002 chkpun(NODE *p)
 10021003 {
 10031004         union dimfun *d1, *d2;
 10041005         NODE *q;
 10051006         int t1, t2;
 10061007 
 10071008         t1 = p->n_left->n_type;
 10081009         t2 = p->n_right->n_type;
 10091010 
 10101011         switch (p->n_op) {
 10111012         case RETURN:
 10121013                 /* return of void allowed but nothing else */
 10131014                 if (t1 == VOID && t2 == VOID)
 10141015                         return;
 10151016                 if (t1 == VOID) {
 10161017                         werror("returning value from void function");
 10171018                         return;
 10181019                 }
 10191020                 if (t2 == VOID) {
 10201021                         uerror("using void value");
 10211022                         return;
 10221023                 }
 10231024                 break;
 10241025         case COLON:
 10251026                 if (t1 == VOID && t2 == VOID)
 10261027                         return;
 10271028                 break;
 10281029         default:
 10291030                 if ((t1 == VOID && t2 != VOID) || (t1 != VOID && t2 == VOID)) {
 10301031                         uerror("value of void expression used");
 10311032                         return;
 10321033                 }
 10331034                 break;
 10341035         }
 10351036 
 10361037         /* allow void pointer assignments in any direction */
 10371038         if (BTYPE(t1) == VOID && (t2 & TMASK))
 10381039                 return;
 10391040         if (BTYPE(t2) == VOID && (t1 & TMASK))
 10401041                 return;
 10411042 
 10421043         /* boolean have special syntax */
 10431044         if (t1 == BOOL) {
 10441045                 if (!ISARY(t2)) /* Anything scalar */
 10451046                         return;
 10461047         }
 10471048 
 10481049         if (ISPTR(t1) || ISARY(t1))
 10491050                 q = p->n_right;
 10501051         else
 10511052                 q = p->n_left;
 10521053 
 10531054         if (!ISPTR(q->n_type) && !ISARY(q->n_type)) {
 10541055                 if (q->n_op != ICON || q->n_lval != 0)
 10551056                         werror("illegal combination of pointer and integer");
 10561057         } else {
 10571058                 if (t1 == t2) {
 10581059                         if (ISSOU(BTYPE(t1)) &&
 10591060                             !suemeq(p->n_left->n_ap, p->n_right->n_ap))
 10601061                                 werror("illegal structure pointer combination");
 10611062                         return;
 10621063                 }
 10631064                 d1 = p->n_left->n_df;
 10641065                 d2 = p->n_right->n_df;
 10651066                 for (;;) {
 10661067                         if (ISARY(t1) || ISPTR(t1)) {
 10671068                                 if (!ISARY(t2) && !ISPTR(t2))
 10681069                                         break;
 10691070                                 if (ISARY(t1) && ISARY(t2) && d1->ddim != d2->ddim) {
 10701071                                         werror("illegal array size combination");
 10711072                                         return;
 10721073                                 }
 10731074                                 if (ISARY(t1))
 10741075                                         ++d1;
 10751076                                 if (ISARY(t2))
 10761077                                         ++d2;
 10771078                         } else if (ISFTN(t1)) {
 10781079                                 if (chkftn(d1->dfun, d2->dfun)) {
 10791080                                         werror("illegal function "
 10801081                                             "pointer combination");
 10811082                                         return;
 10821083                                 }
 10831084                                 ++d1;
 10841085                                 ++d2;
 10851086                         } else
 10861087                                 break;
 10871088                         t1 = DECREF(t1);
 10881089                         t2 = DECREF(t2);
 10891090                 }
 10901091                 if (DEUNSIGN(t1) != DEUNSIGN(t2))
 10911092                         warner(Wpointer_sign, NULL);
 10921093         }
 10931094 }
 10941095 
 10951096 static NODE *
 10961097 offplus(NODE *p, int off, TWORD t, TWORD q, union dimfun *d, struct attr *ap) {
 10971098         if (off != 0) {
 10981099                 p = block(PLUS, p, offcon(off, t, d, ap), t, d, ap);
 10991100                 p->n_qual = q;
 11001101                 p = optim(p);
 11011102         }
 11021103 
 11031104         return buildtree(UMUL, p, NIL);
 11041105 }
 11051106 
 11061107 NODE *
 11071108 stref(NODE *p)
 11081109 {
 11091110         NODE *r;
 11101111         struct attr *ap, *xap, *yap;
 11111112         union dimfun *d;
 11121113         TWORD t, q;
 11131114         int dsc;
 11141115         OFFSZ off;
 11151116         struct symtab *s;
 11161117 
 11171118         /* make p->x */
 11181119         /* this is also used to reference automatic variables */
 11191120 
 11201121         s = p->n_right->n_sp;
 11211122         nfree(p->n_right);
 11221123         r = nfree(p);
 11231124         xap = attr_find(r->n_ap, GCC_ATYP_PACKED);
 11241125 
 11251126         p = pconvert(r);
 11261127 
 11271128         /* make p look like ptr to x */
 11281129 
 11291130         if (!ISPTR(p->n_type))
 11301131                 p->n_type = PTR+UNIONTY;
 11311132 
 11321133         t = INCREF(s->stype);
 11331134         q = INCQAL(s->squal);
 11341135         d = s->sdf;
 11351136         ap = s->sap;
 11361137         if ((yap = attr_find(ap, GCC_ATYP_PACKED)) != NULL)
 11371138                 xap = yap;
 11381139         else if (xap != NULL)
 11391140                 ap = attr_add(ap, attr_dup(xap, 3));
 11401141         /* xap set if packed struct */
 11411142 
 11421143         p = makety(p, t, q, d, ap);
 11431144         if (ISFTN(s->stype)) {
 11441145                 /* direct class call */
 11451146                 p = block(NMLIST, p, nametree(s), INT, 0, 0);
 11461147                 return p;
 11471148         }
 11481149 
 11491150         /* compute the offset to be added */
 11501151 
 11511152         off = s->soffset;
 11521153         dsc = s->sclass;
 11531154 
 11541155         if (dsc & FIELD) {
 11551156                 TWORD ftyp = s->stype;
 11561157                 int fal = talign(ftyp, ap);
 11571158                 off = (off/fal)*fal;
 11581159                 p = offplus(p, off, t, q, d, ap);
 11591160                 p = block(FLD, p, NIL, ftyp, 0, ap);
 11601161                 p->n_qual = q;
 11611162                 p->n_rval = PKFIELD(dsc&FLDSIZ, s->soffset%fal);
 11621163         } else {
 11631164                 p = offplus(p, off, t, q, d, ap);
 11641165 #ifndef CAN_UNALIGN
 11651166                 /* if target cannot handle unaligned addresses, fix here */
 11661167 #endif
 11671168         }
 11681169 
 11691170         p = clocal(p);
 11701171         return p;
 11711172 }
 11721173 
 11731174 int
 11741175 notlval(register NODE *p)
 11751176 {
 11761177         /* return 0 if p an lvalue, 1 otherwise */
 11771178 
 11781179         again:
 11791180 
 11801181         switch( p->n_op ){
 11811182 
 11821183         case FLD:
 11831184                 p = p->n_left;
 11841185                 goto again;
 11851186 
 11861187         case NAME:
 11871188         case OREG:
 11881189         case UMUL:
 11891190                 if( ISARY(p->n_type) || ISFTN(p->n_type) ) return(1);
 11901191         case TEMP:
 11911192         case REG:
 11921193                 return(0);
 11931194 
 11941195         default:
 11951196                 return(1);
 11961197         }
 11971198 }
 11981199 
 11991200 /* make a constant node with value i */
 12001201 NODE *
 12011202 bcon(int i)
 12021203 {
 12031204         return xbcon(i, NULL, INT);
 12041205 }
 12051206 
 12061207 NODE *
 12071208 xbcon(CONSZ val, struct symtab *sp, TWORD type)
 12081209 {
 12091210         NODE *p;
 12101211 
 12111212         p = block(ICON, NIL, NIL, type, 0, 0);
 12121213         p->n_lval = val;
 12131214         p->n_sp = sp;
 12141215         return clocal(p);
 12151216 }
 12161217 
 12171218 NODE *
 12181219 bpsize(NODE *p)
 12191220 {
 12201221         int isdyn(struct symtab *sp);
 12211222         struct symtab s;
 12221223         NODE *q, *r;
 12231224         TWORD t;
 12241225         int sz;
 12251226 
 12261227         s.stype = DECREF(p->n_type);
 12271228         s.sdf = p->n_df;
 12281229         if (isdyn(&s)) {
 12291230                 q = bcon(1);
 12301231                 for (t = s.stype; t > BTMASK; t = DECREF(t)) {
 12311232                         if (ISPTR(t))
 12321233                                 return buildtree(MUL, q, bcon(SZPOINT(t)));
 12331234                         if (ISARY(t)) {
 12341235                                 if (s.sdf->ddim < 0)
 12351236                                         r = tempnode(-s.sdf->ddim, INT, 0, 0);
 12361237                                 else
 12371238                                         r = bcon(s.sdf->ddim/SZCHAR);
 12381239                                 q = buildtree(MUL, q, r);
 12391240                                 s.sdf++;
 12401241                         }
 12411242                 }
 12421243                 sz = (int)tsize(p->n_type, p->n_df, p->n_ap);
 12431244                 p = buildtree(MUL, q, bcon(sz/SZCHAR));
 12441245         } else
 12451246                 p = (offcon(psize(p), p->n_type, p->n_df, p->n_ap));
 12461247         return p;
 12471248 }
 12481249 
 12491250 /*
 12501251  * p is a node of type pointer; psize returns the
 12511252  * size of the thing pointed to
 12521253  */
 12531254 OFFSZ
 12541255 psize(NODE *p)
 12551256 {
 12561257 
 12571258         if (!ISPTR(p->n_type)) {
 12581259                 uerror("pointer required");
 12591260                 return(SZINT);
 12601261         }
 12611262         /* note: no pointers to fields */
 12621263         return(tsize(DECREF(p->n_type), p->n_df, p->n_ap));
 12631264 }
 12641265 
 12651266 /*
 12661267  * convert an operand of p
 12671268  * f is either CVTL or CVTR
 12681269  * operand has type int, and is converted by the size of the other side
 12691270  * convert is called when an integer is to be added to a pointer, for
 12701271  * example in arrays or structures.
 12711272  */
 12721273 NODE *
 12731274 convert(NODE *p, int f)
 12741275 {
 12751276         union dimfun *df;
 12761277         TWORD ty, ty2;
 12771278         NODE *q, *r, *s, *rv;
 12781279 
 12791280         if (f == CVTL) {
 12801281                 q = p->n_left;
 12811282                 s = p->n_right;
 12821283         } else {
 12831284                 q = p->n_right;
 12841285                 s = p->n_left;
 12851286         }
 12861287         ty2 = ty = DECREF(s->n_type);
 12871288         while (ISARY(ty))
 12881289                 ty = DECREF(ty);
 12891290 
 12901291         r = offcon(tsize(ty, s->n_df, s->n_ap), s->n_type, s->n_df, s->n_ap);
 12911292         ty = ty2;
 12921293         rv = bcon(1);
 12931294         df = s->n_df;
 12941295         while (ISARY(ty)) {
 12951296                 rv = buildtree(MUL, rv, df->ddim >= 0 ? bcon(df->ddim) :
 12961297                     tempnode(-df->ddim, INT, 0, 0));
 12971298                 df++;
 12981299                 ty = DECREF(ty);
 12991300         }
 13001301         rv = clocal(MBLOCK(rv, r, INT, 0, 0));
 13011302         rv = optim(rv);
 13021303 
 13031304         r = MBLOCK(q, rv, INT, 0, 0);
 13041305         r = clocal(r);
 13051306         /*
 13061307          * Indexing is only allowed with integer arguments, so insert
 13071308          * SCONV here if arg is not an integer.
 13081309          * XXX - complain?
 13091310          */
 13101311         if (r->n_type != INTPTR)
 13111312                 r = clocal(makety(r, INTPTR, 0, 0, 0));
 13121313         if (f == CVTL)
 13131314                 p->n_left = r;
 13141315         else
 13151316                 p->n_right = r;
 13161317         return(p);
 13171318 }
 13181319 
 13191320 NODE *
 13201321 pconvert(register NODE *p)
 13211322 {
 13221323         /* if p should be changed into a pointer, do so */
 13231324 
 13241325         if( ISARY( p->n_type) ){
 13251326                 p->n_type = DECREF( p->n_type );
 13261327                 ++p->n_df;
 13271328                 return( buildtree( ADDROF, p, NIL ) );
 13281329         }
 13291330         if( ISFTN( p->n_type) )
 13301331                 return( buildtree( ADDROF, p, NIL ) );
 13311332 
 13321333         return( p );
 13331334 }
 13341335 
 13351336 NODE *
 13361337 oconvert(register NODE *p)
 13371338 {
 13381339         /* convert the result itself: used for pointer and unsigned */
 13391340 
 13401341         switch(p->n_op) {
 13411342 
 13421343         case LE:
 13431344         case LT:
 13441345         case GE:
 13451346         case GT:
 13461347                 if(ISUNSIGNED(p->n_left->n_type) ||
 13471348                     ISUNSIGNED(p->n_right->n_type) ||
 13481349                     ISPTR(p->n_left->n_type) ||
 13491350                     ISPTR(p->n_right->n_type))
 13501351                          p->n_op += (ULE-LE);
 13511352                 /* FALLTHROUGH */
 13521353         case EQ:
 13531354         case NE:
 13541355                 return( p );
 13551356 
 13561357         case MINUS:
 13571358                 p->n_type = INTPTR;
 13581359                 p->n_ap = NULL;
 13591360                 return(clocal(VBLOCK(p, bpsize(p->n_left), INT, 0, 0)));
 13601361                 }
 13611362 
 13621363         cerror( "illegal oconvert: %d", p->n_op );
 13631364 
 13641365         return(p);
 13651366 }
 13661367 
 13671368 /*
 13681369  * makes the operands of p agree; they are
 13691370  * either pointers or integers, by this time
 13701371  * with MINUS, the sizes must be the same
 13711372  * with COLON, the types must be the same
 13721373  */
 13731374 NODE *
 13741375 ptmatch(NODE *p)
 13751376 {
 13761377         struct attr *ap, *ap2;
 13771378         union dimfun *d, *d2;
 13781379         TWORD t1, t2, t, q1, q2, q;
 13791380         int o;
 13801381 
 13811382         o = p->n_op;
 13821383         t = t1 = p->n_left->n_type;
 13831384         q = q1 = p->n_left->n_qual;
 13841385         t2 = p->n_right->n_type;
 13851386         q2 = p->n_right->n_qual;
 13861387         d = p->n_left->n_df;
 13871388         d2 = p->n_right->n_df;
 13881389         ap = p->n_left->n_ap;
 13891390         ap2 = p->n_right->n_ap;
 13901391 
 13911392         switch( o ){
 13921393 
 13931394         case ASSIGN:
 13941395         case RETURN:
 13951396                 {  break; }
 13961397 
 13971398         case CAST:
 13981399                 if (t == VOID) {
 13991400                         /* just paint over */
 14001401                         p->n_right = block(SCONV, p->n_right, NIL, VOID, 0, 0);
 14011402                         return p;
 14021403                 }
 14031404                 break;
 14041405 
 14051406         case MINUS: {
 14061407                 int isdyn(struct symtab *sp);
 14071408                 struct symtab s1, s2;
 14081409 
 14091410                 s1.stype = DECREF(t);
 14101411                 s1.sdf = d;
 14111412                 s2.stype = DECREF(t2);
 14121413                 s2.sdf = d2;
 14131414                 if (isdyn(&s1) || isdyn(&s2))
 14141415                         ; /* We don't know */
 14151416                 else if (psize(p->n_left) != psize(p->n_right))
 14161417                         uerror("illegal pointer subtraction");
 14171418                 break;
 14181419                 }
 14191420 
 14201421         case COLON:
 14211422                 if (t1 != t2) {
 14221423                         /*
 14231424                          * Check for void pointer types. They are allowed
 14241425                          * to cast to/from any pointers.
 14251426                          */
 14261427                         if (ISPTR(t1) && ISPTR(t2) &&
 14271428                             (BTYPE(t1) == VOID || BTYPE(t2) == VOID))
 14281429                                 break;
 14291430                         uerror("illegal types in :");
 14301431                 }
 14311432                 break;
 14321433 
 14331434         default/* must work harder: relationals or comparisons */
 14341435 
 14351436                 if( !ISPTR(t1) ){
 14361437                         t = t2;
 14371438                         q = q2;
 14381439                         d = d2;
 14391440                         ap = ap2;
 14401441                         break;
 14411442                         }
 14421443                 if( !ISPTR(t2) ){
 14431444                         break;
 14441445                         }
 14451446 
 14461447                 /* both are pointers */
 14471448                 if( talign(t2,ap2) < talign(t,ap) ){
 14481449                         t = t2;
 14491450                         q = q2;
 14501451                         ap = ap2;
 14511452                         }
 14521453                 break;
 14531454                 }
 14541455 
 14551456         p->n_left = makety( p->n_left, t, q, d, ap );
 14561457         p->n_right = makety( p->n_right, t, q, d, ap );
 14571458         if( o!=MINUS && !clogop(o) ){
 14581459 
 14591460                 p->n_type = t;
 14601461                 p->n_qual = q;
 14611462                 p->n_df = d;
 14621463                 p->n_ap = ap;
 14631464                 }
 14641465 
 14651466         return(clocal(p));
 14661467 }
 14671468 
 14681469 /*
 14691470  * Satisfy the types of various arithmetic binary ops.
 14701471  *
 14711472  * rules are:
 14721473  *  if assignment, type of LHS
 14731474  *  if any doubles, make double
 14741475  *  else if any float make float
 14751476  *  else if any longlongs, make long long
 14761477  *  else if any longs, make long
 14771478  *  else etcetc.
 14781479  *
 14791480  *  If the op with the highest rank is unsigned, this is the resulting type.
 14801481  *  See:  6.3.1.1 rank order equal of signed and unsigned types
 14811482  *        6.3.1.8 Usual arithmetic conversions
 14821483  */
 14831484 static NODE *
 14841485 tymatch(NODE *p)
 14851486 {
 14861487         TWORD tl, tr, t;
 14871488         NODE *l, *r;
 14881489         int o;
 14891490 
 14901491         o = p->n_op;
 14911492         r = p->n_right;
 14921493         l = p->n_left;
 14931494 
 14941495         tl = l->n_type;
 14951496         tr = r->n_type;
 14961497 
 14971498         if (tl == BOOL) tl = BOOL_TYPE;
 14981499         if (tr == BOOL) tr = BOOL_TYPE;
 14991500 
 15001501         if (casgop(o)) {
 15011502                 if (r->n_op != ICON && tl < FLOAT && tr < FLOAT &&
 15021503                     DEUNSIGN(tl) < DEUNSIGN(tr) && o != CAST)
 15031504                         warner(Wtruncate, tnames[tr], tnames[tl]);
 15041505                 p->n_right = makety(p->n_right, l->n_type, 0, 0, 0);
 15051506                 t = p->n_type = l->n_type;
 15061507                 p->n_ap = l->n_ap;
 15071508         } else {
 15081509                 t = tl > tr ? tl : tr; /* MAX */
 15091510                 /* This depends on ctype() called early */
 15101511                 if (o != COLON && t < INT)
 15111512                         t = INT;
 15121513                 if (tl != t) p->n_left = makety(p->n_left, t, 0, 0, 0);
 15131514                 if (tr != t) p->n_right = makety(p->n_right, t, 0, 0, 0);
 15141515                 if (o == COLON && l->n_type == BOOL && r->n_type == BOOL)
 15151516                         t = p->n_type = BOOL;
 15161517                 else if (!clogop(o))
 15171518                         p->n_type = t;
 15181519         }
 15191520 #ifdef PCC_DEBUG
 15201521         if (tdebug) {
 15211522                 printf("tymatch(%p): ", p);
 15221523                 tprint(tl, 0);
 15231524                 printf(" %s ", copst(o));
 15241525                 tprint(tr, 0);
 15251526                 printf(" => ");
 15261527                 tprint(t, 0);
 15271528                 printf("\n");
 15281529                 fwalk(p, eprint, 0);
 15291530         }
 15301531 #endif
 15311532         return p;
 15321533 }
 15331534 
 15341535 /*
 15351536  * make p into type t by inserting a conversion
 15361537  */
 15371538 NODE *
 15381539 makety(NODE *p, TWORD t, TWORD q, union dimfun *d, struct attr *ap)
 15391540 {
 15401541 
 15411542         if (t == p->n_type) {
 15421543                 p->n_df = d;
 15431544                 p->n_ap = ap;
 15441545                 p->n_qual = q;
 15451546                 return(p);
 15461547         }
 15471548 
 15481549         if (ISITY(t) || ISCTY(t) || ISITY(p->n_type) || ISCTY(p->n_type))
 15491550                 cerror("makety");
 15501551 
 15511552         if (concast(p, t))
 15521553                 return clocal(p);
 15531554 
 15541555         p = block(t & TMASK ? PCONV : SCONV, p, NIL, t, d, ap);
 15551556         p->n_qual = q;
 15561557         return clocal(p);
 15571558 }
 15581559 
 15591560 NODE *
 15601561 block(int o, NODE *l, NODE *r, TWORD t, union dimfun *d, struct attr *ap)
 15611562 {
 15621563         register NODE *p;
 15631564 
 15641565         p = talloc();
 15651566         p->n_rval = 0;
 15661567         p->n_op = o;
 15671568         p->n_lval = 0; /* Protect against large lval */
 15681569         p->n_left = l;
 15691570         p->n_right = r;
 15701571         p->n_type = t;
 15711572         p->n_qual = 0;
 15721573         p->n_df = d;
 15731574         p->n_ap = ap;
 15741575 #if !defined(MULTIPASS)
 15751576         /* p->n_reg = */p->n_su = 0;
 15761577         p->n_regw = 0;
 15771578 #endif
 15781579         return(p);
 15791580 }
 15801581 
 15811582 /*
 15821583  * Return the constant value from an ICON.
 15831584  */
 15841585 CONSZ
 15851586 icons(NODE *p)
 15861587 {
 15871588         /* if p is an integer constant, return its value */
 15881589         CONSZ val;
 15891590 
 15901591         if (p->n_op != ICON || p->n_sp != NULL) {
 15911592                 uerror( "constant expected");
 15921593                 val = 1;
 15931594         } else
 15941595                 val = p->n_lval;
 15951596         tfree(p);
 15961597         return(val);
 15971598 }
 15981599 
 15991600 /*
 16001601  * the intent of this table is to examine the
 16011602  * operators, and to check them for
 16021603  * correctness.
 16031604  *
 16041605  * The table is searched for the op and the
 16051606  * modified type (where this is one of the
 16061607  * types INT (includes char and short), LONG,
 16071608  * DOUBLE (includes FLOAT), and POINTER
 16081609  *
 16091610  * The default action is to make the node type integer
 16101611  *
 16111612  * The actions taken include:
 16121613  *      PUN       check for puns
 16131614  *      CVTL      convert the left operand
 16141615  *      CVTR      convert the right operand
 16151616  *      TYPL      the type is determined by the left operand
 16161617  *      TYPR      the type is determined by the right operand
 16171618  *      TYMATCH   force type of left and right to match,by inserting conversions
 16181619  *      PTMATCH   like TYMATCH, but for pointers
 16191620  *      LVAL      left operand must be lval
 16201621  *      CVTO      convert the op
 16211622  *      NCVT      do not convert the operands
 16221623  *      OTHER     handled by code
 16231624  *      NCVTR     convert the left operand, not the right...
 16241625  *
 16251626  */
 16261627 
 16271628 # define MINT 01        /* integer */
 16281629 # define MDBI 02        /* integer or double */
 16291630 # define MSTR 04        /* structure */
 16301631 # define MPTR 010       /* pointer */
 16311632 # define MPTI 020       /* pointer or integer */
 16321633 
 16331634 int
 16341635 opact(NODE *p)
 16351636 {
 16361637         int mt12, mt1, mt2, o;
 16371638 
 16381639         mt1 = mt2 = mt12 = 0;
 16391640 
 16401641         switch (coptype(o = p->n_op)) {
 16411642         case BITYPE:
 16421643                 mt12=mt2 = moditype(p->n_right->n_type);
<> 1644+                /* FALLTHROUGH */
16431645         case UTYPE:
 16441646                 mt12 &= (mt1 = moditype(p->n_left->n_type));
 16451647                 break;
 16461648         }
 16471649 
 16481650         switch( o ){
 16491651 
 16501652         case NAME :
 16511653         case ICON :
 16521654         case FCON :
 16531655         case CALL :
 16541656         case UCALL:
 16551657         case UMUL:
 16561658                 {  return( OTHER ); }
 16571659         case UMINUS:
 16581660                 if( mt1 & MDBI ) return( TYPL+PROML );
 16591661                 break;
 16601662 
 16611663         case COMPL:
 16621664                 if( mt1 & MINT ) return( TYPL+PROML );
 16631665                 break;
 16641666 
 16651667         case ADDROF:
 16661668                 return( NCVT+OTHER );
 16671669         case NOT:
 16681670                 return( PROML );
 16691671 
 16701672 /*      case INIT: */
 16711673         case CM:
 16721674         case CBRANCH:
 16731675         case ANDAND:
 16741676         case OROR:
 16751677                 return( 0 );
 16761678 
 16771679         case MUL:
 16781680         case DIV:
 16791681                 if( mt12 & MDBI ) return( TYMATCH );
 16801682                 break;
 16811683 
 16821684         case MOD:
 16831685         case AND:
 16841686         case OR:
 16851687         case ER:
 16861688                 if( mt12 & MINT ) return( TYMATCH );
 16871689                 break;
 16881690 
 16891691         case LS:
 16901692         case RS:
 16911693                 if( mt12 & MINT ) return( TYPL+OTHER );
 16921694                 break;
 16931695 
 16941696         case EQ:
 16951697         case NE:
 16961698         case LT:
 16971699         case LE:
 16981700         case GT:
 16991701         case GE:
 17001702                 if( mt12 & MDBI ) return( TYMATCH+CVTO );
 17011703                 else if( mt12 & MPTR ) return( PTMATCH+PUN+CVTO );
 17021704                 else if( mt12 & MPTI ) return( PTMATCH+PUN );
 17031705                 else break;
 17041706 
 17051707         case QUEST:
 17061708                 return( TYPR+OTHER );
 17071709         case COMOP:
 17081710                 return( TYPR );
 17091711 
 17101712         case STREF:
 17111713                 return( NCVTR+OTHER );
 17121714 
 17131715         case FORCE:
 17141716                 return( TYPL );
 17151717 
 17161718         case COLON:
 17171719                 if( mt12 & MDBI ) return( TYMATCH );
 17181720                 else if( mt12 & MPTR ) return( TYPL+PTMATCH+PUN );
 17191721                 else if( (mt1&MINT) && (mt2&MPTR) ) return( TYPR+PUN );
 17201722                 else if( (mt1&MPTR) && (mt2&MINT) ) return( TYPL+PUN );
 17211723                 else if( mt12 & MSTR ) return( NCVT+TYPL+OTHER );
 17221724                 break;
 17231725 
 17241726         case ASSIGN:
 17251727         case RETURN:
 17261728                 if( mt12 & MSTR ) return( LVAL+NCVT+TYPL+OTHER );
 17271729         case CAST:
 17281730                 if( mt12 & MDBI ) return( TYPL+LVAL+TYMATCH );
 17291731                 else if( mt1 & MPTR) return( LVAL+PTMATCH+PUN );
 17301732                 else if( mt12 & MPTI ) return( TYPL+LVAL+TYMATCH+PUN );
 17311733                 break;
 17321734 
 17331735         case LSEQ:
 17341736         case RSEQ:
 17351737                 if( mt12 & MINT ) return( TYPL+LVAL+OTHER );
 17361738                 break;
 17371739 
 17381740         case MULEQ:
 17391741         case DIVEQ:
 17401742                 if( mt12 & MDBI ) return( LVAL+TYMATCH );
 17411743                 break;
 17421744 
 17431745         case MODEQ:
 17441746         case ANDEQ:
 17451747         case OREQ:
 17461748         case EREQ:
 17471749                 if (mt12 & MINT)
 17481750                         return(LVAL+TYMATCH);
 17491751                 break;
 17501752 
 17511753         case PLUSEQ:
 17521754         case MINUSEQ:
 17531755         case INCR:
 17541756         case DECR:
 17551757                 if (mt12 & MDBI)
 17561758                         return(TYMATCH+LVAL);
 17571759                 else if ((mt1&MPTR) && (mt2&MINT))
 17581760                         return(TYPL+LVAL+CVTR);
 17591761                 break;
 17601762 
 17611763         case MINUS:
 17621764                 if (mt12 & MPTR)
 17631765                         return(CVTO+PTMATCH+PUN);
 17641766                 if (mt2 & MPTR)
 17651767                         break;
 17661768                 /* FALLTHROUGH */
 17671769         case PLUS:
 17681770                 if (mt12 & MDBI)
 17691771                         return(TYMATCH);
 17701772                 else if ((mt1&MPTR) && (mt2&MINT))
 17711773                         return(TYPL+CVTR);
 17721774                 else if ((mt1&MINT) && (mt2&MPTR))
 17731775                         return(TYPR+CVTL);
 17741776 
 17751777         }
 17761778         uerror("operands of %s have incompatible types", copst(o));
 17771779         return(NCVT);
 17781780 }
 17791781 
 17801782 int
 17811783 moditype(TWORD ty)
 17821784 {
 17831785         switch (ty) {
 17841786 
 17851787         case STRTY:
 17861788         case UNIONTY:
 17871789                 return( MSTR );
 17881790 
 17891791         case BOOL:
 17901792         case CHAR:
 17911793         case SHORT:
 17921794         case UCHAR:
 17931795         case USHORT:
 17941796         case UNSIGNED:
 17951797         case ULONG:
 17961798         case ULONGLONG:
 17971799         case INT:
 17981800         case LONG:
 17991801         case LONGLONG:
 18001802                 return( MINT|MDBI|MPTI );
 18011803         case FLOAT:
 18021804         case DOUBLE:
 18031805         case LDOUBLE:
 18041806 #ifndef NO_COMPLEX
 18051807         case FCOMPLEX:
 18061808         case COMPLEX:
 18071809         case LCOMPLEX:
 18081810         case FIMAG:
 18091811         case IMAG:
 18101812         case LIMAG:
 18111813 #endif
 18121814                 return( MDBI );
 18131815         default:
 18141816                 return( MPTR|MPTI );
 18151817 
 18161818         }
 18171819 }
 18181820 
 18191821 int tvaloff = MAXREGS+NPERMREG > 100 ? MAXREGS+NPERMREG + 100 : 100;
 18201822 
 18211823 /*
 18221824  * Returns a TEMP node with temp number nr.
 18231825  * If nr == 0, return a node with a new number.
 18241826  */
 18251827 NODE *
 18261828 tempnode(int nr, TWORD type, union dimfun *df, struct attr *ap)
 18271829 {
 18281830         NODE *r;
 18291831 
 18301832         if (tvaloff == -NOOFFSET)
 18311833                 tvaloff++; /* Skip this for array indexing */
 18321834         r = block(TEMP, NIL, NIL, type, df, ap);
 18331835         regno(r) = nr ? nr : tvaloff;
 18341836         tvaloff += szty(type);
 18351837         return r;
 18361838 }
 18371839 
 18381840 /*
 18391841  * Do sizeof on p.
 18401842  */
 18411843 NODE *
 18421844 doszof(NODE *p)
 18431845 {
 18441846         extern NODE *arrstk[10];
 18451847         extern int arrstkp;
 18461848         union dimfun *df;
 18471849         TWORD ty;
 18481850         NODE *rv, *q;
 18491851         int astkp;
 18501852 
 18511853         if (p->n_op == FLD)
 18521854                 uerror("can't apply sizeof to bit-field");
 18531855 
 18541856         /*
 18551857          * Arrays may be dynamic, may need to make computations.
 18561858          */
 18571859 
 18581860         rv = bcon(1);
 18591861         df = p->n_df;
 18601862         ty = p->n_type;
 18611863         astkp = 0;
 18621864         while (ISARY(ty)) {
 18631865                 if (df->ddim == NOOFFSET)
 18641866                         uerror("sizeof of incomplete type");
 18651867                 if (df->ddim < 0) {
 18661868                         if (arrstkp)
 18671869                                 q = arrstk[astkp++];
 18681870                         else
 18691871                                 q = tempnode(-df->ddim, INT, 0, 0);
 18701872                 } else
 18711873                         q = bcon(df->ddim);
 18721874                 rv = buildtree(MUL, rv, q);
 18731875                 df++;
 18741876                 ty = DECREF(ty);
 18751877         }
 18761878         rv = buildtree(MUL, rv,
 18771879             xbcon(tsize(ty, p->n_df, p->n_ap)/SZCHAR, NULL, INTPTR));
 18781880         tfree(p);
 18791881         arrstkp = 0; /* XXX - may this fail? */
 18801882         return rv;
 18811883 }
 18821884 
 18831885 #ifdef PCC_DEBUG
 18841886 void
 18851887 eprint(NODE *p, int down, int *a, int *b)
 18861888 {
 18871889         int ty;
 18881890 
 18891891         *a = *b = down+1;
 18901892         while( down > 1 ){
 18911893                 printf( "\t" );
 18921894                 down -= 2;
 18931895                 }
 18941896         if( down ) printf( "    " );
 18951897 
 18961898         ty = coptype( p->n_op );
 18971899 
 18981900         printf("%p) %s, ", p, copst(p->n_op));
 18991901         if (p->n_op == XARG || p->n_op == XASM)
 19001902                 printf("id '%s', ", p->n_name);
 19011903         if (ty == LTYPE) {
 19021904                 printf(CONFMT, p->n_lval);
 19031905                 if (p->n_op == NAME || p->n_op == ICON)
 19041906                         printf(", %p, ", p->n_sp);
 19051907                 else
 19061908                         printf(", %d, ", p->n_rval);
 19071909         }
 19081910         tprint(p->n_type, p->n_qual);
 19091911         printf( ", %p, ", p->n_df);
 19101912         dump_attr(p->n_ap);
 19111913 }
 19121914 # endif
 19131915 
 19141916 /*
 19151917  * Emit everything that should be emitted on the left side
 19161918  * of a comma operator, and remove the operator.
 19171919  * Do not traverse through QUEST, ANDAND and OROR.
 19181920  * Enable this for all targets when stable enough.
 19191921  */
 19201922 static void
 19211923 comops(NODE *p)
 19221924 {
 19231925         int o;
 19241926         NODE *q;
 19251927 
 19261928         while (p->n_op == COMOP) {
 19271929                 /* XXX hack for GCC ({ }) ops */
 19281930                 if (p->n_left->n_op == GOTO) {
 19291931                         int v = (int)p->n_left->n_left->n_lval;
 19301932                         ecomp(p->n_left);
 19311933                         plabel(v+1);
 19321934                 } else
 19331935                         ecomp(p->n_left); /* will recurse if more COMOPs */
 19341936                 q = p->n_right;
 19351937                 *p = *q;
 19361938                 nfree(q);
 19371939         }
 19381940         o = coptype(p->n_op);
 19391941         if (p->n_op == QUEST || p->n_op == ANDAND || p->n_op == OROR)
 19401942                 o = UTYPE;
 19411943         if (o != LTYPE)
 19421944                 comops(p->n_left);
 19431945         if (o == BITYPE)
 19441946                 comops(p->n_right);
 19451947 }
 19461948 
 19471949 /*
 19481950  * Walk up through the tree from the leaves,
 19491951  * removing constant operators.
 19501952  */
 19511953 static void
 19521954 logwalk(NODE *p)
 19531955 {
 19541956         int o = coptype(p->n_op);
 19551957         NODE *l, *r;
 19561958 
 19571959         l = p->n_left;
 19581960         r = p->n_right;
 19591961         switch (o) {
 19601962         case LTYPE:
 19611963                 return;
 19621964         case BITYPE:
 19631965                 logwalk(r);
<> 1966+                /* FALLTHROUGH */
<_19641967         case UTYPE:
 19651968                 logwalk(l);
 19661969         }
 19671970         if (!clogop(p->n_op))
 19681971                 return;
 19691972         if (p->n_op == NOT && l->n_op == ICON) {
 19701973                 p->n_lval = l->n_lval == 0;
 19711974                 nfree(l);
 19721975                 p->n_op = ICON;
 19731976         }
 19741977         if (l->n_op == ICON && r->n_op == ICON) {
 19751978                 if (conval(l, p->n_op, r) == 0) {
 19761979                         /*
 19771980                          * people sometimes tend to do really odd compares,
 19781981                          * like "if ("abc" == "def")" etc.
 19791982                          * do it runtime instead.
 19801983                          */
 19811984                 } else {
 19821985                         p->n_lval = l->n_lval;
 19831986                         p->n_op = ICON;
 19841987                         nfree(l);
 19851988                         nfree(r);
 19861989                 }
 19871990         }
 19881991 }
 19891992 
 19901993 /*
 19911994  * Removes redundant logical operators for branch conditions.
 19921995  */
 19931996 static void
 19941997 fixbranch(NODE *p, int label)
 19951998 {
 19961999 
 19972000         logwalk(p);
 19982001 
 19992002         if (p->n_op == ICON) {
 20002003                 if (p->n_lval != 0)
 20012004                         branch(label);
 20022005                 nfree(p);
 20032006         } else {
 20042007                 if (!clogop(p->n_op)) /* Always conditional */
 20052008                         p = buildtree(NE, p, bcon(0));
 20062009                 ecode(buildtree(CBRANCH, p, bcon(label)));
 20072010         }
 20082011 }
 20092012 
 20102013 /*
 20112014  * Write out logical expressions as branches.
 20122015  */
 20132016 static void
 20142017 andorbr(NODE *p, int true, int false)
 20152018 {
 20162019         NODE *q;
 20172020         int o, lab;
 20182021 
 20192022         lab = -1;
 20202023         switch (o = p->n_op) {
 20212024         case EQ:
 20222025         case NE:
 20232026                 /*
 20242027                  * Remove redundant EQ/NE nodes.
 20252028                  */
 20262029                 while (((o = p->n_left->n_op) == EQ || o == NE) &&
 20272030                     p->n_right->n_op == ICON) {
 20282031                         o = p->n_op;
 20292032                         q = p->n_left;
 20302033                         if (p->n_right->n_lval == 0) {
 20312034                                 nfree(p->n_right);
 20322035                                 *p = *q;
 20332036                                 nfree(q);
 20342037                                 if (o == EQ)
 20352038                                         p->n_op = negrel[p->n_op - EQ];
 20362039 #if 0
 20372040                                         p->n_op = NE; /* toggla */
 20382041 #endif
 20392042                         } else if (p->n_right->n_lval == 1) {
 20402043                                 nfree(p->n_right);
 20412044                                 *p = *q;
 20422045                                 nfree(q);
 20432046                                 if (o == NE)
 20442047                                         p->n_op = negrel[p->n_op - EQ];
 20452048 #if 0
 20462049                                         p->n_op = EQ; /* toggla */
 20472050 #endif
 20482051                         } else
 20492052                                 break; /* XXX - should always be false */
 20502053                         
 20512054                 }
 20522055                 /* FALLTHROUGH */
 20532056         case LE:
 20542057         case LT:
 20552058         case GE:
 20562059         case GT:
 20572060 calc:           if (true < 0) {
 20582061                         p->n_op = negrel[p->n_op - EQ];
 20592062                         true = false;
 20602063                         false = -1;
 20612064                 }
 20622065 
 20632066                 rmcops(p->n_left);
 20642067                 rmcops(p->n_right);
 20652068                 fixbranch(p, true);
 20662069                 if (false >= 0)
 20672070                         branch(false);
 20682071                 break;
 20692072 
 20702073         case ULE:
 20712074         case UGT:
 20722075                 /* Convert to friendlier ops */
 20732076                 if (nncon(p->n_right) && p->n_right->n_lval == 0)
 20742077                         p->n_op = o == ULE ? EQ : NE;
 20752078                 goto calc;
 20762079 
 20772080         case UGE:
 20782081         case ULT:
 20792082                 /* Already true/false by definition */
 20802083                 if (nncon(p->n_right) && p->n_right->n_lval == 0) {
 20812084                         if (true < 0) {
 20822085                                 o = o == ULT ? UGE : ULT;
 20832086                                 true = false;
 20842087                         }
 20852088                         rmcops(p->n_left);
 20862089                         ecode(p->n_left);
 20872090                         rmcops(p->n_right);
 20882091                         ecode(p->n_right);
 20892092                         nfree(p);
 20902093                         if (o == UGE) /* true */
 20912094                                 branch(true);
 20922095                         break;
 20932096                 }
 20942097                 goto calc;
 20952098 
 20962099         case ANDAND:
 20972100                 lab = false<0 ? getlab() : false ;
 20982101                 andorbr(p->n_left, -1, lab);
 20992102                 comops(p->n_right);
 21002103                 andorbr(p->n_right, true, false);
 21012104                 if (false < 0)
 21022105                         plabel( lab);
 21032106                 nfree(p);
 21042107                 break;
 21052108 
 21062109         case OROR:
 21072110                 lab = true<0 ? getlab() : true;
 21082111                 andorbr(p->n_left, lab, -1);
 21092112                 comops(p->n_right);
 21102113                 andorbr(p->n_right, true, false);
 21112114                 if (true < 0)
 21122115                         plabel( lab);
 21132116                 nfree(p);
 21142117                 break;
 21152118 
 21162119         case NOT:
 21172120                 andorbr(p->n_left, false, true);
 21182121                 nfree(p);
 21192122                 break;
 21202123 
 21212124         default:
 21222125                 rmcops(p);
 21232126                 if (true >= 0)
 21242127                         fixbranch(p, true);
 21252128                 if (false >= 0) {
 21262129                         if (true >= 0)
 21272130                                 branch(false);
 21282131                         else
 21292132                                 fixbranch(buildtree(EQ, p, bcon(0)), false);
 21302133                 }
 21312134         }
 21322135 }
 21332136 
 21342137 /*
 21352138  * Create a node for either TEMP or on-stack storage.
 21362139  */
 21372140 NODE *
 21382141 cstknode(TWORD t, union dimfun *df, struct attr *ap)
 21392142 {
 21402143         struct symtab *sp;
 21412144 
 21422145         /* create a symtab entry suitable for this type */
 21432146         sp = getsymtab("0hej", STEMP);
 21442147         sp->stype = t;
 21452148         sp->sdf = df;
 21462149         sp->sap = ap;
 21472150         sp->sclass = AUTO;
 21482151         sp->soffset = NOOFFSET;
 21492152         oalloc(sp, &autooff);
 21502153         return nametree(sp);
 21512154 
 21522155 }
 21532156 
 21542157 /*
 21552158  * Massage the output trees to remove C-specific nodes:
 21562159  *      COMOPs are split into separate statements.
 21572160  *      QUEST/COLON are rewritten to branches.
 21582161  *      ANDAND/OROR/NOT are rewritten to branches for lazy-evaluation.
 21592162  *      CBRANCH conditions are rewritten for lazy-evaluation.
 21602163  */
 21612164 static void
 21622165 rmcops(NODE *p)
 21632166 {
 21642167         TWORD type;
 21652168         NODE *q, *r, *tval;
 21662169         int o, ty, lbl, lbl2;
 21672170 
 21682171         tval = NIL;
 21692172         o = p->n_op;
 21702173         ty = coptype(o);
 21712174         if (BTYPE(p->n_type) == ENUMTY) { /* fixup enum */
 21722175                 struct symtab *sp = strmemb(p->n_ap);
 21732176                 MODTYPE(p->n_type, sp->stype);
 21742177                 /*
 21752178                  * XXX may fail if these are true:
 21762179                  * - variable-sized enums
 21772180                  * - non-byte-addressed targets.
 21782181                  */
 21792182                 if (BTYPE(p->n_type) == ENUMTY && ISPTR(p->n_type))
 21802183                         MODTYPE(p->n_type, INT); /* INT ok? */
 21812184         }
 21822185         switch (o) {
 21832186         case QUEST:
 21842187 
 21852188                 /*
 21862189                  * Create a branch node from ?:
 21872190                  * || and && must be taken special care of.
 21882191                  */
 21892192                 type = p->n_type;
 21902193                 andorbr(p->n_left, -1, lbl = getlab());
 21912194 
 21922195                 /* Make ASSIGN node */
 21932196                 /* Only if type is not void */
 21942197                 q = p->n_right->n_left;
 21952198                 comops(q);
 21962199                 if (type != VOID) {
 21972200                         tval = cstknode(q->n_type, q->n_df, q->n_ap);
 21982201                         q = buildtree(ASSIGN, ccopy(tval), q);
 21992202                 }
 22002203                 rmcops(q);
 22012204                 ecode(q); /* Done with assign */
 22022205                 branch(lbl2 = getlab());
 22032206                 plabel( lbl);
 22042207 
 22052208                 q = p->n_right->n_right;
 22062209                 comops(q);
 22072210                 if (type != VOID) {
 22082211                         q = buildtree(ASSIGN, ccopy(tval), q);
 22092212                 }
 22102213                 rmcops(q);
 22112214                 ecode(q); /* Done with assign */
 22122215 
 22132216                 plabel( lbl2);
 22142217 
 22152218                 nfree(p->n_right);
 22162219                 if (p->n_type != VOID) {
 22172220                         *p = *tval;
 22182221                         nfree(tval);
 22192222                 } else {
 22202223                         p->n_op = ICON;
 22212224                         p->n_lval = 0;
 22222225                         p->n_sp = NULL;
 22232226                 }
 22242227                 break;
 22252228 
 22262229         case ULE:
 22272230         case ULT:
 22282231         case UGE:
 22292232         case UGT:
 22302233         case EQ:
 22312234         case NE:
 22322235         case LE:
 22332236         case LT:
 22342237         case GE:
 22352238         case GT:
 22362239         case ANDAND:
 22372240         case OROR:
 22382241         case NOT:
 22392242 #ifdef SPECIAL_CCODES
 22402243 #error fix for private CCODES handling
 22412244 #else
 22422245                 r = talloc();
 22432246                 *r = *p;
 22442247                 andorbr(r, -1, lbl = getlab());
 22452248 
 22462249                 tval = cstknode(p->n_type, p->n_df, p->n_ap);
 22472250 
 22482251                 ecode(buildtree(ASSIGN, ccopy(tval), bcon(1)));
 22492252                 branch(lbl2 = getlab());
 22502253                 plabel( lbl);
 22512254                 ecode(buildtree(ASSIGN, ccopy(tval), bcon(0)));
 22522255                 plabel( lbl2);
 22532256 
 22542257                 *p = *tval;
 22552258                 nfree(tval);
 22562259 
 22572260 #endif
 22582261                 break;
 22592262         case CBRANCH:
 22602263                 andorbr(p->n_left, p->n_right->n_lval, -1);
 22612264                 nfree(p->n_right);
 22622265                 p->n_op = ICON; p->n_type = VOID;
 22632266                 break;
 22642267         case COMOP:
 22652268                 cerror("COMOP error");
 22662269 
 22672270         default:
 22682271                 if (ty == LTYPE)
 22692272                         return;
 22702273                 rmcops(p->n_left);
 22712274                 if (ty == BITYPE)
 22722275                         rmcops(p->n_right);
 22732276        }
 22742277 }
 22752278 
 22762279 /*
 22772280  * Return 1 if an assignment is found.
 22782281  */
 22792282 static int
 22802283 has_se(NODE *p)
 22812284 {
 22822285         if (cdope(p->n_op) & ASGFLG)
 22832286                 return 1;
 22842287         if (coptype(p->n_op) == LTYPE)
 22852288                 return 0;
 22862289         if (has_se(p->n_left))
 22872290                 return 1;
 22882291         if (coptype(p->n_op) == BITYPE)
 22892292                 return has_se(p->n_right);
 22902293         return 0;
 22912294 }
 22922295 
 22932296 /*
 22942297  * Find and convert asgop's to separate statements.
 22952298  * Be careful about side effects.
 22962299  * assign tells whether ASSIGN should be considered giving
 22972300  * side effects or not.
 22982301  */
 22992302 static NODE *
 23002303 delasgop(NODE *p)
 23012304 {
 23022305         NODE *q, *r;
 23032306         int tval;
 23042307 
 23052308         if (p->n_op == INCR || p->n_op == DECR) {
 23062309                 /*
 23072310                  * Rewrite x++ to (x += 1) -1; and deal with it further down.
 23082311                  * Pass2 will remove -1 if unnecessary.
 23092312                  */
 23102313                 q = ccopy(p);
 23112314                 tfree(p->n_left);
 23122315                 q->n_op = (p->n_op==INCR)?PLUSEQ:MINUSEQ;
 23132316                 p->n_op = (p->n_op==INCR)?MINUS:PLUS;
 23142317                 p->n_left = delasgop(q);
 23152318 
 23162319         } else if ((cdope(p->n_op)&ASGOPFLG) &&
 23172320             p->n_op != RETURN && p->n_op != CAST) {
 23182321                 NODE *l = p->n_left;
 23192322                 NODE *ll = l->n_left;
 23202323 
 23212324                 if (has_se(l)) {
 23222325                         q = tempnode(0, ll->n_type, ll->n_df, ll->n_ap);
 23232326                         tval = regno(q);
 23242327                         r = tempnode(tval, ll->n_type, ll->n_df,ll->n_ap);
 23252328                         l->n_left = q;
 23262329                         /* Now the left side of node p has no side effects. */
 23272330                         /* side effects on the right side must be obeyed */
 23282331                         p = delasgop(p);
 23292332                         
 23302333                         r = buildtree(ASSIGN, r, ll);
 23312334                         r = delasgop(r);
 23322335                         ecode(r);
 23332336                 } else {
 23342337 #if 0 /* Cannot call buildtree() here, it would invoke double add shifts */
 23352338                         p->n_right = buildtree(UNASG p->n_op, ccopy(l),
 23362339                             p->n_right);
 23372340 #else
 23382341                         p->n_right = block(UNASG p->n_op, ccopy(l),
 23392342                             p->n_right, p->n_type, p->n_df, p->n_ap);
 23402343 #endif
 23412344                         p->n_op = ASSIGN;
 23422345                         p->n_right = delasgop(p->n_right);
 23432346                         p->n_right = clocal(p->n_right);
 23442347                 }
 23452348                 
 23462349         } else {
 23472350                 if (coptype(p->n_op) == LTYPE)
 23482351                         return p;
 23492352                 p->n_left = delasgop(p->n_left);
 23502353                 if (coptype(p->n_op) == BITYPE)
 23512354                         p->n_right = delasgop(p->n_right);
 23522355         }
 23532356         return p;
 23542357 }
 23552358 
 23562359 #ifndef FIELDOPS
 23572360 
 23582361 /* avoid promotion to int */
 23592362 #define TYPMOD(o, p, n, t)      clocal(block(o, p, n, t, 0, 0))
 23602363 #define TYPLS(p, n, t)  TYPMOD(LS, p, n, t)
 23612364 #define TYPRS(p, n, t)  TYPMOD(RS, p, n, t)
 23622365 #define TYPOR(p, q, t)  TYPMOD(OR, p, q, t)
 23632366 #define TYPAND(p, q, t) TYPMOD(AND, p, q, t)
 23642367 
 23652368 /*
 23662369  * Read an unaligned bitfield from position pointed to by p starting at
 23672370  * off and size fsz and return a tree of type t with resulting data.
 23682371  */
 23692372 static NODE *
 23702373 rdualfld(NODE *p, TWORD t, TWORD ct, int off, int fsz)
 23712374 {
 23722375         int t2f, inbits, tsz, ctsz;
 23732376         NODE *q, *r;
 23742377 
 23752378         ct = ENUNSIGN(ct);
 23762379         ctsz = (int)tsize(ct, 0, 0);
 23772380 
 23782381         /* traverse until first data byte */
 23792382         for (t2f = 0; off > ctsz; t2f++, off -= ctsz)
 23802383                 ;
 23812384 #ifdef UNALIGNED_ACCESS
 23822385         /* try to squeeze it into an int */
 23832386         if (off + fsz > ctsz && off + fsz <= SZINT) {
 23842387                 ct = UNSIGNED;
 23852388                 ctsz = SZINT;
 23862389         }
 23872390 #endif
 23882391         p = makety(p, PTR|ct, 0, 0, 0);
 23892392         if (off + fsz <= ctsz) {
 23902393                 /* only one operation needed */
 23912394                 q = buildtree(UMUL, buildtree(PLUS, p, bcon(t2f)), 0);
 23922395                 if (!ISUNSIGNED(t)) {
 23932396                         ct = DEUNSIGN(ct);
 23942397                         q = makety(q, ct, 0, 0, 0);
 23952398                 }
 23962399                 q = TYPLS(q, bcon(ctsz-fsz-off), ct);
 23972400                 q = TYPRS(q, bcon(ctsz-fsz), ct);
 23982401                 q = makety(q, t, 0, 0, 0);
 23992402         } else {
 24002403                 q = buildtree(UMUL, buildtree(PLUS, ccopy(p), bcon(t2f)), 0);
 24012404                 q = makety(TYPRS(q, bcon(off), ct), t, 0, 0, 0);
 24022405                 inbits = ctsz - off;
 24032406                 t2f++;
 24042407 
 24052408                 while (fsz > inbits) {
 24062409                         r = buildtree(UMUL,
 24072410                             buildtree(PLUS, ccopy(p), bcon(t2f)), 0);
 24082411                         r = makety(r, t, 0, 0, 0);
 24092412                         r = TYPLS(r, bcon(inbits), t);
 24102413                         q = TYPOR(q, r, t);
 24112414                         inbits += ctsz;
 24122415                         t2f++;
 24132416                 }
 24142417                 /* sign/zero extend XXX - RS must sign extend */
 24152418                 tsz = (int)tsize(t, 0, 0);
 24162419                 if (!ISUNSIGNED(t)) {
 24172420                         t = DEUNSIGN(t);
 24182421                         q = makety(q, t, 0, 0, 0);
 24192422                 }
 24202423                 q = TYPLS(q, bcon(tsz-fsz), t);
 24212424                 q = TYPRS(q, bcon(tsz-fsz), t);
 24222425                 tfree(p);
 24232426         }
 24242427 
 24252428         return q;
 24262429 }
 24272430 
 24282431 /*
 24292432  * Write val to a (unaligned) bitfield with length fsz positioned off bits 
 24302433  * from d. Bitfield type is t, and type to use when writing is ct.
 24312434  * neither f nor d should have any side effects if copied.
 24322435  * Multiples of ct are supposed to be written without problems.
 24332436  * Both val and d are free'd after use.
 24342437  */
 24352438 static NODE *
 24362439 wrualfld(NODE *val, NODE *d, TWORD t, TWORD ct, int off, int fsz)
 24372440 {
 24382441         NODE *p, *q, *r, *rn, *s;
 24392442         int tsz, ctsz, t2f, inbits;
 24402443  
 24412444         tsz = (int)tsize(t, 0, 0);
 24422445         ctsz = (int)tsize(ct, 0, 0);
 24432446  
 24442447         ct = ENUNSIGN(ct);
 24452448         d = makety(d, PTR|ct, 0, 0, 0);
 24462449 
 24472450         for (t2f = 0; off > ctsz; t2f++, off -= ctsz)
 24482451                 ;
 24492452  
 24502453         if (off + fsz <= ctsz) {
 24512454                 r = tempnode(0, ct, 0, 0);
 24522455 
 24532456                 /* only one operation needed */
 24542457                 d = buildtree(UMUL, buildtree(PLUS, d, bcon(t2f)), 0);  
 24552458                 p = ccopy(d);
 24562459                 p = TYPAND(p, xbcon(~(SZMASK(fsz) << off), 0, ct), ct);
 24572460 
 24582461                 val = makety(val, ct, 0, 0, 0);
 24592462                 q = TYPAND(val, xbcon(SZMASK(fsz), 0, ct), ct);
 24602463                 q = buildtree(ASSIGN, ccopy(r), q);
 24612464 
 24622465                 q = TYPLS(q, bcon(off), ct);  
 24632466                 p = TYPOR(p, q, ct);
 24642467                 p = makety(p, t, 0, 0, 0);    
 24652468                 rn = buildtree(ASSIGN, d, p);
 24662469                 rn = buildtree(COMOP, rn, makety(r, t, 0, 0, 0));
 24672470         } else {
 24682471                 s = makety(ccopy(val), t, 0, 0, 0);
 24692472                 s = TYPAND(s, xbcon(SZMASK(fsz), 0, t), t);
 24702473 
 24712474                 r = buildtree(UMUL, buildtree(PLUS, ccopy(d), bcon(t2f)), 0);
 24722475                 p = ccopy(r);
 24732476                 p = TYPAND(p, xbcon(SZMASK(off), 0, ct), ct);
 24742477                 q = ccopy(val);
 24752478                 q = TYPLS(q, bcon(off), t); 
 24762479                 q = makety(q, ct, 0, 0, 0);
 24772480                 p = TYPOR(p, q, ct);
 24782481                 rn = buildtree(ASSIGN, r, p);
 24792482                 inbits = ctsz - off;
 24802483                 t2f++;
 24812484 
 24822485                 while (fsz > inbits+ctsz) {
 24832486                         r = buildtree(UMUL,
 24842487                             buildtree(PLUS, ccopy(d), bcon(t2f)), 0);
 24852488                         q = ccopy(val);
 24862489                         q = TYPRS(q, bcon(inbits), t);
 24872490                         q = makety(q, ct, 0, 0, 0);
 24882491                         rn = buildtree(COMOP, rn, buildtree(ASSIGN, r, q));
 24892492                         t2f++;
 24902493                         inbits += ctsz;
 24912494                 }
 24922495 
 24932496                 r = buildtree(UMUL, buildtree(PLUS, d, bcon(t2f)), 0);
 24942497                 p = ccopy(r);
 24952498                 p = TYPAND(p, makety(xbcon(~SZMASK(fsz-inbits), 0, ct),
 24962499                     ct, 0, 0, 0), ct);
 24972500                 q = TYPRS(val, bcon(inbits), t);
 24982501                 q = TYPAND(q, xbcon(SZMASK(fsz-inbits), 0, t), t);
 24992502                 q = makety(q, ct, 0, 0, 0);
 25002503                 p = TYPOR(p, q, ct);
 25012504                 rn = buildtree(COMOP, rn, buildtree(ASSIGN, r, p));
 25022505                 rn = buildtree(COMOP, rn, s);
 25032506         }
 25042507         return rn;
 25052508 }
 25062509 
 25072510 /*
 25082511  * Rewrite bitfield operations to shifts.
 25092512  */
 25102513 static NODE *
 25112514 rmfldops(NODE *p)
 25122515 {
 25132516         TWORD t, ct;
 25142517         NODE *q, *r, *t1, *t2, *bt, *t3, *t4;
 25152518         int fsz, foff, tsz;
 25162519 
 25172520         if (p->n_op == FLD) {
 25182521                 /* Rewrite a field read operation */
 25192522                 fsz = UPKFSZ(p->n_rval);
 25202523                 foff = UPKFOFF(p->n_rval);
 25212524                 tsz = (int)tsize(p->n_left->n_type, 0, 0);
 25222525                 q = buildtree(ADDROF, p->n_left, NIL);
 25232526 
 25242527                 ct = t = p->n_type;
 25252528                 if (attr_find(p->n_ap, GCC_ATYP_PACKED) &&
 25262529                     coptype(q->n_op) != LTYPE) {
 25272530                         t1 = tempnode(0, q->n_type, 0, 0);
 25282531                         bt = buildtree(ASSIGN, ccopy(t1), q);
 25292532                         q = t1;
 25302533 #ifndef UNALIGNED_ACCESS
 25312534                         ct = UCHAR;
 25322535 #endif
 25332536                 } else
 25342537                         bt = bcon(0);
 25352538                 q = rdualfld(q, t, ct, foff, fsz);
 25362539                 p->n_left = bt;
 25372540                 p->n_right = q;
 25382541                 p->n_op = COMOP;
 25392542         } else if (((cdope(p->n_op)&ASGOPFLG) || p->n_op == ASSIGN ||
 25402543             p->n_op == INCR || p->n_op == DECR) && p->n_left->n_op == FLD) {
 25412544                 /*
 25422545                  * Rewrite a field write operation
 25432546                  * More difficult than a read op since we must care
 25442547                  * about side effects.
 25452548                  */
 25462549                 q = p->n_left;
 25472550                 fsz = UPKFSZ(q->n_rval);
 25482551                 foff = UPKFOFF(q->n_rval);
 25492552                 t = q->n_left->n_type;
 25502553                 tsz = (int)tsize(t, 0, 0);
 25512554 #if TARGET_ENDIAN == TARGET_BE
 25522555                 foff = tsz - fsz - foff;
 25532556 #endif
 25542557                 bt = NULL;
 25552558                 if (p->n_right->n_op != ICON && p->n_right->n_op != NAME) {
 25562559                         t2 = tempnode(0, p->n_right->n_type, 0, 0);
 25572560                         bt = buildtree(ASSIGN, ccopy(t2), p->n_right);
 25582561                 } else
 25592562                         t2 = p->n_right;
 25602563 
 25612564                 ct = t;
 25622565 #ifndef UNALIGNED_ACCESS
 25632566                 if (attr_find(q->n_ap, GCC_ATYP_PACKED))
 25642567                         ct = UCHAR;
 25652568 #endif
 25662569                 /* t2 is what we have to write (RHS of ASSIGN) */
 25672570                 /* bt is (eventually) something that must be written */
 25682571 
 25692572 
 25702573                 if (q->n_left->n_op == UMUL) {
 25712574                         /* LHS of assignment may have side effects */
 25722575                         q = q->n_left;
 25732576                         t1 = tempnode(0, q->n_left->n_type, 0, 0);
 25742577                         r = buildtree(ASSIGN, ccopy(t1), q->n_left);
 25752578                         
 25762579                         bt = bt ? block(COMOP, bt, r, INT, 0, 0) : r;
 25772580                         q->n_left = t1;
 25782581                 }
 25792582                 t1 = buildtree(ADDROF, p->n_left->n_left, 0);
 25802583 
 25812584                 /* t1 is lval where to write (and read) */
 25822585 
 25832586                 if (p->n_op == ASSIGN) {
 25842587                         q = wrualfld(t2, t1, t, ct, foff, fsz);
 25852588                         if (bt)
 25862589                                 q = block(COMOP, bt, q, t, 0, 0);
 25872590                         nfree(p->n_left);
 25882591                         p->n_left = bcon(0);
 25892592                         p->n_right = q;
 25902593                         p->n_op = COMOP;
 25912594                 } else if ((cdope(p->n_op)&ASGOPFLG)) {
 25922595                         /* And here is the asgop-specific code */
 25932596                         t3 = tempnode(0, t, 0, 0);
 25942597                         q = rdualfld(ccopy(t1), t, ct, foff, fsz);
 25952598                         q = buildtree(UNASG p->n_op, q, t2);
 25962599                         q = buildtree(ASSIGN, ccopy(t3), q);
 25972600                         r = wrualfld(ccopy(t3), t1, t, ct, foff, fsz);
 25982601                         q = buildtree(COMOP, q, r);
 25992602                         q = buildtree(COMOP, q, t3);
 26002603 
 26012604                         nfree(p->n_left);
 26022605                         p->n_left = bt ? bt : bcon(0);
 26032606                         p->n_right = q;
 26042607                         p->n_op = COMOP;
 26052608                 } else {
 26062609                         t3 = tempnode(0, t, 0, 0);
 26072610                         t4 = tempnode(0, t, 0, 0);
 26082611 
 26092612                         q = rdualfld(ccopy(t1), t, ct, foff, fsz);
 26102613                         q = buildtree(ASSIGN, ccopy(t3), q);
 26112614                         r = buildtree(p->n_op==INCR?PLUS:MINUS, ccopy(t3), t2);
 26122615                         r = buildtree(ASSIGN, ccopy(t4), r);
 26132616                         q = buildtree(COMOP, q, r);
 26142617                         r = wrualfld(t4, t1, t, ct, foff, fsz);
 26152618                         q = buildtree(COMOP, q, r);
 26162619                 
 26172620                         if (bt)
 26182621                                 q = block(COMOP, bt, q, t, 0, 0);
 26192622                         nfree(p->n_left);
 26202623                         p->n_left = q;
 26212624                         p->n_right = t3;
 26222625                         p->n_op = COMOP;
 26232626                 }
 26242627         }
 26252628         if (coptype(p->n_op) != LTYPE)
 26262629                 p->n_left = rmfldops(p->n_left);
 26272630         if (coptype(p->n_op) == BITYPE)
 26282631                 p->n_right = rmfldops(p->n_right);
 26292632         return p;
 26302633 }
 26312634 #endif
 26322635 
 26332636 void
 26342637 ecomp(NODE *p)
 26352638 {
 26362639 
 26372640 #ifdef PCC_DEBUG
 26382641         if (edebug)
 26392642                 fwalk(p, eprint, 0);
 26402643 #endif
 26412644         if (!reached) {
 26422645                 warner(Wunreachable_code, NULL);
 26432646                 reached = 1;
 26442647         }
 26452648         p = optim(p);
 26462649 #ifndef FIELDOPS
 26472650         p = rmfldops(p);
 26482651 #endif
 26492652         comops(p);
 26502653         rmcops(p);
 26512654         p = delasgop(p);
 26522655         if (p->n_op == ICON && p->n_type == VOID)
 26532656                 tfree(p);
 26542657         else
 26552658                 ecode(p);
 26562659 }
 26572660 
 26582661 
 26592662 #if defined(MULTIPASS)
 26602663 void    
 26612664 p2tree(NODE *p)
 26622665 {
 26632666         struct symtab *q;
 26642667         int ty;
 26652668 
 26662669         myp2tree(p);  /* local action can be taken here */
 26672670 
 2668