Quick Search:

Mode

Context

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

Other Diffs

Ignore

Blank Lines Whitespace: Expand:

Diff

1.318
 
1.319
 
MAIN:plunky:20121022091852
 
trees.c
_>11 /*      $Id$    */
 22 /*
 33  * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
 44  * All rights reserved.
 55  *
 66  * Redistribution and use in source and binary forms, with or without
 77  * modification, are permitted provided that the following conditions
 88  * are met:
 99  * 1. Redistributions of source code must retain the above copyright
 1010  *    notice, this list of conditions and the following disclaimer.
 1111  * 2. Redistributions in binary form must reproduce the above copyright
 1212  *    notice, this list of conditions and the following disclaimer in the
 1313  *    documentation and/or other materials provided with the distribution.
 1414  * 3. The name of the author may not be used to endorse or promote products
 1515  *    derived from this software without specific prior written permission
 1616  *
 1717  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 1818  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 1919  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 2020  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 2121  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 2222  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 2323  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 2424  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 2525  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 2626  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 2727  */
 2828 
 2929 /*
 3030  * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
 3131  *
 3232  * Redistribution and use in source and binary forms, with or without
 3333  * modification, are permitted provided that the following conditions
 3434  * are met:
 3535  *
 3636  * Redistributions of source code and documentation must retain the above
 3737  * copyright notice, this list of conditions and the following disclaimer.
 3838  * Redistributions in binary form must reproduce the above copyright
 3939  * notice, this list of conditionsand the following disclaimer in the
 4040  * documentation and/or other materials provided with the distribution.
 4141  * All advertising materials mentioning features or use of this software
 4242  * must display the following acknowledgement:
 4343  *      This product includes software developed or owned by Caldera
 4444  *      International, Inc.
 4545  * Neither the name of Caldera International, Inc. nor the names of other
 4646  * contributors may be used to endorse or promote products derived from
 4747  * this software without specific prior written permission.
 4848  *
 4949  * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
 5050  * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
 5151  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 5252  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 5353  * DISCLAIMED.  IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE
 5454  * FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 5555  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 5656  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 5757  * HOWEVER CAUSED AND ON ANY THEORY OFLIABILITY, WHETHER IN CONTRACT,
 5858  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 5959  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 6060  * POSSIBILITY OF SUCH DAMAGE.
 6161  */
 6262 /*
 6363  * Some of the changes from 32V include:
 6464  * - Understand "void" as type.
 6565  * - Handle enums as ints everywhere.
 6666  * - Convert some C-specific ops into branches.
 6767  */
 6868 
 6969 # include "pass1.h"
 7070 # include "pass2.h"
 7171 
 7272 # include <stdarg.h>
 7373 # include <string.h>
 7474 
 7575 static void chkpun(NODE *p);
 7676 static int opact(NODE *p);
 7777 static int moditype(TWORD);
 7878 static NODE *strargs(NODE *);
 7979 static void rmcops(NODE *p);
 8080 static NODE *tymatch(NODE *p);
 8181 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 );
