Quick Search:

Mode

Context

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

Other Diffs

Ignore

Blank Lines Whitespace: Expand:

Diff

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