Quick Search:

Mode

Context

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

Other Diffs

Ignore

Blank Lines Whitespace: Expand:

Diff

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