Quick Search:

Mode

Context

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

Other Diffs

Ignore

Blank Lines Whitespace: Expand:

Diff

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