<> 426+                        /* FALLTHROUGH */
426427                 case UTYPE:
 427428                         p->n_left = pconvert( p->n_left );
 428429 
 429430                         }
 430431                 }
 431432 
 432433         if ((actions&PUN) && (o!=CAST))
 433434                 chkpun(p);
 434435 
 435436         if( actions & (TYPL|TYPR) ){
 436437 
 437438                 q = (actions&TYPL) ? p->n_left : p->n_right;
 438439 
 439440                 p->n_type = q->n_type;
 440441                 p->n_qual = q->n_qual;
 441442                 p->n_df = q->n_df;
 442443                 p->n_ap = q->n_ap;
 443444                 }
 444445 
 445446         if( actions & CVTL ) p = convert( p, CVTL );
 446447         if( actions & CVTR ) p = convert( p, CVTR );
 447448         if( actions & TYMATCH ) p = tymatch(p);
 448449         if( actions & PTMATCH ) p = ptmatch(p);
 449450 
 450451         if( actions & OTHER ){
 451452                 struct symtab *sp1;
 452453 
 453454                 l = p->n_left;
 454455                 r = p->n_right;
 455456 
 456457                 switch(o){
 457458 
 458459                 case NAME:
 459460                         cerror("buildtree NAME");
 460461 
 461462                 case STREF:
 462463                         /* p->x turned into *(p+offset) */
 463464                         /* rhs must be a name; check correctness */
 464465 
 465466                         /* Find member symbol struct */
 466467                         if (l->n_type != PTR+STRTY && l->n_type != PTR+UNIONTY){
 467468                                 uerror("struct or union required");
 468469                                 break;
 469470                         }
 470471 
 471472                         if ((sp1 = strmemb(l->n_ap)) == NULL) {
 472473                                 uerror("undefined struct or union");
 473474                                 break;
 474475                         }
 475476 
 476477                         if ((sp = findmember(sp1, r->n_name)) == NULL) {
 477478                                 uerror("member '%s' not declared", r->n_name);
 478479                                 break;
 479480                         }
 480481 
 481482                         r->n_sp = sp;
 482483                         p = stref(p);
 483484                         break;
 484485 
 485486                 case UMUL:
 486487                         if (l->n_op == ADDROF) {
 487488                                 nfree(p);
 488489                                 p = nfree(l);
 489490                         }
 490491                         if( !ISPTR(l->n_type))uerror("illegal indirection");
 491492                         p->n_type = DECREF(l->n_type);
 492493                         p->n_qual = DECREF(l->n_qual);
 493494                         p->n_df = l->n_df;
 494495                         p->n_ap = l->n_ap;
 495496                         break;
 496497 
 497498                 case ADDROF:
 498499                         switch( l->n_op ){
 499500 
 500501                         case UMUL:
 501502                                 nfree(p);
 502503                                 p = nfree(l);
 503504                                 /* FALLTHROUGH */
 504505                         case TEMP:
 505506                         case NAME:
 506507                                 p->n_type = INCREF(l->n_type);
 507508                                 p->n_qual = INCQAL(l->n_qual);
 508509                                 p->n_df = l->n_df;
 509510                                 p->n_ap = l->n_ap;
 510511                                 break;
 511512 
 512513                         case COMOP:
 513514                                 nfree(p);
 514515                                 lr = buildtree(ADDROF, l->n_right, NIL);
 515516                                 p = buildtree( COMOP, l->n_left, lr );
 516517                                 nfree(l);
 517518                                 break;
 518519 
 519520                         case QUEST:
 520521                                 lr = buildtree( ADDROF, l->n_right->n_right, NIL );
 521522                                 ll = buildtree( ADDROF, l->n_right->n_left, NIL );
 522523                                 nfree(p); nfree(l->n_right);
 523524                                 p = buildtree( QUEST, l->n_left, buildtree( COLON, ll, lr ) );
 524525                                 nfree(l);
 525526                                 break;
 526527 
 527528                         default:
 528529                                 uerror("unacceptable operand of &: %d", l->n_op );
 529530                                 break;
 530531                                 }
 531532                         break;
 532533 
 533534                 case LS:
 534535                 case RS: /* must make type size at least int... */
 535536                         if (p->n_type == CHAR || p->n_type == SHORT) {
 536537                                 p->n_left = makety(l, INT, 0, 0, 0);
 537538                         } else if (p->n_type == UCHAR || p->n_type == USHORT) {
 538539                                 p->n_left = makety(l, UNSIGNED, 0, 0, 0);
 539540                         }
 540541                         l = p->n_left;
 541542                         p->n_type = l->n_type;
 542543                         p->n_qual = l->n_qual;
 543544                         p->n_df = l->n_df;
 544545                         p->n_ap = l->n_ap;
 545546                         if(tsize(r->n_type, r->n_df, r->n_ap) > SZINT)
 546547                                 p->n_right = makety(r, INT, 0, 0, 0);
 547548                         break;
 548549 
 549550                 case RETURN:
 550551                 case ASSIGN:
 551552                 case CAST:
 552553                         /* structure assignment */
 553554                         /* take the addresses of the two sides; then make an
 554555                          * operator using STASG and
 555556                          * the addresses of left and right */
 556557 
 557558                         if (strmemb(l->n_ap) != strmemb(r->n_ap))
 558559                                 uerror("assignment of different structures");
 559560 
 560561                         r = buildtree(ADDROF, r, NIL);
 561562 
 562563                         l = block(STASG, l, r, r->n_type, r->n_df, r->n_ap);
 563564                         l = clocal(l);
 564565 
 565566                         if( o == RETURN ){
 566567                                 nfree(p);
 567568                                 p = l;
 568569                                 break;
 569570                         }
 570571 
 571572                         p->n_op = UMUL;
 572573                         p->n_left = l;
 573574                         p->n_right = NIL;
 574575                         break;
 575576 
 576577                 case QUEST: /* fixup types of : */
 577578                         if (r->n_left->n_type != p->n_type)
 578579                                 r->n_left = makety(r->n_left, p->n_type,
 579580                                     p->n_qual, p->n_df, p->n_ap);
 580581                         if (r->n_right->n_type != p->n_type)
 581582                                 r->n_right = makety(r->n_right, p->n_type,
 582583                                     p->n_qual, p->n_df, p->n_ap);
 583584                         break;
 584585 
 585586                 case COLON:
 586587                         /* structure colon */
 587588 
 588589                         if (strmemb(l->n_ap) != strmemb(r->n_ap))
 589590                                 uerror( "type clash in conditional" );
 590591                         break;
 591592 
 592593                 case CALL:
 593594                         p->n_right = r = strargs(p->n_right);
 594595                         p = funcode(p);
 595596                         /* FALLTHROUGH */
 596597                 case UCALL:
 597598                         if (!ISPTR(l->n_type))
 598599                                 uerror("illegal function");
 599600                         p->n_type = DECREF(l->n_type);
 600601                         if (!ISFTN(p->n_type))
 601602                                 uerror("illegal function");
 602603                         p->n_type = DECREF(p->n_type);
 603604                         p->n_df = l->n_df+1; /* add one for prototypes */
 604605                         p->n_ap = l->n_ap;
 605606                         if (p->n_type == STRTY || p->n_type == UNIONTY) {
 606607                                 /* function returning structure */
 607608                                 /*  make function really return ptr to str., with * */
 608609 
 609610                                 p->n_op += STCALL-CALL;
 610611                                 p->n_type = INCREF(p->n_type);
 611612                                 p = clocal(p); /* before recursing */
 612613                                 p = buildtree(UMUL, p, NIL);
 613614 
 614615                                 }
 615616                         break;
 616617 
 617618                 default:
 618619                         cerror( "other code %d", o );
 619620                         }
 620621 
 621622                 }
 622623 
 623624         /*
 624625          * Allow (void)0 casts.
 625626          * XXX - anything on the right side must be possible to cast.
 626627          * XXX - remove void types further on.
 627628          */
 628629         if (p->n_op == CAST && p->n_type == VOID &&
 629630             p->n_right->n_op == ICON)
 630631                 p->n_right->n_type = VOID;
 631632 
 632633         if (actions & CVTO)
 633634                 p = oconvert(p);
 634635         p = clocal(p);
 635636 
 636637 #ifdef PCC_DEBUG
 637638         if (bdebug) {
 638639                 printf("End of buildtree:\n");
 639640                 fwalk(p, eprint, 0);
 640641         }
 641642 #endif
 642643 
 643644         return(p);
 644645 
 645646         }
 646647 
 647648 /*                     
 648649  * Rewrite ++/-- to (t=p, p++, t) ops on types that do not act act as usual.
 649650  */
 650651 static NODE *
 651652 rewincop(NODE *p1, NODE *p2, int op)
 652653 {
 653654         NODE *t, *r;
 654655                 
 655656         t = cstknode(p1->n_type, p1->n_df, p1->n_ap);
 656657         r = buildtree(ASSIGN, ccopy(t), ccopy(p1));
 657658         r = buildtree(COMOP, r, buildtree(op, p1, eve(p2)));
 658659         return buildtree(COMOP, r, t);
 659660 }
 660661 
 661662 
 662663 /* Find a member in a struct or union.  May be an unnamed member */
 663664 static struct symtab *
 664665 findmember(struct symtab *sp, char *s)
 665666 {
 666667         struct symtab *sp2, *sp3;
 667668 
 668669         for (; sp != NULL; sp = sp->snext) {
 669670                 if (sp->sname[0] == '*') {
 670671                         /* unnamed member, recurse down */
 671672                         if ((sp2 = findmember(strmemb(sp->sap), s))) {
 672673                                 sp3 = tmpalloc(sizeof (struct symtab));
 673674                                 *sp3 = *sp2;
 674675                                 sp3->soffset += sp->soffset;
 675676                                 return sp3;
 676677                         }
 677678                 } else if (sp->sname == s)
 678679                         return sp;
 679680         }
 680681         return NULL;
 681682 }
 682683 
 683684 
 684685 /*
 685686  * Check if there will be a lost label destination inside of a ?:
 686687  * It cannot be reached so just print it out.
 687688  */
 688689 void
 689690 putjops(NODE *p, void *arg)
 690691 {
 691692         if (p->n_op == COMOP && p->n_left->n_op == GOTO)
 692693                 plabel((int)p->n_left->n_left->n_lval+1);
 693694 }
 694695 
 695696 /*
 696697  * Build a name node based on a symtab entry.
 697698  * broken out from buildtree().
 698699  */
 699700 NODE *
 700701 nametree(struct symtab *sp)
 701702 {
 702703         NODE *p;
 703704 
 704705         p = block(NAME, NIL, NIL, sp->stype, sp->sdf, sp->sap);
 705706         p->n_qual = sp->squal;
 706707         p->n_sp = sp;
 707708 
 708709 #ifndef NO_C_BUILTINS
 709710         if (sp->sname[0] == '_' && strncmp(sp->sname, "__builtin_", 10) == 0)
 710711                 return p/* do not touch builtins here */
 711712         
 712713 #endif
 713714 
 714715         if (sp->sflags & STNODE) {
 715716                 /* Generated for optimizer */
 716717                 p->n_op = TEMP;
 717718                 p->n_rval = sp->soffset;
 718719         }
 719720 
 720721 #ifdef GCC_COMPAT
 721722         /* Get a label name */
 722723         if (sp->sflags == SLBLNAME)
 723724                 sp->stype = p->n_type = VOID;
 724725 #endif
 725726         if (sp->stype == UNDEF) {
 726727                 uerror("%s undefined", sp->sname);
 727728                 /* make p look reasonable */
 728729                 p->n_type = INT;
 729730                 p->n_df = NULL;
 730731                 defid(p, SNULL);
 731732         }
 732733         if (sp->sclass == MOE) {
 733734                 p->n_op = ICON;
 734735                 p->n_lval = sp->soffset;
 735736                 p->n_df = NULL;
 736737                 p->n_sp = NULL;
 737738         }
 738739         return clocal(p);
 739740 }
 740741 
 741742 /*
 742743  * Cast a node to another type by inserting a cast.
 743744  * Just a nicer interface to buildtree.
 744745  * Returns the new tree.
 745746  */
 746747 NODE *
 747748 cast(NODE *p, TWORD t, TWORD u)
 748749 {
 749750         NODE *q;
 750751 
 751752         q = block(NAME, NIL, NIL, t, 0, 0);
 752753         q->n_qual = u;
 753754         q = buildtree(CAST, q, p);
 754755         p = q->n_right;
 755756         nfree(q->n_left);
 756757         nfree(q);
 757758         return p;
 758759 }
 759760 
 760761 /*
 761762  * Cast and complain if necessary by not inserining a cast.
 762763  */
 763764 NODE *
 764765 ccast(NODE *p, TWORD t, TWORD u, union dimfun *df, struct attr *ap)
 765766 {
 766767         NODE *q;
 767768 
 768769         /* let buildtree do typechecking (and casting) */
 769770         q = block(NAME, NIL, NIL, t, df, ap);
 770771         p = buildtree(ASSIGN, q, p);
 771772         nfree(p->n_left);
 772773         q = optim(p->n_right);
 773774         nfree(p);
 774775         return q;
 775776 }
 776777 
 777778 /*
 778779  * Do an actual cast of a constant (if possible).
 779780  * Routine assumes 2-complement (is there anything else today?)
 780781  * Returns 1 if handled, 0 otherwise.
 781782  */
 782783 int
 783784 concast(NODE *p, TWORD t)
 784785 {
 785786         extern short sztable[];
 786787         CONSZ val;
 787788 
 788789         if (p->n_op != ICON && p->n_op != FCON) /* only constants */
 789790                 return 0;
 790791         if (p->n_op == ICON && p->n_sp != NULL) { /* no addresses */
 791792                 if (t == BOOL) {
 792793                         p->n_lval = 1, p->n_type = BOOL, p->n_sp = NULL;
 793794                         return 1;
 794795                 }
 795796                 return 0;
 796797         }
 797798         if (((p->n_type & TMASK) && t != BOOL) || (t & TMASK)) /* no pointers */
 798799                 return 0;
 799800 
 800801 //printf("concast till %d\n", t);
 801802 //fwalk(p, eprint, 0);
 802803 
 803804 #define TYPMSK(y) ((((1LL << (y-1))-1) << 1) | 1)
 804805         if (p->n_op == ICON) {
 805806                 val = p->n_lval;
 806807 
 807808                 if (t == BOOL) {
 808809                         if (val)
 809810                                 p->n_lval = 1;
 810811                 } else if (t <= ULONGLONG) {
 811812                         p->n_lval = val & TYPMSK(sztable[t]);
 812813                         if (!ISUNSIGNED(t)) {
 813814                                 if (val & (1LL << (sztable[t]-1)))
 814815                                         p->n_lval |= ~TYPMSK(sztable[t]);
 815816                         }
 816817                 } else if (t <= LDOUBLE) {
 817818                         p->n_op = FCON;
 818819                         p->n_dcon = FLOAT_CAST(val, p->n_type);
 819820                 }
 820821         } else { /* p->n_op == FCON */
 821822                 if (t == BOOL) {
 822823                         p->n_op = ICON;
 823824                         p->n_lval = FLOAT_NE(p->n_dcon,0.0);
 824825                         p->n_sp = NULL;
 825826                 } else if (t <= ULONGLONG) {
 826827                         p->n_op = ICON;
 827828                         p->n_lval = ISUNSIGNED(t) ? /* XXX FIXME */
 828829                             ((U_CONSZ)p->n_dcon) : p->n_dcon;
 829830                         p->n_sp = NULL;
 830831                 } else {
 831832                         p->n_dcon = t == FLOAT ? (float)p->n_dcon :
 832833                             t == DOUBLE ? (double)p->n_dcon : p->n_dcon;
 833834                 }
 834835         }
 835836         p->n_type = t;
 836837 //fwalk(p, eprint, 0);
 837838         return 1;
 838839 }
 839840 
 840841 /*
 841842  * Do a conditional branch.
 842843  */
 843844 void
 844845 cbranch(NODE *p, NODE *q)
 845846 {
 846847         p = buildtree(CBRANCH, p, q);
 847848         if (p->n_left->n_op == ICON) {
 848849                 if (p->n_left->n_lval != 0) {
 849850                         branch((int)q->n_lval); /* branch always */
 850851                         reached = 0;
 851852                 }
 852853                 tfree(p);
 853854                 tfree(q);
 854855                 return;
 855856         }
 856857         ecomp(p);
 857858 }
 858859 
 859860 NODE *
 860861 strargs(register NODE *p)
 861862 {
 862863         /* rewrite structure flavored arguments */
 863864 
 864865         if( p->n_op == CM ){
 865866                 p->n_left = strargs( p->n_left );
 866867                 p->n_right = strargs( p->n_right );
 867868                 return( p );
 868869                 }
 869870 
 870871         if( p->n_type == STRTY || p->n_type == UNIONTY ){
 871872                 p = block(STARG, p, NIL, p->n_type, p->n_df, p->n_ap);
 872873                 p->n_left = buildtree( ADDROF, p->n_left, NIL );
 873874                 p = clocal(p);
 874875                 }
 875876         return( p );
 876877 }
 877878 
 878879 /*
 879880  * apply the op o to the lval part of p; if binary, rhs is val
 880881  */
 881882 int
 882883 conval(NODE *p, int o, NODE *q)
 883884 {
 884885         TWORD tl = p->n_type, tr = q->n_type, td;
 885886         int i, u;
 886887         CONSZ val;
 887888         U_CONSZ v1, v2;
 888889 
 889890         val = q->n_lval;
 890891 
 891892         /* make both sides same type */
 892893         if (tl < BTMASK && tr < BTMASK) {
 893894                 td = tl > tr ? tl : tr;
 894895                 if (td < INT)
 895896                         td = INT;
 896897                 u = ISUNSIGNED(td);
 897898                 if (tl != td)
 898899                         p = makety(p, td, 0, 0, 0);
 899900                 if (tr != td)
 900901                         q = makety(q, td, 0, 0, 0);
 901902         } else
 902903                 u = ISUNSIGNED(tl) || ISUNSIGNED(tr);
 903904         if( u && (o==LE||o==LT||o==GE||o==GT)) o += (UGE-GE);
 904905 
 905906         if (p->n_sp != NULL && q->n_sp != NULL)
 906907                 return(0);
 907908         if (q->n_sp != NULL && o != PLUS)
 908909                 return(0);
 909910         if (p->n_sp != NULL && o != PLUS && o != MINUS)
 910911                 return(0);
 911912 
 912913         v1 = p->n_lval;
 913914         v2 = q->n_lval;
 914915         if (v2 == 0 && (cdope(o) & DIVFLG))
 915916                 return 0; /* leave division by zero to runtime */
 916917         switch( o ){
 917918 
 918919         case PLUS:
 919920                 p->n_lval += val;
 920921                 if (p->n_sp == NULL) {
 921922                         p->n_right = q->n_right;
 922923                         p->n_type = q->n_type;
 923924                 }
 924925                 break;
 925926         case MINUS:
 926927                 p->n_lval -= val;
 927928                 break;
 928929         case MUL:
 929930                 p->n_lval *= val;
 930931                 break;
 931932         case DIV:
 932933                 if (u) {
 933934                         v1 /= v2;
 934935                         p->n_lval = v1;
 935936                 } else
 936937                         p->n_lval /= val;
 937938                 break;
 938939         case MOD:
 939940                 if (u) {
 940941                         v1 %= v2;
 941942                         p->n_lval = v1;
 942943                 } else
 943944                         p->n_lval %= val;
 944945                 break;
 945946         case AND:
 946947                 p->n_lval &= val;
 947948                 break;
 948949         case OR:
 949950                 p->n_lval |= val;
 950951                 break;
 951952         case ER:
 952953                 p->n_lval ^= val;
 953954                 break;
 954955         case LS:
 955956                 i = (int)val;
 956957                 p->n_lval = p->n_lval << i;
 957958                 break;
 958959         case RS:
 959960                 i = (int)val;
 960961                 if (u) {
 961962                         v1 = v1 >> i;
 962963                         p->n_lval = v1;
 963964                 } else
 964965                         p->n_lval = p->n_lval >> i;
 965966                 break;
 966967 
 967968         case UMINUS:
 968969                 p->n_lval = - p->n_lval;
 969970                 break;
 970971         case COMPL:
 971972                 p->n_lval = ~p->n_lval;
 972973                 break;
 973974         case NOT:
 974975                 p->n_lval = !p->n_lval;
 975976                 break;
 976977         case LT:
 977978                 p->n_lval = p->n_lval < val;
 978979                 break;
 979980         case LE:
 980981                 p->n_lval = p->n_lval <= val;
 981982                 break;
 982983         case GT:
 983984                 p->n_lval = p->n_lval > val;
 984985                 break;
 985986         case GE:
 986987                 p->n_lval = p->n_lval >= val;
 987988                 break;
 988989         case ULT:
 989990                 p->n_lval = v1 < v2;
 990991                 break;
 991992         case ULE:
 992993                 p->n_lval = v1 <= v2;
 993994                 break;
 994995         case UGT:
 995996                 p->n_lval = v1 > v2;
 996997                 break;
 997998         case UGE:
 998999                 p->n_lval = v1 >= v2;
 9991000                 break;
 10001001         case EQ:
 10011002                 p->n_lval = p->n_lval == val;
 10021003                 break;
 10031004         case NE:
 10041005                 p->n_lval = p->n_lval != val;
 10051006                 break;
 10061007         case ANDAND:
 10071008                 p->n_lval = p->n_lval && val;
 10081009                 break;
 10091010         case OROR:
 10101011                 p->n_lval = p->n_lval || val;
 10111012                 break;
 10121013         default:
 10131014                 return(0);
 10141015                 }
 10151016         /* Do the best in making everything type correct after calc */
 10161017         if (p->n_sp == NULL && q->n_sp == NULL)
 10171018                 p->n_lval = valcast(p->n_lval, p->n_type);
 10181019         return(1);
 10191020         }
 10201021 
 10211022 /*
 10221023  * Ensure that v matches the type t; sign- or zero-extended
 10231024  * as suitable to CONSZ.
 10241025  * Only to be used for integer types.
 10251026  */
 10261027 CONSZ
 10271028 valcast(CONSZ v, TWORD t)
 10281029 {
 10291030         CONSZ r;
 10301031         int sz;
 10311032 
 10321033         if (t < CHAR || t > ULONGLONG)
 10331034                 return v; /* cannot cast */
 10341035 
 10351036         if (t >= LONGLONG)
 10361037                 return v; /* already largest */
 10371038 
 10381039 #define M(x)    ((((1ULL << ((x)-1)) - 1) << 1) + 1)
 10391040 #define NOTM(x) (~M(x))
 10401041 #define SBIT(x) (1ULL << ((x)-1))
 10411042 
 10421043         sz = (int)tsize(t, NULL, NULL);
 10431044         r = v & M(sz);
 10441045         if (!ISUNSIGNED(t) && (SBIT(sz) & r))
 10451046                 r = r | NOTM(sz);
 10461047         return r;
 10471048 }
 10481049 
 10491050 /*
 10501051  * Checks p for the existance of a pun.  This is called when the op of p
 10511052  * is ASSIGN, RETURN, CAST, COLON, or relational.
 10521053  * One case is when enumerations are used: this applies only to lint.
 10531054  * In the other case, one operand is a pointer, the other integer type
 10541055  * we check that this integer is in fact a constant zero...
 10551056  * in the case of ASSIGN, any assignment of pointer to integer is illegal
 10561057  * this falls out, because the LHS is never 0.
 10571058  * XXX - check for COMOPs in assignment RHS?
 10581059  */
 10591060 void
 10601061 chkpun(NODE *p)
 10611062 {
 10621063         union dimfun *d1, *d2;
 10631064         NODE *q;
 10641065         int t1, t2;
 10651066 
 10661067         t1 = p->n_left->n_type;
 10671068         t2 = p->n_right->n_type;
 10681069 
 10691070         switch (p->n_op) {
 10701071         case RETURN:
 10711072                 /* return of void allowed but nothing else */
 10721073                 if (t1 == VOID && t2 == VOID)
 10731074                         return;
 10741075                 if (t1 == VOID) {
 10751076                         werror("returning value from void function");
 10761077                         return;
 10771078                 }
 10781079                 if (t2 == VOID) {
 10791080                         uerror("using void value");
 10801081                         return;
 10811082                 }
 10821083                 break;
 10831084         case COLON:
 10841085                 if (t1 == VOID && t2 == VOID)
 10851086                         return;
 10861087                 break;
 10871088         default:
 10881089                 if ((t1 == VOID && t2 != VOID) || (t1 != VOID && t2 == VOID)) {
 10891090                         uerror("value of void expression used");
 10901091                         return;
 10911092                 }
 10921093                 break;
 10931094         }
 10941095 
 10951096         /* allow void pointer assignments in any direction */
 10961097         if (BTYPE(t1) == VOID && (t2 & TMASK))
 10971098                 return;
 10981099         if (BTYPE(t2) == VOID && (t1 & TMASK))
 10991100                 return;
 11001101 
 11011102         /* boolean have special syntax */
 11021103         if (t1 == BOOL) {
 11031104                 if (!ISARY(t2)) /* Anything scalar */
 11041105                         return;
 11051106         }
 11061107 
 11071108         if (ISPTR(t1) || ISARY(t1))
 11081109                 q = p->n_right;
 11091110         else
 11101111                 q = p->n_left;
 11111112 
 11121113         if (!ISPTR(q->n_type) && !ISARY(q->n_type)) {
 11131114                 if (q->n_op != ICON || q->n_lval != 0)
 11141115                         werror("illegal combination of pointer and integer");
 11151116         } else {
 11161117                 if (t1 == t2) {
 11171118                         if (ISSOU(BTYPE(t1)) &&
 11181119                             !suemeq(p->n_left->n_ap, p->n_right->n_ap))
 11191120                                 werror("illegal structure pointer combination");
 11201121                         return;
 11211122                 }
 11221123                 d1 = p->n_left->n_df;
 11231124                 d2 = p->n_right->n_df;
 11241125                 for (;;) {
 11251126                         if (ISARY(t1) || ISPTR(t1)) {
 11261127                                 if (!ISARY(t2) && !ISPTR(t2))
 11271128                                         break;
 11281129                                 if (ISARY(t1) && ISARY(t2) && d1->ddim != d2->ddim) {
 11291130                                         werror("illegal array size combination");
 11301131                                         return;
 11311132                                 }
 11321133                                 if (ISARY(t1))
 11331134                                         ++d1;
 11341135                                 if (ISARY(t2))
 11351136                                         ++d2;
 11361137                         } else if (ISFTN(t1)) {
 11371138                                 if (chkftn(d1->dfun, d2->dfun)) {
 11381139                                         werror("illegal function "
 11391140                                             "pointer combination");
 11401141                                         return;
 11411142                                 }
 11421143                                 ++d1;
 11431144                                 ++d2;
 11441145                         } else
 11451146                                 break;
 11461147                         t1 = DECREF(t1);
 11471148                         t2 = DECREF(t2);
 11481149                 }
 11491150                 if (DEUNSIGN(t1) != DEUNSIGN(t2))
 11501151                         warner(Wpointer_sign, NULL);
 11511152         }
 11521153 }
 11531154 
 11541155 static NODE *
 11551156 offplus(NODE *p, int off, TWORD t, TWORD q, union dimfun *d, struct attr *ap) {
 11561157         if (off != 0) {
 11571158                 p = block(PLUS, p, offcon(off, t, d, ap), t, d, ap);
 11581159                 p->n_qual = q;
 11591160                 p = optim(p);
 11601161         }
 11611162 
 11621163         return buildtree(UMUL, p, NIL);
 11631164 }
 11641165 
 11651166 NODE *
 11661167 stref(NODE *p)
 11671168 {
 11681169         NODE *r;
 11691170         struct attr *ap, *xap, *yap;
 11701171         union dimfun *d;
 11711172         TWORD t, q;
 11721173         int dsc;
 11731174         OFFSZ off;
 11741175         struct symtab *s;
 11751176 
 11761177         /* make p->x */
 11771178         /* this is also used to reference automatic variables */
 11781179 
 11791180         s = p->n_right->n_sp;
 11801181         nfree(p->n_right);
 11811182         r = nfree(p);
 11821183         xap = attr_find(r->n_ap, GCC_ATYP_PACKED);
 11831184 
 11841185         p = pconvert(r);
 11851186 
 11861187         /* make p look like ptr to x */
 11871188 
 11881189         if (!ISPTR(p->n_type))
 11891190                 p->n_type = PTR+UNIONTY;
 11901191 
 11911192         t = INCREF(s->stype);
 11921193         q = INCQAL(s->squal);
 11931194         d = s->sdf;
 11941195         ap = s->sap;
 11951196         if ((yap = attr_find(ap, GCC_ATYP_PACKED)) != NULL)
 11961197                 xap = yap;
 11971198         else if (xap != NULL)
 11981199                 ap = attr_add(ap, attr_dup(xap, 3));
 11991200         /* xap set if packed struct */
 12001201 
 12011202         p = makety(p, t, q, d, ap);
 12021203 
 12031204         /* compute the offset to be added */
 12041205 
 12051206         off = s->soffset;
 12061207         dsc = s->sclass;
 12071208 
 12081209         if (dsc & FIELD) {
 12091210                 TWORD ftyp = s->stype;
 12101211                 int fal = talign(ftyp, ap);
 12111212                 off = (off/fal)*fal;
 12121213                 p = offplus(p, off, t, q, d, ap);
 12131214                 p = block(FLD, p, NIL, ftyp, 0, ap);
 12141215                 p->n_qual = q;
 12151216                 p->n_rval = PKFIELD(dsc&FLDSIZ, s->soffset%fal);
 12161217         } else {
 12171218                 p = offplus(p, off, t, q, d, ap);
 12181219 #ifndef CAN_UNALIGN
 12191220                 /* if target cannot handle unaligned addresses, fix here */
 12201221 #endif
 12211222         }
 12221223 
 12231224         p = clocal(p);
 12241225         return p;
 12251226 }
 12261227 
 12271228 int
 12281229 notlval(register NODE *p)
 12291230 {
 12301231         /* return 0 if p an lvalue, 1 otherwise */
 12311232 
 12321233         again:
 12331234 
 12341235         switch( p->n_op ){
 12351236 
 12361237         case FLD:
 12371238                 p = p->n_left;
 12381239                 goto again;
 12391240 
 12401241         case NAME:
 12411242         case OREG:
 12421243         case UMUL:
 12431244                 if( ISARY(p->n_type) || ISFTN(p->n_type) ) return(1);
<> 1245+                /* FALLTHROUGH */
12441246         case TEMP:
 12451247         case REG:
 12461248                 return(0);
 12471249 
 12481250         default:
 12491251                 return(1);
 12501252         }
 12511253 }
 12521254 
 12531255 /* make a constant node with value i */
 12541256 NODE *
 12551257 bcon(int i)
 12561258 {
 12571259         return xbcon(i, NULL, INT);
 12581260 }
 12591261 
 12601262 NODE *
 12611263 xbcon(CONSZ val, struct symtab *sp, TWORD type)
 12621264 {
 12631265         NODE *p;
 12641266 
 12651267         p = block(ICON, NIL, NIL, type, 0, 0);
 12661268         p->n_lval = val;
 12671269         p->n_sp = sp;
 12681270         return clocal(p);
 12691271 }
 12701272 
 12711273 NODE *
 12721274 bpsize(NODE *p)
 12731275 {
 12741276         int isdyn(struct symtab *sp);
 12751277         struct symtab s;
 12761278         NODE *q, *r;
 12771279         TWORD t;
 12781280         int sz;
 12791281 
 12801282         s.stype = DECREF(p->n_type);
 12811283         s.sdf = p->n_df;
 12821284         if (isdyn(&s)) {
 12831285                 q = bcon(1);
 12841286                 for (t = s.stype; t > BTMASK; t = DECREF(t)) {
 12851287                         if (ISPTR(t))
 12861288                                 return buildtree(MUL, q, bcon(SZPOINT(t)));
 12871289                         if (ISARY(t)) {
 12881290                                 if (s.sdf->ddim < 0)
 12891291                                         r = tempnode(-s.sdf->ddim, INT, 0, 0);
 12901292                                 else
 12911293                                         r = bcon(s.sdf->ddim/SZCHAR);
 12921294                                 q = buildtree(MUL, q, r);
 12931295                                 s.sdf++;
 12941296                         }
 12951297                 }
 12961298                 sz = (int)tsize(t, s.sdf, p->n_ap);
 12971299                 p = buildtree(MUL, q, bcon(sz/SZCHAR));
 12981300         } else
 12991301                 p = (offcon(psize(p), p->n_type, p->n_df, p->n_ap));
 13001302         return p;
 13011303 }
 13021304 
 13031305 /*
 13041306  * p is a node of type pointer; psize returns the
 13051307  * size of the thing pointed to
 13061308  */
 13071309 OFFSZ
 13081310 psize(NODE *p)
 13091311 {
 13101312 
 13111313         if (!ISPTR(p->n_type)) {
 13121314                 uerror("pointer required");
 13131315                 return(SZINT);
 13141316         }
 13151317         /* note: no pointers to fields */
 13161318         return(tsize(DECREF(p->n_type), p->n_df, p->n_ap));
 13171319 }
 13181320 
 13191321 /*
 13201322  * convert an operand of p
 13211323  * f is either CVTL or CVTR
 13221324  * operand has type int, and is converted by the size of the other side
 13231325  * convert is called when an integer is to be added to a pointer, for
 13241326  * example in arrays or structures.
 13251327  */
 13261328 NODE *
 13271329 convert(NODE *p, int f)
 13281330 {
 13291331         union dimfun *df;
 13301332         TWORD ty, ty2;
 13311333         NODE *q, *r, *s, *rv;
 13321334 
 13331335         if (f == CVTL) {
 13341336                 q = p->n_left;
 13351337                 s = p->n_right;
 13361338         } else {
 13371339                 q = p->n_right;
 13381340                 s = p->n_left;
 13391341         }
 13401342         ty2 = ty = DECREF(s->n_type);
 13411343         while (ISARY(ty))
 13421344                 ty = DECREF(ty);
 13431345 
 13441346         r = offcon(tsize(ty, s->n_df, s->n_ap), s->n_type, s->n_df, s->n_ap);
 13451347         ty = ty2;
 13461348         rv = bcon(1);
 13471349         df = s->n_df;
 13481350         while (ISARY(ty)) {
 13491351                 rv = buildtree(MUL, rv, df->ddim >= 0 ? bcon(df->ddim) :
 13501352                     tempnode(-df->ddim, INT, 0, 0));
 13511353                 df++;
 13521354                 ty = DECREF(ty);
 13531355         }
 13541356         rv = clocal(MBLOCK(rv, r, INT, 0, 0));
 13551357         rv = optim(rv);
 13561358 
 13571359         r = MBLOCK(q, rv, INT, 0, 0);
 13581360         r = clocal(r);
 13591361         /*
 13601362          * Indexing is only allowed with integer arguments, so insert
 13611363          * SCONV here if arg is not an integer.
 13621364          * XXX - complain?
 13631365          */
 13641366         if (r->n_type != INTPTR)
 13651367                 r = clocal(makety(r, INTPTR, 0, 0, 0));
 13661368         if (f == CVTL)
 13671369                 p->n_left = r;
 13681370         else
 13691371                 p->n_right = r;
 13701372         return(p);
 13711373 }
 13721374 
 13731375 NODE *
 13741376 pconvert(register NODE *p)
 13751377 {
 13761378         /* if p should be changed into a pointer, do so */
 13771379 
 13781380         if( ISARY( p->n_type) ){
 13791381                 p->n_type = DECREF( p->n_type );
 13801382                 ++p->n_df;
 13811383                 return( buildtree( ADDROF, p, NIL ) );
 13821384         }
 13831385         if( ISFTN( p->n_type) )
 13841386                 return( buildtree( ADDROF, p, NIL ) );
 13851387 
 13861388         return( p );
 13871389 }
 13881390 
 13891391 NODE *
 13901392 oconvert(register NODE *p)
 13911393 {
 13921394         /* convert the result itself: used for pointer and unsigned */
 13931395 
 13941396         switch(p->n_op) {
 13951397 
 13961398         case LE:
 13971399         case LT:
 13981400         case GE:
 13991401         case GT:
 14001402                 if(ISUNSIGNED(p->n_left->n_type) ||
 14011403                     ISUNSIGNED(p->n_right->n_type) ||
 14021404                     ISPTR(p->n_left->n_type) ||
 14031405                     ISPTR(p->n_right->n_type))
 14041406                          p->n_op += (ULE-LE);
 14051407                 /* FALLTHROUGH */
 14061408         case EQ:
 14071409         case NE:
 14081410                 return( p );
 14091411 
 14101412         case MINUS:
 14111413                 p->n_type = INTPTR;
 14121414                 p->n_ap = NULL;
 14131415                 return(clocal(VBLOCK(p, bpsize(p->n_left), INT, 0, 0)));
 14141416                 }
 14151417 
 14161418         cerror( "illegal oconvert: %d", p->n_op );
 14171419 
 14181420         return(p);
 14191421 }
 14201422 
 14211423 /*
 14221424  * makes the operands of p agree; they are
 14231425  * either pointers or integers, by this time
 14241426  * with MINUS, the sizes must be the same
 14251427  * with COLON, the types must be the same
 14261428  */
 14271429 NODE *
 14281430 ptmatch(NODE *p)
 14291431 {
 14301432         struct attr *ap, *ap2;
 14311433         union dimfun *d, *d2;
 14321434         TWORD t1, t2, t, q1, q2, q;
 14331435         int o;
 14341436 
 14351437         o = p->n_op;
 14361438         t = t1 = p->n_left->n_type;
 14371439         q = q1 = p->n_left->n_qual;
 14381440         t2 = p->n_right->n_type;
 14391441         q2 = p->n_right->n_qual;
 14401442         d = p->n_left->n_df;
 14411443         d2 = p->n_right->n_df;
 14421444         ap = p->n_left->n_ap;
 14431445         ap2 = p->n_right->n_ap;
 14441446 
 14451447         switch( o ){
 14461448 
 14471449         case ASSIGN:
 14481450         case RETURN:
 14491451                 {  break; }
 14501452 
 14511453         case CAST:
 14521454                 if (t == VOID) {
 14531455                         /* just paint over */
 14541456                         p->n_right = block(SCONV, p->n_right, NIL, VOID, 0, 0);
 14551457                         return p;
 14561458                 }
 14571459                 break;
 14581460 
 14591461         case MINUS: {
 14601462                 int isdyn(struct symtab *sp);
 14611463                 struct symtab s1, s2;
 14621464 
 14631465                 s1.stype = DECREF(t);
 14641466                 s1.sdf = d;
 14651467                 s2.stype = DECREF(t2);
 14661468                 s2.sdf = d2;
 14671469                 if (isdyn(&s1) || isdyn(&s2))
 14681470                         ; /* We don't know */
 14691471                 else if (psize(p->n_left) != psize(p->n_right))
 14701472                         uerror("illegal pointer subtraction");
 14711473                 break;
 14721474                 }
 14731475 
 14741476         case COLON:
 14751477                 if (t1 != t2) {
 14761478                         /*
 14771479                          * Check for void pointer types. They are allowed
 14781480                          * to cast to/from any pointers.
 14791481                          */
 14801482                         if (ISPTR(t1) && ISPTR(t2) &&
 14811483                             (BTYPE(t1) == VOID || BTYPE(t2) == VOID))
 14821484                                 break;
 14831485                         uerror("illegal types in :");
 14841486                 }
 14851487                 break;
 14861488 
 14871489         default/* must work harder: relationals or comparisons */
 14881490 
 14891491                 if( !ISPTR(t1) ){
 14901492                         t = t2;
 14911493                         q = q2;
 14921494                         d = d2;
 14931495                         ap = ap2;
 14941496                         break;
 14951497                         }
 14961498                 if( !ISPTR(t2) ){
 14971499                         break;
 14981500                         }
 14991501 
 15001502                 /* both are pointers */
 15011503                 if( talign(t2,ap2) < talign(t,ap) ){
 15021504                         t = t2;
 15031505                         q = q2;
 15041506                         ap = ap2;
 15051507                         }
 15061508                 break;
 15071509                 }
 15081510 
 15091511         p->n_left = makety( p->n_left, t, q, d, ap );
 15101512         p->n_right = makety( p->n_right, t, q, d, ap );
 15111513         if( o!=MINUS && !clogop(o) ){
 15121514 
 15131515                 p->n_type = t;
 15141516                 p->n_qual = q;
 15151517                 p->n_df = d;
 15161518                 p->n_ap = ap;
 15171519                 }
 15181520 
 15191521         return(clocal(p));
 15201522 }
 15211523 
 15221524 /*
 15231525  * Satisfy the types of various arithmetic binary ops.
 15241526  *
 15251527  * rules are:
 15261528  *  if assignment, type of LHS
 15271529  *  if any doubles, make double
 15281530  *  else if any float make float
 15291531  *  else if any longlongs, make long long
 15301532  *  else if any longs, make long
 15311533  *  else etcetc.
 15321534  *
 15331535  *  If the op with the highest rank is unsigned, this is the resulting type.
 15341536  *  See:  6.3.1.1 rank order equal of signed and unsigned types
 15351537  *        6.3.1.8 Usual arithmetic conversions
 15361538  */
 15371539 static NODE *
 15381540 tymatch(NODE *p)
 15391541 {
 15401542         TWORD tl, tr, t;
 15411543         NODE *l, *r;
 15421544         int o;
 15431545 
 15441546         o = p->n_op;
 15451547         r = p->n_right;
 15461548         l = p->n_left;
 15471549 
 15481550         tl = l->n_type;
 15491551         tr = r->n_type;
 15501552 
 15511553         if (tl == BOOL) tl = BOOL_TYPE;
 15521554         if (tr == BOOL) tr = BOOL_TYPE;
 15531555 
 15541556         if (casgop(o)) {
 15551557                 if (r->n_op != ICON && tl < FLOAT && tr < FLOAT &&
 15561558                     DEUNSIGN(tl) < DEUNSIGN(tr) && o != CAST)
 15571559                         warner(Wtruncate, tnames[tr], tnames[tl]);
 15581560                 p->n_right = makety(p->n_right, l->n_type, 0, 0, 0);
 15591561                 t = p->n_type = l->n_type;
 15601562                 p->n_ap = l->n_ap;
 15611563         } else {
 15621564                 t = tl > tr ? tl : tr; /* MAX */
 15631565                 /* This depends on ctype() called early */
 15641566                 if (o != COLON && t < INT)
 15651567                         t = INT;
 15661568                 if (tl != t) p->n_left = makety(p->n_left, t, 0, 0, 0);
 15671569                 if (tr != t) p->n_right = makety(p->n_right, t, 0, 0, 0);
 15681570                 if (o == COLON && l->n_type == BOOL && r->n_type == BOOL)
 15691571                         t = p->n_type = BOOL;
 15701572                 else if (!clogop(o))
 15711573                         p->n_type = t;
 15721574         }
 15731575 #ifdef PCC_DEBUG
 15741576         if (tdebug) {
 15751577                 printf("tymatch(%p): ", p);
 15761578                 tprint(tl, 0);
 15771579                 printf(" %s ", copst(o));
 15781580                 tprint(tr, 0);
 15791581                 printf(" => ");
 15801582                 tprint(t, 0);
 15811583                 printf("\n");
 15821584                 fwalk(p, eprint, 0);
 15831585         }
 15841586 #endif
 15851587         return p;
 15861588 }
 15871589 
 15881590 /*
 15891591  * make p into type t by inserting a conversion
 15901592  */
 15911593 NODE *
 15921594 makety(NODE *p, TWORD t, TWORD q, union dimfun *d, struct attr *ap)
 15931595 {
 15941596 
 15951597         if (t == p->n_type) {
 15961598                 p->n_df = d;
 15971599                 p->n_ap = ap;
 15981600                 p->n_qual = q;
 15991601                 return(p);
 16001602         }
 16011603 
 16021604         if (ISITY(t) || ISCTY(t) || ISITY(p->n_type) || ISCTY(p->n_type))
 16031605                 cerror("makety");
 16041606 
 16051607         if (concast(p, t))
 16061608                 return clocal(p);
 16071609 
 16081610         p = block(t & TMASK ? PCONV : SCONV, p, NIL, t, d, ap);
 16091611         p->n_qual = q;
 16101612         return clocal(p);
 16111613 }
 16121614 
 16131615 NODE *
 16141616 block(int o, NODE *l, NODE *r, TWORD t, union dimfun *d, struct attr *ap)
 16151617 {
 16161618         register NODE *p;
 16171619 
 16181620         p = talloc();
 16191621         p->n_rval = 0;
 16201622         p->n_op = o;
 16211623         p->n_lval = 0; /* Protect against large lval */
 16221624         p->n_left = l;
 16231625         p->n_right = r;
 16241626         p->n_type = t;
 16251627         p->n_qual = 0;
 16261628         p->n_df = d;
 16271629         p->n_ap = ap;
 16281630 #if !defined(MULTIPASS)
 16291631         /* p->n_reg = */p->n_su = 0;
 16301632         p->n_regw = 0;
 16311633 #endif
 16321634         return(p);
 16331635 }
 16341636 
 16351637 /*
 16361638  * Return the constant value from an ICON.
 16371639  */
 16381640 CONSZ
 16391641 icons(NODE *p)
 16401642 {
 16411643         /* if p is an integer constant, return its value */
 16421644         CONSZ val;
 16431645 
 16441646         if (p->n_op != ICON || p->n_sp != NULL) {
 16451647                 uerror( "constant expected");
 16461648                 val = 1;
 16471649         } else
 16481650                 val = p->n_lval;
 16491651         tfree(p);
 16501652         return(val);
 16511653 }
 16521654 
 16531655 /*
 16541656  * the intent of this table is to examine the
 16551657  * operators, and to check them for
 16561658  * correctness.
 16571659  *
 16581660  * The table is searched for the op and the
 16591661  * modified type (where this is one of the
 16601662  * types INT (includes char and short), LONG,
 16611663  * DOUBLE (includes FLOAT), and POINTER
 16621664  *
 16631665  * The default action is to make the node type integer
 16641666  *
 16651667  * The actions taken include:
 16661668  *      PUN       check for puns
 16671669  *      CVTL      convert the left operand
 16681670  *      CVTR      convert the right operand
 16691671  *      TYPL      the type is determined by the left operand
 16701672  *      TYPR      the type is determined by the right operand
 16711673  *      TYMATCH   force type of left and right to match,by inserting conversions
 16721674  *      PTMATCH   like TYMATCH, but for pointers
 16731675  *      LVAL      left operand must be lval
 16741676  *      CVTO      convert the op
 16751677  *      NCVT      do not convert the operands
 16761678  *      OTHER     handled by code
 16771679  *      NCVTR     convert the left operand, not the right...
 16781680  *
 16791681  */
 16801682 
 16811683 # define MINT 01        /* integer */
 16821684 # define MDBI 02        /* integer or double */
 16831685 # define MSTR 04        /* structure */
 16841686 # define MPTR 010       /* pointer */
 16851687 # define MPTI 020       /* pointer or integer */
 16861688 
 16871689 int
 16881690 opact(NODE *p)
 16891691 {
 16901692         int mt12, mt1, mt2, o;
 16911693 
 16921694         mt1 = mt2 = mt12 = 0;
 16931695 
 16941696         switch (coptype(o = p->n_op)) {
 16951697         case BITYPE:
 16961698                 mt12=mt2 = moditype(p->n_right->n_type);
<> 1699+                /* FALLTHROUGH */
16971700         case UTYPE:
 16981701                 mt12 &= (mt1 = moditype(p->n_left->n_type));
 16991702                 break;
 17001703         }
 17011704 
 17021705         switch( o ){
 17031706 
 17041707         case NAME :
 17051708         case ICON :
 17061709         case FCON :
 17071710         case CALL :
 17081711         case UCALL:
 17091712         case UMUL:
 17101713                 {  return( OTHER ); }
 17111714         case UMINUS:
 17121715                 if( mt1 & MDBI ) return( TYPL+PROML );
 17131716                 break;
 17141717 
 17151718         case COMPL:
 17161719                 if( mt1 & MINT ) return( TYPL+PROML );
 17171720                 break;
 17181721 
 17191722         case ADDROF:
 17201723                 return( NCVT+OTHER );
 17211724         case NOT:
 17221725                 return( PROML );
 17231726 
 17241727 /*      case INIT: */
 17251728         case CM:
 17261729         case CBRANCH:
 17271730         case ANDAND:
 17281731         case OROR:
 17291732                 return( 0 );
 17301733 
 17311734         case MUL:
 17321735         case DIV:
 17331736                 if( mt12 & MDBI ) return( TYMATCH );
 17341737                 break;
 17351738 
 17361739         case MOD:
 17371740         case AND:
 17381741         case OR:
 17391742         case ER:
 17401743                 if( mt12 & MINT ) return( TYMATCH );
 17411744                 break;
 17421745 
 17431746         case LS:
 17441747         case RS:
 17451748                 if( mt12 & MINT ) return( TYPL+OTHER );
 17461749                 break;
 17471750 
 17481751         case EQ:
 17491752         case NE:
 17501753         case LT:
 17511754         case LE:
 17521755         case GT:
 17531756         case GE:
 17541757                 if( mt12 & MDBI ) return( TYMATCH+CVTO );
 17551758                 else if( mt12 & MPTR ) return( PTMATCH+PUN+CVTO );
 17561759                 else if( mt12 & MPTI ) return( PTMATCH+PUN );
 17571760                 else break;
 17581761 
 17591762         case QUEST:
 17601763                 return( TYPR+OTHER );
 17611764         case COMOP:
 17621765                 return( TYPR );
 17631766 
 17641767         case STREF:
 17651768                 return( NCVTR+OTHER );
 17661769 
 17671770         case FORCE:
 17681771                 return( TYPL );
 17691772 
 17701773         case COLON:
 17711774                 if( mt12 & MDBI ) return( TYMATCH );
 17721775                 else if( mt12 & MPTR ) return( TYPL+PTMATCH+PUN );
 17731776                 else if( (mt1&MINT) && (mt2&MPTR) ) return( TYPR+PUN );
 17741777                 else if( (mt1&MPTR) && (mt2&MINT) ) return( TYPL+PUN );
 17751778                 else if( mt12 & MSTR ) return( NCVT+TYPL+OTHER );
 17761779                 break;
 17771780 
 17781781         case ASSIGN:
 17791782         case RETURN:
 17801783                 if( mt12 & MSTR ) return( LVAL+NCVT+TYPL+OTHER );
<> 1784+                /* FALLTHROUGH */
17811785         case CAST:
 17821786                 if( mt12 & MDBI ) return( TYPL+LVAL+TYMATCH );
 17831787                 else if( mt1 & MPTR) return( LVAL+PTMATCH+PUN );
 17841788                 else if( mt12 & MPTI ) return( TYPL+LVAL+TYMATCH+PUN );
 17851789                 break;
 17861790 
 17871791         case MINUS:
 17881792                 if (mt12 & MPTR)
 17891793                         return(CVTO+PTMATCH+PUN);
 17901794                 if (mt2 & MPTR)
 17911795                         break;
 17921796                 /* FALLTHROUGH */
 17931797         case PLUS:
 17941798                 if (mt12 & MDBI)
 17951799                         return(TYMATCH);
 17961800                 else if ((mt1&MPTR) && (mt2&MINT))
 17971801                         return(TYPL+CVTR);
 17981802                 else if ((mt1&MINT) && (mt2&MPTR))
 17991803                         return(TYPR+CVTL);
 18001804 
 18011805         }
 18021806         uerror("operands of %s have incompatible types", copst(o));
 18031807         return(NCVT);
 18041808 }
 18051809 
 18061810 int
 18071811 moditype(TWORD ty)
 18081812 {
 18091813         switch (ty) {
 18101814 
 18111815         case STRTY:
 18121816         case UNIONTY:
 18131817                 return( MSTR );
 18141818 
 18151819         case BOOL:
 18161820         case CHAR:
 18171821         case SHORT:
 18181822         case UCHAR:
 18191823         case USHORT:
 18201824         case UNSIGNED:
 18211825         case ULONG:
 18221826         case ULONGLONG:
 18231827         case INT:
 18241828         case LONG:
 18251829         case LONGLONG:
 18261830                 return( MINT|MDBI|MPTI );
 18271831         case FLOAT:
 18281832         case DOUBLE:
 18291833         case LDOUBLE:
 18301834 #ifndef NO_COMPLEX
 18311835         case FCOMPLEX:
 18321836         case COMPLEX:
 18331837         case LCOMPLEX:
 18341838         case FIMAG:
 18351839         case IMAG:
 18361840         case LIMAG:
 18371841 #endif
 18381842                 return( MDBI );
 18391843         default:
 18401844                 return( MPTR|MPTI );
 18411845 
 18421846         }
 18431847 }
 18441848 
 18451849 int tvaloff = MAXREGS+NPERMREG > 100 ? MAXREGS+NPERMREG + 100 : 100;
 18461850 
 18471851 /*
 18481852  * Returns a TEMP node with temp number nr.
 18491853  * If nr == 0, return a node with a new number.
 18501854  */
 18511855 NODE *
 18521856 tempnode(int nr, TWORD type, union dimfun *df, struct attr *ap)
 18531857 {
 18541858         NODE *r;
 18551859 
 18561860         if (tvaloff == -NOOFFSET)
 18571861                 tvaloff++; /* Skip this for array indexing */
 18581862         r = block(TEMP, NIL, NIL, type, df, ap);
 18591863         regno(r) = nr ? nr : tvaloff;
 18601864         tvaloff += szty(type);
 18611865         return r;
 18621866 }
 18631867 
 18641868 /*
 18651869  * Do sizeof on p.
 18661870  */
 18671871 NODE *
 18681872 doszof(NODE *p)
 18691873 {
 18701874         extern NODE *arrstk[10];
 18711875         extern int arrstkp;
 18721876         union dimfun *df;
 18731877         TWORD ty;
 18741878         NODE *rv, *q;
 18751879         int astkp;
 18761880 
 18771881         if (p->n_op == FLD)
 18781882                 uerror("can't apply sizeof to bit-field");
 18791883 
 18801884         /*
 18811885          * Arrays may be dynamic, may need to make computations.
 18821886          */
 18831887 
 18841888         rv = bcon(1);
 18851889         df = p->n_df;
 18861890         ty = p->n_type;
 18871891         astkp = 0;
 18881892         while (ISARY(ty)) {
 18891893                 if (df->ddim == NOOFFSET)
 18901894                         uerror("sizeof of incomplete type");
 18911895                 if (df->ddim < 0) {
 18921896                         if (arrstkp)
 18931897                                 q = arrstk[astkp++];
 18941898                         else
 18951899                                 q = tempnode(-df->ddim, INT, 0, 0);
 18961900                 } else
 18971901                         q = bcon(df->ddim);
 18981902                 rv = buildtree(MUL, rv, q);
 18991903                 df++;
 19001904                 ty = DECREF(ty);
 19011905         }
 19021906         rv = buildtree(MUL, rv,
 19031907             xbcon(tsize(ty, p->n_df, p->n_ap)/SZCHAR, NULL, INTPTR));
 19041908         tfree(p);
 19051909         arrstkp = 0; /* XXX - may this fail? */
 19061910         return rv;
 19071911 }
 19081912 
 19091913 #ifdef PCC_DEBUG
 19101914 void
 19111915 eprint(NODE *p, int down, int *a, int *b)
 19121916 {
 19131917         int ty;
 19141918 
 19151919         *a = *b = down+1;
 19161920         while( down > 1 ){
 19171921                 printf( "\t" );
 19181922                 down -= 2;
 19191923                 }
 19201924         if( down ) printf( "    " );
 19211925 
 19221926         ty = coptype( p->n_op );
 19231927 
 19241928         printf("%p) %s, ", p, copst(p->n_op));
 19251929         if (p->n_op == XARG || p->n_op == XASM)
 19261930                 printf("id '%s', ", p->n_name);
 19271931         if (ty == LTYPE) {
 19281932                 printf(CONFMT, p->n_lval);
 19291933                 if (p->n_op == NAME || p->n_op == ICON)
 19301934                         printf(", %p, ", p->n_sp);
 19311935                 else
 19321936                         printf(", %d, ", p->n_rval);
 19331937         }
 19341938         tprint(p->n_type, p->n_qual);
 19351939         printf( ", %p, ", p->n_df);
 19361940         dump_attr(p->n_ap);
 19371941 }
 19381942 # endif
 19391943 
 19401944 /*
 19411945  * Emit everything that should be emitted on the left side
 19421946  * of a comma operator, and remove the operator.
 19431947  * Do not traverse through QUEST, ANDAND and OROR.
 19441948  * Enable this for all targets when stable enough.
 19451949  */
 19461950 static void
 19471951 comops(NODE *p)
 19481952 {
 19491953         int o;
 19501954         NODE *q;
 19511955 
 19521956         while (p->n_op == COMOP) {
 19531957                 /* XXX hack for GCC ({ }) ops */
 19541958                 if (p->n_left->n_op == GOTO) {
 19551959                         int v = (int)p->n_left->n_left->n_lval;
 19561960                         ecomp(p->n_left);
 19571961                         plabel(v+1);
 19581962                 } else
 19591963                         ecomp(p->n_left); /* will recurse if more COMOPs */
 19601964                 q = p->n_right;
 19611965                 *p = *q;
 19621966                 nfree(q);
 19631967         }
 19641968         o = coptype(p->n_op);
 19651969         if (p->n_op == QUEST || p->n_op == ANDAND || p->n_op == OROR)
 19661970                 o = UTYPE;
 19671971         if (o != LTYPE)
 19681972                 comops(p->n_left);
 19691973         if (o == BITYPE)
 19701974                 comops(p->n_right);
 19711975 }
 19721976 
 19731977 /*
 19741978  * Walk up through the tree from the leaves,
 19751979  * removing constant operators.
 19761980  */
 19771981 static void
 19781982 logwalk(NODE *p)
 19791983 {
 19801984         int o = coptype(p->n_op);
 19811985         NODE *l, *r;
 19821986 
 19831987         l = p->n_left;
 19841988         r = p->n_right;
 19851989         switch (o) {
 19861990         case LTYPE:
 19871991                 return;
 19881992         case BITYPE:
 19891993                 logwalk(r);
<> 1994+                /* FALLTHROUGH */
19901995         case UTYPE:
 19911996                 logwalk(l);
 19921997         }
 19931998         if (!clogop(p->n_op))
 19941999                 return;
 19952000         if (p->n_op == NOT && l->n_op == ICON) {
 19962001                 p->n_lval = l->n_lval == 0;
 19972002                 nfree(l);
 19982003                 p->n_op = ICON;
 19992004         }
 20002005         if (l->n_op == ICON && r->n_op == ICON) {
 20012006                 if (conval(l, p->n_op, r) == 0) {
 20022007                         /*
 20032008                          * people sometimes tend to do really odd compares,
 20042009                          * like "if ("abc" == "def")" etc.
 20052010                          * do it runtime instead.
 20062011                          */
 20072012                 } else {
 20082013                         p->n_lval = l->n_lval;
 20092014                         p->n_op = ICON;
 20102015                         nfree(l);
 20112016                         nfree(r);
 20122017                 }
 20132018         }
 20142019 }
 20152020 
 20162021 /*
 20172022  * Removes redundant logical operators for branch conditions.
 20182023  */
 20192024 static void
 20202025 fixbranch(NODE *p, int label)
 20212026 {
 20222027 
 20232028         logwalk(p);
 20242029 
 20252030         if (p->n_op == ICON) {
 20262031                 if (p->n_lval != 0)
 20272032                         branch(label);
 20282033                 nfree(p);
 20292034         } else {
 20302035                 if (!clogop(p->n_op)) /* Always conditional */
 20312036                         p = buildtree(NE, p, bcon(0));
 20322037                 ecode(buildtree(CBRANCH, p, bcon(label)));
 20332038         }
 20342039 }
 20352040 
 20362041 /*
 20372042  * Write out logical expressions as branches.
 20382043  */
 20392044 static void
 20402045 andorbr(NODE *p, int true, int false)
 20412046 {
 20422047         NODE *q;
 20432048         int o, lab;
 20442049 
 20452050         lab = -1;
 20462051         switch (o = p->n_op) {
 20472052         case EQ:
 20482053         case NE:
 20492054                 /*
 20502055                  * Remove redundant EQ/NE nodes.
 20512056                  */
 20522057                 while (((o = p->n_left->n_op) == EQ || o == NE) &&
 20532058                     p->n_right->n_op == ICON) {
 20542059                         o = p->n_op;
 20552060                         q = p->n_left;
 20562061                         if (p->n_right->n_lval == 0) {
 20572062                                 nfree(p->n_right);
 20582063                                 *p = *q;
 20592064                                 nfree(q);
 20602065                                 if (o == EQ)
 20612066                                         p->n_op = negrel[p->n_op - EQ];
 20622067 #if 0
 20632068                                         p->n_op = NE; /* toggla */
 20642069 #endif
 20652070                         } else if (p->n_right->n_lval == 1) {
 20662071                                 nfree(p->n_right);
 20672072                                 *p = *q;
 20682073                                 nfree(q);
 20692074                                 if (o == NE)
 20702075                                         p->n_op = negrel[p->n_op - EQ];
 20712076 #if 0
 20722077                                         p->n_op = EQ; /* toggla */
 20732078 #endif
 20742079                         } else
 20752080                                 break; /* XXX - should always be false */
 20762081                         
 20772082                 }
 20782083                 /* FALLTHROUGH */
 20792084         case LE:
 20802085         case LT:
 20812086         case GE:
 20822087         case GT:
 20832088 calc:           if (true < 0) {
 20842089                         p->n_op = negrel[p->n_op - EQ];
 20852090                         true = false;
 20862091                         false = -1;
 20872092                 }
 20882093 
 20892094                 rmcops(p->n_left);
 20902095                 rmcops(p->n_right);
 20912096                 fixbranch(p, true);
 20922097                 if (false >= 0)
 20932098                         branch(false);
 20942099                 break;
 20952100 
 20962101         case ULE:
 20972102         case UGT:
 20982103                 /* Convert to friendlier ops */
 20992104                 if (nncon(p->n_right) && p->n_right->n_lval == 0)
 21002105                         p->n_op = o == ULE ? EQ : NE;
 21012106                 goto calc;
 21022107 
 21032108         case UGE:
 21042109         case ULT:
 21052110                 /* Already true/false by definition */
 21062111                 if (nncon(p->n_right) && p->n_right->n_lval == 0) {
 21072112                         if (true < 0) {
 21082113                                 o = o == ULT ? UGE : ULT;
 21092114                                 true = false;
 21102115                         }
 21112116                         rmcops(p->n_left);
 21122117                         ecode(p->n_left);
 21132118                         rmcops(p->n_right);
 21142119                         ecode(p->n_right);
 21152120                         nfree(p);
 21162121                         if (o == UGE) /* true */
 21172122                                 branch(true);
 21182123                         break;
 21192124                 }
 21202125                 goto calc;
 21212126 
 21222127         case ANDAND:
 21232128                 lab = false<0 ? getlab() : false ;
 21242129                 andorbr(p->n_left, -1, lab);
 21252130                 comops(p->n_right);
 21262131                 andorbr(p->n_right, true, false);
 21272132                 if (false < 0)
 21282133                         plabel( lab);
 21292134                 nfree(p);
 21302135                 break;
 21312136 
 21322137         case OROR:
 21332138                 lab = true<0 ? getlab() : true;
 21342139                 andorbr(p->n_left, lab, -1);
 21352140                 comops(p->n_right);
 21362141                 andorbr(p->n_right, true, false);
 21372142                 if (true < 0)
 21382143                         plabel( lab);
 21392144                 nfree(p);
 21402145                 break;
 21412146 
 21422147         case NOT:
 21432148                 andorbr(p->n_left, false, true);
 21442149                 nfree(p);
 21452150                 break;
 21462151 
 21472152         default:
 21482153                 rmcops(p);
 21492154                 if (true >= 0)
 21502155                         fixbranch(p, true);
 21512156                 if (false >= 0) {
 21522157                         if (true >= 0)
 21532158                                 branch(false);
 21542159                         else
 21552160                                 fixbranch(buildtree(EQ, p, bcon(0)), false);
 21562161                 }
 21572162         }
 21582163 }
 21592164 
 21602165 /*
 21612166  * Create a node for either TEMP or on-stack storage.
 21622167  */
 21632168 NODE *
 21642169 cstknode(TWORD t, union dimfun *df, struct attr *ap)
 21652170 {
 21662171         struct symtab *sp;
 21672172 
 21682173         /* create a symtab entry suitable for this type */
 21692174         sp = getsymtab("0hej", STEMP);
 21702175         sp->stype = t;
 21712176         sp->sdf = df;
 21722177         sp->sap = ap;
 21732178         sp->sclass = AUTO;
 21742179         sp->soffset = NOOFFSET;
 21752180         oalloc(sp, &autooff);
 21762181         return nametree(sp);
 21772182 
 21782183 }
 21792184 
 21802185 /*
 21812186  * Massage the output trees to remove C-specific nodes:
 21822187  *      COMOPs are split into separate statements.
 21832188  *      QUEST/COLON are rewritten to branches.
 21842189  *      ANDAND/OROR/NOT are rewritten to branches for lazy-evaluation.
 21852190  *      CBRANCH conditions are rewritten for lazy-evaluation.
 21862191  */
 21872192 static void
 21882193 rmcops(NODE *p)
 21892194 {
 21902195         TWORD type;
 21912196         NODE *q, *r, *tval;
 21922197         int o, ty, lbl, lbl2;
 21932198 
 21942199         tval = NIL;
 21952200         o = p->n_op;
 21962201         ty = coptype(o);
 21972202         if (BTYPE(p->n_type) == ENUMTY) { /* fixup enum */
 21982203                 struct symtab *sp = strmemb(p->n_ap);
 21992204                 MODTYPE(p->n_type, sp->stype);
 22002205                 /*
 22012206                  * XXX may fail if these are true:
 22022207                  * - variable-sized enums
 22032208                  * - non-byte-addressed targets.
 22042209                  */
 22052210                 if (BTYPE(p->n_type) == ENUMTY && ISPTR(p->n_type))
 22062211                         MODTYPE(p->n_type, INT); /* INT ok? */
 22072212         }
 22082213         switch (o) {
 22092214         case QUEST:
 22102215 
 22112216                 /*
 22122217                  * Create a branch node from ?:
 22132218                  * || and && must be taken special care of.
 22142219                  */
 22152220                 type = p->n_type;
 22162221                 andorbr(p->n_left, -1, lbl = getlab());
 22172222 
 22182223                 /* Make ASSIGN node */
 22192224                 /* Only if type is not void */
 22202225                 q = p->n_right->n_left;
 22212226                 comops(q);
 22222227                 if (type != VOID) {
 22232228                         tval = cstknode(q->n_type, q->n_df, q->n_ap);
 22242229                         q = buildtree(ASSIGN, ccopy(tval), q);
 22252230                 }
 22262231                 rmcops(q);
 22272232                 ecode(q); /* Done with assign */
 22282233                 branch(lbl2 = getlab());
 22292234                 plabel( lbl);
 22302235 
 22312236                 q = p->n_right->n_right;
 22322237                 comops(q);
 22332238                 if (type != VOID) {
 22342239                         q = buildtree(ASSIGN, ccopy(tval), q);
 22352240                 }
 22362241                 rmcops(q);
 22372242                 ecode(q); /* Done with assign */
 22382243 
 22392244                 plabel( lbl2);
 22402245 
 22412246                 nfree(p->n_right);
 22422247                 if (p->n_type != VOID) {
 22432248                         *p = *tval;
 22442249                         nfree(tval);
 22452250                 } else {
 22462251                         p->n_op = ICON;
 22472252                         p->n_lval = 0;
 22482253                         p->n_sp = NULL;
 22492254                 }
 22502255                 break;
 22512256 
 22522257         case ULE:
 22532258         case ULT:
 22542259         case UGE:
 22552260         case UGT:
 22562261         case EQ:
 22572262         case NE:
 22582263         case LE:
 22592264         case LT:
 22602265         case GE:
 22612266         case GT:
 22622267         case ANDAND:
 22632268         case OROR:
 22642269         case NOT:
 22652270 #ifdef SPECIAL_CCODES
 22662271 #error fix for private CCODES handling
 22672272 #else
 22682273                 r = talloc();
 22692274                 *r = *p;
 22702275                 andorbr(r, -1, lbl = getlab());
 22712276 
 22722277                 tval = cstknode(p->n_type, p->n_df, p->n_ap);
 22732278 
 22742279                 ecode(buildtree(ASSIGN, ccopy(tval), bcon(1)));
 22752280                 branch(lbl2 = getlab());
 22762281                 plabel( lbl);
 22772282                 ecode(buildtree(ASSIGN, ccopy(tval), bcon(0)));
 22782283                 plabel( lbl2);
 22792284 
 22802285                 *p = *tval;
 22812286                 nfree(tval);
 22822287 
 22832288 #endif
 22842289                 break;
 22852290         case CBRANCH:
 22862291                 andorbr(p->n_left, p->n_right->n_lval, -1);
 22872292                 nfree(p->n_right);
 22882293                 p->n_op = ICON; p->n_type = VOID;
 22892294                 break;
 22902295         case COMOP:
 22912296                 cerror("COMOP error");
 22922297 
 22932298         default:
 22942299                 if (ty == LTYPE)
 22952300                         return;
 22962301                 rmcops(p->n_left);
 22972302                 if (ty == BITYPE)
 22982303                         rmcops(p->n_right);
 22992304        }
 23002305 }
 23012306 
 23022307 /*
 23032308  * Return 1 if an assignment is found.
 23042309  */
 23052310 static int
 23062311 has_se(NODE *p)
 23072312 {
 23082313         if (cdope(p->n_op) & ASGFLG)
 23092314                 return 1;
 23102315         if (coptype(p->n_op) == LTYPE)
 23112316                 return 0;
 23122317         if (has_se(p->n_left))
 23132318                 return 1;
 23142319         if (coptype(p->n_op) == BITYPE)
 23152320                 return has_se(p->n_right);
 23162321         return 0;
 23172322 }
 23182323 
 23192324 #ifndef FIELDOPS
 23202325 
 23212326 /* avoid promotion to int */
 23222327 #define TYPMOD(o, p, n, t)      clocal(block(o, p, n, t, 0, 0))
 23232328 #define TYPLS(p, n, t)  TYPMOD(LS, p, n, t)
 23242329 #define TYPRS(p, n, t)  TYPMOD(RS, p, n, t)
 23252330 #define TYPOR(p, q, t)  TYPMOD(OR, p, q, t)
 23262331 #define TYPAND(p, q, t) TYPMOD(AND, p, q, t)
 23272332 
 23282333 /*
 23292334  * Read an unaligned bitfield from position pointed to by p starting at
 23302335  * off and size fsz and return a tree of type t with resulting data.
 23312336  * ct is the type we must use to read data.
 23322337  */
 23332338 static NODE *
 23342339 rdualfld(NODE *p, TWORD t, TWORD ct, int off, int fsz)
 23352340 {
 23362341         int t2f, inbits, tsz, ctsz;
 23372342         NODE *q, *r;
 23382343 
 23392344         ct = ENUNSIGN(ct);
 23402345         ctsz = (int)tsize(ct, 0, 0);
 23412346 
 23422347         /* traverse until first data byte */
 23432348         for (t2f = 0; off >= ctsz; t2f++, off -= ctsz)
 23442349                 ;
 23452350 #ifdef UNALIGNED_ACCESS
 23462351         /* try to squeeze it into an int */
 23472352         if (off + fsz > ctsz && off + fsz <= SZINT) {
 23482353                 ct = UNSIGNED;
 23492354                 ctsz = SZINT;
 23502355         }
 23512356 #endif
 23522357         p = makety(p, PTR|ct, 0, 0, 0);
 23532358         if (off + fsz <= ctsz) {
 23542359                 /* only one operation needed */
 23552360                 q = buildtree(UMUL, buildtree(PLUS, p, bcon(t2f)), 0);
 23562361                 if (!ISUNSIGNED(t)) {
 23572362                         ct = DEUNSIGN(ct);
 23582363                         q = makety(q, ct, 0, 0, 0);
 23592364                 }
 23602365                 q = TYPLS(q, bcon(ctsz-fsz-off), ct);
 23612366                 q = TYPRS(q, bcon(ctsz-fsz), ct);
 23622367                 q = makety(q, t, 0, 0, 0);
 23632368         } else {
 23642369                 q = buildtree(UMUL, buildtree(PLUS, ccopy(p), bcon(t2f)), 0);
 23652370                 q = makety(TYPRS(q, bcon(off), ct), t, 0, 0, 0);
 23662371                 inbits = ctsz - off;
 23672372                 t2f++;
 23682373 
 23692374                 while (fsz > inbits) {
 23702375                         r = buildtree(UMUL,
 23712376                             buildtree(PLUS, ccopy(p), bcon(t2f)), 0);
 23722377                         r = makety(r, t, 0, 0, 0);
 23732378                         r = TYPLS(r, bcon(inbits), t);
 23742379                         q = TYPOR(q, r, t);
 23752380                         inbits += ctsz;
 23762381                         t2f++;
 23772382                 }
 23782383                 /* sign/zero extend XXX - RS must sign extend */
 23792384                 tsz = (int)tsize(t, 0, 0);
 23802385                 if (!ISUNSIGNED(t)) {
 23812386                         t = DEUNSIGN(t);
 23822387                         q = makety(q, t, 0, 0, 0);
 23832388                 }
 23842389                 q = TYPLS(q, bcon(tsz-fsz), t);
 23852390                 q = TYPRS(q, bcon(tsz-fsz), t);
 23862391                 tfree(p);
 23872392         }
 23882393 
 23892394         return q;
 23902395 }
 23912396 
 23922397 /*
 23932398  * Write val to a (unaligned) bitfield with length fsz positioned off bits 
 23942399  * from d. Bitfield type is t, and type to use when writing is ct.
 23952400  * neither f nor d should have any side effects if copied.
 23962401  * Multiples of ct are supposed to be written without problems.
 23972402  * Both val and d are free'd after use.
 23982403  */
 23992404 static NODE *
 24002405 wrualfld(NODE *val, NODE *d, TWORD t, TWORD ct, int off, int fsz)
 24012406 {
 24022407         NODE *p, *q, *r, *rn, *s;
 24032408         int tsz, ctsz, t2f, inbits;
 24042409  
 24052410         tsz = (int)tsize(t, 0, 0);
 24062411         ctsz = (int)tsize(ct, 0, 0);
 24072412  
 24082413         ct = ENUNSIGN(ct);
 24092414         d = makety(d, PTR|ct, 0, 0, 0);
 24102415 
 24112416         for (t2f = 0; off >= ctsz; t2f++, off -= ctsz)
 24122417                 ;
 24132418  
 24142419         if (off + fsz <= ctsz) {
 24152420                 r = tempnode(0, ct, 0, 0);
 24162421 
 24172422                 /* only one operation needed */
 24182423                 d = buildtree(UMUL, buildtree(PLUS, d, bcon(t2f)), 0);  
 24192424                 p = ccopy(d);
 24202425                 p = TYPAND(p, xbcon(~(SZMASK(fsz) << off), 0, ct), ct);
 24212426 
 24222427                 val = makety(val, ct, 0, 0, 0);
 24232428                 q = TYPAND(val, xbcon(SZMASK(fsz), 0, ct), ct);
 24242429                 q = buildtree(ASSIGN, ccopy(r), q);
 24252430 
 24262431                 q = TYPLS(q, bcon(off), ct);  
 24272432                 p = TYPOR(p, q, ct);
 24282433                 p = makety(p, t, 0, 0, 0);    
 24292434                 rn = buildtree(ASSIGN, d, p);
 24302435                 rn = buildtree(COMOP, rn, makety(r, t, 0, 0, 0));
 24312436         } else {
 24322437                 s = makety(ccopy(val), t, 0, 0, 0);
 24332438                 s = TYPAND(s, xbcon(SZMASK(fsz), 0, t), t);
 24342439 
 24352440                 r = buildtree(UMUL, buildtree(PLUS, ccopy(d), bcon(t2f)), 0);
 24362441                 p = ccopy(r);
 24372442                 p = TYPAND(p, xbcon(SZMASK(off), 0, ct), ct);
 24382443                 q = ccopy(val);
 24392444                 q = TYPLS(q, bcon(off), t); 
 24402445                 q = makety(q, ct, 0, 0, 0);
 24412446                 p = TYPOR(p, q, ct);
 24422447                 rn = buildtree(ASSIGN, r, p);
 24432448                 inbits = ctsz - off;
 24442449                 t2f++;
 24452450 
 24462451                 while (fsz > inbits+ctsz) {
 24472452                         r = buildtree(UMUL,
 24482453                             buildtree(PLUS, ccopy(d), bcon(t2f)), 0);
 24492454                         q = ccopy(val);
 24502455                         q = TYPRS(q, bcon(inbits), t);
 24512456                         q = makety(q, ct, 0, 0, 0);
 24522457                         rn = buildtree(COMOP, rn, buildtree(ASSIGN, r, q));
 24532458                         t2f++;
 24542459                         inbits += ctsz;
 24552460                 }
 24562461 
 24572462                 r = buildtree(UMUL, buildtree(PLUS, d, bcon(t2f)), 0);
 24582463                 p = ccopy(r);
 24592464                 p = TYPAND(p, makety(xbcon(~SZMASK(fsz-inbits), 0, ct),
 24602465                     ct, 0, 0, 0), ct);
 24612466                 q = TYPRS(val, bcon(inbits), t);
 24622467                 q = TYPAND(q, xbcon(SZMASK(fsz-inbits), 0, t), t);
 24632468                 q = makety(q, ct, 0, 0, 0);
 24642469                 p = TYPOR(p, q, ct);
 24652470                 rn = buildtree(COMOP, rn, buildtree(ASSIGN, r, p));
 24662471                 rn = buildtree(COMOP, rn, s);
 24672472         }
 24682473         return rn;
 24692474 }
 24702475 
 24712476 /*
 24722477  * Rewrite bitfield operations to shifts.
 24732478  */
 24742479 static NODE *
 24752480 rmfldops(NODE *p)
 24762481 {
 24772482         TWORD t, ct;
 24782483         NODE *q, *r, *t1, *t2, *bt, *t3, *t4;
 24792484         int fsz, foff, tsz;
 24802485 
 24812486         if (p->n_op == FLD) {
 24822487                 /* Rewrite a field read operation */
 24832488                 fsz = UPKFSZ(p->n_rval);
 24842489                 foff = UPKFOFF(p->n_rval);
 24852490                 tsz = (int)tsize(p->n_left->n_type, 0, 0);
 24862491                 q = buildtree(ADDROF, p->n_left, NIL);
 24872492 
 24882493                 ct = t = p->n_type;
 24892494                 if (attr_find(p->n_ap, GCC_ATYP_PACKED) &&
 24902495                     coptype(q->n_op) != LTYPE) {
 24912496                         t1 = tempnode(0, q->n_type, 0, 0);
 24922497                         bt = buildtree(ASSIGN, ccopy(t1), q);
 24932498                         q = t1;
 24942499 #ifndef UNALIGNED_ACCESS
 24952500                         ct = UCHAR;
 24962501 #endif
 24972502                 } else
 24982503                         bt = bcon(0);
 24992504                 q = rdualfld(q, t, ct, foff, fsz);
 25002505                 p->n_left = bt;
 25012506                 p->n_right = q;
 25022507                 p->n_op = COMOP;
 25032508         } else if (((cdope(p->n_op)&ASGOPFLG) || p->n_op == ASSIGN ||
 25042509             p->n_op == INCR || p->n_op == DECR) && p->n_left->n_op == FLD) {
 25052510                 /*
 25062511                  * Rewrite a field write operation
 25072512                  * More difficult than a read op since we must care
 25082513                  * about side effects.
 25092514                  */
 25102515                 q = p->n_left;
 25112516                 fsz = UPKFSZ(q->n_rval);
 25122517                 foff = UPKFOFF(q->n_rval);
 25132518                 t = q->n_left->n_type;
 25142519                 tsz = (int)tsize(t, 0, 0);
 25152520 #if TARGET_ENDIAN == TARGET_BE
 25162521                 foff = tsz - fsz - foff;
 25172522 #endif
 25182523                 bt = NULL;
 25192524                 if (p->n_right->n_op != ICON && p->n_right->n_op != NAME) {
 25202525                         t2 = tempnode(0, p->n_right->n_type, 0, 0);
 25212526                         bt = buildtree(ASSIGN, ccopy(t2), p->n_right);
 25222527                 } else
 25232528                         t2 = p->n_right;
 25242529 
 25252530                 ct = t;
 25262531 #ifndef UNALIGNED_ACCESS
 25272532                 if (attr_find(q->n_ap, GCC_ATYP_PACKED))
 25282533                         ct = UCHAR;
 25292534 #endif
 25302535                 /* t2 is what we have to write (RHS of ASSIGN) */
 25312536                 /* bt is (eventually) something that must be written */
 25322537 
 25332538 
 25342539                 if (q->n_left->n_op == UMUL) {
 25352540                         /* LHS of assignment may have side effects */
 25362541