Quick Search:

Mode

Context

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

Other Diffs

Ignore

Blank Lines Whitespace: Expand:

Diff

1.5
 
1.6
 
MAIN:plunky:20121022091342
 
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 );
 377377                 case UTYPE:
 378378                         p->n_left = pconvert( p->n_left );
 379379 
 380380                         }
 381381                 }
 382382 
 383383         if ((actions&PUN) && (o!=CAST))
 384384                 chkpun(p);
 385385 
 386386         if( actions & (TYPL|TYPR) ){
 387387 
 388388                 q = (actions&TYPL) ? p->n_left : p->n_right;
 389389 
 390390                 p->n_type = q->n_type;
 391391                 p->n_qual = q->n_qual;
 392392                 p->n_df = q->n_df;
 393393                 p->n_ap = q->n_ap;
 394394                 }
 395395 
 396396         if( actions & CVTL ) p = convert( p, CVTL );
 397397         if( actions & CVTR ) p = convert( p, CVTR );
 398398         if( actions & TYMATCH ) p = tymatch(p);
 399399         if( actions & PTMATCH ) p = ptmatch(p);
 400400 
 401401         if( actions & OTHER ){
 402402                 struct symtab *sp1;
 403403 
 404404                 l = p->n_left;
 405405                 r = p->n_right;
 406406 
 407407                 switch(o){
 408408 
 409409                 case NAME:
 410410                         cerror("buildtree NAME");
 411411 
 412412                 case STREF:
 413413                         /* p->x turned into *(p+offset) */
 414414                         /* rhs must be a name; check correctness */
 415415 
 416416                         /* Find member symbol struct */
 417417                         if (l->n_type != PTR+STRTY && l->n_type != PTR+UNIONTY){
 418418                                 uerror("struct or union required");
 419419                                 break;
 420420                         }
 421421 
 422422                         if ((sp1 = strmemb(l->n_ap)) == NULL) {
 423423                                 uerror("undefined struct or union");
 424424                                 break;
 425425                         }
 426426 
 427427                         if ((sp = findmember(sp1, r->n_name)) == NULL) {
 428428                                 uerror("member '%s' not declared", r->n_name);
 429429                                 break;
 430430                         }
 431431 
 432432                         r->n_sp = sp;
 433433                         p = stref(p);
 434434                         break;
 435435 
 436436                 case UMUL:
 437437                         if (l->n_op == ADDROF) {
 438438                                 nfree(p);
 439439                                 p = nfree(l);
 440440                         }
 441441                         if( !ISPTR(l->n_type))uerror("illegal indirection");
 442442                         p->n_type = DECREF(l->n_type);
 443443                         p->n_qual = DECREF(l->n_qual);
 444444                         p->n_df = l->n_df;
 445445                         p->n_ap = l->n_ap;
 446446                         break;
 447447 
 448448                 case ADDROF:
 449449                         switch( l->n_op ){
 450450 
 451451                         case UMUL:
 452452                                 nfree(p);
 453453                                 p = nfree(l);
 454454                                 /* FALLTHROUGH */
 455455                         case TEMP:
 456456                         case NAME:
 457457                                 p->n_type = INCREF(l->n_type);
 458458                                 p->n_qual = INCQAL(l->n_qual);
 459459                                 p->n_df = l->n_df;
 460460                                 p->n_ap = l->n_ap;
 461461                                 break;
 462462 
 463463                         case COMOP:
 464464                                 nfree(p);
 465465                                 lr = buildtree(ADDROF, l->n_right, NIL);
 466466                                 p = buildtree( COMOP, l->n_left, lr );
 467467                                 nfree(l);
 468468                                 break;
 469469 
 470470                         case QUEST:
 471471                                 lr = buildtree( ADDROF, l->n_right->n_right, NIL );
 472472                                 ll = buildtree( ADDROF, l->n_right->n_left, NIL );
 473473                                 nfree(p); nfree(l->n_right);
 474474                                 p = buildtree( QUEST, l->n_left, buildtree( COLON, ll, lr ) );
 475475                                 nfree(l);
 476476                                 break;
 477477 
 478478                         default:
 479479                                 uerror("unacceptable operand of &: %d", l->n_op );
 480480                                 break;
 481481                                 }
 482482                         break;
 483483 
 484484                 case LS:
 485485                 case RS: /* must make type size at least int... */
 486486                         if (p->n_type == CHAR || p->n_type == SHORT) {
 487487                                 p->n_left = makety(l, INT, 0, 0, 0);
 488488                         } else if (p->n_type == UCHAR || p->n_type == USHORT) {
 489489                                 p->n_left = makety(l, UNSIGNED, 0, 0, 0);
 490490                         }
 491491                         l = p->n_left;
 492492                         p->n_type = l->n_type;
 493493                         p->n_qual = l->n_qual;
 494494                         p->n_df = l->n_df;
 495495                         p->n_ap = l->n_ap;
 496496 
 497497                         /* FALLTHROUGH */
 498498                 case LSEQ:
 499499                 case RSEQ: /* ...but not for assigned types */
 500500                         if(tsize(r->n_type, r->n_df, r->n_ap) > SZINT)
 501501                                 p->n_right = makety(r, INT, 0, 0, 0);
 502502                         break;
 503503 
 504504                 case RETURN:
 505505                 case ASSIGN:
 506506                 case CAST:
 507507                         /* structure assignment */
 508508                         /* take the addresses of the two sides; then make an
 509509                          * operator using STASG and
 510510                          * the addresses of left and right */
 511511 
 512512                         if (strmemb(l->n_ap) != strmemb(r->n_ap))
 513513                                 uerror("assignment of different structures");
 514514 
 515515                         r = buildtree(ADDROF, r, NIL);
 516516 
 517517                         l = block(STASG, l, r, r->n_type, r->n_df, r->n_ap);
 518518                         l = clocal(l);
 519519 
 520520                         if( o == RETURN ){
 521521                                 nfree(p);
 522522                                 p = l;
 523523                                 break;
 524524                         }
 525525 
 526526                         p->n_op = UMUL;
 527527                         p->n_left = l;
 528528                         p->n_right = NIL;
 529529                         break;
 530530 
 531531                 case QUEST: /* fixup types of : */
 532532                         if (r->n_left->n_type != p->n_type)
 533533                                 r->n_left = makety(r->n_left, p->n_type,
 534534                                     p->n_qual, p->n_df, p->n_ap);
 535535                         if (r->n_right->n_type != p->n_type)
 536536                                 r->n_right = makety(r->n_right, p->n_type,
 537537                                     p->n_qual, p->n_df, p->n_ap);
 538538                         break;
 539539 
 540540                 case COLON:
 541541                         /* structure colon */
 542542 
 543543                         if (strmemb(l->n_ap) != strmemb(r->n_ap))
 544544                                 uerror( "type clash in conditional" );
 545545                         break;
 546546 
 547547                 case CALL:
 548548                         p->n_right = r = strargs(p->n_right);
 549549                         p = funcode(p);
 550550                         /* FALLTHROUGH */
 551551                 case UCALL:
 552552                         if (!ISPTR(l->n_type))
 553553                                 uerror("illegal function");
 554554                         p->n_type = DECREF(l->n_type);
 555555                         if (!ISFTN(p->n_type))
 556556                                 uerror("illegal function");
 557557                         p->n_type = DECREF(p->n_type);
 558558                         p->n_df = l->n_df+1; /* add one for prototypes */
 559559                         p->n_ap = l->n_ap;
 560560                         if (p->n_type == STRTY || p->n_type == UNIONTY) {
 561561                                 /* function returning structure */
 562562                                 /*  make function really return ptr to str., with * */
 563563 
 564564                                 p->n_op += STCALL-CALL;
 565565                                 p->n_type = INCREF(p->n_type);
 566566                                 p = clocal(p); /* before recursing */
 567567                                 p = buildtree(UMUL, p, NIL);
 568568 
 569569                                 }
 570570                         break;
 571571 
 572572                 default:
 573573                         cerror( "other code %d", o );
 574574                         }
 575575 
 576576                 }
 577577 
 578578         /*
 579579          * Allow (void)0 casts.
 580580          * XXX - anything on the right side must be possible to cast.
 581581          * XXX - remove void types further on.
 582582          */
 583583         if (p->n_op == CAST && p->n_type == VOID &&
 584584             p->n_right->n_op == ICON)
 585585                 p->n_right->n_type = VOID;
 586586 
 587587         if (actions & CVTO)
 588588                 p = oconvert(p);
 589589         p = clocal(p);
 590590 
 591591 #ifdef PCC_DEBUG
 592592         if (bdebug) {
 593593                 printf("End of buildtree:\n");
 594594                 fwalk(p, eprint, 0);
 595595         }
 596596 #endif
 597597 
 598598         return(p);
 599599 
 600600         }
 601601 
 602602 /* Find a member in a struct or union.  May be an unnamed member */
 603603 static struct symtab *
 604604 findmember(struct symtab *sp, char *s)
 605605 {
 606606         struct symtab *sp2, *sp3;
 607607 
 608608         for (; sp != NULL; sp = sp->snext) {
 609609                 if (sp->sname[0] == '*') {
 610610                         /* unnamed member, recurse down */
 611611                         if ((sp2 = findmember(strmemb(sp->sap), s))) {
 612612                                 sp3 = tmpalloc(sizeof (struct symtab));
 613613                                 *sp3 = *sp2;
 614614                                 sp3->soffset += sp->soffset;
 615615                                 return sp3;
 616616                         }
 617617                 } else if (sp->sname == s)
 618618                         return sp;
 619619         }
 620620         return NULL;
 621621 }
 622622 
 623623 
 624624 /*
 625625  * Check if there will be a lost label destination inside of a ?:
 626626  * It cannot be reached so just print it out.
 627627  */
 628628 void
 629629 putjops(NODE *p, void *arg)
 630630 {
 631631         if (p->n_op == COMOP && p->n_left->n_op == GOTO)
 632632                 plabel((int)p->n_left->n_left->n_lval+1);
 633633 }
 634634 
 635635 /*
 636636  * Build a name node based on a symtab entry.
 637637  * broken out from buildtree().
 638638  */
 639639 NODE *
 640640 nametree(struct symtab *sp)
 641641 {
 642642         NODE *p;
 643643 
 644644         p = block(NAME, NIL, NIL, sp->stype, sp->sdf, sp->sap);
 645645         p->n_qual = sp->squal;
 646646         p->n_sp = sp;
 647647 
 648648 #ifndef NO_C_BUILTINS
 649649         if (sp->sname[0] == '_' && strncmp(sp->sname, "__builtin_", 10) == 0)
 650650                 return p/* do not touch builtins here */
 651651         
 652652 #endif
 653653 
 654654         if (sp->sflags & STNODE) {
 655655                 /* Generated for optimizer */
 656656                 p->n_op = TEMP;
 657657                 p->n_rval = sp->soffset;
 658658         }
 659659 
 660660 #ifdef GCC_COMPAT
 661661         /* Get a label name */
 662662         if (sp->sflags == SLBLNAME) {
 663663                 p->n_type = VOID;
 664664         }
 665665 #endif
 666666         if (sp->stype == UNDEF) {
 667667                 uerror("%s undefined", sp->sname);
 668668                 /* make p look reasonable */
 669669                 p->n_type = INT;
 670670                 p->n_df = NULL;
 671671                 defid(p, SNULL);
 672672         }
 673673         if (sp->sclass == MOE) {
 674674                 p->n_op = ICON;
 675675                 p->n_lval = sp->soffset;
 676676                 p->n_df = NULL;
 677677                 p->n_sp = NULL;
 678678         }
 679679         return clocal(p);
 680680 }
 681681 
 682682 /*
 683683  * Cast a node to another type by inserting a cast.
 684684  * Just a nicer interface to buildtree.
 685685  * Returns the new tree.
 686686  */
 687687 NODE *
 688688 cast(NODE *p, TWORD t, TWORD u)
 689689 {
 690690         NODE *q;
 691691 
 692692         q = block(NAME, NIL, NIL, t, 0, 0);
 693693         q->n_qual = u;
 694694         q = buildtree(CAST, q, p);
 695695         p = q->n_right;
 696696         nfree(q->n_left);
 697697         nfree(q);
 698698         return p;
 699699 }
 700700 
 701701 /*
 702702  * Cast and complain if necessary by not inserining a cast.
 703703  */
 704704 NODE *
 705705 ccast(NODE *p, TWORD t, TWORD u, union dimfun *df, struct attr *ap)
 706706 {
 707707         NODE *q;
 708708 
 709709         /* let buildtree do typechecking (and casting) */
 710710         q = block(NAME, NIL, NIL, t, df, ap);
 711711         p = buildtree(ASSIGN, q, p);
 712712         nfree(p->n_left);
 713713         q = optim(p->n_right);
 714714         nfree(p);
 715715         return q;
 716716 }
 717717 
 718718 /*
 719719  * Do an actual cast of a constant (if possible).
 720720  * Routine assumes 2-complement (is there anything else today?)
 721721  * Returns 1 if handled, 0 otherwise.
 722722  */
 723723 int
 724724 concast(NODE *p, TWORD t)
 725725 {
 726726         extern short sztable[];
 727727         CONSZ val;
 728728 
 729729         if (p->n_op != ICON && p->n_op != FCON) /* only constants */
 730730                 return 0;
 731731         if (p->n_op == ICON && p->n_sp != NULL) { /* no addresses */
 732732                 if (t == BOOL) {
 733733                         p->n_lval = 1, p->n_type = BOOL, p->n_sp = NULL;
 734734                         return 1;
 735735                 }
 736736                 return 0;
 737737         }
 738738         if ((p->n_type & TMASK) || (t & TMASK)) /* no cast of pointers */
 739739                 return 0;
 740740 
 741741 //printf("concast till %d\n", t);
 742742 //fwalk(p, eprint, 0);
 743743 
 744744 #define TYPMSK(y) ((((1LL << (y-1))-1) << 1) | 1)
 745745         if (p->n_op == ICON) {
 746746                 val = p->n_lval;
 747747 
 748748                 if (t == BOOL) {
 749749                         if (val)
 750750                                 p->n_lval = 1;
 751751                 } else if (t <= ULONGLONG) {
 752752                         p->n_lval = val & TYPMSK(sztable[t]);
 753753                         if (!ISUNSIGNED(t)) {
 754754                                 if (val & (1LL << (sztable[t]-1)))
 755755                                         p->n_lval |= ~TYPMSK(sztable[t]);
 756756                         }
 757757                 } else if (t <= LDOUBLE) {
 758758                         p->n_op = FCON;
 759759                         p->n_dcon = FLOAT_CAST(val, p->n_type);
 760760                 }
 761761         } else { /* p->n_op == FCON */
 762762                 if (t == BOOL) {
 763763                         p->n_op = ICON;
 764764                         p->n_lval = FLOAT_NE(p->n_dcon,0.0);
 765765                         p->n_sp = NULL;
 766766                 } else if (t <= ULONGLONG) {
 767767                         p->n_op = ICON;
 768768                         p->n_lval = ISUNSIGNED(t) ? /* XXX FIXME */
 769769                             ((U_CONSZ)p->n_dcon) : p->n_dcon;
 770770                         p->n_sp = NULL;
 771771                 } else {
 772772                         p->n_dcon = t == FLOAT ? (float)p->n_dcon :
 773773                             t == DOUBLE ? (double)p->n_dcon : p->n_dcon;
 774774                 }
 775775         }
 776776         p->n_type = t;
 777777 //fwalk(p, eprint, 0);
 778778         return 1;
 779779 }
 780780 
 781781 /*
 782782  * Do a conditional branch.
 783783  */
 784784 void
 785785 cbranch(NODE *p, NODE *q)
 786786 {
 787787         p = buildtree(CBRANCH, p, q);
 788788         if (p->n_left->n_op == ICON) {
 789789                 if (p->n_left->n_lval != 0) {
 790790                         branch((int)q->n_lval); /* branch always */
 791791                         reached = 0;
 792792                 }
 793793                 tfree(p);
 794794                 tfree(q);
 795795                 return;
 796796         }
 797797         ecomp(p);
 798798 }
 799799 
 800800 NODE *
 801801 strargs(register NODE *p)
 802802 {
 803803         /* rewrite structure flavored arguments */
 804804 
 805805         if( p->n_op == CM ){
 806806                 p->n_left = strargs( p->n_left );
 807807                 p->n_right = strargs( p->n_right );
 808808                 return( p );
 809809                 }
 810810 
 811811         if( p->n_type == STRTY || p->n_type == UNIONTY ){
 812812                 p = block(STARG, p, NIL, p->n_type, p->n_df, p->n_ap);
 813813                 p->n_left = buildtree( ADDROF, p->n_left, NIL );
 814814                 p = clocal(p);
 815815                 }
 816816         return( p );
 817817 }
 818818 
 819819 /*
 820820  * apply the op o to the lval part of p; if binary, rhs is val
 821821  */
 822822 int
 823823 conval(NODE *p, int o, NODE *q)
 824824 {
 825825         TWORD tl = p->n_type, tr = q->n_type, td;
 826826         int i, u;
 827827         CONSZ val;
 828828         U_CONSZ v1, v2;
 829829 
 830830         val = q->n_lval;
 831831 
 832832         /* make both sides same type */
 833833         if (tl < BTMASK && tr < BTMASK) {
 834834                 td = tl > tr ? tl : tr;
 835835                 if (td < INT)
 836836                         td = INT;
 837837                 u = ISUNSIGNED(td);
 838838                 if (tl != td)
 839839                         p = makety(p, td, 0, 0, 0);
 840840                 if (tr != td)
 841841                         q = makety(q, td, 0, 0, 0);
 842842         } else
 843843                 u = ISUNSIGNED(tl) || ISUNSIGNED(tr);
 844844         if( u && (o==LE||o==LT||o==GE||o==GT)) o += (UGE-GE);
 845845 
 846846         if (p->n_sp != NULL && q->n_sp != NULL)
 847847                 return(0);
 848848         if (q->n_sp != NULL && o != PLUS)
 849849                 return(0);
 850850         if (p->n_sp != NULL && o != PLUS && o != MINUS)
 851851                 return(0);
 852852 
 853853         v1 = p->n_lval;
 854854         v2 = q->n_lval;
 855855         if (v2 == 0 && (cdope(o) & DIVFLG))
 856856                 return 0; /* leave division by zero to runtime */
 857857         switch( o ){
 858858 
 859859         case PLUS:
 860860                 p->n_lval += val;
 861861                 if (p->n_sp == NULL) {
 862862                         p->n_right = q->n_right;
 863863                         p->n_type = q->n_type;
 864864                 }
 865865                 break;
 866866         case MINUS:
 867867                 p->n_lval -= val;
 868868                 break;
 869869         case MUL:
 870870                 p->n_lval *= val;
 871871                 break;
 872872         case DIV:
 873873                 if (u) {
 874874                         v1 /= v2;
 875875                         p->n_lval = v1;
 876876                 } else
 877877                         p->n_lval /= val;
 878878                 break;
 879879         case MOD:
 880880                 if (u) {
 881881                         v1 %= v2;
 882882                         p->n_lval = v1;
 883883                 } else
 884884                         p->n_lval %= val;
 885885                 break;
 886886         case AND:
 887887                 p->n_lval &= val;
 888888                 break;
 889889         case OR:
 890890                 p->n_lval |= val;
 891891                 break;
 892892         case ER:
 893893                 p->n_lval ^= val;
 894894                 break;
 895895         case LS:
 896896                 i = (int)val;
 897897                 p->n_lval = p->n_lval << i;
 898898                 break;
 899899         case RS:
 900900                 i = (int)val;
 901901                 if (u) {
 902902                         v1 = v1 >> i;
 903903                         p->n_lval = v1;
 904904                 } else
 905905                         p->n_lval = p->n_lval >> i;
 906906                 break;
 907907 
 908908         case UMINUS:
 909909                 p->n_lval = - p->n_lval;
 910910                 break;
 911911         case COMPL:
 912912                 p->n_lval = ~p->n_lval;
 913913                 break;
 914914         case NOT:
 915915                 p->n_lval = !p->n_lval;
 916916                 break;
 917917         case LT:
 918918                 p->n_lval = p->n_lval < val;
 919919                 break;
 920920         case LE:
 921921                 p->n_lval = p->n_lval <= val;
 922922                 break;
 923923         case GT:
 924924                 p->n_lval = p->n_lval > val;
 925925                 break;
 926926         case GE:
 927927                 p->n_lval = p->n_lval >= val;
 928928                 break;
 929929         case ULT:
 930930                 p->n_lval = v1 < v2;
 931931                 break;
 932932         case ULE:
 933933                 p->n_lval = v1 <= v2;
 934934                 break;
 935935         case UGT:
 936936                 p->n_lval = v1 > v2;
 937937                 break;
 938938         case UGE:
 939939                 p->n_lval = v1 >= v2;
 940940                 break;
 941941         case EQ:
 942942                 p->n_lval = p->n_lval == val;
 943943                 break;
 944944         case NE:
 945945                 p->n_lval = p->n_lval != val;
 946946                 break;
 947947         case ANDAND:
 948948                 p->n_lval = p->n_lval && val;
 949949                 break;
 950950         case OROR:
 951951                 p->n_lval = p->n_lval || val;
 952952                 break;
 953953         default:
 954954                 return(0);
 955955                 }
 956956         /* Do the best in making everything type correct after calc */
 957957         if (p->n_sp == NULL && q->n_sp == NULL)
 958958                 p->n_lval = valcast(p->n_lval, p->n_type);
 959959         return(1);
 960960         }
 961961 
 962962 /*
 963963  * Ensure that v matches the type t; sign- or zero-extended
 964964  * as suitable to CONSZ.
 965965  * Only to be used for integer types.
 966966  */
 967967 CONSZ
 968968 valcast(CONSZ v, TWORD t)
 969969 {
 970970         CONSZ r;
 971971         int sz;
 972972 
 973973         if (t < CHAR || t > ULONGLONG)
 974974                 return v; /* cannot cast */
 975975 
 976976         if (t >= LONGLONG)
 977977                 return v; /* already largest */
 978978 
 979979 #define M(x)    ((((1ULL << ((x)-1)) - 1) << 1) + 1)
 980980 #define NOTM(x) (~M(x))
 981981 #define SBIT(x) (1ULL << ((x)-1))
 982982 
 983983         sz = (int)tsize(t, NULL, NULL);
 984984         r = v & M(sz);
 985985         if (!ISUNSIGNED(t) && (SBIT(sz) & r))
 986986                 r = r | NOTM(sz);
 987987         return r;
 988988 }
 989989 
 990990 /*
 991991  * Checks p for the existance of a pun.  This is called when the op of p
 992992  * is ASSIGN, RETURN, CAST, COLON, or relational.
 993993  * One case is when enumerations are used: this applies only to lint.
 994994  * In the other case, one operand is a pointer, the other integer type
 995995  * we check that this integer is in fact a constant zero...
 996996  * in the case of ASSIGN, any assignment of pointer to integer is illegal
 997997  * this falls out, because the LHS is never 0.
 998998  * XXX - check for COMOPs in assignment RHS?
 999999  */
 10001000 void
 10011001 chkpun(NODE *p)
 10021002 {
 10031003         union dimfun *d1, *d2;
 10041004         NODE *q;
 10051005         int t1, t2;
 10061006 
 10071007         t1 = p->n_left->n_type;
 10081008         t2 = p->n_right->n_type;
 10091009 
 10101010         switch (p->n_op) {
 10111011         case RETURN:
 10121012                 /* return of void allowed but nothing else */
 10131013                 if (t1 == VOID && t2 == VOID)
 10141014                         return;
 10151015                 if (t1 == VOID) {
 10161016                         werror("returning value from void function");
 10171017                         return;
 10181018                 }
 10191019                 if (t2 == VOID) {
 10201020                         uerror("using void value");
 10211021                         return;
 10221022                 }
<> 1023+                break;
<_10231024         case COLON:
 10241025                 if (t1 == VOID && t2 == VOID)
 10251026                         return;
 10261027                 break;
 10271028         default:
 10281029                 if ((t1 == VOID && t2 != VOID) || (t1 != VOID && t2 == VOID)) {
 10291030                         uerror("value of void expression used");
 10301031                         return;
 10311032                 }
 10321033                 break;
 10331034         }
 10341035 
 10351036         /* allow void pointer assignments in any direction */
 10361037         if (BTYPE(t1) == VOID && (t2 & TMASK))
 10371038                 return;
 10381039         if (BTYPE(t2) == VOID && (t1 & TMASK))
 10391040                 return;
 10401041 
 10411042         /* boolean have special syntax */
 10421043         if (t1 == BOOL) {
 10431044                 if (!ISARY(t2)) /* Anything scalar */
 10441045                         return;
 10451046         }
 10461047 
 10471048         if (ISPTR(t1) || ISARY(t1))
 10481049                 q = p->n_right;
 10491050         else
 10501051                 q = p->n_left;
 10511052 
 10521053         if (!ISPTR(q->n_type) && !ISARY(q->n_type)) {
 10531054                 if (q->n_op != ICON || q->n_lval != 0)
 10541055                         werror("illegal combination of pointer and integer");
 10551056         } else {
 10561057                 if (t1 == t2) {
 10571058                         if (ISSOU(BTYPE(t1)) &&
 10581059                             !suemeq(p->n_left->n_ap, p->n_right->n_ap))
 10591060                                 werror("illegal structure pointer combination");
 10601061                         return;
 10611062                 }
 10621063                 d1 = p->n_left->n_df;
 10631064                 d2 = p->n_right->n_df;
 10641065                 for (;;) {
 10651066                         if (ISARY(t1) || ISPTR(t1)) {
 10661067                                 if (!ISARY(t2) && !ISPTR(t2))
 10671068                                         break;
 10681069                                 if (ISARY(t1) && ISARY(t2) && d1->ddim != d2->ddim) {
 10691070                                         werror("illegal array size combination");
 10701071                                         return;
 10711072                                 }
 10721073                                 if (ISARY(t1))
 10731074                                         ++d1;
 10741075                                 if (ISARY(t2))
 10751076                                         ++d2;
 10761077                         } else if (ISFTN(t1)) {
 10771078                                 if (chkftn(d1->dfun, d2->dfun)) {
 10781079                                         werror("illegal function "
 10791080                                             "pointer combination");
 10801081                                         return;
 10811082                                 }
 10821083                                 ++d1;
 10831084                                 ++d2;
 10841085                         } else
 10851086                                 break;
 10861087                         t1 = DECREF(t1);
 10871088                         t2 = DECREF(t2);
 10881089                 }
 10891090                 if (DEUNSIGN(t1) != DEUNSIGN(t2))
 10901091                         warner(Wpointer_sign, NULL);
 10911092         }
 10921093 }
 10931094 
 10941095 static NODE *
 10951096 offplus(NODE *p, int off, TWORD t, TWORD q, union dimfun *d, struct attr *ap) {
 10961097         if (off != 0) {
 10971098                 p = block(PLUS, p, offcon(off, t, d, ap), t, d, ap);
 10981099                 p->n_qual = q;
 10991100                 p = optim(p);
 11001101         }
 11011102 
 11021103         return buildtree(UMUL, p, NIL);
 11031104 }
 11041105 
 11051106 NODE *
 11061107 stref(NODE *p)
 11071108 {
 11081109         NODE *r;
 11091110         struct attr *ap, *xap, *yap;
 11101111         union dimfun *d;
 11111112         TWORD t, q;
 11121113         int dsc;
 11131114         OFFSZ off;
 11141115         struct symtab *s;
 11151116 
 11161117         /* make p->x */
 11171118         /* this is also used to reference automatic variables */
 11181119 
 11191120         s = p->n_right->n_sp;
 11201121         nfree(p->n_right);
 11211122         r = nfree(p);
 11221123         xap = attr_find(r->n_ap, GCC_ATYP_PACKED);
 11231124 
 11241125         p = pconvert(r);
 11251126 
 11261127         /* make p look like ptr to x */
 11271128 
 11281129         if (!ISPTR(p->n_type))
 11291130                 p->n_type = PTR+UNIONTY;
 11301131 
 11311132         t = INCREF(s->stype);
 11321133         q = INCQAL(s->squal);
 11331134         d = s->sdf;
 11341135         ap = s->sap;
 11351136         if ((yap = attr_find(ap, GCC_ATYP_PACKED)) != NULL)
 11361137                 xap = yap;
 11371138         else if (xap != NULL)
 11381139                 ap = attr_add(ap, attr_dup(xap, 3));
 11391140         /* xap set if packed struct */
 11401141 
 11411142         p = makety(p, t, q, d, ap);
 11421143         if (ISFTN(s->stype)) {
 11431144                 /* direct class call */
 11441145                 p = block(NMLIST, p, nametree(s), INT, 0, 0);
 11451146                 return p;
 11461147         }
 11471148 
 11481149         /* compute the offset to be added */
 11491150 
 11501151         off = s->soffset;
 11511152         dsc = s->sclass;
 11521153 
 11531154         if (dsc & FIELD) {
 11541155                 TWORD ftyp = s->stype;
 11551156                 int fal = talign(ftyp, ap);
 11561157                 off = (off/fal)*fal;
 11571158                 p = offplus(p, off, t, q, d, ap);
 11581159                 p = block(FLD, p, NIL, ftyp, 0, ap);
 11591160                 p->n_qual = q;
 11601161                 p->n_rval = PKFIELD(dsc&FLDSIZ, s->soffset%fal);
 11611162         } else {
 11621163                 p = offplus(p, off, t, q, d, ap);
 11631164 #ifndef CAN_UNALIGN
 11641165                 /* if target cannot handle unaligned addresses, fix here */
 11651166 #endif
 11661167         }
 11671168 
 11681169         p = clocal(p);
 11691170         return p;
 11701171 }
 11711172 
 11721173 int
 11731174 notlval(register NODE *p)
 11741175 {
 11751176         /* return 0 if p an lvalue, 1 otherwise */
 11761177 
 11771178         again:
 11781179 
 11791180         switch( p->n_op ){
 11801181 
 11811182         case FLD:
 11821183                 p = p->n_left;
 11831184                 goto again;
 11841185 
 11851186         case NAME:
 11861187         case OREG:
 11871188         case UMUL:
 11881189                 if( ISARY(p->n_type) || ISFTN(p->n_type) ) return(1);
 11891190         case TEMP:
 11901191         case REG:
 11911192                 return(0);
 11921193 
 11931194         default:
 11941195                 return(1);
 11951196         }
 11961197 }
 11971198 
 11981199 /* make a constant node with value i */
 11991200 NODE *
 12001201 bcon(int i)
 12011202 {
 12021203         return xbcon(i, NULL, INT);
 12031204 }
 12041205 
 12051206 NODE *
 12061207 xbcon(CONSZ val, struct symtab *sp, TWORD type)
 12071208 {
 12081209         NODE *p;
 12091210 
 12101211         p = block(ICON, NIL, NIL, type, 0, 0);
 12111212         p->n_lval = val;
 12121213         p->n_sp = sp;
 12131214         return clocal(p);
 12141215 }
 12151216 
 12161217 NODE *
 12171218 bpsize(NODE *p)
 12181219 {
 12191220         int isdyn(struct symtab *sp);
 12201221         struct symtab s;
 12211222         NODE *q, *r;
 12221223         TWORD t;
 12231224         int sz;
 12241225 
 12251226         s.stype = DECREF(p->n_type);
 12261227         s.sdf = p->n_df;
 12271228         if (isdyn(&s)) {
 12281229                 q = bcon(1);
 12291230                 for (t = s.stype; t > BTMASK; t = DECREF(t)) {
 12301231                         if (ISPTR(t))
 12311232                                 return buildtree(MUL, q, bcon(SZPOINT(t)));
 12321233                         if (ISARY(t)) {
 12331234                                 if (s.sdf->ddim < 0)
 12341235                                         r = tempnode(-s.sdf->ddim, INT, 0, 0);
 12351236                                 else
 12361237                                         r = bcon(s.sdf->ddim/SZCHAR);
 12371238                                 q = buildtree(MUL, q, r);
 12381239                                 s.sdf++;
 12391240                         }
 12401241                 }
 12411242                 sz = (int)tsize(p->n_type, p->n_df, p->n_ap);
 12421243                 p = buildtree(MUL, q, bcon(sz/SZCHAR));
 12431244         } else
 12441245                 p = (offcon(psize(p), p->n_type, p->n_df, p->n_ap));
 12451246         return p;
 12461247 }
 12471248 
 12481249 /*
 12491250  * p is a node of type pointer; psize returns the
 12501251  * size of the thing pointed to
 12511252  */
 12521253 OFFSZ
 12531254 psize(NODE *p)
 12541255 {
 12551256 
 12561257         if (!ISPTR(p->n_type)) {
 12571258                 uerror("pointer required");
 12581259                 return(SZINT);
 12591260         }
 12601261         /* note: no pointers to fields */
 12611262         return(tsize(DECREF(p->n_type), p->n_df, p->n_ap));
 12621263 }
 12631264 
 12641265 /*
 12651266  * convert an operand of p
 12661267  * f is either CVTL or CVTR
 12671268  * operand has type int, and is converted by the size of the other side
 12681269  * convert is called when an integer is to be added to a pointer, for
 12691270  * example in arrays or structures.
 12701271  */
 12711272 NODE *
 12721273 convert(NODE *p, int f)
 12731274 {
 12741275         union dimfun *df;
 12751276         TWORD ty, ty2;
 12761277         NODE *q, *r, *s, *rv;
 12771278 
 12781279         if (f == CVTL) {
 12791280                 q = p->n_left;
 12801281                 s = p->n_right;
 12811282         } else {
 12821283                 q = p->n_right;
 12831284                 s = p->n_left;
 12841285         }
 12851286         ty2 = ty = DECREF(s->n_type);
 12861287         while (ISARY(ty))
 12871288                 ty = DECREF(ty);
 12881289 
 12891290         r = offcon(tsize(ty, s->n_df, s->n_ap), s->n_type, s->n_df, s->n_ap);
 12901291         ty = ty2;
 12911292         rv = bcon(1);
 12921293         df = s->n_df;
 12931294         while (ISARY(ty)) {
 12941295                 rv = buildtree(MUL, rv, df->ddim >= 0 ? bcon(df->ddim) :
 12951296                     tempnode(-df->ddim, INT, 0, 0));
 12961297                 df++;
 12971298                 ty = DECREF(ty);
 12981299         }
 12991300         rv = clocal(MBLOCK(rv, r, INT, 0, 0));
 13001301         rv = optim(rv);
 13011302 
 13021303         r = MBLOCK(q, rv, INT, 0, 0);
 13031304         r = clocal(r);
 13041305         /*
 13051306          * Indexing is only allowed with integer arguments, so insert
 13061307          * SCONV here if arg is not an integer.
 13071308          * XXX - complain?
 13081309          */
 13091310         if (r->n_type != INTPTR)
 13101311                 r = clocal(makety(r, INTPTR, 0, 0, 0));
 13111312         if (f == CVTL)
 13121313                 p->n_left = r;
 13131314         else
 13141315                 p->n_right = r;
 13151316         return(p);
 13161317 }
 13171318 
 13181319 NODE *
 13191320 pconvert(register NODE *p)
 13201321 {
 13211322         /* if p should be changed into a pointer, do so */
 13221323 
 13231324         if( ISARY( p->n_type) ){
 13241325                 p->n_type = DECREF( p->n_type );
 13251326                 ++p->n_df;
 13261327                 return( buildtree( ADDROF, p, NIL ) );
 13271328         }
 13281329         if( ISFTN( p->n_type) )
 13291330                 return( buildtree( ADDROF, p, NIL ) );
 13301331 
 13311332         return( p );
 13321333 }
 13331334 
 13341335 NODE *
 13351336 oconvert(register NODE *p)
 13361337 {
 13371338         /* convert the result itself: used for pointer and unsigned */
 13381339 
 13391340         switch(p->n_op) {
 13401341 
 13411342         case LE:
 13421343         case LT:
 13431344         case GE:
 13441345         case GT:
 13451346                 if(ISUNSIGNED(p->n_left->n_type) ||
 13461347                     ISUNSIGNED(p->n_right->n_type) ||
 13471348                     ISPTR(p->n_left->n_type) ||
 13481349                     ISPTR(p->n_right->n_type))
 13491350                          p->n_op += (ULE-LE);
 13501351                 /* FALLTHROUGH */
 13511352         case EQ:
 13521353         case NE:
 13531354                 return( p );
 13541355 
 13551356         case MINUS:
 13561357                 p->n_type = INTPTR;
 13571358                 p->n_ap = NULL;
 13581359                 return(clocal(VBLOCK(p, bpsize(p->n_left), INT, 0, 0)));
 13591360                 }
 13601361 
 13611362         cerror( "illegal oconvert: %d", p->n_op );
 13621363 
 13631364         return(p);
 13641365 }
 13651366 
 13661367 /*
 13671368  * makes the operands of p agree; they are
 13681369  * either pointers or integers, by this time
 13691370  * with MINUS, the sizes must be the same
 13701371  * with COLON, the types must be the same
 13711372  */
 13721373 NODE *
 13731374 ptmatch(NODE *p)
 13741375 {
 13751376         struct attr *ap, *ap2;
 13761377         union dimfun *d, *d2;
 13771378         TWORD t1, t2, t, q1, q2, q;
 13781379         int o;
 13791380 
 13801381         o = p->n_op;
 13811382         t = t1 = p->n_left->n_type;
 13821383         q = q1 = p->n_left->n_qual;
 13831384         t2 = p->n_right->n_type;
 13841385         q2 = p->n_right->n_qual;
 13851386         d = p->n_left->n_df;
 13861387         d2 = p->n_right->n_df;
 13871388         ap = p->n_left->n_ap;
 13881389         ap2 = p->n_right->n_ap;
 13891390 
 13901391         switch( o ){
 13911392 
 13921393         case ASSIGN:
 13931394         case RETURN:
 13941395                 {  break; }
 13951396 
 13961397         case CAST:
 13971398                 if (t == VOID) {
 13981399                         /* just paint over */
 13991400                         p->n_right = block(SCONV, p->n_right, NIL, VOID, 0, 0);
 14001401                         return p;
 14011402                 }
 14021403                 break;
 14031404 
 14041405         case MINUS: {
 14051406                 int isdyn(struct symtab *sp);
 14061407                 struct symtab s1, s2;
 14071408 
 14081409                 s1.stype = DECREF(t);
 14091410                 s1.sdf = d;
 14101411                 s2.stype = DECREF(t2);
 14111412                 s2.sdf = d2;
 14121413                 if (isdyn(&s1) || isdyn(&s2))
 14131414                         ; /* We don't know */
 14141415                 else if (psize(p->n_left) != psize(p->n_right))
 14151416                         uerror("illegal pointer subtraction");
 14161417                 break;
 14171418                 }
 14181419 
 14191420         case COLON:
 14201421                 if (t1 != t2) {
 14211422                         /*
 14221423                          * Check for void pointer types. They are allowed
 14231424                          * to cast to/from any pointers.
 14241425                          */
 14251426                         if (ISPTR(t1) && ISPTR(t2) &&
 14261427                             (BTYPE(t1) == VOID || BTYPE(t2) == VOID))
 14271428                                 break;
 14281429                         uerror("illegal types in :");
 14291430                 }
 14301431                 break;
 14311432 
 14321433         default/* must work harder: relationals or comparisons */
 14331434 
 14341435                 if( !ISPTR(t1) ){
 14351436                         t = t2;
 14361437                         q = q2;
 14371438                         d = d2;
 14381439                         ap = ap2;
 14391440                         break;
 14401441                         }
 14411442                 if( !ISPTR(t2) ){
 14421443                         break;
 14431444                         }
 14441445 
 14451446                 /* both are pointers */
 14461447                 if( talign(t2,ap2) < talign(t,ap) ){
 14471448                         t = t2;
 14481449                         q = q2;
 14491450                         ap = ap2;
 14501451                         }
 14511452                 break;
 14521453                 }
 14531454 
 14541455         p->n_left = makety( p->n_left, t, q, d, ap );
 14551456         p->n_right = makety( p->n_right, t, q, d, ap );
 14561457         if( o!=MINUS && !clogop(o) ){
 14571458 
 14581459                 p->n_type = t;
 14591460                 p->n_qual = q;
 14601461                 p->n_df = d;
 14611462                 p->n_ap = ap;
 14621463                 }
 14631464 
 14641465         return(clocal(p));
 14651466 }
 14661467 
 14671468 /*
 14681469  * Satisfy the types of various arithmetic binary ops.
 14691470  *
 14701471  * rules are:
 14711472  *  if assignment, type of LHS
 14721473  *  if any doubles, make double
 14731474  *  else if any float make float
 14741475  *  else if any longlongs, make long long
 14751476  *  else if any longs, make long
 14761477  *  else etcetc.
 14771478  *
 14781479  *  If the op with the highest rank is unsigned, this is the resulting type.
 14791480  *  See:  6.3.1.1 rank order equal of signed and unsigned types
 14801481  *        6.3.1.8 Usual arithmetic conversions
 14811482  */
 14821483 static NODE *
 14831484 tymatch(NODE *p)
 14841485 {
 14851486         TWORD tl, tr, t;
 14861487         NODE *l, *r;
 14871488         int o;
 14881489 
 14891490         o = p->n_op;
 14901491         r = p->n_right;
 14911492         l = p->n_left;
 14921493 
 14931494         tl = l->n_type;
 14941495         tr = r->n_type;
 14951496 
 14961497         if (tl == BOOL) tl = BOOL_TYPE;
 14971498         if (tr == BOOL) tr = BOOL_TYPE;
 14981499 
 14991500         if (casgop(o)) {
 15001501                 if (r->n_op != ICON && tl < FLOAT && tr < FLOAT &&
 15011502                     DEUNSIGN(tl) < DEUNSIGN(tr) && o != CAST)
 15021503                         warner(Wtruncate, tnames[tr], tnames[tl]);
 15031504                 p->n_right = makety(p->n_right, l->n_type, 0, 0, 0);
 15041505                 t = p->n_type = l->n_type;
 15051506                 p->n_ap = l->n_ap;
 15061507         } else {
 15071508                 t = tl > tr ? tl : tr; /* MAX */
 15081509                 /* This depends on ctype() called early */
 15091510                 if (o != COLON && t < INT)
 15101511                         t = INT;
 15111512                 if (tl != t) p->n_left = makety(p->n_left, t, 0, 0, 0);
 15121513                 if (tr != t) p->n_right = makety(p->n_right, t, 0, 0, 0);
 15131514                 if (o == COLON && l->n_type == BOOL && r->n_type == BOOL)
 15141515                         t = p->n_type = BOOL;
 15151516                 else if (!clogop(o))
 15161517                         p->n_type = t;
 15171518         }
 15181519 #ifdef PCC_DEBUG
 15191520         if (tdebug) {
 15201521                 printf("tymatch(%p): ", p);
 15211522                 tprint(tl, 0);
 15221523                 printf(" %s ", copst(o));
 15231524                 tprint(tr, 0);
 15241525                 printf(" => ");
 15251526                 tprint(t, 0);
 15261527                 printf("\n");
 15271528                 fwalk(p, eprint, 0);
 15281529         }
 15291530 #endif
 15301531         return p;
 15311532 }
 15321533 
 15331534 /*
 15341535  * make p into type t by inserting a conversion
 15351536  */
 15361537 NODE *
 15371538 makety(NODE *p, TWORD t, TWORD q, union dimfun *d, struct attr *ap)
 15381539 {
 15391540 
 15401541         if (t == p->n_type) {
 15411542                 p->n_df = d;
 15421543                 p->n_ap = ap;
 15431544                 p->n_qual = q;
 15441545                 return(p);
 15451546         }
 15461547 
 15471548         if (ISITY(t) || ISCTY(t) || ISITY(p->n_type) || ISCTY(p->n_type))
 15481549                 cerror("makety");
 15491550 
 15501551         if (concast(p, t))
 15511552                 return clocal(p);
 15521553 
 15531554         p = block(t & TMASK ? PCONV : SCONV, p, NIL, t, d, ap);
 15541555         p->n_qual = q;
 15551556         return clocal(p);
 15561557 }
 15571558 
 15581559 NODE *
 15591560 block(int o, NODE *l, NODE *r, TWORD t, union dimfun *d, struct attr *ap)
 15601561 {
 15611562         register NODE *p;
 15621563 
 15631564         p = talloc();
 15641565         p->n_rval = 0;
 15651566         p->n_op = o;
 15661567         p->n_lval = 0; /* Protect against large lval */
 15671568         p->n_left = l;
 15681569         p->n_right = r;
 15691570         p->n_type = t;
 15701571         p->n_qual = 0;
 15711572         p->n_df = d;
 15721573         p->n_ap = ap;
 15731574 #if !defined(MULTIPASS)
 15741575         /* p->n_reg = */p->n_su = 0;
 15751576         p->n_regw = 0;
 15761577 #endif
 15771578         return(p);
 15781579 }
 15791580 
 15801581 /*
 15811582  * Return the constant value from an ICON.
 15821583  */
 15831584 CONSZ
 15841585 icons(NODE *p)
 15851586 {
 15861587         /* if p is an integer constant, return its value */
 15871588         CONSZ val;
 15881589 
 15891590         if (p->n_op != ICON || p->n_sp != NULL) {
 15901591                 uerror( "constant expected");
 15911592                 val = 1;
 15921593         } else
 15931594                 val = p->n_lval;
 15941595         tfree(p);
 15951596         return(val);
 15961597 }
 15971598 
 15981599 /*
 15991600  * the intent of this table is to examine the
 16001601  * operators, and to check them for
 16011602  * correctness.
 16021603  *
 16031604  * The table is searched for the op and the
 16041605  * modified type (where this is one of the
 16051606  * types INT (includes char and short), LONG,
 16061607  * DOUBLE (includes FLOAT), and POINTER
 16071608  *
 16081609  * The default action is to make the node type integer
 16091610  *
 16101611  * The actions taken include:
 16111612  *      PUN       check for puns
 16121613  *      CVTL      convert the left operand
 16131614  *      CVTR      convert the right operand
 16141615  *      TYPL      the type is determined by the left operand
 16151616  *      TYPR      the type is determined by the right operand
 16161617  *      TYMATCH   force type of left and right to match,by inserting conversions
 16171618  *      PTMATCH   like TYMATCH, but for pointers
 16181619  *      LVAL      left operand must be lval
 16191620  *      CVTO      convert the op
 16201621  *      NCVT      do not convert the operands
 16211622  *      OTHER     handled by code
 16221623  *      NCVTR     convert the left operand, not the right...
 16231624  *
 16241625  */
 16251626 
 16261627 # define MINT 01        /* integer */
 16271628 # define MDBI 02        /* integer or double */
 16281629 # define MSTR 04        /* structure */
 16291630 # define MPTR 010       /* pointer */
 16301631 # define MPTI 020       /* pointer or integer */
 16311632 
 16321633 int
 16331634 opact(NODE *p)
 16341635 {
 16351636         int mt12, mt1, mt2, o;
 16361637 
 16371638         mt1 = mt2 = mt12 = 0;
 16381639 
 16391640         switch (coptype(o = p->n_op)) {
 16401641         case BITYPE:
 16411642                 mt12=mt2 = moditype(p->n_right->n_type);
 16421643         case UTYPE:
 16431644                 mt12 &= (mt1 = moditype(p->n_left->n_type));
 16441645                 break;
 16451646         }
 16461647 
 16471648         switch( o ){
 16481649 
 16491650         case NAME :
 16501651         case ICON :
 16511652         case FCON :
 16521653         case CALL :
 16531654         case UCALL:
 16541655         case UMUL:
 16551656                 {  return( OTHER ); }
 16561657         case UMINUS:
 16571658                 if( mt1 & MDBI ) return( TYPL+PROML );
 16581659                 break;
 16591660 
 16601661         case COMPL:
 16611662                 if( mt1 & MINT ) return( TYPL+PROML );
 16621663                 break;
 16631664 
 16641665         case ADDROF:
 16651666                 return( NCVT+OTHER );
 16661667         case NOT:
 16671668                 return( PROML );
 16681669 
 16691670 /*      case INIT: */
 16701671         case CM:
 16711672         case CBRANCH:
 16721673         case ANDAND:
 16731674         case OROR:
 16741675                 return( 0 );
 16751676 
 16761677         case MUL:
 16771678         case DIV:
 16781679                 if( mt12 & MDBI ) return( TYMATCH );
 16791680                 break;
 16801681 
 16811682         case MOD:
 16821683         case AND:
 16831684         case OR:
 16841685         case ER:
 16851686                 if( mt12 & MINT ) return( TYMATCH );
 16861687                 break;
 16871688 
 16881689         case LS:
 16891690         case RS:
 16901691                 if( mt12 & MINT ) return( TYPL+OTHER );
 16911692                 break;
 16921693 
 16931694         case EQ:
 16941695         case NE:
 16951696         case LT:
 16961697         case LE:
 16971698         case GT:
 16981699         case GE:
 16991700                 if( mt12 & MDBI ) return( TYMATCH+CVTO );
 17001701                 else if( mt12 & MPTR ) return( PTMATCH+PUN+CVTO );
 17011702                 else if( mt12 & MPTI ) return( PTMATCH+PUN );
 17021703                 else break;
 17031704 
 17041705         case QUEST:
 17051706                 return( TYPR+OTHER );
 17061707         case COMOP:
 17071708                 return( TYPR );
 17081709 
 17091710         case STREF:
 17101711                 return( NCVTR+OTHER );
 17111712 
 17121713         case FORCE:
 17131714                 return( TYPL );
 17141715 
 17151716         case COLON:
 17161717                 if( mt12 & MDBI ) return( TYMATCH );
 17171718                 else if( mt12 & MPTR ) return( TYPL+PTMATCH+PUN );
 17181719                 else if( (mt1&MINT) && (mt2&MPTR) ) return( TYPR+PUN );
 17191720                 else if( (mt1&MPTR) && (mt2&MINT) ) return( TYPL+PUN );
 17201721                 else if( mt12 & MSTR ) return( NCVT+TYPL+OTHER );
 17211722                 break;
 17221723 
 17231724         case ASSIGN:
 17241725         case RETURN:
 17251726                 if( mt12 & MSTR ) return( LVAL+NCVT+TYPL+OTHER );
 17261727         case CAST:
 17271728                 if( mt12 & MDBI ) return( TYPL+LVAL+TYMATCH );
 17281729                 else if( mt1 & MPTR) return( LVAL+PTMATCH+PUN );
 17291730                 else if( mt12 & MPTI ) return( TYPL+LVAL+TYMATCH+PUN );
 17301731                 break;
 17311732 
 17321733         case LSEQ:
 17331734         case RSEQ:
 17341735                 if( mt12 & MINT ) return( TYPL+LVAL+OTHER );
 17351736                 break;
 17361737 
 17371738         case MULEQ:
 17381739         case DIVEQ:
 17391740                 if( mt12 & MDBI ) return( LVAL+TYMATCH );
 17401741                 break;
 17411742 
 17421743         case MODEQ:
 17431744         case ANDEQ:
 17441745         case OREQ:
 17451746         case EREQ:
 17461747                 if (mt12 & MINT)
 17471748                         return(LVAL+TYMATCH);
 17481749                 break;
 17491750 
 17501751         case PLUSEQ:
 17511752         case MINUSEQ:
 17521753         case INCR:
 17531754         case DECR:
 17541755                 if (mt12 & MDBI)
 17551756                         return(TYMATCH+LVAL);
 17561757                 else if ((mt1&MPTR) && (mt2&MINT))
 17571758                         return(TYPL+LVAL+CVTR);
 17581759                 break;
 17591760 
 17601761         case MINUS:
 17611762                 if (mt12 & MPTR)
 17621763                         return(CVTO+PTMATCH+PUN);
 17631764                 if (mt2 & MPTR)
 17641765                         break;
 17651766                 /* FALLTHROUGH */
 17661767         case PLUS:
 17671768                 if (mt12 & MDBI)
 17681769                         return(TYMATCH);
 17691770                 else if ((mt1&MPTR) && (mt2&MINT))
 17701771                         return(TYPL+CVTR);
 17711772                 else if ((mt1&MINT) && (mt2&MPTR))
 17721773                         return(TYPR+CVTL);
 17731774 
 17741775         }
 17751776         uerror("operands of %s have incompatible types", copst(o));
 17761777         return(NCVT);
 17771778 }
 17781779 
 17791780 int
 17801781 moditype(TWORD ty)
 17811782 {
 17821783         switch (ty) {
 17831784 
 17841785         case STRTY:
 17851786         case UNIONTY:
 17861787                 return( MSTR );
 17871788 
 17881789         case BOOL:
 17891790         case CHAR:
 17901791         case SHORT:
 17911792         case UCHAR:
 17921793         case USHORT:
 17931794         case UNSIGNED:
 17941795         case ULONG:
 17951796         case ULONGLONG:
 17961797         case INT:
 17971798         case LONG:
 17981799         case LONGLONG:
 17991800                 return( MINT|MDBI|MPTI );
 18001801         case FLOAT:
 18011802         case DOUBLE:
 18021803         case LDOUBLE:
 18031804 #ifndef NO_COMPLEX
 18041805         case FCOMPLEX:
 18051806         case COMPLEX:
 18061807         case LCOMPLEX:
 18071808         case FIMAG:
 18081809         case IMAG:
 18091810         case LIMAG:
 18101811 #endif
 18111812                 return( MDBI );
 18121813         default:
 18131814                 return( MPTR|MPTI );
 18141815 
 18151816         }
 18161817 }
 18171818 
 18181819 int tvaloff = MAXREGS+NPERMREG > 100 ? MAXREGS+NPERMREG + 100 : 100;
 18191820 
 18201821 /*
 18211822  * Returns a TEMP node with temp number nr.
 18221823  * If nr == 0, return a node with a new number.
 18231824  */
 18241825 NODE *
 18251826 tempnode(int nr, TWORD type, union dimfun *df, struct attr *ap)
 18261827 {
 18271828         NODE *r;
 18281829 
 18291830         if (tvaloff == -NOOFFSET)
 18301831                 tvaloff++; /* Skip this for array indexing */
 18311832         r = block(TEMP, NIL, NIL, type, df, ap);
 18321833         regno(r) = nr ? nr : tvaloff;
 18331834         tvaloff += szty(type);
 18341835         return r;
 18351836 }
 18361837 
 18371838 /*
 18381839  * Do sizeof on p.
 18391840  */
 18401841 NODE *
 18411842 doszof(NODE *p)
 18421843 {
 18431844         extern NODE *arrstk[10];
 18441845         extern int arrstkp;
 18451846         union dimfun *df;
 18461847         TWORD ty;
 18471848         NODE *rv, *q;
 18481849         int astkp;
 18491850 
 18501851         if (p->n_op == FLD)
 18511852                 uerror("can't apply sizeof to bit-field");
 18521853 
 18531854         /*
 18541855          * Arrays may be dynamic, may need to make computations.
 18551856          */
 18561857 
 18571858         rv = bcon(1);
 18581859         df = p->n_df;
 18591860         ty = p->n_type;
 18601861         astkp = 0;
 18611862         while (ISARY(ty)) {
 18621863                 if (df->ddim == NOOFFSET)
 18631864                         uerror("sizeof of incomplete type");
 18641865                 if (df->ddim < 0) {
 18651866                         if (arrstkp)
 18661867                                 q = arrstk[astkp++];
 18671868                         else
 18681869                                 q = tempnode(-df->ddim, INT, 0, 0);
 18691870                 } else
 18701871                         q = bcon(df->ddim);
 18711872                 rv = buildtree(MUL, rv, q);
 18721873                 df++;
 18731874                 ty = DECREF(ty);
 18741875         }
 18751876         rv = buildtree(MUL, rv,
 18761877             xbcon(tsize(ty, p->n_df, p->n_ap)/SZCHAR, NULL, INTPTR));
 18771878         tfree(p);
 18781879         arrstkp = 0; /* XXX - may this fail? */
 18791880         return rv;
 18801881 }
 18811882 
 18821883 #ifdef PCC_DEBUG
 18831884 void
 18841885 eprint(NODE *p, int down, int *a, int *b)
 18851886 {
 18861887         int ty;
 18871888 
 18881889         *a = *b = down+1;
 18891890         while( down > 1 ){
 18901891                 printf( "\t" );
 18911892                 down -= 2;
 18921893                 }
 18931894         if( down ) printf( "    " );
 18941895 
 18951896         ty = coptype( p->n_op );
 18961897 
 18971898         printf("%p) %s, ", p, copst(p->n_op));
 18981899         if (p->n_op == XARG || p->n_op == XASM)
 18991900                 printf("id '%s', ", p->n_name);
 19001901         if (ty == LTYPE) {
 19011902                 printf(CONFMT, p->n_lval);
 19021903                 if (p->n_op == NAME || p->n_op == ICON)
 19031904                         printf(", %p, ", p->n_sp);
 19041905                 else
 19051906                         printf(", %d, ", p->n_rval);
 19061907         }
 19071908         tprint(p->n_type, p->n_qual);
 19081909         printf( ", %p, ", p->n_df);
 19091910         dump_attr(p->n_ap);
 19101911 }
 19111912 # endif
 19121913 
 19131914 /*
 19141915  * Emit everything that should be emitted on the left side
 19151916  * of a comma operator, and remove the operator.
 19161917  * Do not traverse through QUEST, ANDAND and OROR.
 19171918  * Enable this for all targets when stable enough.
 19181919  */
 19191920 static void
 19201921 comops(NODE *p)
 19211922 {
 19221923         int o;
 19231924         NODE *q;
 19241925 
 19251926         while (p->n_op == COMOP) {
 19261927                 /* XXX hack for GCC ({ }) ops */
 19271928                 if (p->n_left->n_op == GOTO) {
 19281929                         int v = (int)p->n_left->n_left->n_lval;
 19291930                         ecomp(p->n_left);
 19301931                         plabel(v+1);
 19311932                 } else
 19321933                         ecomp(p->n_left); /* will recurse if more COMOPs */
 19331934                 q = p->n_right;
 19341935                 *p = *q;
 19351936                 nfree(q);
 19361937         }
 19371938         o = coptype(p->n_op);
 19381939         if (p->n_op == QUEST || p->n_op == ANDAND || p->n_op == OROR)
 19391940                 o = UTYPE;
 19401941         if (o != LTYPE)
 19411942                 comops(p->n_left);
 19421943         if (o == BITYPE)
 19431944                 comops(p->n_right);
 19441945 }
 19451946 
 19461947 /*
 19471948  * Walk up through the tree from the leaves,
 19481949  * removing constant operators.
 19491950  */
 19501951 static void
 19511952 logwalk(NODE *p)
 19521953 {
 19531954         int o = coptype(p->n_op);
 19541955         NODE *l, *r;
 19551956 
 19561957         l = p->n_left;
 19571958         r = p->n_right;
 19581959         switch (o) {
 19591960         case LTYPE:
 19601961                 return;
 19611962         case BITYPE:
 19621963                 logwalk(r);
 19631964         case UTYPE:
 19641965                 logwalk(l);
 19651966         }
 19661967         if (!clogop(p->n_op))
 19671968                 return;
 19681969         if (p->n_op == NOT && l->n_op == ICON) {
 19691970                 p->n_lval = l->n_lval == 0;
 19701971                 nfree(l);
 19711972                 p->n_op = ICON;
 19721973         }
 19731974         if (l->n_op == ICON && r->n_op == ICON) {
 19741975                 if (conval(l, p->n_op, r) == 0) {
 19751976                         /*
 19761977                          * people sometimes tend to do really odd compares,
 19771978                          * like "if ("abc" == "def")" etc.
 19781979                          * do it runtime instead.
 19791980                          */
 19801981                 } else {
 19811982                         p->n_lval = l->n_lval;
 19821983                         p->n_op = ICON;
 19831984                         nfree(l);
 19841985                         nfree(r);
 19851986                 }
 19861987         }
 19871988 }
 19881989 
 19891990 /*
 19901991  * Removes redundant logical operators for branch conditions.
 19911992  */
 19921993 static void
 19931994 fixbranch(NODE *p, int label)
 19941995 {
 19951996 
 19961997         logwalk(p);
 19971998 
 19981999         if (p->n_op == ICON) {
 19992000                 if (p->n_lval != 0)
 20002001                         branch(label);
 20012002                 nfree(p);
 20022003         } else {
 20032004                 if (!clogop(p->n_op)) /* Always conditional */
 20042005                         p = buildtree(NE, p, bcon(0));
 20052006                 ecode(buildtree(CBRANCH, p, bcon(label)));
 20062007         }
 20072008 }
 20082009 
 20092010 /*
 20102011  * Write out logical expressions as branches.
 20112012  */
 20122013 static void
 20132014 andorbr(NODE *p, int true, int false)
 20142015 {
 20152016         NODE *q;
 20162017         int o, lab;
 20172018 
 20182019         lab = -1;
 20192020         switch (o = p->n_op) {
 20202021         case EQ:
 20212022         case NE:
 20222023                 /*
 20232024                  * Remove redundant EQ/NE nodes.
 20242025                  */
 20252026                 while (((o = p->n_left->n_op) == EQ || o == NE) &&
 20262027                     p->n_right->n_op == ICON) {
 20272028                         o = p->n_op;
 20282029                         q = p->n_left;
 20292030                         if (p->n_right->n_lval == 0) {
 20302031                                 nfree(p->n_right);
 20312032                                 *p = *q;
 20322033                                 nfree(q);
 20332034                                 if (o == EQ)
 20342035                                         p->n_op = negrel[p->n_op - EQ];
 20352036 #if 0
 20362037                                         p->n_op = NE; /* toggla */
 20372038 #endif
 20382039                         } else if (p->n_right->n_lval == 1) {
 20392040                                 nfree(p->n_right);
 20402041                                 *p = *q;
 20412042                                 nfree(q);
 20422043                                 if (o == NE)
 20432044                                         p->n_op = negrel[p->n_op - EQ];
 20442045 #if 0
 20452046                                         p->n_op = EQ; /* toggla */
 20462047 #endif
 20472048                         } else
 20482049                                 break; /* XXX - should always be false */
 20492050                         
 20502051                 }
 20512052                 /* FALLTHROUGH */
 20522053         case LE:
 20532054         case LT:
 20542055         case GE:
 20552056         case GT:
 20562057 calc:           if (true < 0) {
 20572058                         p->n_op = negrel[p->n_op - EQ];
 20582059                         true = false;
 20592060                         false = -1;
 20602061                 }
 20612062 
 20622063                 rmcops(p->n_left);
 20632064                 rmcops(p->n_right);
 20642065                 fixbranch(p, true);
 20652066                 if (false >= 0)
 20662067                         branch(false);
 20672068                 break;
 20682069 
 20692070         case ULE:
 20702071         case UGT:
 20712072                 /* Convert to friendlier ops */
 20722073                 if (nncon(p->n_right) && p->n_right->n_lval == 0)
 20732074                         p->n_op = o == ULE ? EQ : NE;
 20742075                 goto calc;
 20752076 
 20762077         case UGE:
 20772078         case ULT:
 20782079                 /* Already true/false by definition */
 20792080                 if (nncon(p->n_right) && p->n_right->n_lval == 0) {
 20802081                         if (true < 0) {
 20812082                                 o = o == ULT ? UGE : ULT;
 20822083                                 true = false;
 20832084                         }
 20842085                         rmcops(p->n_left);
 20852086                         ecode(p->n_left);
 20862087                         rmcops(p->n_right);
 20872088                         ecode(p->n_right);
 20882089                         nfree(p);
 20892090                         if (o == UGE) /* true */
 20902091                                 branch(true);
 20912092                         break;
 20922093                 }
 20932094                 goto calc;
 20942095 
 20952096         case ANDAND:
 20962097                 lab = false<0 ? getlab() : false ;
 20972098                 andorbr(p->n_left, -1, lab);
 20982099                 comops(p->n_right);
 20992100                 andorbr(p->n_right, true, false);
 21002101                 if (false < 0)
 21012102                         plabel( lab);
 21022103                 nfree(p);
 21032104                 break;
 21042105 
 21052106         case OROR:
 21062107                 lab = true<0 ? getlab() : true;
 21072108                 andorbr(p->n_left, lab, -1);
 21082109                 comops(p->n_right);
 21092110                 andorbr(p->n_right, true, false);
 21102111                 if (true < 0)
 21112112                         plabel( lab);
 21122113                 nfree(p);
 21132114                 break;
 21142115 
 21152116         case NOT:
 21162117                 andorbr(p->n_left, false, true);
 21172118                 nfree(p);
 21182119                 break;
 21192120 
 21202121         default:
 21212122                 rmcops(p);
 21222123                 if (true >= 0)
 21232124                         fixbranch(p, true);
 21242125                 if (false >= 0) {
 21252126                         if (true >= 0)
 21262127                                 branch(false);
 21272128                         else
 21282129                                 fixbranch(buildtree(EQ, p, bcon(0)), false);
 21292130                 }
 21302131         }
 21312132 }
 21322133 
 21332134 /*
 21342135  * Create a node for either TEMP or on-stack storage.
 21352136  */
 21362137 NODE *
 21372138 cstknode(TWORD t, union dimfun *df, struct attr *ap)
 21382139 {
 21392140         struct symtab *sp;
 21402141 
 21412142         /* create a symtab entry suitable for this type */
 21422143         sp = getsymtab("0hej", STEMP);
 21432144         sp->stype = t;
 21442145         sp->sdf = df;
 21452146         sp->sap = ap;
 21462147         sp->sclass = AUTO;
 21472148         sp->soffset = NOOFFSET;
 21482149         oalloc(sp, &autooff);
 21492150         return nametree(sp);
 21502151 
 21512152 }
 21522153 
 21532154 /*
 21542155  * Massage the output trees to remove C-specific nodes:
 21552156  *      COMOPs are split into separate statements.
 21562157  *      QUEST/COLON are rewritten to branches.
 21572158  *      ANDAND/OROR/NOT are rewritten to branches for lazy-evaluation.
 21582159  *      CBRANCH conditions are rewritten for lazy-evaluation.
 21592160  */
 21602161 static void
 21612162 rmcops(NODE *p)
 21622163 {
 21632164         TWORD type;
 21642165         NODE *q, *r, *tval;
 21652166         int o, ty, lbl, lbl2;
 21662167 
 21672168         tval = NIL;
 21682169         o = p->n_op;
 21692170         ty = coptype(o);
 21702171         if (BTYPE(p->n_type) == ENUMTY) { /* fixup enum */
 21712172                 struct symtab *sp = strmemb(p->n_ap);
 21722173                 MODTYPE(p->n_type, sp->stype);
 21732174                 /*
 21742175                  * XXX may fail if these are true:
 21752176                  * - variable-sized enums
 21762177                  * - non-byte-addressed targets.
 21772178                  */
 21782179                 if (BTYPE(p->n_type) == ENUMTY && ISPTR(p->n_type))
 21792180                         MODTYPE(p->n_type, INT); /* INT ok? */
 21802181         }
 21812182         switch (o) {
 21822183         case QUEST:
 21832184 
 21842185                 /*
 21852186                  * Create a branch node from ?:
 21862187                  * || and && must be taken special care of.
 21872188                  */
 21882189                 type = p->n_type;
 21892190                 andorbr(p->n_left, -1, lbl = getlab());
 21902191 
 21912192                 /* Make ASSIGN node */
 21922193                 /* Only if type is not void */
 21932194                 q = p->n_right->n_left;
 21942195                 comops(q);
 21952196                 if (type != VOID) {
 21962197                         tval = cstknode(q->n_type, q->n_df, q->n_ap);
 21972198                         q = buildtree(ASSIGN, ccopy(tval), q);
 21982199                 }
 21992200                 rmcops(q);
 22002201                 ecode(q); /* Done with assign */
 22012202                 branch(lbl2 = getlab());
 22022203                 plabel( lbl);
 22032204 
 22042205                 q = p->n_right->n_right;
 22052206                 comops(q);
 22062207                 if (type != VOID) {
 22072208                         q = buildtree(ASSIGN, ccopy(tval), q);
 22082209                 }
 22092210                 rmcops(q);
 22102211                 ecode(q); /* Done with assign */
 22112212 
 22122213                 plabel( lbl2);
 22132214 
 22142215                 nfree(p->n_right);
 22152216                 if (p->n_type != VOID) {
 22162217                         *p = *tval;
 22172218                         nfree(tval);
 22182219                 } else {
 22192220                         p->n_op = ICON;
 22202221                         p->n_lval = 0;
 22212222                         p->n_sp = NULL;
 22222223                 }
 22232224                 break;
 22242225 
 22252226         case ULE:
 22262227         case ULT:
 22272228         case UGE:
 22282229         case UGT:
 22292230         case EQ:
 22302231         case NE:
 22312232         case LE:
 22322233         case LT:
 22332234         case GE:
 22342235         case GT:
 22352236         case ANDAND:
 22362237         case OROR:
 22372238         case NOT:
 22382239 #ifdef SPECIAL_CCODES
 22392240 #error fix for private CCODES handling
 22402241 #else
 22412242                 r = talloc();
 22422243                 *r = *p;
 22432244                 andorbr(r, -1, lbl = getlab());
 22442245 
 22452246                 tval = cstknode(p->n_type, p->n_df, p->n_ap);
 22462247 
 22472248                 ecode(buildtree(ASSIGN, ccopy(tval), bcon(1)));
 22482249                 branch(lbl2 = getlab());
 22492250                 plabel( lbl);
 22502251                 ecode(buildtree(ASSIGN, ccopy(tval), bcon(0)));
 22512252                 plabel( lbl2);
 22522253 
 22532254                 *p = *tval;
 22542255                 nfree(tval);
 22552256 
 22562257 #endif
 22572258                 break;
 22582259         case CBRANCH:
 22592260                 andorbr(p->n_left, p->n_right->n_lval, -1);
 22602261                 nfree(p->n_right);
 22612262                 p->n_op = ICON; p->n_type = VOID;
 22622263                 break;
 22632264         case COMOP:
 22642265                 cerror("COMOP error");
 22652266 
 22662267         default:
 22672268                 if (ty == LTYPE)
 22682269                         return;
 22692270                 rmcops(p->n_left);
 22702271                 if (ty == BITYPE)
 22712272                         rmcops(p->n_right);
 22722273        }
 22732274 }
 22742275 
 22752276 /*
 22762277  * Return 1 if an assignment is found.
 22772278  */
 22782279 static int
 22792280 has_se(NODE *p)
 22802281 {
 22812282         if (cdope(p->n_op) & ASGFLG)
 22822283                 return 1;
 22832284         if (coptype(p->n_op) == LTYPE)
 22842285                 return 0;
 22852286         if (has_se(p->n_left))
 22862287                 return 1;
 22872288         if (coptype(p->n_op) == BITYPE)
 22882289                 return has_se(p->n_right);
 22892290         return 0;
 22902291 }
 22912292 
 22922293 /*
 22932294  * Find and convert asgop's to separate statements.
 22942295  * Be careful about side effects.
 22952296  * assign tells whether ASSIGN should be considered giving
 22962297  * side effects or not.
 22972298  */
 22982299 static NODE *
 22992300 delasgop(NODE *p)
 23002301 {
 23012302         NODE *q, *r;
 23022303         int tval;
 23032304 
 23042305         if (p->n_op == INCR || p->n_op == DECR) {
 23052306                 /*
 23062307                  * Rewrite x++ to (x += 1) -1; and deal with it further down.
 23072308                  * Pass2 will remove -1 if unnecessary.
 23082309                  */
 23092310                 q = ccopy(p);
 23102311                 tfree(p->n_left);
 23112312                 q->n_op = (p->n_op==INCR)?PLUSEQ:MINUSEQ;
 23122313                 p->n_op = (p->n_op==INCR)?MINUS:PLUS;
 23132314                 p->n_left = delasgop(q);
 23142315 
 23152316         } else if ((cdope(p->n_op)&ASGOPFLG) &&
 23162317             p->n_op != RETURN && p->n_op != CAST) {
 23172318                 NODE *l = p->n_left;
 23182319                 NODE *ll = l->n_left;
 23192320 
 23202321                 if (has_se(l)) {
 23212322                         q = tempnode(0, ll->n_type, ll->n_df, ll->n_ap);
 23222323                         tval = regno(q);
 23232324                         r = tempnode(tval, ll->n_type, ll->n_df,ll->n_ap);
 23242325                         l->n_left = q;
 23252326                         /* Now the left side of node p has no side effects. */
 23262327                         /* side effects on the right side must be obeyed */
 23272328                         p = delasgop(p);
 23282329                         
 23292330                         r = buildtree(ASSIGN, r, ll);
 23302331                         r = delasgop(r);
 23312332                         ecode(r);
 23322333                 } else {
 23332334 #if 0 /* Cannot call buildtree() here, it would invoke double add shifts */
 23342335                         p->n_right = buildtree(UNASG p->n_op, ccopy(l),
 23352336                             p->n_right);
 23362337 #else
 23372338                         p->n_right = block(UNASG p->n_op, ccopy(l),
 23382339                             p->n_right, p->n_type, p->n_df, p->n_ap);
 23392340 #endif
 23402341                         p->n_op = ASSIGN;
 23412342                         p->n_right = delasgop(p->n_right);
 23422343                         p->n_right = clocal(p->n_right);
 23432344                 }
 23442345                 
 23452346         } else {
 23462347                 if (coptype(p->n_op) == LTYPE)
 23472348                         return p;
 23482349                 p->n_left = delasgop(p->n_left);
 23492350                 if (coptype(p->n_op) == BITYPE)
 23502351                         p->n_right = delasgop(p->n_right);
 23512352         }
 23522353         return p;
 23532354 }
 23542355 
 23552356 #ifndef FIELDOPS
 23562357 
 23572358 /* avoid promotion to int */
 23582359 #define TYPMOD(o, p, n, t)      clocal(block(o, p, n, t, 0, 0))
 23592360 #define TYPLS(p, n, t)  TYPMOD(LS, p, n, t)
 23602361 #define TYPRS(p, n, t)  TYPMOD(RS, p, n, t)
 23612362 #define TYPOR(p, q, t)  TYPMOD(OR, p, q, t)
 23622363 #define TYPAND(p, q, t) TYPMOD(AND, p, q, t)
 23632364 
 23642365 /*
 23652366  * Read an unaligned bitfield from position pointed to by p starting at
 23662367  * off and size fsz and return a tree of type t with resulting data.
 23672368  */
 23682369 static NODE *
 23692370 rdualfld(NODE *p, TWORD t, TWORD ct, int off, int fsz)
 23702371 {
 23712372         int t2f, inbits, tsz, ctsz;
 23722373         NODE *q, *r;
 23732374 
 23742375         ct = ENUNSIGN(ct);
 23752376         ctsz = (int)tsize(ct, 0, 0);
 23762377 
 23772378         /* traverse until first data byte */
 23782379         for (t2f = 0; off > ctsz; t2f++, off -= ctsz)
 23792380                 ;
 23802381 #ifdef UNALIGNED_ACCESS
 23812382         /* try to squeeze it into an int */
 23822383         if (off + fsz > ctsz && off + fsz <= SZINT) {
 23832384                 ct = UNSIGNED;
 23842385                 ctsz = SZINT;
 23852386         }
 23862387 #endif
 23872388         p = makety(p, PTR|ct, 0, 0, 0);
 23882389         if (off + fsz <= ctsz) {
 23892390                 /* only one operation needed */
 23902391                 q = buildtree(UMUL, buildtree(PLUS, p, bcon(t2f)), 0);
 23912392                 if (!ISUNSIGNED(t)) {
 23922393                         ct = DEUNSIGN(ct);
 23932394                         q = makety(q, ct, 0, 0, 0);
 23942395                 }
 23952396                 q = TYPLS(q, bcon(ctsz-fsz-off), ct);
 23962397                 q = TYPRS(q, bcon(ctsz-fsz), ct);
 23972398                 q = makety(q, t, 0, 0, 0);
 23982399         } else {
 23992400                 q = buildtree(UMUL, buildtree(PLUS, ccopy(p), bcon(t2f)), 0);
 24002401                 q = makety(TYPRS(q, bcon(off), ct), t, 0, 0, 0);
 24012402                 inbits = ctsz - off;
 24022403                 t2f++;
 24032404 
 24042405                 while (fsz > inbits) {
 24052406                         r = buildtree(UMUL,
 24062407                             buildtree(PLUS, ccopy(p), bcon(t2f)), 0);
 24072408                         r = makety(r, t, 0, 0, 0);
 24082409                         r = TYPLS(r, bcon(inbits), t);
 24092410                         q = TYPOR(q, r, t);
 24102411                         inbits += ctsz;
 24112412                         t2f++;
 24122413                 }
 24132414                 /* sign/zero extend XXX - RS must sign extend */
 24142415                 tsz = (int)tsize(t, 0, 0);
 24152416                 if (!ISUNSIGNED(t)) {
 24162417                         t = DEUNSIGN(t);
 24172418                         q = makety(q, t, 0, 0, 0);
 24182419                 }
 24192420                 q = TYPLS(q, bcon(tsz-fsz), t);
 24202421                 q = TYPRS(q, bcon(tsz-fsz), t);
 24212422                 tfree(p);
 24222423         }
 24232424 
 24242425         return q;
 24252426 }
 24262427 
 24272428 /*
 24282429  * Write val to a (unaligned) bitfield with length fsz positioned off bits 
 24292430  * from d. Bitfield type is t, and type to use when writing is ct.
 24302431  * neither f nor d should have any side effects if copied.
 24312432  * Multiples of ct are supposed to be written without problems.
 24322433  * Both val and d are free'd after use.
 24332434  */
 24342435 static NODE *
 24352436 wrualfld(NODE *val, NODE *d, TWORD t, TWORD ct, int off, int fsz)
 24362437 {
 24372438         NODE *p, *q, *r, *rn, *s;
 24382439         int tsz, ctsz, t2f, inbits;
 24392440  
 24402441         tsz = (int)tsize(t, 0, 0);
 24412442         ctsz = (int)tsize(ct, 0, 0);
 24422443  
 24432444         ct = ENUNSIGN(ct);
 24442445         d = makety(d, PTR|ct, 0, 0, 0);
 24452446 
 24462447         for (t2f = 0; off > ctsz; t2f++, off -= ctsz)
 24472448                 ;
 24482449  
 24492450         if (off + fsz <= ctsz) {
 24502451                 r = tempnode(0, ct, 0, 0);
 24512452 
 24522453                 /* only one operation needed */
 24532454                 d = buildtree(UMUL, buildtree(PLUS, d, bcon(t2f)), 0);  
 24542455                 p = ccopy(d);
 24552456                 p = TYPAND(p, xbcon(~(SZMASK(fsz) << off), 0, ct), ct);
 24562457 
 24572458                 val = makety(val, ct, 0, 0, 0);
 24582459                 q = TYPAND(val, xbcon(SZMASK(fsz), 0, ct), ct);
 24592460                 q = buildtree(ASSIGN, ccopy(r), q);
 24602461 
 24612462                 q = TYPLS(q, bcon(off), ct);  
 24622463                 p = TYPOR(p, q, ct);
 24632464                 p = makety(p, t, 0, 0, 0);    
 24642465                 rn = buildtree(ASSIGN, d, p);
 24652466                 rn = buildtree(COMOP, rn, makety(r, t, 0, 0, 0));
 24662467         } else {
 24672468                 s = makety(ccopy(val), t, 0, 0, 0);
 24682469                 s = TYPAND(s, xbcon(SZMASK(fsz), 0, t), t);
 24692470 
 24702471                 r = buildtree(UMUL, buildtree(PLUS, ccopy(d), bcon(t2f)), 0);
 24712472                 p = ccopy(r);
 24722473                 p = TYPAND(p, xbcon(SZMASK(off), 0, ct), ct);
 24732474                 q = ccopy(val);
 24742475                 q = TYPLS(q, bcon(off), t); 
 24752476                 q = makety(q, ct, 0, 0, 0);
 24762477                 p = TYPOR(p, q, ct);
 24772478                 rn = buildtree(ASSIGN, r, p);
 24782479                 inbits = ctsz - off;
 24792480                 t2f++;
 24802481 
 24812482                 while (fsz > inbits+ctsz) {
 24822483                         r = buildtree(UMUL,
 24832484                             buildtree(PLUS, ccopy(d), bcon(t2f)), 0);
 24842485                         q = ccopy(val);
 24852486                         q = TYPRS(q, bcon(inbits), t);
 24862487                         q = makety(q, ct, 0, 0, 0);
 24872488                         rn = buildtree(COMOP, rn, buildtree(ASSIGN, r, q));
 24882489                         t2f++;
 24892490                         inbits += ctsz;
 24902491                 }
 24912492 
 24922493                 r = buildtree(UMUL, buildtree(PLUS, d, bcon(t2f)), 0);
 24932494                 p = ccopy(r);
 24942495                 p = TYPAND(p, makety(xbcon(~SZMASK(fsz-inbits), 0, ct),
 24952496                     ct, 0, 0, 0), ct);
 24962497                 q = TYPRS(val, bcon(inbits), t);
 24972498                 q = TYPAND(q, xbcon(SZMASK(fsz-inbits), 0, t), t);
 24982499                 q = makety(q, ct, 0, 0, 0);
 24992500                 p = TYPOR(p, q, ct);
 25002501                 rn = buildtree(COMOP, rn, buildtree(ASSIGN, r, p));
 25012502                 rn = buildtree(COMOP, rn, s);
 25022503         }
 25032504         return rn;
 25042505 }
 25052506 
 25062507 /*
 25072508  * Rewrite bitfield operations to shifts.
 25082509  */
 25092510 static NODE *
 25102511 rmfldops(NODE *p)
 25112512 {
 25122513         TWORD t, ct;
 25132514         NODE *q, *r, *t1, *t2, *bt, *t3, *t4;
 25142515         int fsz, foff, tsz;
 25152516 
 25162517         if (p->n_op == FLD) {
 25172518                 /* Rewrite a field read operation */
 25182519                 fsz = UPKFSZ(p->n_rval);
 25192520                 foff = UPKFOFF(p->n_rval);
 25202521                 tsz = (int)tsize(p->n_left->n_type, 0, 0);
 25212522                 q = buildtree(ADDROF, p->n_left, NIL);
 25222523 
 25232524                 ct = t = p->n_type;
 25242525                 if (attr_find(p->n_ap, GCC_ATYP_PACKED) &&
 25252526                     coptype(q->n_op) != LTYPE) {
 25262527                         t1 = tempnode(0, q->n_type, 0, 0);
 25272528                         bt = buildtree(ASSIGN, ccopy(t1), q);
 25282529                         q = t1;
 25292530 #ifndef UNALIGNED_ACCESS
 25302531                         ct = UCHAR;
 25312532 #endif
 25322533                 } else
 25332534                         bt = bcon(0);
 25342535                 q = rdualfld(q, t, ct, foff, fsz);
 25352536                 p->n_left = bt;
 25362537                 p->n_right = q;
 25372538                 p->n_op = COMOP;
 25382539         } else if (((cdope(p->n_op)&ASGOPFLG) || p->n_op == ASSIGN ||
 25392540             p->n_op == INCR || p->n_op == DECR) && p->n_left->n_op == FLD) {
 25402541                 /*
 25412542                  * Rewrite a field write operation
 25422543                  * More difficult than a read op since we must care
 25432544                  * about side effects.
 25442545                  */
 25452546                 q = p->n_left;
 25462547                 fsz = UPKFSZ(q->n_rval);
 25472548                 foff = UPKFOFF(q->n_rval);
 25482549                 t = q->n_left->n_type;
 25492550                 tsz = (int)tsize(t, 0, 0);
 25502551 #if TARGET_ENDIAN == TARGET_BE
 25512552                 foff = tsz - fsz - foff;
 25522553 #endif
 25532554                 bt = NULL;
 25542555                 if (p->n_right->n_op != ICON && p->n_right->n_op != NAME) {
 25552556                         t2 = tempnode(0, p->n_right->n_type, 0, 0);
 25562557                         bt = buildtree(ASSIGN, ccopy(t2), p->n_right);
 25572558                 } else
 25582559                         t2 = p->n_right;
 25592560 
 25602561                 ct = t;
 25612562 #ifndef UNALIGNED_ACCESS
 25622563                 if (attr_find(q->n_ap, GCC_ATYP_PACKED))
 25632564                         ct = UCHAR;
 25642565 #endif
 25652566                 /* t2 is what we have to write (RHS of ASSIGN) */
 25662567                 /* bt is (eventually) something that must be written */
 25672568 
 25682569 
 25692570                 if (q->n_left->n_op == UMUL) {
 25702571                         /* LHS of assignment may have side effects */
 25712572                         q = q->n_left;
 25722573                         t1 = tempnode(0, q->n_left->n_type, 0, 0);
 25732574                         r = buildtree(ASSIGN, ccopy(t1), q->n_left);
 25742575                         
 25752576                         bt = bt ? block(COMOP, bt, r, INT, 0, 0) : r;
 25762577                         q->n_left = t1;
 25772578                 }
 25782579                 t1 = buildtree(ADDROF, p->n_left->n_left, 0);
 25792580 
 25802581                 /* t1 is lval where to write (and read) */
 25812582 
 25822583                 if (p->n_op == ASSIGN) {
 25832584                         q = wrualfld(t2, t1, t, ct, foff, fsz);
 25842585                         if (bt)
 25852586                                 q = block(COMOP, bt, q, t, 0, 0);
 25862587                         nfree(p->n_left);
 25872588                         p->n_left = bcon(0);
 25882589                         p->n_right = q;
 25892590                         p->n_op = COMOP;
 25902591                 } else if ((cdope(p->n_op)&ASGOPFLG)) {
 25912592                         /* And here is the asgop-specific code */
 25922593                         t3 = tempnode(0, t, 0, 0);
 25932594                         q = rdualfld(ccopy(t1), t, ct, foff, fsz);
 25942595                         q = buildtree(UNASG p->n_op, q, t2);
 25952596                         q = buildtree(ASSIGN, ccopy(t3), q);
 25962597                         r = wrualfld(ccopy(t3), t1, t, ct, foff, fsz);
 25972598                         q = buildtree(COMOP, q, r);
 25982599                         q = buildtree(COMOP, q, t3);
 25992600 
 26002601                         nfree(p->n_left);
 26012602                         p->n_left = bt ? bt : bcon(0);
 26022603                         p->n_right = q;
 26032604                         p->n_op = COMOP;
 26042605                 } else {
 26052606                         t3 = tempnode(0, t, 0, 0);
 26062607                         t4 = tempnode(0, t, 0, 0);
 26072608 
 26082609                         q = rdualfld(ccopy(t1), t, ct, foff, fsz);
 26092610                         q = buildtree(ASSIGN, ccopy(t3), q);
 26102611                         r = buildtree(p->n_op==INCR?PLUS:MINUS, ccopy(t3), t2);
 26112612                         r = buildtree(ASSIGN, ccopy(t4), r);
 26122613                         q = buildtree(COMOP, q, r);
 26132614                         r = wrualfld(t4, t1, t, ct, foff, fsz);
 26142615                         q = buildtree(COMOP, q, r);
 26152616                 
 26162617                         if (bt)
 26172618                                 q = block(COMOP, bt, q, t, 0, 0);
 26182619                         nfree(p->n_left);
 26192620                         p->n_left = q;
 26202621                         p->n_right = t3;
 26212622                         p->n_op = COMOP;
 26222623                 }
 26232624         }
 26242625         if (coptype(p->n_op) != LTYPE)
 26252626                 p->n_left = rmfldops(p->n_left);
 26262627         if (coptype(p->n_op) == BITYPE)
 26272628                 p->n_right = rmfldops(p->n_right);
 26282629         return p;
 26292630 }
 26302631 #endif
 26312632 
 26322633 void
 26332634 ecomp(NODE *p)
 26342635 {
 26352636 
 26362637 #ifdef PCC_DEBUG
 26372638         if (edebug)
 26382639                 fwalk(p, eprint, 0);
 26392640 #endif
 26402641         if (!reached) {
 26412642                 warner(Wunreachable_code, NULL);
 26422643                 reached = 1;
 26432644         }
 26442645         p = optim(p);
 26452646 #ifndef FIELDOPS
 26462647         p = rmfldops(p);
 26472648 #endif
 26482649         comops(p);
 26492650         rmcops(p);
 26502651         p = delasgop(p);
 26512652         if (p->n_op == ICON && p->n_type == VOID)
 26522653                 tfree(p);
 26532654         else
 26542655                 ecode(p);
 26552656 }
 26562657 
 26572658 
 26582659 #if defined(MULTIPASS)
 26592660 void    
 26602661 p2tree(NODE *p)
 26612662 {
 26622663         struct symtab *q;
 26632664         int ty;
 26642665 
 26652666         myp2tree(p);  /* local action can be taken here */
 26662667 
 26672668         ty = coptype(p->n_op);
 26682669 
 26692670         printf("%d\t", p->n_op);
 26702671 
 26712672         if (ty == LTYPE) {
 26722673                 printf(CONFMT, p->n_lval);