Quick Search:

Mode

Context

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

Other Diffs

Ignore

Blank Lines Whitespace: Expand:

Diff

1.7
 
1.8
 
MAIN:plunky:20121022092949
 
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                         /* FALLTHROUGH */
 378378                 case UTYPE:
 379379                         p->n_left = pconvert( p->n_left );
 380380 
 381381                         }
 382382                 }
 383383 
 384384         if ((actions&PUN) && (o!=CAST))
 385385                 chkpun(p);
 386386 
 387387         if( actions & (TYPL|TYPR) ){
 388388 
 389389                 q = (actions&TYPL) ? p->n_left : p->n_right;
 390390 
 391391                 p->n_type = q->n_type;
 392392                 p->n_qual = q->n_qual;
 393393                 p->n_df = q->n_df;
 394394                 p->n_ap = q->n_ap;
 395395                 }
 396396 
 397397         if( actions & CVTL ) p = convert( p, CVTL );
 398398         if( actions & CVTR ) p = convert( p, CVTR );
 399399         if( actions & TYMATCH ) p = tymatch(p);
 400400         if( actions & PTMATCH ) p = ptmatch(p);
 401401 
 402402         if( actions & OTHER ){
 403403                 struct symtab *sp1;
 404404 
 405405                 l = p->n_left;
 406406                 r = p->n_right;
 407407 
 408408                 switch(o){
 409409 
 410410                 case NAME:
 411411                         cerror("buildtree NAME");
 412412 
 413413                 case STREF:
 414414                         /* p->x turned into *(p+offset) */
 415415                         /* rhs must be a name; check correctness */
 416416 
 417417                         /* Find member symbol struct */
 418418                         if (l->n_type != PTR+STRTY && l->n_type != PTR+UNIONTY){
 419419                                 uerror("struct or union required");
 420420                                 break;
 421421                         }
 422422 
 423423                         if ((sp1 = strmemb(l->n_ap)) == NULL) {
 424424                                 uerror("undefined struct or union");
 425425                                 break;
 426426                         }
 427427 
 428428                         if ((sp = findmember(sp1, r->n_name)) == NULL) {
 429429                                 uerror("member '%s' not declared", r->n_name);
 430430                                 break;
 431431                         }
 432432 
 433433                         r->n_sp = sp;
 434434                         p = stref(p);
 435435                         break;
 436436 
 437437                 case UMUL:
 438438                         if (l->n_op == ADDROF) {
 439439                                 nfree(p);
 440440                                 p = nfree(l);
 441441                         }
 442442                         if( !ISPTR(l->n_type))uerror("illegal indirection");
 443443                         p->n_type = DECREF(l->n_type);
 444444                         p->n_qual = DECREF(l->n_qual);
 445445                         p->n_df = l->n_df;
 446446                         p->n_ap = l->n_ap;
 447447                         break;
 448448 
 449449                 case ADDROF:
 450450                         switch( l->n_op ){
 451451 
 452452                         case UMUL:
 453453                                 nfree(p);
 454454                                 p = nfree(l);
 455455                                 /* FALLTHROUGH */
 456456                         case TEMP:
 457457                         case NAME:
 458458                                 p->n_type = INCREF(l->n_type);
 459459                                 p->n_qual = INCQAL(l->n_qual);
 460460                                 p->n_df = l->n_df;
 461461                                 p->n_ap = l->n_ap;
 462462                                 break;
 463463 
 464464                         case COMOP:
 465465                                 nfree(p);
 466466                                 lr = buildtree(ADDROF, l->n_right, NIL);
 467467                                 p = buildtree( COMOP, l->n_left, lr );
 468468                                 nfree(l);
 469469                                 break;
 470470 
 471471                         case QUEST:
 472472                                 lr = buildtree( ADDROF, l->n_right->n_right, NIL );
 473473                                 ll = buildtree( ADDROF, l->n_right->n_left, NIL );
 474474                                 nfree(p); nfree(l->n_right);
 475475                                 p = buildtree( QUEST, l->n_left, buildtree( COLON, ll, lr ) );
 476476                                 nfree(l);
 477477                                 break;
 478478 
 479479                         default:
 480480                                 uerror("unacceptable operand of &: %d", l->n_op );
 481481                                 break;
 482482                                 }
 483483                         break;
 484484 
 485485                 case LS:
 486486                 case RS: /* must make type size at least int... */
 487487                         if (p->n_type == CHAR || p->n_type == SHORT) {
 488488                                 p->n_left = makety(l, INT, 0, 0, 0);
 489489                         } else if (p->n_type == UCHAR || p->n_type == USHORT) {
 490490                                 p->n_left = makety(l, UNSIGNED, 0, 0, 0);
 491491                         }
 492492                         l = p->n_left;
 493493                         p->n_type = l->n_type;
 494494                         p->n_qual = l->n_qual;
 495495                         p->n_df = l->n_df;
 496496                         p->n_ap = l->n_ap;
 497497 
 498498                         /* FALLTHROUGH */
 499499                 case LSEQ:
 500500                 case RSEQ: /* ...but not for assigned types */
 501501                         if(tsize(r->n_type, r->n_df, r->n_ap) > SZINT)
 502502                                 p->n_right = makety(r, INT, 0, 0, 0);
 503503                         break;
 504504 
 505505                 case RETURN:
 506506                 case ASSIGN:
 507507                 case CAST:
 508508                         /* structure assignment */
 509509                         /* take the addresses of the two sides; then make an
 510510                          * operator using STASG and
 511511                          * the addresses of left and right */
 512512 
 513513                         if (strmemb(l->n_ap) != strmemb(r->n_ap))
 514514                                 uerror("assignment of different structures");
 515515 
 516516                         r = buildtree(ADDROF, r, NIL);
 517517 
 518518                         l = block(STASG, l, r, r->n_type, r->n_df, r->n_ap);
 519519                         l = clocal(l);
 520520 
 521521                         if( o == RETURN ){
 522522                                 nfree(p);
 523523                                 p = l;
 524524                                 break;
 525525                         }
 526526 
 527527                         p->n_op = UMUL;
 528528                         p->n_left = l;
 529529                         p->n_right = NIL;
 530530                         break;
 531531 
 532532                 case QUEST: /* fixup types of : */
 533533                         if (r->n_left->n_type != p->n_type)
 534534                                 r->n_left = makety(r->n_left, p->n_type,
 535535                                     p->n_qual, p->n_df, p->n_ap);
 536536                         if (r->n_right->n_type != p->n_type)
 537537                                 r->n_right = makety(r->n_right, p->n_type,
 538538                                     p->n_qual, p->n_df, p->n_ap);
 539539                         break;
 540540 
 541541                 case COLON:
 542542                         /* structure colon */
 543543 
 544544                         if (strmemb(l->n_ap) != strmemb(r->n_ap))
 545545                                 uerror( "type clash in conditional" );
 546546                         break;
 547547 
 548548                 case CALL:
 549549                         p->n_right = r = strargs(p->n_right);
 550550                         p = funcode(p);
 551551                         /* FALLTHROUGH */
 552552                 case UCALL:
 553553                         if (!ISPTR(l->n_type))
 554554                                 uerror("illegal function");
 555555                         p->n_type = DECREF(l->n_type);
 556556                         if (!ISFTN(p->n_type))
 557557                                 uerror("illegal function");
 558558                         p->n_type = DECREF(p->n_type);
 559559                         p->n_df = l->n_df+1; /* add one for prototypes */
 560560                         p->n_ap = l->n_ap;
 561561                         if (p->n_type == STRTY || p->n_type == UNIONTY) {
 562562                                 /* function returning structure */
 563563                                 /*  make function really return ptr to str., with * */
 564564 
 565565                                 p->n_op += STCALL-CALL;
 566566                                 p->n_type = INCREF(p->n_type);
 567567                                 p = clocal(p); /* before recursing */
 568568                                 p = buildtree(UMUL, p, NIL);
 569569 
 570570                                 }
 571571                         break;
 572572 
 573573                 default:
 574574                         cerror( "other code %d", o );
 575575                         }
 576576 
 577577                 }
 578578 
 579579         /*
 580580          * Allow (void)0 casts.
 581581          * XXX - anything on the right side must be possible to cast.
 582582          * XXX - remove void types further on.
 583583          */
 584584         if (p->n_op == CAST && p->n_type == VOID &&
 585585             p->n_right->n_op == ICON)
 586586                 p->n_right->n_type = VOID;
 587587 
 588588         if (actions & CVTO)
 589589                 p = oconvert(p);
 590590         p = clocal(p);
 591591 
 592592 #ifdef PCC_DEBUG
 593593         if (bdebug) {
 594594                 printf("End of buildtree:\n");
 595595                 fwalk(p, eprint, 0);
 596596         }
 597597 #endif
 598598 
 599599         return(p);
 600600 
 601601         }
 602602 
 603603 /* Find a member in a struct or union.  May be an unnamed member */
 604604 static struct symtab *
 605605 findmember(struct symtab *sp, char *s)
 606606 {
 607607         struct symtab *sp2, *sp3;
 608608 
 609609         for (; sp != NULL; sp = sp->snext) {
 610610                 if (sp->sname[0] == '*') {
 611611                         /* unnamed member, recurse down */
 612612                         if ((sp2 = findmember(strmemb(sp->sap), s))) {
 613613                                 sp3 = tmpalloc(sizeof (struct symtab));
 614614                                 *sp3 = *sp2;
 615615                                 sp3->soffset += sp->soffset;
 616616                                 return sp3;
 617617                         }
 618618                 } else if (sp->sname == s)
 619619                         return sp;
 620620         }
 621621         return NULL;
 622622 }
 623623 
 624624 
 625625 /*
 626626  * Check if there will be a lost label destination inside of a ?:
 627627  * It cannot be reached so just print it out.
 628628  */
 629629 void
 630630 putjops(NODE *p, void *arg)
 631631 {
 632632         if (p->n_op == COMOP && p->n_left->n_op == GOTO)
 633633                 plabel((int)p->n_left->n_left->n_lval+1);
 634634 }
 635635 
 636636 /*
 637637  * Build a name node based on a symtab entry.
 638638  * broken out from buildtree().
 639639  */
 640640 NODE *
 641641 nametree(struct symtab *sp)
 642642 {
 643643         NODE *p;
 644644 
 645645         p = block(NAME, NIL, NIL, sp->stype, sp->sdf, sp->sap);
 646646         p->n_qual = sp->squal;
 647647         p->n_sp = sp;
 648648 
 649649 #ifndef NO_C_BUILTINS
 650650         if (sp->sname[0] == '_' && strncmp(sp->sname, "__builtin_", 10) == 0)
 651651                 return p/* do not touch builtins here */
 652652         
 653653 #endif
 654654 
 655655         if (sp->sflags & STNODE) {
 656656                 /* Generated for optimizer */
 657657                 p->n_op = TEMP;
 658658                 p->n_rval = sp->soffset;
 659659         }
 660660 
 661661 #ifdef GCC_COMPAT
 662662         /* Get a label name */
 663663         if (sp->sflags == SLBLNAME) {
 664664                 p->n_type = VOID;
 665665         }
 666666 #endif
 667667         if (sp->stype == UNDEF) {
 668668                 uerror("%s undefined", sp->sname);
 669669                 /* make p look reasonable */
 670670                 p->n_type = INT;
 671671                 p->n_df = NULL;
 672672                 defid(p, SNULL);
 673673         }
 674674         if (sp->sclass == MOE) {
 675675                 p->n_op = ICON;
 676676                 p->n_lval = sp->soffset;
 677677                 p->n_df = NULL;
 678678                 p->n_sp = NULL;
 679679         }
 680680         return clocal(p);
 681681 }
 682682 
 683683 /*
 684684  * Cast a node to another type by inserting a cast.
 685685  * Just a nicer interface to buildtree.
 686686  * Returns the new tree.
 687687  */
 688688 NODE *
 689689 cast(NODE *p, TWORD t, TWORD u)
 690690 {
 691691         NODE *q;
 692692 
 693693         q = block(NAME, NIL, NIL, t, 0, 0);
 694694         q->n_qual = u;
 695695         q = buildtree(CAST, q, p);
 696696         p = q->n_right;
 697697         nfree(q->n_left);
 698698         nfree(q);
 699699         return p;
 700700 }
 701701 
 702702 /*
 703703  * Cast and complain if necessary by not inserining a cast.
 704704  */
 705705 NODE *
 706706 ccast(NODE *p, TWORD t, TWORD u, union dimfun *df, struct attr *ap)
 707707 {
 708708         NODE *q;
 709709 
 710710         /* let buildtree do typechecking (and casting) */
 711711         q = block(NAME, NIL, NIL, t, df, ap);
 712712         p = buildtree(ASSIGN, q, p);
 713713         nfree(p->n_left);
 714714         q = optim(p->n_right);
 715715         nfree(p);
 716716         return q;
 717717 }
 718718 
 719719 /*
 720720  * Do an actual cast of a constant (if possible).
 721721  * Routine assumes 2-complement (is there anything else today?)
 722722  * Returns 1 if handled, 0 otherwise.
 723723  */
 724724 int
 725725 concast(NODE *p, TWORD t)
 726726 {
 727727         extern short sztable[];
 728728         CONSZ val;
 729729 
 730730         if (p->n_op != ICON && p->n_op != FCON) /* only constants */
 731731                 return 0;
 732732         if (p->n_op == ICON && p->n_sp != NULL) { /* no addresses */
 733733                 if (t == BOOL) {
 734734                         p->n_lval = 1, p->n_type = BOOL, p->n_sp = NULL;
 735735                         return 1;
 736736                 }
 737737                 return 0;
 738738         }
 739739         if ((p->n_type & TMASK) || (t & TMASK)) /* no cast of pointers */
 740740                 return 0;
 741741 
 742742 //printf("concast till %d\n", t);
 743743 //fwalk(p, eprint, 0);
 744744 
 745745 #define TYPMSK(y) ((((1LL << (y-1))-1) << 1) | 1)
 746746         if (p->n_op == ICON) {
 747747                 val = p->n_lval;
 748748 
 749749                 if (t == BOOL) {
 750750                         if (val)
 751751                                 p->n_lval = 1;
 752752                 } else if (t <= ULONGLONG) {
 753753                         p->n_lval = val & TYPMSK(sztable[t]);
 754754                         if (!ISUNSIGNED(t)) {
 755755                                 if (val & (1LL << (sztable[t]-1)))
 756756                                         p->n_lval |= ~TYPMSK(sztable[t]);
 757757                         }
 758758                 } else if (t <= LDOUBLE) {
 759759                         p->n_op = FCON;
 760760                         p->n_dcon = FLOAT_CAST(val, p->n_type);
 761761                 }
 762762         } else { /* p->n_op == FCON */
 763763                 if (t == BOOL) {
 764764                         p->n_op = ICON;
 765765                         p->n_lval = FLOAT_NE(p->n_dcon,0.0);
 766766                         p->n_sp = NULL;
 767767                 } else if (t <= ULONGLONG) {
 768768                         p->n_op = ICON;
 769769                         p->n_lval = ISUNSIGNED(t) ? /* XXX FIXME */
 770770                             ((U_CONSZ)p->n_dcon) : p->n_dcon;
 771771                         p->n_sp = NULL;
 772772                 } else {
 773773                         p->n_dcon = t == FLOAT ? (float)p->n_dcon :
 774774                             t == DOUBLE ? (double)p->n_dcon : p->n_dcon;
 775775                 }
 776776         }
 777777         p->n_type = t;
 778778 //fwalk(p, eprint, 0);
 779779         return 1;
 780780 }
 781781 
 782782 /*
 783783  * Do a conditional branch.
 784784  */
 785785 void
 786786 cbranch(NODE *p, NODE *q)
 787787 {
 788788         p = buildtree(CBRANCH, p, q);
 789789         if (p->n_left->n_op == ICON) {
 790790                 if (p->n_left->n_lval != 0) {
 791791                         branch((int)q->n_lval); /* branch always */
 792792                         reached = 0;
 793793                 }
 794794                 tfree(p);
 795795                 tfree(q);
 796796                 return;
 797797         }
 798798         ecomp(p);
 799799 }
 800800 
 801801 NODE *
 802802 strargs(register NODE *p)
 803803 {
 804804         /* rewrite structure flavored arguments */
 805805 
 806806         if( p->n_op == CM ){
 807807                 p->n_left = strargs( p->n_left );
 808808                 p->n_right = strargs( p->n_right );
 809809                 return( p );
 810810                 }
 811811 
 812812         if( p->n_type == STRTY || p->n_type == UNIONTY ){
 813813                 p = block(STARG, p, NIL, p->n_type, p->n_df, p->n_ap);
 814814                 p->n_left = buildtree( ADDROF, p->n_left, NIL );
 815815                 p = clocal(p);
 816816                 }
 817817         return( p );
 818818 }
 819819 
 820820 /*
 821821  * apply the op o to the lval part of p; if binary, rhs is val
 822822  */
 823823 int
 824824 conval(NODE *p, int o, NODE *q)
 825825 {
 826826         TWORD tl = p->n_type, tr = q->n_type, td;
 827827         int i, u;
 828828         CONSZ val;
 829829         U_CONSZ v1, v2;
 830830 
 831831         val = q->n_lval;
 832832 
 833833         /* make both sides same type */
 834834         if (tl < BTMASK && tr < BTMASK) {
 835835                 td = tl > tr ? tl : tr;
 836836                 if (td < INT)
 837837                         td = INT;
 838838                 u = ISUNSIGNED(td);
 839839                 if (tl != td)
 840840                         p = makety(p, td, 0, 0, 0);
 841841                 if (tr != td)
 842842                         q = makety(q, td, 0, 0, 0);
 843843         } else
 844844                 u = ISUNSIGNED(tl) || ISUNSIGNED(tr);
 845845         if( u && (o==LE||o==LT||o==GE||o==GT)) o += (UGE-GE);
 846846 
 847847         if (p->n_sp != NULL && q->n_sp != NULL)
 848848                 return(0);
 849849         if (q->n_sp != NULL && o != PLUS)
 850850                 return(0);
 851851         if (p->n_sp != NULL && o != PLUS && o != MINUS)
 852852                 return(0);
 853853 
 854854         v1 = p->n_lval;
 855855         v2 = q->n_lval;
 856856         if (v2 == 0 && (cdope(o) & DIVFLG))
 857857                 return 0; /* leave division by zero to runtime */
 858858         switch( o ){
 859859 
 860860         case PLUS:
 861861                 p->n_lval += val;
 862862                 if (p->n_sp == NULL) {
 863863                         p->n_right = q->n_right;
 864864                         p->n_type = q->n_type;
 865865                 }
 866866                 break;
 867867         case MINUS:
 868868                 p->n_lval -= val;
 869869                 break;
 870870         case MUL:
 871871                 p->n_lval *= val;
 872872                 break;
 873873         case DIV:
 874874                 if (u) {
 875875                         v1 /= v2;
 876876                         p->n_lval = v1;
 877877                 } else
 878878                         p->n_lval /= val;
 879879                 break;
 880880         case MOD:
 881881                 if (u) {
 882882                         v1 %= v2;
 883883                         p->n_lval = v1;
 884884                 } else
 885885                         p->n_lval %= val;
 886886                 break;
 887887         case AND:
 888888                 p->n_lval &= val;
 889889                 break;
 890890         case OR:
 891891                 p->n_lval |= val;
 892892                 break;
 893893         case ER:
 894894                 p->n_lval ^= val;
 895895                 break;
 896896         case LS:
 897897                 i = (int)val;
 898898                 p->n_lval = p->n_lval << i;
 899899                 break;
 900900         case RS:
 901901                 i = (int)val;
 902902                 if (u) {
 903903                         v1 = v1 >> i;
 904904                         p->n_lval = v1;
 905905                 } else
 906906                         p->n_lval = p->n_lval >> i;
 907907                 break;
 908908 
 909909         case UMINUS:
 910910                 p->n_lval = - p->n_lval;
 911911                 break;
 912912         case COMPL:
 913913                 p->n_lval = ~p->n_lval;
 914914                 break;
 915915         case NOT:
 916916                 p->n_lval = !p->n_lval;
 917917                 break;
 918918         case LT:
 919919                 p->n_lval = p->n_lval < val;
 920920                 break;
 921921         case LE:
 922922                 p->n_lval = p->n_lval <= val;
 923923                 break;
 924924         case GT:
 925925                 p->n_lval = p->n_lval > val;
 926926                 break;
 927927         case GE:
 928928                 p->n_lval = p->n_lval >= val;
 929929                 break;
 930930         case ULT:
 931931                 p->n_lval = v1 < v2;
 932932                 break;
 933933         case ULE:
 934934                 p->n_lval = v1 <= v2;
 935935                 break;
 936936         case UGT:
 937937                 p->n_lval = v1 > v2;
 938938                 break;
 939939         case UGE:
 940940                 p->n_lval = v1 >= v2;
 941941                 break;
 942942         case EQ:
 943943                 p->n_lval = p->n_lval == val;
 944944                 break;
 945945         case NE:
 946946                 p->n_lval = p->n_lval != val;
 947947                 break;
 948948         case ANDAND:
 949949                 p->n_lval = p->n_lval && val;
 950950                 break;
 951951         case OROR:
 952952                 p->n_lval = p->n_lval || val;
 953953                 break;
 954954         default:
 955955                 return(0);
 956956                 }
 957957         /* Do the best in making everything type correct after calc */
 958958         if (p->n_sp == NULL && q->n_sp == NULL)
 959959                 p->n_lval = valcast(p->n_lval, p->n_type);
 960960         return(1);
 961961         }
 962962 
 963963 /*
 964964  * Ensure that v matches the type t; sign- or zero-extended
 965965  * as suitable to CONSZ.
 966966  * Only to be used for integer types.
 967967  */
 968968 CONSZ
 969969 valcast(CONSZ v, TWORD t)
 970970 {
 971971         CONSZ r;
 972972         int sz;
 973973 
 974974         if (t < CHAR || t > ULONGLONG)
 975975                 return v; /* cannot cast */
 976976 
 977977         if (t >= LONGLONG)
 978978                 return v; /* already largest */
 979979 
 980980 #define M(x)    ((((1ULL << ((x)-1)) - 1) << 1) + 1)
 981981 #define NOTM(x) (~M(x))
 982982 #define SBIT(x) (1ULL << ((x)-1))
 983983 
 984984         sz = (int)tsize(t, NULL, NULL);
 985985         r = v & M(sz);
 986986         if (!ISUNSIGNED(t) && (SBIT(sz) & r))
 987987                 r = r | NOTM(sz);
 988988         return r;
 989989 }
 990990 
 991991 /*
 992992  * Checks p for the existance of a pun.  This is called when the op of p
 993993  * is ASSIGN, RETURN, CAST, COLON, or relational.
 994994  * One case is when enumerations are used: this applies only to lint.
 995995  * In the other case, one operand is a pointer, the other integer type
 996996  * we check that this integer is in fact a constant zero...
 997997  * in the case of ASSIGN, any assignment of pointer to integer is illegal
 998998  * this falls out, because the LHS is never 0.
 999999  * XXX - check for COMOPs in assignment RHS?
 10001000  */
 10011001 void
 10021002 chkpun(NODE *p)
 10031003 {
 10041004         union dimfun *d1, *d2;
 10051005         NODE *q;
 10061006         int t1, t2;
 10071007 
 10081008         t1 = p->n_left->n_type;
 10091009         t2 = p->n_right->n_type;
 10101010 
 10111011         switch (p->n_op) {
 10121012         case RETURN:
 10131013                 /* return of void allowed but nothing else */
 10141014                 if (t1 == VOID && t2 == VOID)
 10151015                         return;
 10161016                 if (t1 == VOID) {
 10171017                         werror("returning value from void function");
 10181018                         return;
 10191019                 }
 10201020                 if (t2 == VOID) {
 10211021                         uerror("using void value");
 10221022                         return;
 10231023                 }
 10241024                 break;
 10251025         case COLON:
 10261026                 if (t1 == VOID && t2 == VOID)
 10271027                         return;
 10281028                 break;
 10291029         default:
 10301030                 if ((t1 == VOID && t2 != VOID) || (t1 != VOID && t2 == VOID)) {
 10311031                         uerror("value of void expression used");
 10321032                         return;
 10331033                 }
 10341034                 break;
 10351035         }
 10361036 
 10371037         /* allow void pointer assignments in any direction */
 10381038         if (BTYPE(t1) == VOID && (t2 & TMASK))
 10391039                 return;
 10401040         if (BTYPE(t2) == VOID && (t1 & TMASK))
 10411041                 return;
 10421042 
 10431043         /* boolean have special syntax */
 10441044         if (t1 == BOOL) {
 10451045                 if (!ISARY(t2)) /* Anything scalar */
 10461046                         return;
 10471047         }
 10481048 
 10491049         if (ISPTR(t1) || ISARY(t1))
 10501050                 q = p->n_right;
 10511051         else
 10521052                 q = p->n_left;
 10531053 
 10541054         if (!ISPTR(q->n_type) && !ISARY(q->n_type)) {
 10551055                 if (q->n_op != ICON || q->n_lval != 0)
 10561056                         werror("illegal combination of pointer and integer");
 10571057         } else {
 10581058                 if (t1 == t2) {
 10591059                         if (ISSOU(BTYPE(t1)) &&
 10601060                             !suemeq(p->n_left->n_ap, p->n_right->n_ap))
 10611061                                 werror("illegal structure pointer combination");
 10621062                         return;
 10631063                 }
 10641064                 d1 = p->n_left->n_df;
 10651065                 d2 = p->n_right->n_df;
 10661066                 for (;;) {
 10671067                         if (ISARY(t1) || ISPTR(t1)) {
 10681068                                 if (!ISARY(t2) && !ISPTR(t2))
 10691069                                         break;
 10701070                                 if (ISARY(t1) && ISARY(t2) && d1->ddim != d2->ddim) {
 10711071                                         werror("illegal array size combination");
 10721072                                         return;
 10731073                                 }
 10741074                                 if (ISARY(t1))
 10751075                                         ++d1;
 10761076                                 if (ISARY(t2))
 10771077                                         ++d2;
 10781078                         } else if (ISFTN(t1)) {
 10791079                                 if (chkftn(d1->dfun, d2->dfun)) {
 10801080                                         werror("illegal function "
 10811081                                             "pointer combination");
 10821082                                         return;
 10831083                                 }
 10841084                                 ++d1;
 10851085                                 ++d2;
 10861086                         } else
 10871087                                 break;
 10881088                         t1 = DECREF(t1);
 10891089                         t2 = DECREF(t2);
 10901090                 }
 10911091                 if (DEUNSIGN(t1) != DEUNSIGN(t2))
 10921092                         warner(Wpointer_sign, NULL);
 10931093         }
 10941094 }
 10951095 
 10961096 static NODE *
 10971097 offplus(NODE *p, int off, TWORD t, TWORD q, union dimfun *d, struct attr *ap) {
 10981098         if (off != 0) {
 10991099                 p = block(PLUS, p, offcon(off, t, d, ap), t, d, ap);
 11001100                 p->n_qual = q;
 11011101                 p = optim(p);
 11021102         }
 11031103 
 11041104         return buildtree(UMUL, p, NIL);
 11051105 }
 11061106 
 11071107 NODE *
 11081108 stref(NODE *p)
 11091109 {
 11101110         NODE *r;
 11111111         struct attr *ap, *xap, *yap;
 11121112         union dimfun *d;
 11131113         TWORD t, q;
 11141114         int dsc;
 11151115         OFFSZ off;
 11161116         struct symtab *s;
 11171117 
 11181118         /* make p->x */
 11191119         /* this is also used to reference automatic variables */
 11201120 
 11211121         s = p->n_right->n_sp;
 11221122         nfree(p->n_right);
 11231123         r = nfree(p);
 11241124         xap = attr_find(r->n_ap, GCC_ATYP_PACKED);
 11251125 
 11261126         p = pconvert(r);
 11271127 
 11281128         /* make p look like ptr to x */
 11291129 
 11301130         if (!ISPTR(p->n_type))
 11311131                 p->n_type = PTR+UNIONTY;
 11321132 
 11331133         t = INCREF(s->stype);
 11341134         q = INCQAL(s->squal);
 11351135         d = s->sdf;
 11361136         ap = s->sap;
 11371137         if ((yap = attr_find(ap, GCC_ATYP_PACKED)) != NULL)
 11381138                 xap = yap;
 11391139         else if (xap != NULL)
 11401140                 ap = attr_add(ap, attr_dup(xap, 3));
 11411141         /* xap set if packed struct */
 11421142 
 11431143         p = makety(p, t, q, d, ap);
 11441144         if (ISFTN(s->stype)) {
 11451145                 /* direct class call */
 11461146                 p = block(NMLIST, p, nametree(s), INT, 0, 0);
 11471147                 return p;
 11481148         }
 11491149 
 11501150         /* compute the offset to be added */
 11511151 
 11521152         off = s->soffset;
 11531153         dsc = s->sclass;
 11541154 
 11551155         if (dsc & FIELD) {
 11561156                 TWORD ftyp = s->stype;
 11571157                 int fal = talign(ftyp, ap);
 11581158                 off = (off/fal)*fal;
 11591159                 p = offplus(p, off, t, q, d, ap);
 11601160                 p = block(FLD, p, NIL, ftyp, 0, ap);
 11611161                 p->n_qual = q;
 11621162                 p->n_rval = PKFIELD(dsc&FLDSIZ, s->soffset%fal);
 11631163         } else {
 11641164                 p = offplus(p, off, t, q, d, ap);
 11651165 #ifndef CAN_UNALIGN
 11661166                 /* if target cannot handle unaligned addresses, fix here */
 11671167 #endif
 11681168         }
 11691169 
 11701170         p = clocal(p);
 11711171         return p;
 11721172 }
 11731173 
 11741174 int
 11751175 notlval(register NODE *p)
 11761176 {
 11771177         /* return 0 if p an lvalue, 1 otherwise */
 11781178 
 11791179         again:
 11801180 
 11811181         switch( p->n_op ){
 11821182 
 11831183         case FLD:
 11841184                 p = p->n_left;
 11851185                 goto again;
 11861186 
 11871187         case NAME:
 11881188         case OREG:
 11891189         case UMUL:
 11901190                 if( ISARY(p->n_type) || ISFTN(p->n_type) ) return(1);
 11911191         case TEMP:
 11921192         case REG:
 11931193                 return(0);
 11941194 
 11951195         default:
 11961196                 return(1);
 11971197         }
 11981198 }
 11991199 
 12001200 /* make a constant node with value i */
 12011201 NODE *
 12021202 bcon(int i)
 12031203 {
 12041204         return xbcon(i, NULL, INT);
 12051205 }
 12061206 
 12071207 NODE *
 12081208 xbcon(CONSZ val, struct symtab *sp, TWORD type)
 12091209 {
 12101210         NODE *p;
 12111211 
 12121212         p = block(ICON, NIL, NIL, type, 0, 0);
 12131213         p->n_lval = val;
 12141214         p->n_sp = sp;
 12151215         return clocal(p);
 12161216 }
 12171217 
 12181218 NODE *
 12191219 bpsize(NODE *p)
 12201220 {
 12211221         int isdyn(struct symtab *sp);
 12221222         struct symtab s;
 12231223         NODE *q, *r;
 12241224         TWORD t;
 12251225         int sz;
 12261226 
 12271227         s.stype = DECREF(p->n_type);
 12281228         s.sdf = p->n_df;
 12291229         if (isdyn(&s)) {
 12301230                 q = bcon(1);
 12311231                 for (t = s.stype; t > BTMASK; t = DECREF(t)) {
 12321232                         if (ISPTR(t))
 12331233                                 return buildtree(MUL, q, bcon(SZPOINT(t)));
 12341234                         if (ISARY(t)) {
 12351235                                 if (s.sdf->ddim < 0)
 12361236                                         r = tempnode(-s.sdf->ddim, INT, 0, 0);
 12371237                                 else
 12381238                                         r = bcon(s.sdf->ddim/SZCHAR);
 12391239                                 q = buildtree(MUL, q, r);
 12401240                                 s.sdf++;
 12411241                         }
 12421242                 }
 12431243                 sz = (int)tsize(p->n_type, p->n_df, p->n_ap);
 12441244                 p = buildtree(MUL, q, bcon(sz/SZCHAR));
 12451245         } else
 12461246                 p = (offcon(psize(p), p->n_type, p->n_df, p->n_ap));
 12471247         return p;
 12481248 }
 12491249 
 12501250 /*
 12511251  * p is a node of type pointer; psize returns the
 12521252  * size of the thing pointed to
 12531253  */
 12541254 OFFSZ
 12551255 psize(NODE *p)
 12561256 {
 12571257 
 12581258         if (!ISPTR(p->n_type)) {
 12591259                 uerror("pointer required");
 12601260                 return(SZINT);
 12611261         }
 12621262         /* note: no pointers to fields */
 12631263         return(tsize(DECREF(p->n_type), p->n_df, p->n_ap));
 12641264 }
 12651265 
 12661266 /*
 12671267  * convert an operand of p
 12681268  * f is either CVTL or CVTR
 12691269  * operand has type int, and is converted by the size of the other side
 12701270  * convert is called when an integer is to be added to a pointer, for
 12711271  * example in arrays or structures.
 12721272  */
 12731273 NODE *
 12741274 convert(NODE *p, int f)
 12751275 {
 12761276         union dimfun *df;
 12771277         TWORD ty, ty2;
 12781278         NODE *q, *r, *s, *rv;
 12791279 
 12801280         if (f == CVTL) {
 12811281                 q = p->n_left;
 12821282                 s = p->n_right;
 12831283         } else {
 12841284                 q = p->n_right;
 12851285                 s = p->n_left;
 12861286         }
 12871287         ty2 = ty = DECREF(s->n_type);
 12881288         while (ISARY(ty))
 12891289                 ty = DECREF(ty);
 12901290 
 12911291         r = offcon(tsize(ty, s->n_df, s->n_ap), s->n_type, s->n_df, s->n_ap);
 12921292         ty = ty2;
 12931293         rv = bcon(1);
 12941294         df = s->n_df;
 12951295         while (ISARY(ty)) {
 12961296                 rv = buildtree(MUL, rv, df->ddim >= 0 ? bcon(df->ddim) :
 12971297                     tempnode(-df->ddim, INT, 0, 0));
 12981298                 df++;
 12991299                 ty = DECREF(ty);
 13001300         }
 13011301         rv = clocal(MBLOCK(rv, r, INT, 0, 0));
 13021302         rv = optim(rv);
 13031303 
 13041304         r = MBLOCK(q, rv, INT, 0, 0);
 13051305         r = clocal(r);
 13061306         /*
 13071307          * Indexing is only allowed with integer arguments, so insert
 13081308          * SCONV here if arg is not an integer.
 13091309          * XXX - complain?
 13101310          */
 13111311         if (r->n_type != INTPTR)
 13121312                 r = clocal(makety(r, INTPTR, 0, 0, 0));
 13131313         if (f == CVTL)
 13141314                 p->n_left = r;
 13151315         else
 13161316                 p->n_right = r;
 13171317         return(p);
 13181318 }
 13191319 
 13201320 NODE *
 13211321 pconvert(register NODE *p)
 13221322 {
 13231323         /* if p should be changed into a pointer, do so */
 13241324 
 13251325         if( ISARY( p->n_type) ){
 13261326                 p->n_type = DECREF( p->n_type );
 13271327                 ++p->n_df;
 13281328                 return( buildtree( ADDROF, p, NIL ) );
 13291329         }
 13301330         if( ISFTN( p->n_type) )
 13311331                 return( buildtree( ADDROF, p, NIL ) );
 13321332 
 13331333         return( p );
 13341334 }
 13351335 
 13361336 NODE *
 13371337 oconvert(register NODE *p)
 13381338 {
 13391339         /* convert the result itself: used for pointer and unsigned */
 13401340 
 13411341         switch(p->n_op) {
 13421342 
 13431343         case LE:
 13441344         case LT:
 13451345         case GE:
 13461346         case GT:
 13471347                 if(ISUNSIGNED(p->n_left->n_type) ||
 13481348                     ISUNSIGNED(p->n_right->n_type) ||
 13491349                     ISPTR(p->n_left->n_type) ||
 13501350                     ISPTR(p->n_right->n_type))
 13511351                          p->n_op += (ULE-LE);
 13521352                 /* FALLTHROUGH */
 13531353         case EQ:
 13541354         case NE:
 13551355                 return( p );
 13561356 
 13571357         case MINUS:
 13581358                 p->n_type = INTPTR;
 13591359                 p->n_ap = NULL;
 13601360                 return(clocal(VBLOCK(p, bpsize(p->n_left), INT, 0, 0)));
 13611361                 }
 13621362 
 13631363         cerror( "illegal oconvert: %d", p->n_op );
 13641364 
 13651365         return(p);
 13661366 }
 13671367 
 13681368 /*
 13691369  * makes the operands of p agree; they are
 13701370  * either pointers or integers, by this time
 13711371  * with MINUS, the sizes must be the same
 13721372  * with COLON, the types must be the same
 13731373  */
 13741374 NODE *
 13751375 ptmatch(NODE *p)
 13761376 {
 13771377         struct attr *ap, *ap2;
 13781378         union dimfun *d, *d2;
 13791379         TWORD t1, t2, t, q1, q2, q;
 13801380         int o;
 13811381 
 13821382         o = p->n_op;
 13831383         t = t1 = p->n_left->n_type;
 13841384         q = q1 = p->n_left->n_qual;
 13851385         t2 = p->n_right->n_type;
 13861386         q2 = p->n_right->n_qual;
 13871387         d = p->n_left->n_df;
 13881388         d2 = p->n_right->n_df;
 13891389         ap = p->n_left->n_ap;
 13901390         ap2 = p->n_right->n_ap;
 13911391 
 13921392         switch( o ){
 13931393 
 13941394         case ASSIGN:
 13951395         case RETURN:
 13961396                 {  break; }
 13971397 
 13981398         case CAST:
 13991399                 if (t == VOID) {
 14001400                         /* just paint over */
 14011401                         p->n_right = block(SCONV, p->n_right, NIL, VOID, 0, 0);
 14021402                         return p;
 14031403                 }
 14041404                 break;
 14051405 
 14061406         case MINUS: {
 14071407                 int isdyn(struct symtab *sp);
 14081408                 struct symtab s1, s2;
 14091409 
 14101410                 s1.stype = DECREF(t);
 14111411                 s1.sdf = d;
 14121412                 s2.stype = DECREF(t2);
 14131413                 s2.sdf = d2;
 14141414                 if (isdyn(&s1) || isdyn(&s2))
 14151415                         ; /* We don't know */
 14161416                 else if (psize(p->n_left) != psize(p->n_right))
 14171417                         uerror("illegal pointer subtraction");
 14181418                 break;
 14191419                 }
 14201420 
 14211421         case COLON:
 14221422                 if (t1 != t2) {
 14231423                         /*
 14241424                          * Check for void pointer types. They are allowed
 14251425                          * to cast to/from any pointers.
 14261426                          */
 14271427                         if (ISPTR(t1) && ISPTR(t2) &&
 14281428                             (BTYPE(t1) == VOID || BTYPE(t2) == VOID))
 14291429                                 break;
 14301430                         uerror("illegal types in :");
 14311431                 }
 14321432                 break;
 14331433 
 14341434         default/* must work harder: relationals or comparisons */
 14351435 
 14361436                 if( !ISPTR(t1) ){
 14371437                         t = t2;
 14381438                         q = q2;
 14391439                         d = d2;
 14401440                         ap = ap2;
 14411441                         break;
 14421442                         }
 14431443                 if( !ISPTR(t2) ){
 14441444                         break;
 14451445                         }
 14461446 
 14471447                 /* both are pointers */
 14481448                 if( talign(t2,ap2) < talign(t,ap) ){
 14491449                         t = t2;
 14501450                         q = q2;
 14511451                         ap = ap2;
 14521452                         }
 14531453                 break;
 14541454                 }
 14551455 
 14561456         p->n_left = makety( p->n_left, t, q, d, ap );
 14571457         p->n_right = makety( p->n_right, t, q, d, ap );
 14581458         if( o!=MINUS && !clogop(o) ){
 14591459 
 14601460                 p->n_type = t;
 14611461                 p->n_qual = q;
 14621462                 p->n_df = d;
 14631463                 p->n_ap = ap;
 14641464                 }
 14651465 
 14661466         return(clocal(p));
 14671467 }
 14681468 
 14691469 /*
 14701470  * Satisfy the types of various arithmetic binary ops.
 14711471  *
 14721472  * rules are:
 14731473  *  if assignment, type of LHS
 14741474  *  if any doubles, make double
 14751475  *  else if any float make float
 14761476  *  else if any longlongs, make long long
 14771477  *  else if any longs, make long
 14781478  *  else etcetc.
 14791479  *
 14801480  *  If the op with the highest rank is unsigned, this is the resulting type.
 14811481  *  See:  6.3.1.1 rank order equal of signed and unsigned types
 14821482  *        6.3.1.8 Usual arithmetic conversions
 14831483  */
 14841484 static NODE *
 14851485 tymatch(NODE *p)
 14861486 {
 14871487         TWORD tl, tr, t;
 14881488         NODE *l, *r;
 14891489         int o;
 14901490 
 14911491         o = p->n_op;
 14921492         r = p->n_right;
 14931493         l = p->n_left;
 14941494 
 14951495         tl = l->n_type;
 14961496         tr = r->n_type;
 14971497 
 14981498         if (tl == BOOL) tl = BOOL_TYPE;
 14991499         if (tr == BOOL) tr = BOOL_TYPE;
 15001500 
 15011501         if (casgop(o)) {
 15021502                 if (r->n_op != ICON && tl < FLOAT && tr < FLOAT &&
 15031503                     DEUNSIGN(tl) < DEUNSIGN(tr) && o != CAST)
 15041504                         warner(Wtruncate, tnames[tr], tnames[tl]);
 15051505                 p->n_right = makety(p->n_right, l->n_type, 0, 0, 0);
 15061506                 t = p->n_type = l->n_type;
 15071507                 p->n_ap = l->n_ap;
 15081508         } else {
 15091509                 t = tl > tr ? tl : tr; /* MAX */
 15101510                 /* This depends on ctype() called early */
 15111511                 if (o != COLON && t < INT)
 15121512                         t = INT;
 15131513                 if (tl != t) p->n_left = makety(p->n_left, t, 0, 0, 0);
 15141514                 if (tr != t) p->n_right = makety(p->n_right, t, 0, 0, 0);
 15151515                 if (o == COLON && l->n_type == BOOL && r->n_type == BOOL)
 15161516                         t = p->n_type = BOOL;
 15171517                 else if (!clogop(o))
 15181518                         p->n_type = t;
 15191519         }
 15201520 #ifdef PCC_DEBUG
 15211521         if (tdebug) {
 15221522                 printf("tymatch(%p): ", p);
 15231523                 tprint(tl, 0);
 15241524                 printf(" %s ", copst(o));
 15251525                 tprint(tr, 0);
 15261526                 printf(" => ");
 15271527                 tprint(t, 0);
 15281528                 printf("\n");
 15291529                 fwalk(p, eprint, 0);
 15301530         }
 15311531 #endif
 15321532         return p;
 15331533 }
 15341534 
 15351535 /*
 15361536  * make p into type t by inserting a conversion
 15371537  */
 15381538 NODE *
 15391539 makety(NODE *p, TWORD t, TWORD q, union dimfun *d, struct attr *ap)
 15401540 {
 15411541 
 15421542         if (t == p->n_type) {
 15431543                 p->n_df = d;
 15441544                 p->n_ap = ap;
 15451545                 p->n_qual = q;
 15461546                 return(p);
 15471547         }
 15481548 
 15491549         if (ISITY(t) || ISCTY(t) || ISITY(p->n_type) || ISCTY(p->n_type))
 15501550                 cerror("makety");
 15511551 
 15521552         if (concast(p, t))
 15531553                 return clocal(p);
 15541554 
 15551555         p = block(t & TMASK ? PCONV : SCONV, p, NIL, t, d, ap);
 15561556         p->n_qual = q;
 15571557         return clocal(p);
 15581558 }
 15591559 
 15601560 NODE *
 15611561 block(int o, NODE *l, NODE *r, TWORD t, union dimfun *d, struct attr *ap)
 15621562 {
 15631563         register NODE *p;
 15641564 
 15651565         p = talloc();
 15661566         p->n_rval = 0;
 15671567         p->n_op = o;
 15681568         p->n_lval = 0; /* Protect against large lval */
 15691569         p->n_left = l;
 15701570         p->n_right = r;
 15711571         p->n_type = t;
 15721572         p->n_qual = 0;
 15731573         p->n_df = d;
 15741574         p->n_ap = ap;
 15751575 #if !defined(MULTIPASS)
 15761576         /* p->n_reg = */p->n_su = 0;
 15771577         p->n_regw = 0;
 15781578 #endif
 15791579         return(p);
 15801580 }
 15811581 
 15821582 /*
 15831583  * Return the constant value from an ICON.
 15841584  */
 15851585 CONSZ
 15861586 icons(NODE *p)
 15871587 {
 15881588         /* if p is an integer constant, return its value */
 15891589         CONSZ val;
 15901590 
 15911591         if (p->n_op != ICON || p->n_sp != NULL) {
 15921592                 uerror( "constant expected");
 15931593                 val = 1;
 15941594         } else
 15951595                 val = p->n_lval;
 15961596         tfree(p);
 15971597         return(val);
 15981598 }
 15991599 
 16001600 /*
 16011601  * the intent of this table is to examine the
 16021602  * operators, and to check them for
 16031603  * correctness.
 16041604  *
 16051605  * The table is searched for the op and the
 16061606  * modified type (where this is one of the
 16071607  * types INT (includes char and short), LONG,
 16081608  * DOUBLE (includes FLOAT), and POINTER
 16091609  *
 16101610  * The default action is to make the node type integer
 16111611  *
 16121612  * The actions taken include:
 16131613  *      PUN       check for puns
 16141614  *      CVTL      convert the left operand
 16151615  *      CVTR      convert the right operand
 16161616  *      TYPL      the type is determined by the left operand
 16171617  *      TYPR      the type is determined by the right operand
 16181618  *      TYMATCH   force type of left and right to match,by inserting conversions
 16191619  *      PTMATCH   like TYMATCH, but for pointers
 16201620  *      LVAL      left operand must be lval
 16211621  *      CVTO      convert the op
 16221622  *      NCVT      do not convert the operands
 16231623  *      OTHER     handled by code
 16241624  *      NCVTR     convert the left operand, not the right...
 16251625  *
 16261626  */
 16271627 
 16281628 # define MINT 01        /* integer */
 16291629 # define MDBI 02        /* integer or double */
 16301630 # define MSTR 04        /* structure */
 16311631 # define MPTR 010       /* pointer */
 16321632 # define MPTI 020       /* pointer or integer */
 16331633 
 16341634 int
 16351635 opact(NODE *p)
 16361636 {
 16371637         int mt12, mt1, mt2, o;
 16381638 
 16391639         mt1 = mt2 = mt12 = 0;
 16401640 
 16411641         switch (coptype(o = p->n_op)) {
 16421642         case BITYPE:
 16431643                 mt12=mt2 = moditype(p->n_right->n_type);
 16441644                 /* FALLTHROUGH */
 16451645         case UTYPE:
 16461646                 mt12 &= (mt1 = moditype(p->n_left->n_type));
 16471647                 break;
 16481648         }
 16491649 
 16501650         switch( o ){
 16511651 
 16521652         case NAME :
 16531653         case ICON :
 16541654         case FCON :
 16551655         case CALL :
 16561656         case UCALL:
 16571657         case UMUL:
 16581658                 {  return( OTHER ); }
 16591659         case UMINUS:
 16601660                 if( mt1 & MDBI ) return( TYPL+PROML );
 16611661                 break;
 16621662 
 16631663         case COMPL:
 16641664                 if( mt1 & MINT ) return( TYPL+PROML );
 16651665                 break;
 16661666 
 16671667         case ADDROF:
 16681668                 return( NCVT+OTHER );
 16691669         case NOT:
 16701670                 return( PROML );
 16711671 
 16721672 /*      case INIT: */
 16731673         case CM:
 16741674         case CBRANCH:
 16751675         case ANDAND:
 16761676         case OROR:
 16771677                 return( 0 );
 16781678 
 16791679         case MUL:
 16801680         case DIV:
 16811681                 if( mt12 & MDBI ) return( TYMATCH );
 16821682                 break;
 16831683 
 16841684         case MOD:
 16851685         case AND:
 16861686         case OR:
 16871687         case ER:
 16881688                 if( mt12 & MINT ) return( TYMATCH );
 16891689                 break;
 16901690 
 16911691         case LS:
 16921692         case RS:
 16931693                 if( mt12 & MINT ) return( TYPL+OTHER );
 16941694                 break;
 16951695 
 16961696         case EQ:
 16971697         case NE:
 16981698         case LT:
 16991699         case LE:
 17001700         case GT:
 17011701         case GE:
 17021702                 if( mt12 & MDBI ) return( TYMATCH+CVTO );
 17031703                 else if( mt12 & MPTR ) return( PTMATCH+PUN+CVTO );
 17041704                 else if( mt12 & MPTI ) return( PTMATCH+PUN );
 17051705                 else break;
 17061706 
 17071707         case QUEST:
 17081708                 return( TYPR+OTHER );
 17091709         case COMOP:
 17101710                 return( TYPR );
 17111711 
 17121712         case STREF:
 17131713                 return( NCVTR+OTHER );
 17141714 
 17151715         case FORCE:
 17161716                 return( TYPL );
 17171717 
 17181718         case COLON:
 17191719                 if( mt12 & MDBI ) return( TYMATCH );
 17201720                 else if( mt12 & MPTR ) return( TYPL+PTMATCH+PUN );
 17211721                 else if( (mt1&MINT) && (mt2&MPTR) ) return( TYPR+PUN );
 17221722                 else if( (mt1&MPTR) && (mt2&MINT) ) return( TYPL+PUN );
 17231723                 else if( mt12 & MSTR ) return( NCVT+TYPL+OTHER );
 17241724                 break;
 17251725 
 17261726         case ASSIGN:
 17271727         case RETURN:
 17281728                 if( mt12 & MSTR ) return( LVAL+NCVT+TYPL+OTHER );
 17291729         case CAST:
 17301730                 if( mt12 & MDBI ) return( TYPL+LVAL+TYMATCH );
 17311731                 else if( mt1 & MPTR) return( LVAL+PTMATCH+PUN );
 17321732                 else if( mt12 & MPTI ) return( TYPL+LVAL+TYMATCH+PUN );
 17331733                 break;
 17341734 
 17351735         case LSEQ:
 17361736         case RSEQ:
 17371737                 if( mt12 & MINT ) return( TYPL+LVAL+OTHER );
 17381738                 break;
 17391739 
 17401740         case MULEQ:
 17411741         case DIVEQ:
 17421742                 if( mt12 & MDBI ) return( LVAL+TYMATCH );
 17431743                 break;
 17441744 
 17451745         case MODEQ:
 17461746         case ANDEQ:
 17471747         case OREQ:
 17481748         case EREQ:
 17491749                 if (mt12 & MINT)
 17501750                         return(LVAL+TYMATCH);
 17511751                 break;
 17521752 
 17531753         case PLUSEQ:
 17541754         case MINUSEQ:
 17551755         case INCR:
 17561756         case DECR:
 17571757                 if (mt12 & MDBI)
 17581758                         return(TYMATCH+LVAL);
 17591759                 else if ((mt1&MPTR) && (mt2&MINT))
 17601760                         return(TYPL+LVAL+CVTR);
 17611761                 break;
 17621762 
 17631763         case MINUS:
 17641764                 if (mt12 & MPTR)
 17651765                         return(CVTO+PTMATCH+PUN);
 17661766                 if (mt2 & MPTR)
 17671767                         break;
 17681768                 /* FALLTHROUGH */
 17691769         case PLUS:
 17701770                 if (mt12 & MDBI)
 17711771                         return(TYMATCH);
 17721772                 else if ((mt1&MPTR) && (mt2&MINT))
 17731773                         return(TYPL+CVTR);
 17741774                 else if ((mt1&MINT) && (mt2&MPTR))
 17751775                         return(TYPR+CVTL);
 17761776 
 17771777         }
 17781778         uerror("operands of %s have incompatible types", copst(o));
 17791779         return(NCVT);
 17801780 }
 17811781 
 17821782 int
 17831783 moditype(TWORD ty)
 17841784 {
 17851785         switch (ty) {
 17861786 
 17871787         case STRTY:
 17881788         case UNIONTY:
 17891789                 return( MSTR );
 17901790 
 17911791         case BOOL:
 17921792         case CHAR:
 17931793         case SHORT:
 17941794         case UCHAR:
 17951795         case USHORT:
 17961796         case UNSIGNED:
 17971797         case ULONG:
 17981798         case ULONGLONG:
 17991799         case INT:
 18001800         case LONG:
 18011801         case LONGLONG:
 18021802                 return( MINT|MDBI|MPTI );
 18031803         case FLOAT:
 18041804         case DOUBLE:
 18051805         case LDOUBLE:
 18061806 #ifndef NO_COMPLEX
 18071807         case FCOMPLEX:
 18081808         case COMPLEX:
 18091809         case LCOMPLEX:
 18101810         case FIMAG:
 18111811         case IMAG:
 18121812         case LIMAG:
 18131813 #endif
 18141814                 return( MDBI );
 18151815         default:
 18161816                 return( MPTR|MPTI );
 18171817 
 18181818         }
 18191819 }
 18201820 
 18211821 int tvaloff = MAXREGS+NPERMREG > 100 ? MAXREGS+NPERMREG + 100 : 100;
 18221822 
 18231823 /*
 18241824  * Returns a TEMP node with temp number nr.
 18251825  * If nr == 0, return a node with a new number.
 18261826  */
 18271827 NODE *
 18281828 tempnode(int nr, TWORD type, union dimfun *df, struct attr *ap)
 18291829 {
 18301830         NODE *r;
 18311831 
 18321832         if (tvaloff == -NOOFFSET)
 18331833                 tvaloff++; /* Skip this for array indexing */
 18341834         r = block(TEMP, NIL, NIL, type, df, ap);
 18351835         regno(r) = nr ? nr : tvaloff;
 18361836         tvaloff += szty(type);
 18371837         return r;
 18381838 }
 18391839 
 18401840 /*
 18411841  * Do sizeof on p.
 18421842  */
 18431843 NODE *
 18441844 doszof(NODE *p)
 18451845 {
 18461846         extern NODE *arrstk[10];
 18471847         extern int arrstkp;
 18481848         union dimfun *df;
 18491849         TWORD ty;
 18501850         NODE *rv, *q;
 18511851         int astkp;
 18521852 
 18531853         if (p->n_op == FLD)
 18541854                 uerror("can't apply sizeof to bit-field");
 18551855 
 18561856         /*
 18571857          * Arrays may be dynamic, may need to make computations.
 18581858          */
 18591859 
 18601860         rv = bcon(1);
 18611861         df = p->n_df;
 18621862         ty = p->n_type;
 18631863         astkp = 0;
 18641864         while (ISARY(ty)) {
 18651865                 if (df->ddim == NOOFFSET)
 18661866                         uerror("sizeof of incomplete type");
 18671867                 if (df->ddim < 0) {
 18681868                         if (arrstkp)
 18691869                                 q = arrstk[astkp++];
 18701870                         else
 18711871                                 q = tempnode(-df->ddim, INT, 0, 0);
 18721872                 } else
 18731873                         q = bcon(df->ddim);
 18741874                 rv = buildtree(MUL, rv, q);
 18751875                 df++;
 18761876                 ty = DECREF(ty);
 18771877         }
 18781878         rv = buildtree(MUL, rv,
 18791879             xbcon(tsize(ty, p->n_df, p->n_ap)/SZCHAR, NULL, INTPTR));
 18801880         tfree(p);
 18811881         arrstkp = 0; /* XXX - may this fail? */
 18821882         return rv;
 18831883 }
 18841884 
 18851885 #ifdef PCC_DEBUG
 18861886 void
 18871887 eprint(NODE *p, int down, int *a, int *b)
 18881888 {
 18891889         int ty;
 18901890 
 18911891         *a = *b = down+1;
 18921892         while( down > 1 ){
 18931893                 printf( "\t" );
 18941894                 down -= 2;
 18951895                 }
 18961896         if( down ) printf( "    " );
 18971897 
 18981898         ty = coptype( p->n_op );
 18991899 
 19001900         printf("%p) %s, ", p, copst(p->n_op));
 19011901         if (p->n_op == XARG || p->n_op == XASM)
 19021902                 printf("id '%s', ", p->n_name);
 19031903         if (ty == LTYPE) {
 19041904                 printf(CONFMT, p->n_lval);
 19051905                 if (p->n_op == NAME || p->n_op == ICON)
 19061906                         printf(", %p, ", p->n_sp);
 19071907                 else
 19081908                         printf(", %d, ", p->n_rval);
 19091909         }
 19101910         tprint(p->n_type, p->n_qual);
 19111911         printf( ", %p, ", p->n_df);
 19121912         dump_attr(p->n_ap);
 19131913 }
 19141914 # endif
 19151915 
 19161916 /*
 19171917  * Emit everything that should be emitted on the left side
 19181918  * of a comma operator, and remove the operator.
 19191919  * Do not traverse through QUEST, ANDAND and OROR.
 19201920  * Enable this for all targets when stable enough.
 19211921  */
 19221922 static void
 19231923 comops(NODE *p)
 19241924 {
 19251925         int o;
 19261926         NODE *q;
 19271927 
 19281928         while (p->n_op == COMOP) {
 19291929                 /* XXX hack for GCC ({ }) ops */
 19301930                 if (p->n_left->n_op == GOTO) {
 19311931                         int v = (int)p->n_left->n_left->n_lval;
 19321932                         ecomp(p->n_left);
 19331933                         plabel(v+1);
 19341934                 } else
 19351935                         ecomp(p->n_left); /* will recurse if more COMOPs */
 19361936                 q = p->n_right;
 19371937                 *p = *q;
 19381938                 nfree(q);
 19391939         }
 19401940         o = coptype(p->n_op);
 19411941         if (p->n_op == QUEST || p->n_op == ANDAND || p->n_op == OROR)
 19421942                 o = UTYPE;
 19431943         if (o != LTYPE)
 19441944                 comops(p->n_left);
 19451945         if (o == BITYPE)
 19461946                 comops(p->n_right);
 19471947 }
 19481948 
 19491949 /*
 19501950  * Walk up through the tree from the leaves,
 19511951  * removing constant operators.
 19521952  */
 19531953 static void
 19541954 logwalk(NODE *p)
 19551955 {
 19561956         int o = coptype(p->n_op);
 19571957         NODE *l, *r;
 19581958 
 19591959         l = p->n_left;
 19601960         r = p->n_right;
 19611961         switch (o) {
 19621962         case LTYPE:
 19631963                 return;
 19641964         case BITYPE:
 19651965                 logwalk(r);
 19661966                 /* FALLTHROUGH */
 19671967         case UTYPE:
 19681968                 logwalk(l);
 19691969         }
 19701970         if (!clogop(p->n_op))
 19711971                 return;
 19721972         if (p->n_op == NOT && l->n_op == ICON) {
 19731973                 p->n_lval = l->n_lval == 0;
 19741974                 nfree(l);
 19751975                 p->n_op = ICON;
 19761976         }
 19771977         if (l->n_op == ICON && r->n_op == ICON) {
 19781978                 if (conval(l, p->n_op, r) == 0) {
 19791979                         /*
 19801980                          * people sometimes tend to do really odd compares,
 19811981                          * like "if ("abc" == "def")" etc.
 19821982                          * do it runtime instead.
 19831983                          */
 19841984                 } else {
 19851985                         p->n_lval = l->n_lval;
 19861986                         p->n_op = ICON;
 19871987                         nfree(l);
 19881988                         nfree(r);
 19891989                 }
 19901990         }
 19911991 }
 19921992 
 19931993 /*
 19941994  * Removes redundant logical operators for branch conditions.
 19951995  */
 19961996 static void
 19971997 fixbranch(NODE *p, int label)
 19981998 {
 19991999 
 20002000         logwalk(p);
 20012001 
 20022002         if (p->n_op == ICON) {
 20032003                 if (p->n_lval != 0)
 20042004                         branch(label);
 20052005                 nfree(p);
 20062006         } else {
 20072007                 if (!clogop(p->n_op)) /* Always conditional */
 20082008                         p = buildtree(NE, p, bcon(0));
 20092009                 ecode(buildtree(CBRANCH, p, bcon(label)));
 20102010         }
 20112011 }
 20122012 
 20132013 /*
 20142014  * Write out logical expressions as branches.
 20152015  */
 20162016 static void
 20172017 andorbr(NODE *p, int true, int false)
 20182018 {
 20192019         NODE *q;
 20202020         int o, lab;
 20212021 
 20222022         lab = -1;
 20232023         switch (o = p->n_op) {
 20242024         case EQ:
 20252025         case NE:
 20262026                 /*
 20272027                  * Remove redundant EQ/NE nodes.
 20282028                  */
 20292029                 while (((o = p->n_left->n_op) == EQ || o == NE) &&
 20302030                     p->n_right->n_op == ICON) {
 20312031                         o = p->n_op;
 20322032                         q = p->n_left;
 20332033                         if (p->n_right->n_lval == 0) {
 20342034                                 nfree(p->n_right);
 20352035                                 *p = *q;
 20362036                                 nfree(q);
 20372037                                 if (o == EQ)
 20382038                                         p->n_op = negrel[p->n_op - EQ];
 20392039 #if 0
 20402040                                         p->n_op = NE; /* toggla */
 20412041 #endif
 20422042                         } else if (p->n_right->n_lval == 1) {
 20432043                                 nfree(p->n_right);
 20442044                                 *p = *q;
 20452045                                 nfree(q);
 20462046                                 if (o == NE)
 20472047                                         p->n_op = negrel[p->n_op - EQ];
 20482048 #if 0
 20492049                                         p->n_op = EQ; /* toggla */
 20502050 #endif
 20512051                         } else
 20522052                                 break; /* XXX - should always be false */
 20532053                         
 20542054                 }
 20552055                 /* FALLTHROUGH */
 20562056         case LE:
 20572057         case LT:
 20582058         case GE:
 20592059         case GT:
 20602060 calc:           if (true < 0) {
 20612061                         p->n_op = negrel[p->n_op - EQ];
 20622062                         true = false;
 20632063                         false = -1;
 20642064                 }
 20652065 
 20662066                 rmcops(p->n_left);
 20672067                 rmcops(p->n_right);
 20682068                 fixbranch(p, true);
 20692069                 if (false >= 0)
 20702070                         branch(false);
 20712071                 break;
 20722072 
 20732073         case ULE:
 20742074         case UGT:
 20752075                 /* Convert to friendlier ops */
 20762076                 if (nncon(p->n_right) && p->n_right->n_lval == 0)
 20772077                         p->n_op = o == ULE ? EQ : NE;
 20782078                 goto calc;
 20792079 
 20802080         case UGE:
 20812081         case ULT:
 20822082                 /* Already true/false by definition */
 20832083                 if (nncon(p->n_right) && p->n_right->n_lval == 0) {
 20842084                         if (true < 0) {
 20852085                                 o = o == ULT ? UGE : ULT;
 20862086                                 true = false;
 20872087                         }
 20882088                         rmcops(p->n_left);
 20892089                         ecode(p->n_left);
 20902090                         rmcops(p->n_right);
 20912091                         ecode(p->n_right);
 20922092                         nfree(p);
 20932093                         if (o == UGE) /* true */
 20942094                                 branch(true);
 20952095                         break;
 20962096                 }
 20972097                 goto calc;
 20982098 
 20992099         case ANDAND:
 21002100                 lab = false<0 ? getlab() : false ;
 21012101                 andorbr(p->n_left, -1, lab);
 21022102                 comops(p->n_right);
 21032103                 andorbr(p->n_right, true, false);
 21042104                 if (false < 0)
 21052105                         plabel( lab);
 21062106                 nfree(p);
 21072107                 break;
 21082108 
 21092109         case OROR:
 21102110                 lab = true<0 ? getlab() : true;
 21112111                 andorbr(p->n_left, lab, -1);
 21122112                 comops(p->n_right);
 21132113                 andorbr(p->n_right, true, false);
 21142114                 if (true < 0)
 21152115                         plabel( lab);
 21162116                 nfree(p);
 21172117                 break;
 21182118 
 21192119         case NOT:
 21202120                 andorbr(p->n_left, false, true);
 21212121                 nfree(p);
 21222122                 break;
 21232123 
 21242124         default:
 21252125                 rmcops(p);
 21262126                 if (true >= 0)
 21272127                         fixbranch(p, true);
 21282128                 if (false >= 0) {
 21292129                         if (true >= 0)
 21302130                                 branch(false);
 21312131                         else
 21322132                                 fixbranch(buildtree(EQ, p, bcon(0)), false);
 21332133                 }
 21342134         }
 21352135 }
 21362136 
 21372137 /*
 21382138  * Create a node for either TEMP or on-stack storage.
 21392139  */
 21402140 NODE *
 21412141 cstknode(TWORD t, union dimfun *df, struct attr *ap)
 21422142 {
 21432143         struct symtab *sp;
 21442144 
 21452145         /* create a symtab entry suitable for this type */
 21462146         sp = getsymtab("0hej", STEMP);
 21472147         sp->stype = t;
 21482148         sp->sdf = df;
 21492149         sp->sap = ap;
 21502150         sp->sclass = AUTO;
 21512151         sp->soffset = NOOFFSET;
 21522152         oalloc(sp, &autooff);
 21532153         return nametree(sp);
 21542154 
 21552155 }
 21562156 
 21572157 /*
 21582158  * Massage the output trees to remove C-specific nodes:
 21592159  *      COMOPs are split into separate statements.
 21602160  *      QUEST/COLON are rewritten to branches.
 21612161  *      ANDAND/OROR/NOT are rewritten to branches for lazy-evaluation.
 21622162  *      CBRANCH conditions are rewritten for lazy-evaluation.
 21632163  */
 21642164 static void
 21652165 rmcops(NODE *p)
 21662166 {
 21672167         TWORD type;
 21682168         NODE *q, *r, *tval;
 21692169         int o, ty, lbl, lbl2;
 21702170 
 21712171         tval = NIL;
 21722172         o = p->n_op;
 21732173         ty = coptype(o);
 21742174         if (BTYPE(p->n_type) == ENUMTY) { /* fixup enum */
 21752175                 struct symtab *sp = strmemb(p->n_ap);
 21762176                 MODTYPE(p->n_type, sp->stype);
 21772177                 /*
 21782178                  * XXX may fail if these are true:
 21792179                  * - variable-sized enums
 21802180                  * - non-byte-addressed targets.
 21812181                  */
 21822182                 if (BTYPE(p->n_type) == ENUMTY && ISPTR(p->n_type))
 21832183                         MODTYPE(p->n_type, INT); /* INT ok? */
 21842184         }
 21852185         switch (o) {
 21862186         case QUEST:
 21872187 
 21882188                 /*
 21892189                  * Create a branch node from ?:
 21902190                  * || and && must be taken special care of.
 21912191                  */
 21922192                 type = p->n_type;
 21932193                 andorbr(p->n_left, -1, lbl = getlab());
 21942194 
 21952195                 /* Make ASSIGN node */
 21962196                 /* Only if type is not void */
 21972197                 q = p->n_right->n_left;
 21982198                 comops(q);
 21992199                 if (type != VOID) {
 22002200                         tval = cstknode(q->n_type, q->n_df, q->n_ap);
 22012201                         q = buildtree(ASSIGN, ccopy(tval), q);
 22022202                 }
 22032203                 rmcops(q);
 22042204                 ecode(q); /* Done with assign */
 22052205                 branch(lbl2 = getlab());
 22062206                 plabel( lbl);
 22072207 
 22082208                 q = p->n_right->n_right;
 22092209                 comops(q);
 22102210                 if (type != VOID) {
 22112211                         q = buildtree(ASSIGN, ccopy(tval), q);
 22122212                 }
 22132213                 rmcops(q);
 22142214                 ecode(q); /* Done with assign */
 22152215 
 22162216                 plabel( lbl2);
 22172217 
 22182218                 nfree(p->n_right);
 22192219                 if (p->n_type != VOID) {
 22202220                         *p = *tval;
 22212221                         nfree(tval);
 22222222                 } else {
 22232223                         p->n_op = ICON;
 22242224                         p->n_lval = 0;
 22252225                         p->n_sp = NULL;
 22262226                 }
 22272227                 break;
 22282228 
 22292229         case ULE:
 22302230         case ULT:
 22312231         case UGE:
 22322232         case UGT:
 22332233         case EQ:
 22342234         case NE:
 22352235         case LE:
 22362236         case LT:
 22372237         case GE:
 22382238         case GT:
 22392239         case ANDAND:
 22402240         case OROR:
 22412241         case NOT:
 22422242 #ifdef SPECIAL_CCODES
 22432243 #error fix for private CCODES handling
 22442244 #else
 22452245                 r = talloc();
 22462246                 *r = *p;
 22472247                 andorbr(r, -1, lbl = getlab());
 22482248 
 22492249                 tval = cstknode(p->n_type, p->n_df, p->n_ap);
 22502250 
 22512251                 ecode(buildtree(ASSIGN, ccopy(tval), bcon(1)));
 22522252                 branch(lbl2 = getlab());
 22532253                 plabel( lbl);
 22542254                 ecode(buildtree(ASSIGN, ccopy(tval), bcon(0)));
 22552255                 plabel( lbl2);
 22562256 
 22572257                 *p = *tval;
 22582258                 nfree(tval);
 22592259 
 22602260 #endif
 22612261                 break;
 22622262         case CBRANCH:
 22632263                 andorbr(p->n_left, p->n_right->n_lval, -1);
 22642264                 nfree(p->n_right);
 22652265                 p->n_op = ICON; p->n_type = VOID;
 22662266                 break;
 22672267         case COMOP:
 22682268                 cerror("COMOP error");
 22692269 
 22702270         default:
 22712271                 if (ty == LTYPE)
 22722272                         return;
 22732273                 rmcops(p->n_left);
 22742274                 if (ty == BITYPE)
 22752275                         rmcops(p->n_right);
 22762276        }
 22772277 }
 22782278 
 22792279 /*
 22802280  * Return 1 if an assignment is found.
 22812281  */
 22822282 static int
 22832283 has_se(NODE *p)
 22842284 {
 22852285         if (cdope(p->n_op) & ASGFLG)
 22862286                 return 1;
 22872287         if (coptype(p->n_op) == LTYPE)
 22882288                 return 0;
 22892289         if (has_se(p->n_left))
 22902290                 return 1;
 22912291         if (coptype(p->n_op) == BITYPE)
 22922292                 return has_se(p->n_right);
 22932293         return 0;
 22942294 }
 22952295 
 22962296 /*
 22972297  * Find and convert asgop's to separate statements.
 22982298  * Be careful about side effects.
 22992299  * assign tells whether ASSIGN should be considered giving
 23002300  * side effects or not.
 23012301  */
 23022302 static NODE *
 23032303 delasgop(NODE *p)
 23042304 {
 23052305         NODE *q, *r;
 23062306         int tval;
 23072307 
 23082308         if (p->n_op == INCR || p->n_op == DECR) {
 23092309                 /*
 23102310                  * Rewrite x++ to (x += 1) -1; and deal with it further down.
 23112311                  * Pass2 will remove -1 if unnecessary.
 23122312                  */
 23132313                 q = ccopy(p);
 23142314                 tfree(p->n_left);
 23152315                 q->n_op = (p->n_op==INCR)?PLUSEQ:MINUSEQ;
 23162316                 p->n_op = (p->n_op==INCR)?MINUS:PLUS;
 23172317                 p->n_left = delasgop(q);
 23182318 
 23192319         } else if ((cdope(p->n_op)&ASGOPFLG) &&
 23202320             p->n_op != RETURN && p->n_op != CAST) {
 23212321                 NODE *l = p->n_left;
 23222322                 NODE *ll = l->n_left;
 23232323 
 23242324                 if (has_se(l)) {
 23252325                         q = tempnode(0, ll->n_type, ll->n_df, ll->n_ap);
 23262326                         tval = regno(q);
 23272327                         r = tempnode(tval, ll->n_type, ll->n_df,ll->n_ap);
 23282328                         l->n_left = q;
 23292329                         /* Now the left side of node p has no side effects. */
 23302330                         /* side effects on the right side must be obeyed */
 23312331                         p = delasgop(p);
 23322332                         
 23332333                         r = buildtree(ASSIGN, r, ll);
 23342334                         r = delasgop(r);
 23352335                         ecode(r);
 23362336                 } else {
 23372337 #if 0 /* Cannot call buildtree() here, it would invoke double add shifts */
 23382338                         p->n_right = buildtree(UNASG p->n_op, ccopy(l),
 23392339                             p->n_right);
 23402340 #else
 23412341                         p->n_right = block(UNASG p->n_op, ccopy(l),
 23422342                             p->n_right, p->n_type, p->n_df, p->n_ap);
 23432343 #endif
 23442344                         p->n_op = ASSIGN;
 23452345                         p->n_right = delasgop(p->n_right);
 23462346                         p->n_right = clocal(p->n_right);
 23472347                 }
 23482348                 
 23492349         } else {
 23502350                 if (coptype(p->n_op) == LTYPE)
 23512351                         return p;
 23522352                 p->n_left = delasgop(p->n_left);
 23532353                 if (coptype(p->n_op) == BITYPE)
 23542354                         p->n_right = delasgop(p->n_right);
 23552355         }
 23562356         return p;
 23572357 }
 23582358 
 23592359 #ifndef FIELDOPS
 23602360 
 23612361 /* avoid promotion to int */
 23622362 #define TYPMOD(o, p, n, t)      clocal(block(o, p, n, t, 0, 0))
 23632363 #define TYPLS(p, n, t)  TYPMOD(LS, p, n, t)
 23642364 #define TYPRS(p, n, t)  TYPMOD(RS, p, n, t)
 23652365 #define TYPOR(p, q, t)  TYPMOD(OR, p, q, t)
 23662366 #define TYPAND(p, q, t) TYPMOD(AND, p, q, t)
 23672367 
 23682368 /*
 23692369  * Read an unaligned bitfield from position pointed to by p starting at
 23702370  * off and size fsz and return a tree of type t with resulting data.
 23712371  */
 23722372 static NODE *
 23732373 rdualfld(NODE *p, TWORD t, TWORD ct, int off, int fsz)
 23742374 {
 23752375         int t2f, inbits, tsz, ctsz;
 23762376         NODE *q, *r;
 23772377 
 23782378         ct = ENUNSIGN(ct);
 23792379         ctsz = (int)tsize(ct, 0, 0);
 23802380 
 23812381         /* traverse until first data byte */
 23822382         for (t2f = 0; off > ctsz; t2f++, off -= ctsz)
 23832383                 ;
 23842384 #ifdef UNALIGNED_ACCESS
 23852385         /* try to squeeze it into an int */
 23862386         if (off + fsz > ctsz && off + fsz <= SZINT) {
 23872387                 ct = UNSIGNED;
 23882388                 ctsz = SZINT;
 23892389         }
 23902390 #endif
 23912391         p = makety(p, PTR|ct, 0, 0, 0);
 23922392         if (off + fsz <= ctsz) {
 23932393                 /* only one operation needed */
 23942394                 q = buildtree(UMUL, buildtree(PLUS, p, bcon(t2f)), 0);
 23952395                 if (!ISUNSIGNED(t)) {
 23962396                         ct = DEUNSIGN(ct);
 23972397                         q = makety(q, ct, 0, 0, 0);
 23982398                 }
 23992399                 q = TYPLS(q, bcon(ctsz-fsz-off), ct);
 24002400                 q = TYPRS(q, bcon(ctsz-fsz), ct);
 24012401                 q = makety(q, t, 0, 0, 0);
 24022402         } else {
 24032403                 q = buildtree(UMUL, buildtree(PLUS, ccopy(p), bcon(t2f)), 0);
 24042404                 q = makety(TYPRS(q, bcon(off), ct), t, 0, 0, 0);
 24052405                 inbits = ctsz - off;
 24062406                 t2f++;
 24072407 
 24082408                 while (fsz > inbits) {
 24092409                         r = buildtree(UMUL,
 24102410                             buildtree(PLUS, ccopy(p), bcon(t2f)), 0);
 24112411                         r = makety(r, t, 0, 0, 0);
 24122412                         r = TYPLS(r, bcon(inbits), t);
 24132413                         q = TYPOR(q, r, t);
 24142414                         inbits += ctsz;
 24152415                         t2f++;
 24162416                 }
 24172417                 /* sign/zero extend XXX - RS must sign extend */
 24182418                 tsz = (int)tsize(t, 0, 0);
 24192419                 if (!ISUNSIGNED(t)) {
 24202420                         t = DEUNSIGN(t);
 24212421                         q = makety(q, t, 0, 0, 0);
 24222422                 }
 24232423                 q = TYPLS(q, bcon(tsz-fsz), t);
 24242424                 q = TYPRS(q, bcon(tsz-fsz), t);
 24252425                 tfree(p);
 24262426         }
 24272427 
 24282428         return q;
 24292429 }
 24302430 
 24312431 /*
 24322432  * Write val to a (unaligned) bitfield with length fsz positioned off bits 
 24332433  * from d. Bitfield type is t, and type to use when writing is ct.
 24342434  * neither f nor d should have any side effects if copied.
 24352435  * Multiples of ct are supposed to be written without problems.
 24362436  * Both val and d are free'd after use.
 24372437  */
 24382438 static NODE *
 24392439 wrualfld(NODE *val, NODE *d, TWORD t, TWORD ct, int off, int fsz)
 24402440 {
 24412441         NODE *p, *q, *r, *rn, *s;
<>2442 -        int tsz, ctsz, t2f, inbits;
  2442+        int ctsz, t2f, inbits;
24432443  
<>2444 -        tsz = (int)tsize(t, 0, 0);
<_24452444         ctsz = (int)tsize(ct, 0, 0);
 24462445  
 24472446         ct = ENUNSIGN(ct);
 24482447         d = makety(d, PTR|ct, 0, 0, 0);
 24492448 
 24502449         for (t2f = 0; off > ctsz; t2f++, off -= ctsz)
 24512450                 ;
 24522451  
 24532452         if (off + fsz <= ctsz) {
 24542453                 r = tempnode(0, ct, 0, 0);
 24552454 
 24562455                 /* only one operation needed */
 24572456                 d = buildtree(UMUL, buildtree(PLUS, d, bcon(t2f)), 0);  
 24582457                 p = ccopy(d);
 24592458                 p = TYPAND(p, xbcon(~(SZMASK(fsz) << off), 0, ct), ct);
 24602459 
 24612460                 val = makety(val, ct, 0, 0, 0);
 24622461                 q = TYPAND(val, xbcon(SZMASK(fsz), 0, ct), ct);
 24632462                 q = buildtree(ASSIGN, ccopy(r), q);
 24642463 
 24652464                 q = TYPLS(q, bcon(off), ct);  
 24662465                 p = TYPOR(p, q, ct);
 24672466                 p = makety(p, t, 0, 0, 0);    
 24682467                 rn = buildtree(ASSIGN, d, p);
 24692468                 rn = buildtree(COMOP, rn, makety(r, t, 0, 0, 0));
 24702469         } else {
 24712470                 s = makety(ccopy(val), t, 0, 0, 0);
 24722471                 s = TYPAND(s, xbcon(SZMASK(fsz), 0, t), t);
 24732472 
 24742473                 r = buildtree(UMUL, buildtree(PLUS, ccopy(d), bcon(t2f)), 0);
 24752474                 p = ccopy(r);
 24762475                 p = TYPAND(p, xbcon(SZMASK(off), 0, ct), ct);
 24772476                 q = ccopy(val);
 24782477                 q = TYPLS(q, bcon(off), t); 
 24792478                 q = makety(q, ct, 0, 0, 0);
 24802479                 p = TYPOR(p, q, ct);
 24812480                 rn = buildtree(ASSIGN, r, p);
 24822481                 inbits = ctsz - off;
 24832482                 t2f++;
 24842483 
 24852484                 while (fsz > inbits+ctsz) {
 24862485                         r = buildtree(UMUL,
 24872486                             buildtree(PLUS, ccopy(d), bcon(t2f)), 0);
 24882487                         q = ccopy(val);
 24892488                         q = TYPRS(q, bcon(inbits), t);
 24902489                         q = makety(q, ct, 0, 0, 0);
 24912490                         rn = buildtree(COMOP, rn, buildtree(ASSIGN, r, q));
 24922491                         t2f++;
 24932492                         inbits += ctsz;
 24942493                 }
 24952494 
 24962495                 r = buildtree(UMUL, buildtree(PLUS, d, bcon(t2f)), 0);
 24972496                 p = ccopy(r);
 24982497                 p = TYPAND(p, makety(xbcon(~SZMASK(fsz-inbits), 0, ct),
 24992498                     ct, 0, 0, 0), ct);
 25002499                 q = TYPRS(val, bcon(inbits), t);
 25012500                 q = TYPAND(q, xbcon(SZMASK(fsz-inbits), 0, t), t);
 25022501                 q = makety(q, ct, 0, 0, 0);
 25032502                 p = TYPOR(p, q, ct);
 25042503                 rn = buildtree(COMOP, rn, buildtree(ASSIGN, r, p));
 25052504                 rn = buildtree(COMOP, rn, s);
 25062505         }
 25072506         return rn;
 25082507 }
 25092508 
 25102509 /*
 25112510  * Rewrite bitfield operations to shifts.
 25122511  */
 25132512 static NODE *
 25142513 rmfldops(NODE *p)
 25152514 {
 25162515         TWORD t, ct;
 25172516         NODE *q, *r, *t1, *t2, *bt, *t3, *t4;
 25182517         int fsz, foff, tsz;
 25192518 
 25202519         if (p->n_op == FLD) {
 25212520                 /* Rewrite a field read operation */
 25222521                 fsz = UPKFSZ(p->n_rval);
 25232522                 foff = UPKFOFF(p->n_rval);
 25242523                 tsz = (int)tsize(p->n_left->n_type, 0, 0);
 25252524                 q = buildtree(ADDROF, p->n_left, NIL);
 25262525 
 25272526                 ct = t = p->n_type;
 25282527                 if (attr_find(p->n_ap, GCC_ATYP_PACKED) &&
 25292528                     coptype(q->n_op) != LTYPE) {
 25302529                         t1 = tempnode(0, q->n_type, 0, 0);
 25312530                         bt = buildtree(ASSIGN, ccopy(t1), q);
 25322531                         q = t1;
 25332532 #ifndef UNALIGNED_ACCESS
 25342533                         ct = UCHAR;
 25352534 #endif
 25362535                 } else
 25372536                         bt = bcon(0);
 25382537                 q = rdualfld(q, t, ct, foff, fsz);
 25392538                 p->n_left = bt;
 25402539                 p->n_right = q;
 25412540                 p->n_op = COMOP;
 25422541         } else if (((cdope(p->n_op)&ASGOPFLG) || p->n_op == ASSIGN ||
 25432542             p->n_op == INCR || p->n_op == DECR) && p->n_left->n_op == FLD) {
 25442543                 /*
 25452544                  * Rewrite a field write operation
 25462545                  * More difficult than a read op since we must care
 25472546                  * about side effects.
 25482547                  */
 25492548                 q = p->n_left;
 25502549                 fsz = UPKFSZ(q->n_rval);
 25512550                 foff = UPKFOFF(q->n_rval);
 25522551                 t = q->n_left->n_type;
 25532552                 tsz = (int)tsize(t, 0, 0);
 25542553 #if TARGET_ENDIAN == TARGET_BE
 25552554                 foff = tsz - fsz - foff;
 25562555 #endif
 25572556                 bt = NULL;
 25582557                 if (p->n_right->n_op != ICON && p->n_right->n_op != NAME) {
 25592558                         t2 = tempnode(0, p->n_right->n_type, 0, 0);
 25602559                         bt = buildtree(ASSIGN, ccopy(t2), p->n_right);
 25612560                 } else
 25622561                         t2 = p->n_right;
 25632562 
 25642563                 ct = t;
 25652564 #ifndef UNALIGNED_ACCESS
 25662565                 if (attr_find(q->n_ap, GCC_ATYP_PACKED))
 25672566                         ct = UCHAR;
 25682567 #endif
 25692568                 /* t2 is what we have to write (RHS of ASSIGN) */
 25702569                 /* bt is (eventually) something that must be written */
 25712570 
 25722571 
 25732572                 if (q->n_left->n_op == UMUL) {
 25742573                         /* LHS of assignment may have side effects */
 25752574                         q = q->n_left;
 25762575                         t1 = tempnode(0, q->n_left->n_type, 0, 0);
 25772576                         r = buildtree(ASSIGN, ccopy(t1), q->n_left);
 25782577                         
 25792578                         bt = bt ? block(COMOP, bt, r, INT, 0, 0) : r;
 25802579                         q->n_left = t1;
 25812580                 }
 25822581                 t1 = buildtree(ADDROF, p->n_left->n_left, 0);
 25832582 
 25842583                 /* t1 is lval where to write (and read) */
 25852584 
 25862585                 if (p->n_op == ASSIGN) {
 25872586                         q = wrualfld(t2, t1, t, ct, foff, fsz);
 25882587                         if (bt)
 25892588                                 q = block(COMOP, bt, q, t, 0, 0);
 25902589                         nfree(p->n_left);
 25912590                         p->n_left = bcon(0);
 25922591                         p->n_right = q;
 25932592                         p->n_op = COMOP;
 25942593                 } else if ((cdope(p->n_op)&ASGOPFLG)) {
 25952594                         /* And here is the asgop-specific code */
 25962595                         t3 = tempnode(0, t, 0, 0);
 25972596                         q = rdualfld(ccopy(t1), t, ct, foff, fsz);
 25982597                         q = buildtree(UNASG p->n_op, q, t2);
 25992598                         q = buildtree(ASSIGN, ccopy(t3), q);
 26002599                         r = wrualfld(ccopy(t3), t1, t, ct, foff, fsz);
 26012600                         q = buildtree(COMOP, q, r);
 26022601                         q = buildtree(COMOP, q, t3);
 26032602 
 26042603                         nfree(p->n_left);
 26052604                         p->n_left = bt ? bt : bcon(0);
 26062605                         p->n_right = q;
 26072606                         p->n_op = COMOP;
 26082607                 } else {
 26092608                         t3 = tempnode(0, t, 0, 0);
 26102609                         t4 = tempnode(0, t, 0, 0);
 26112610 
 26122611                         q = rdualfld(ccopy(t1), t, ct, foff, fsz);
 26132612                         q = buildtree(ASSIGN, ccopy(t3), q);
 26142613                         r = buildtree(p->n_op==INCR?PLUS:MINUS, ccopy(t3), t2);
 26152614                         r = buildtree(ASSIGN, ccopy(t4), r);
 26162615                         q = buildtree(COMOP, q, r);
 26172616                         r = wrualfld(t4, t1, t, ct, foff, fsz);
 26182617                         q = buildtree(COMOP, q, r);
 26192618                 
 26202619                         if (bt)
 26212620                                 q = block(COMOP, bt, q, t, 0, 0);
 26222621                         nfree(p->n_left);
 26232622                         p->n_left = q;
 26242623                         p->n_right = t3;
 26252624                         p->n_op = COMOP;
 26262625                 }
 26272626         }
 26282627         if (coptype(p->n_op) != LTYPE)
 26292628                 p->n_left = rmfldops(p->n_left);
 26302629         if (coptype(p->n_op) == BITYPE)
 26312630                 p->n_right = rmfldops(p->n_right);
 26322631         return p;
 26332632 }
 26342633 #endif
 26352634 
 26362635 void
 26372636 ecomp(NODE *p)
 26382637 {
 26392638 
 26402639 #ifdef PCC_DEBUG
 26412640         if (edebug)
 26422641                 fwalk(p, eprint, 0);
 26432642 #endif
 26442643         if (!reached) {
 26452644                 warner(Wunreachable_code, NULL);
 26462645                 reached = 1;
 26472646         }
 26482647         p = optim(p);
 26492648 #ifndef FIELDOPS
 26502649         p = rmfldops(p);
 26512650 #endif
 26522651         comops(p);
 26532652         rmcops(p);
 26542653         p = delasgop(p);
 26552654         if (p->n_op == ICON && p->n_type == VOID)
 26562655                 tfree(p);
 26572656         else
 26582657                 ecode(p);
 26592658 }
 26602659 
 26612660 
 26622661 #if defined(MULTIPASS)
 26632662 void    
 26642663 p2tree(NODE *p)
 26652664 {
 26662665         struct symtab *q;
 26672666         int ty;
 26682667 
 26692668         myp2tree(p);  /* local action can be taken here */
 26702669 
 26712670