Annotation of gcc/fold-const.c, revision 1.1

1.1     ! root        1: /* Fold a constant sub-tree into a single node for C-compiler
        !             2:    Copyright (C) 1987, 1988, 1992 Free Software Foundation, Inc.
        !             3: 
        !             4: This file is part of GNU CC.
        !             5: 
        !             6: GNU CC is free software; you can redistribute it and/or modify
        !             7: it under the terms of the GNU General Public License as published by
        !             8: the Free Software Foundation; either version 2, or (at your option)
        !             9: any later version.
        !            10: 
        !            11: GNU CC is distributed in the hope that it will be useful,
        !            12: but WITHOUT ANY WARRANTY; without even the implied warranty of
        !            13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        !            14: GNU General Public License for more details.
        !            15: 
        !            16: You should have received a copy of the GNU General Public License
        !            17: along with GNU CC; see the file COPYING.  If not, write to
        !            18: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
        !            19: 
        !            20: /*@@ Fix lossage on folding division of big integers.  */
        !            21: 
        !            22: /*@@ This file should be rewritten to use an arbitary precision
        !            23:   @@ representation for "struct tree_int_cst" and "struct tree_real_cst".
        !            24:   @@ Perhaps the routines could also be used for bc/dc, and made a lib.
        !            25:   @@ The routines that translate from the ap rep should
        !            26:   @@ warn if precision et. al. is lost.
        !            27:   @@ This would also make life easier when this technology is used
        !            28:   @@ for cross-compilers.  */
        !            29: 
        !            30: 
        !            31: /* The entry points in this file are fold, size_int and size_binop.
        !            32: 
        !            33:    fold takes a tree as argument and returns a simplified tree.
        !            34: 
        !            35:    size_binop takes a tree code for an arithmetic operation
        !            36:    and two operands that are trees, and produces a tree for the
        !            37:    result, assuming the type comes from `sizetype'.
        !            38: 
        !            39:    size_int takes an integer value, and creates a tree constant
        !            40:    with type from `sizetype'.  */
        !            41:    
        !            42: #include <stdio.h>
        !            43: #include <setjmp.h>
        !            44: #include "config.h"
        !            45: #include "flags.h"
        !            46: #include "tree.h"
        !            47: 
        !            48: void lshift_double ();
        !            49: void rshift_double ();
        !            50: void lrotate_double ();
        !            51: void rrotate_double ();
        !            52: static tree const_binop ();
        !            53: 
        !            54: /* To do constant folding on INTEGER_CST nodes requires 64-bit arithmetic.
        !            55:    We do that by representing the 64-bit integer as 8 shorts,
        !            56:    with only 8 bits stored in each short, as a positive number.  */
        !            57: 
        !            58: /* Unpack a 64-bit integer into 8 shorts.
        !            59:    LOW and HI are the integer, as two `int' pieces.
        !            60:    SHORTS points to the array of shorts.  */
        !            61: 
        !            62: static void
        !            63: encode (shorts, low, hi)
        !            64:      short *shorts;
        !            65:      int low, hi;
        !            66: {
        !            67:   shorts[0] = low & 0xff;
        !            68:   shorts[1] = (low >> 8) & 0xff;
        !            69:   shorts[2] = (low >> 16) & 0xff;
        !            70:   shorts[3] = (low >> 24) & 0xff;
        !            71:   shorts[4] = hi & 0xff;
        !            72:   shorts[5] = (hi >> 8) & 0xff;
        !            73:   shorts[6] = (hi >> 16) & 0xff;
        !            74:   shorts[7] = (hi >> 24) & 0xff;
        !            75: }
        !            76: 
        !            77: /* Pack an array of 8 shorts into a 64-bit integer.
        !            78:    SHORTS points to the array of shorts.
        !            79:    The integer is stored into *LOW and *HI as two `int' pieces.  */
        !            80: 
        !            81: static void
        !            82: decode (shorts, low, hi)
        !            83:      short *shorts;
        !            84:      int *low, *hi;
        !            85: {
        !            86:   /* The casts in the following statement should not be
        !            87:      needed, but they get around bugs in some C compilers.  */
        !            88:   *low = (((long)shorts[3] << 24) | ((long)shorts[2] << 16)
        !            89:          | ((long)shorts[1] << 8) | (long)shorts[0]);
        !            90:   *hi = (((long)shorts[7] << 24) | ((long)shorts[6] << 16)
        !            91:         | ((long)shorts[5] << 8) | (long)shorts[4]);
        !            92: }
        !            93: 
        !            94: /* Make the integer constant T valid for its type
        !            95:    by setting to 0 or 1 all the bits in the constant
        !            96:    that don't belong in the type.  */
        !            97: 
        !            98: static void
        !            99: force_fit_type (t)
        !           100:      tree t;
        !           101: {
        !           102:   register int prec = TYPE_PRECISION (TREE_TYPE (t));
        !           103: 
        !           104:   if (TREE_CODE (TREE_TYPE (t)) == POINTER_TYPE)
        !           105:     prec = POINTER_SIZE;
        !           106: 
        !           107:   /* First clear all bits that are beyond the type's precision.  */
        !           108: 
        !           109:   if (prec == 2 * HOST_BITS_PER_INT)
        !           110:     ;
        !           111:   else if (prec > HOST_BITS_PER_INT)
        !           112:     {
        !           113:       TREE_INT_CST_HIGH (t)
        !           114:        &= ~((-1) << (prec - HOST_BITS_PER_INT));
        !           115:     }
        !           116:   else
        !           117:     {
        !           118:       TREE_INT_CST_HIGH (t) = 0;
        !           119:       if (prec < HOST_BITS_PER_INT)
        !           120:        TREE_INT_CST_LOW (t)
        !           121:          &= ~((-1) << prec);
        !           122:     }
        !           123: 
        !           124:   /* If it's a signed type and value's sign bit is set, extend the sign.  */
        !           125: 
        !           126:   if (! TREE_UNSIGNED (TREE_TYPE (t))
        !           127:       && prec != 2 * HOST_BITS_PER_INT
        !           128:       && (prec > HOST_BITS_PER_INT
        !           129:          ? TREE_INT_CST_HIGH (t) & (1 << (prec - HOST_BITS_PER_INT - 1))
        !           130:          : TREE_INT_CST_LOW (t) & (1 << (prec - 1))))
        !           131:     {
        !           132:       /* Value is negative:
        !           133:         set to 1 all the bits that are outside this type's precision.  */
        !           134:       if (prec > HOST_BITS_PER_INT)
        !           135:        {
        !           136:          TREE_INT_CST_HIGH (t)
        !           137:            |= ((-1) << (prec - HOST_BITS_PER_INT));
        !           138:        }
        !           139:       else
        !           140:        {
        !           141:          TREE_INT_CST_HIGH (t) = -1;
        !           142:          if (prec < HOST_BITS_PER_INT)
        !           143:            TREE_INT_CST_LOW (t)
        !           144:              |= ((-1) << prec);
        !           145:        }
        !           146:     }
        !           147: }
        !           148: 
        !           149: /* Add two 64-bit integers with 64-bit result.
        !           150:    Each argument is given as two `int' pieces.
        !           151:    One argument is L1 and H1; the other, L2 and H2.
        !           152:    The value is stored as two `int' pieces in *LV and *HV.
        !           153:    We use the 8-shorts representation internally.  */
        !           154: 
        !           155: void
        !           156: add_double (l1, h1, l2, h2, lv, hv)
        !           157:      int l1, h1, l2, h2;
        !           158:      int *lv, *hv;
        !           159: {
        !           160:   short arg1[8];
        !           161:   short arg2[8];
        !           162:   register int carry = 0;
        !           163:   register int i;
        !           164: 
        !           165:   encode (arg1, l1, h1);
        !           166:   encode (arg2, l2, h2);
        !           167: 
        !           168:   for (i = 0; i < 8; i++)
        !           169:     {
        !           170:       carry += arg1[i] + arg2[i];
        !           171:       arg1[i] = carry & 0xff;
        !           172:       carry >>= 8;
        !           173:     }
        !           174: 
        !           175:   decode (arg1, lv, hv);
        !           176: }
        !           177: 
        !           178: /* Negate a 64-bit integers with 64-bit result.
        !           179:    The argument is given as two `int' pieces in L1 and H1.
        !           180:    The value is stored as two `int' pieces in *LV and *HV.
        !           181:    We use the 8-shorts representation internally.  */
        !           182: 
        !           183: void
        !           184: neg_double (l1, h1, lv, hv)
        !           185:      int l1, h1;
        !           186:      int *lv, *hv;
        !           187: {
        !           188:   if (l1 == 0)
        !           189:     {
        !           190:       *lv = 0;
        !           191:       *hv = - h1;
        !           192:     }
        !           193:   else
        !           194:     {
        !           195:       *lv = - l1;
        !           196:       *hv = ~ h1;
        !           197:     }
        !           198: }
        !           199: 
        !           200: /* Multiply two 64-bit integers with 64-bit result.
        !           201:    Each argument is given as two `int' pieces.
        !           202:    One argument is L1 and H1; the other, L2 and H2.
        !           203:    The value is stored as two `int' pieces in *LV and *HV.
        !           204:    We use the 8-shorts representation internally.  */
        !           205: 
        !           206: void
        !           207: mul_double (l1, h1, l2, h2, lv, hv)
        !           208:      int l1, h1, l2, h2;
        !           209:      int *lv, *hv;
        !           210: {
        !           211:   short arg1[8];
        !           212:   short arg2[8];
        !           213:   short prod[16];
        !           214:   register int carry = 0;
        !           215:   register int i, j, k;
        !           216: 
        !           217:   /* These two cases are used extensively, arising from pointer
        !           218:      combinations.  */
        !           219:   if (h2 == 0)
        !           220:     {
        !           221:       if (l2 == 2)
        !           222:        {
        !           223:          unsigned temp = l1 + l1;
        !           224:          *hv = h1 * 2 + (temp < l1);
        !           225:          *lv = temp;
        !           226:          return;
        !           227:        }
        !           228:       if (l2 == 4)
        !           229:        {
        !           230:          unsigned temp = l1 + l1;
        !           231:          h1 = h1 * 4 + ((temp < l1) << 1);
        !           232:          l1 = temp;
        !           233:          temp += temp;
        !           234:          h1 += (temp < l1);
        !           235:          *lv = temp;
        !           236:          *hv = h1;
        !           237:          return;
        !           238:        }
        !           239:       if (l2 == 8)
        !           240:        {
        !           241:          unsigned temp = l1 + l1;
        !           242:          h1 = h1 * 8 + ((temp < l1) << 2);
        !           243:          l1 = temp;
        !           244:          temp += temp;
        !           245:          h1 += (temp < l1) << 1;
        !           246:          l1 = temp;
        !           247:          temp += temp;
        !           248:          h1 += (temp < l1);
        !           249:          *lv = temp;
        !           250:          *hv = h1;
        !           251:          return;
        !           252:        }
        !           253:     }
        !           254: 
        !           255:   encode (arg1, l1, h1);
        !           256:   encode (arg2, l2, h2);
        !           257: 
        !           258:   bzero (prod, sizeof prod);
        !           259: 
        !           260:   for (i = 0; i < 8; i++)
        !           261:     for (j = 0; j < 8; j++)
        !           262:       {
        !           263:        k = i + j;
        !           264:        carry = arg1[i] * arg2[j];
        !           265:        while (carry)
        !           266:          {
        !           267:            carry += prod[k];
        !           268:            prod[k] = carry & 0xff;
        !           269:            carry >>= 8;
        !           270:            k++;
        !           271:          }
        !           272:       }
        !           273: 
        !           274:   decode (prod, lv, hv);       /* @@decode ignores prod[8] -> prod[15] */
        !           275: }
        !           276: 
        !           277: /* Shift the 64-bit integer in L1, H1 left by COUNT places
        !           278:    keeping only PREC bits of result.
        !           279:    Shift right if COUNT is negative.
        !           280:    ARITH nonzero specifies arithmetic shifting; otherwise use logical shift.
        !           281:    Store the value as two `int' pieces in *LV and *HV.  */
        !           282: 
        !           283: void
        !           284: lshift_double (l1, h1, count, prec, lv, hv, arith)
        !           285:      int l1, h1, count, prec;
        !           286:      int *lv, *hv;
        !           287:      int arith;
        !           288: {
        !           289:   short arg1[8];
        !           290:   register int i;
        !           291:   register int carry;
        !           292: 
        !           293:   if (count < 0)
        !           294:     {
        !           295:       rshift_double (l1, h1, - count, prec, lv, hv, arith);
        !           296:       return;
        !           297:     }
        !           298: 
        !           299:   encode (arg1, l1, h1);
        !           300: 
        !           301:   if (count > prec)
        !           302:     count = prec;
        !           303: 
        !           304:   while (count > 0)
        !           305:     {
        !           306:       carry = 0;
        !           307:       for (i = 0; i < 8; i++)
        !           308:        {
        !           309:          carry += arg1[i] << 1;
        !           310:          arg1[i] = carry & 0xff;
        !           311:          carry >>= 8;
        !           312:        }
        !           313:       count--;
        !           314:     }
        !           315: 
        !           316:   decode (arg1, lv, hv);
        !           317: }
        !           318: 
        !           319: /* Shift the 64-bit integer in L1, H1 right by COUNT places
        !           320:    keeping only PREC bits of result.  COUNT must be positive.
        !           321:    ARITH nonzero specifies arithmetic shifting; otherwise use logical shift.
        !           322:    Store the value as two `int' pieces in *LV and *HV.  */
        !           323: 
        !           324: void
        !           325: rshift_double (l1, h1, count, prec, lv, hv, arith)
        !           326:      int l1, h1, count, prec;
        !           327:      int *lv, *hv;
        !           328:      int arith;
        !           329: {
        !           330:   short arg1[8];
        !           331:   register int i;
        !           332:   register int carry;
        !           333: 
        !           334:   encode (arg1, l1, h1);
        !           335: 
        !           336:   if (count > prec)
        !           337:     count = prec;
        !           338: 
        !           339:   while (count > 0)
        !           340:     {
        !           341:       carry = arith && arg1[7] >> 7; 
        !           342:      for (i = 7; i >= 0; i--)
        !           343:        {
        !           344:          carry <<= 8;
        !           345:          carry += arg1[i];
        !           346:          arg1[i] = (carry >> 1) & 0xff;
        !           347:        }
        !           348:       count--;
        !           349:     }
        !           350: 
        !           351:   decode (arg1, lv, hv);
        !           352: }
        !           353: 
        !           354: /* Rotate the 64-bit integer in L1, H1 left by COUNT places
        !           355:    keeping only PREC bits of result.
        !           356:    Rotate right if COUNT is negative.
        !           357:    Store the value as two `int' pieces in *LV and *HV.  */
        !           358: 
        !           359: void
        !           360: lrotate_double (l1, h1, count, prec, lv, hv)
        !           361:      int l1, h1, count, prec;
        !           362:      int *lv, *hv;
        !           363: {
        !           364:   short arg1[8];
        !           365:   register int i;
        !           366:   register int carry;
        !           367: 
        !           368:   if (count < 0)
        !           369:     {
        !           370:       rrotate_double (l1, h1, - count, prec, lv, hv);
        !           371:       return;
        !           372:     }
        !           373: 
        !           374:   encode (arg1, l1, h1);
        !           375: 
        !           376:   if (count > prec)
        !           377:     count = prec;
        !           378: 
        !           379:   carry = arg1[7] >> 7;
        !           380:   while (count > 0)
        !           381:     {
        !           382:       for (i = 0; i < 8; i++)
        !           383:        {
        !           384:          carry += arg1[i] << 1;
        !           385:          arg1[i] = carry & 0xff;
        !           386:          carry >>= 8;
        !           387:        }
        !           388:       count--;
        !           389:     }
        !           390: 
        !           391:   decode (arg1, lv, hv);
        !           392: }
        !           393: 
        !           394: /* Rotate the 64-bit integer in L1, H1 left by COUNT places
        !           395:    keeping only PREC bits of result.  COUNT must be positive.
        !           396:    Store the value as two `int' pieces in *LV and *HV.  */
        !           397: 
        !           398: void
        !           399: rrotate_double (l1, h1, count, prec, lv, hv)
        !           400:      int l1, h1, count, prec;
        !           401:      int *lv, *hv;
        !           402: {
        !           403:   short arg1[8];
        !           404:   register int i;
        !           405:   register int carry;
        !           406: 
        !           407:   encode (arg1, l1, h1);
        !           408: 
        !           409:   if (count > prec)
        !           410:     count = prec;
        !           411: 
        !           412:   carry = arg1[0] & 1;
        !           413:   while (count > 0)
        !           414:     {
        !           415:       for (i = 7; i >= 0; i--)
        !           416:        {
        !           417:          carry <<= 8;
        !           418:          carry += arg1[i];
        !           419:          arg1[i] = (carry >> 1) & 0xff;
        !           420:        }
        !           421:       count--;
        !           422:     }
        !           423: 
        !           424:   decode (arg1, lv, hv);
        !           425: }
        !           426: 
        !           427: /* Divide 64 bit integer LNUM, HNUM by 64 bit integer LDEN, HDEN
        !           428:    for a quotient (stored in *LQUO, *HQUO) and remainder (in *LREM, *HREM).
        !           429:    CODE is a tree code for a kind of division, one of
        !           430:    TRUNC_DIV_EXPR, FLOOR_DIV_EXPR, CEIL_DIV_EXPR, ROUND_DIV_EXPR
        !           431:    or EXACT_DIV_EXPR
        !           432:    It controls how the quotient is rounded to a integer.
        !           433:    UNS nonzero says do unsigned division.  */
        !           434: 
        !           435: static void
        !           436: div_and_round_double (code, uns,
        !           437:                      lnum_orig, hnum_orig, lden_orig, hden_orig,
        !           438:                      lquo, hquo, lrem, hrem)
        !           439:      enum tree_code code;
        !           440:      int uns;
        !           441:      int lnum_orig, hnum_orig;         /* num == numerator == dividend */
        !           442:      int lden_orig, hden_orig;         /* den == denominator == divisor */
        !           443:      int *lquo, *hquo, *lrem, *hrem;
        !           444: {
        !           445:   int quo_neg = 0;
        !           446:   short num[9], den[8], quo[8];        /* extra element for scaling.  */
        !           447:   register int i, j, work;
        !           448:   register int carry = 0;
        !           449:   unsigned int lnum = lnum_orig;
        !           450:   int hnum = hnum_orig;
        !           451:   unsigned int lden = lden_orig;
        !           452:   int hden = hden_orig;
        !           453: 
        !           454:   if ((hden == 0) && (lden == 0))
        !           455:     abort ();
        !           456: 
        !           457:   /* calculate quotient sign and convert operands to unsigned.  */
        !           458:   if (!uns) 
        !           459:     {
        !           460:       if (hden < 0) 
        !           461:        {
        !           462:          quo_neg = ~ quo_neg;
        !           463:          neg_double (lden, hden, &lden, &hden);
        !           464:        }
        !           465:       if (hnum < 0)
        !           466:        {
        !           467:          quo_neg = ~ quo_neg;
        !           468:          neg_double (lnum, hnum, &lnum, &hnum);
        !           469:        }
        !           470:     }
        !           471: 
        !           472:   if (hnum == 0 && hden == 0)
        !           473:     {                          /* single precision */
        !           474:       *hquo = *hrem = 0;
        !           475:       *lquo = lnum / lden;     /* rounds toward zero since positive args */
        !           476:       goto finish_up;
        !           477:     }
        !           478: 
        !           479:   if (hnum == 0)
        !           480:     {                          /* trivial case: dividend < divisor */
        !           481:       /* hden != 0 already checked.  */
        !           482:       *hquo = *lquo = 0;
        !           483:       *hrem = hnum;
        !           484:       *lrem = lnum;
        !           485:       goto finish_up;
        !           486:     }
        !           487: 
        !           488:   bzero (quo, sizeof quo);
        !           489: 
        !           490:   bzero (num, sizeof num);     /* to zero 9th element */
        !           491:   bzero (den, sizeof den);
        !           492: 
        !           493:   encode (num, lnum, hnum); 
        !           494:   encode (den, lden, hden);
        !           495: 
        !           496:   /* This code requires more than just hden == 0.
        !           497:      We also have to require that we don't need more than three bytes
        !           498:      to hold CARRY.  If we ever did need four bytes to hold it, we
        !           499:      would lose part of it when computing WORK on the next round.  */
        !           500:   if (hden == 0 && ((lden << 8) >> 8) == lden)
        !           501:     {                          /* simpler algorithm */
        !           502:       /* hnum != 0 already checked.  */
        !           503:       for (i = 7; i >= 0; i--)
        !           504:        {
        !           505:          work = num[i] + (carry << 8);
        !           506:          quo[i] = work / lden;
        !           507:          carry = work % lden;
        !           508:        }
        !           509:     }
        !           510:   else {                       /* full double precision,
        !           511:                                   with thanks to Don Knuth's
        !           512:                                   "Semi-Numericial Algorithms".  */
        !           513: #define BASE 256
        !           514:     int quo_est, scale, num_hi_sig, den_hi_sig, quo_hi_sig;
        !           515: 
        !           516:     /* Find the highest non-zero divisor digit.  */
        !           517:     for (i = 7; ; i--)
        !           518:       if (den[i] != 0) {
        !           519:        den_hi_sig = i;
        !           520:        break;
        !           521:       }
        !           522:     for (i = 7; ; i--)
        !           523:       if (num[i] != 0) {
        !           524:        num_hi_sig = i;
        !           525:        break;
        !           526:       }
        !           527:     quo_hi_sig = num_hi_sig - den_hi_sig + 1;
        !           528: 
        !           529:     /* Insure that the first digit of the divisor is at least BASE/2.
        !           530:        This is required by the quotient digit estimation algorithm.  */
        !           531: 
        !           532:     scale = BASE / (den[den_hi_sig] + 1);
        !           533:     if (scale > 1) {           /* scale divisor and dividend */
        !           534:       carry = 0;
        !           535:       for (i = 0; i <= 8; i++) {
        !           536:        work = (num[i] * scale) + carry;
        !           537:        num[i] = work & 0xff;
        !           538:        carry = work >> 8;
        !           539:        if (num[i] != 0) num_hi_sig = i;
        !           540:       }
        !           541:       carry = 0;
        !           542:       for (i = 0; i <= 7; i++) {
        !           543:        work = (den[i] * scale) + carry;
        !           544:        den[i] = work & 0xff;
        !           545:        carry = work >> 8;
        !           546:        if (den[i] != 0) den_hi_sig = i;
        !           547:       }
        !           548:     }
        !           549: 
        !           550:     /* Main loop */
        !           551:     for (i = quo_hi_sig; i > 0; i--) {
        !           552:       /* quess the next quotient digit, quo_est, by dividing the first
        !           553:         two remaining dividend digits by the high order quotient digit.
        !           554:         quo_est is never low and is at most 2 high.  */
        !           555: 
        !           556:       int num_hi;              /* index of highest remaining dividend digit */
        !           557: 
        !           558:       num_hi = i + den_hi_sig;
        !           559: 
        !           560:       work = (num[num_hi] * BASE) + (num_hi > 0 ? num[num_hi - 1] : 0);
        !           561:       if (num[num_hi] != den[den_hi_sig]) {
        !           562:        quo_est = work / den[den_hi_sig];
        !           563:       }
        !           564:       else {
        !           565:        quo_est = BASE - 1;
        !           566:       }
        !           567: 
        !           568:       /* refine quo_est so it's usually correct, and at most one high.   */
        !           569:       while ((den[den_hi_sig - 1] * quo_est)
        !           570:             > (((work - (quo_est * den[den_hi_sig])) * BASE)
        !           571:                 + ((num_hi - 1) > 0 ? num[num_hi - 2] : 0)))
        !           572:        quo_est--;
        !           573: 
        !           574:       /* Try QUO_EST as the quotient digit, by multiplying the
        !           575:          divisor by QUO_EST and subtracting from the remaining dividend.
        !           576:         Keep in mind that QUO_EST is the I - 1st digit.  */
        !           577: 
        !           578:       carry = 0;
        !           579: 
        !           580:       for (j = 0; j <= den_hi_sig; j++)
        !           581:        {
        !           582:          int digit;
        !           583: 
        !           584:          work = num[i + j - 1] - (quo_est * den[j]) + carry;
        !           585:          digit = work & 0xff;
        !           586:          carry = work >> 8;
        !           587:          if (digit < 0)
        !           588:            {
        !           589:              digit += BASE;
        !           590:              carry--;
        !           591:            }
        !           592:          num[i + j - 1] = digit;
        !           593:        }
        !           594: 
        !           595:       /* if quo_est was high by one, then num[i] went negative and
        !           596:         we need to correct things.  */
        !           597: 
        !           598:       if (num[num_hi] < 0)
        !           599:        {
        !           600:          quo_est--;
        !           601:          carry = 0;            /* add divisor back in */
        !           602:          for (j = 0; j <= den_hi_sig; j++)
        !           603:            {
        !           604:              work = num[i + j - 1] + den[j] + carry;
        !           605:              if (work > BASE)
        !           606:                {
        !           607:                  work -= BASE;
        !           608:                  carry = 1;
        !           609:                }
        !           610:              else
        !           611:                {
        !           612:                  carry = 0;
        !           613:                }
        !           614:              num[i + j - 1] = work;
        !           615:            }
        !           616:          num [num_hi] += carry;
        !           617:        }
        !           618: 
        !           619:       /* store the quotient digit.  */
        !           620:       quo[i - 1] = quo_est;
        !           621:     }
        !           622:   }
        !           623: 
        !           624:   decode (quo, lquo, hquo);
        !           625: 
        !           626:  finish_up:
        !           627:   /* if result is negative, make it so.  */
        !           628:   if (quo_neg)
        !           629:     neg_double (*lquo, *hquo, lquo, hquo);
        !           630: 
        !           631:   /* compute trial remainder:  rem = num - (quo * den)  */
        !           632:   mul_double (*lquo, *hquo, lden_orig, hden_orig, lrem, hrem);
        !           633:   neg_double (*lrem, *hrem, lrem, hrem);
        !           634:   add_double (lnum_orig, hnum_orig, *lrem, *hrem, lrem, hrem);
        !           635: 
        !           636:   switch (code)
        !           637:     {
        !           638:     case TRUNC_DIV_EXPR:
        !           639:     case TRUNC_MOD_EXPR:       /* round toward zero */
        !           640:     case EXACT_DIV_EXPR:       /* for this one, it shouldn't matter */
        !           641:       return;
        !           642: 
        !           643:     case FLOOR_DIV_EXPR:
        !           644:     case FLOOR_MOD_EXPR:       /* round toward negative infinity */
        !           645:       if (quo_neg && (*lrem != 0 || *hrem != 0))   /* ratio < 0 && rem != 0 */
        !           646:        {
        !           647:          /* quo = quo - 1;  */
        !           648:          add_double (*lquo, *hquo, -1, -1, lquo, hquo);
        !           649:        }
        !           650:       else return;
        !           651:       break;
        !           652: 
        !           653:     case CEIL_DIV_EXPR:
        !           654:     case CEIL_MOD_EXPR:                /* round toward positive infinity */
        !           655:       if (!quo_neg && (*lrem != 0 || *hrem != 0))  /* ratio > 0 && rem != 0 */
        !           656:        {
        !           657:          add_double (*lquo, *hquo, 1, 0, lquo, hquo);
        !           658:        }
        !           659:       else return;
        !           660:       break;
        !           661:     
        !           662:     case ROUND_DIV_EXPR:
        !           663:     case ROUND_MOD_EXPR:       /* round to closest integer */
        !           664:       {
        !           665:        int labs_rem = *lrem, habs_rem = *hrem;
        !           666:        int labs_den = lden, habs_den = hden, ltwice, htwice;
        !           667: 
        !           668:        /* get absolute values */
        !           669:        if (*hrem < 0) neg_double (*lrem, *hrem, &labs_rem, &habs_rem);
        !           670:        if (hden < 0) neg_double (lden, hden, &labs_den, &habs_den);
        !           671: 
        !           672:        /* if (2 * abs (lrem) >= abs (lden)) */
        !           673:        mul_double (2, 0, labs_rem, habs_rem, &ltwice, &htwice);
        !           674:        if (((unsigned) habs_den < (unsigned) htwice)
        !           675:            || (((unsigned) habs_den == (unsigned) htwice)
        !           676:                && ((unsigned) labs_den < (unsigned) ltwice)))
        !           677:          {
        !           678:            if (*hquo < 0)
        !           679:              /* quo = quo - 1;  */
        !           680:              add_double (*lquo, *hquo, -1, -1, lquo, hquo);
        !           681:            else
        !           682:              /* quo = quo + 1; */
        !           683:              add_double (*lquo, *hquo, 1, 0, lquo, hquo);
        !           684:          }
        !           685:        else return;
        !           686:       }
        !           687:       break;
        !           688: 
        !           689:     default:
        !           690:       abort ();
        !           691:     }
        !           692: 
        !           693:   /* compute true remainder:  rem = num - (quo * den)  */
        !           694:   mul_double (*lquo, *hquo, lden_orig, hden_orig, lrem, hrem);
        !           695:   neg_double (*lrem, *hrem, lrem, hrem);
        !           696:   add_double (lnum_orig, hnum_orig, *lrem, *hrem, lrem, hrem);
        !           697: }
        !           698: 
        !           699: #if TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
        !           700: 
        !           701: /* Check for infinity in an IEEE double precision number.  */
        !           702: 
        !           703: int
        !           704: target_isinf (x)
        !           705:      REAL_VALUE_TYPE x;
        !           706: {
        !           707:   /* The IEEE 64-bit double format.  */
        !           708:   union {
        !           709:     REAL_VALUE_TYPE d;
        !           710:     struct {
        !           711:       unsigned sign      :  1;
        !           712:       unsigned exponent  : 11;
        !           713:       unsigned mantissa1 : 20;
        !           714:       unsigned mantissa2;
        !           715:     } little_endian;
        !           716:     struct {
        !           717:       unsigned mantissa2;
        !           718:       unsigned mantissa1 : 20;
        !           719:       unsigned exponent  : 11;
        !           720:       unsigned sign      :  1;
        !           721:     } big_endian;    
        !           722:   } u;
        !           723: 
        !           724:   u.d = dconstm1;
        !           725:   if (u.big_endian.sign == 1)
        !           726:     {
        !           727:       u.d = x;
        !           728:       return (u.big_endian.exponent == 2047
        !           729:              && u.big_endian.mantissa1 == 0
        !           730:              && u.big_endian.mantissa2 == 0);
        !           731:     }
        !           732:   else
        !           733:     {
        !           734:       u.d = x;
        !           735:       return (u.little_endian.exponent == 2047
        !           736:              && u.little_endian.mantissa1 == 0
        !           737:              && u.little_endian.mantissa2 == 0);
        !           738:     }
        !           739: }
        !           740: 
        !           741: /* Check for minus zero in an IEEE double precision number.  */
        !           742: 
        !           743: int
        !           744: target_minus_zero (x)
        !           745:      REAL_VALUE_TYPE x;
        !           746: {
        !           747:   REAL_VALUE_TYPE d1, d2;
        !           748: 
        !           749:   d1 = REAL_VALUE_NEGATE (x);
        !           750:   d2 = dconst0;
        !           751: 
        !           752:   return !bcmp (&d1, &d2, sizeof (d1));
        !           753: }
        !           754: #else /* Target not IEEE */
        !           755: 
        !           756: /* Let's assume other float formats don't have infinity.
        !           757:    (This can be overridden by redefining REAL_VALUE_ISINF.)  */
        !           758: 
        !           759: target_isinf (x)
        !           760:      REAL_VALUE_TYPE x;
        !           761: {
        !           762:   return 0;
        !           763: }
        !           764: 
        !           765: /* Let's assume other float formats don't have minus zero.
        !           766:    (This can be overridden by redefining REAL_VALUE_MINUS_ZERO.)  */
        !           767: 
        !           768: target_minus_zero (x)
        !           769:      REAL_VALUE_TYPE x;
        !           770: {
        !           771:   return 0;
        !           772: }
        !           773: #endif /* Target not IEEE */
        !           774: 
        !           775: /* Split a tree IN into a constant and a variable part
        !           776:    that could be combined with CODE to make IN.
        !           777:    CODE must be a commutative arithmetic operation.
        !           778:    Store the constant part into *CONP and the variable in &VARP.
        !           779:    Return 1 if this was done; zero means the tree IN did not decompose
        !           780:    this way.
        !           781: 
        !           782:    If CODE is PLUS_EXPR we also split trees that use MINUS_EXPR.
        !           783:    Therefore, we must tell the caller whether the variable part
        !           784:    was subtracted.  We do this by storing 1 or -1 into *VARSIGNP.
        !           785:    The value stored is the coefficient for the variable term.
        !           786:    The constant term we return should always be added;
        !           787:    we negate it if necessary.  */
        !           788: 
        !           789: static int
        !           790: split_tree (in, code, varp, conp, varsignp)
        !           791:      tree in;
        !           792:      enum tree_code code;
        !           793:      tree *varp, *conp;
        !           794:      int *varsignp;
        !           795: {
        !           796:   register tree outtype = TREE_TYPE (in);
        !           797:   *varp = 0;
        !           798:   *conp = 0;
        !           799: 
        !           800:   /* Strip any conversions that don't change the machine mode.  */
        !           801:   while ((TREE_CODE (in) == NOP_EXPR
        !           802:          || TREE_CODE (in) == CONVERT_EXPR)
        !           803:         && (TYPE_MODE (TREE_TYPE (in))
        !           804:             == TYPE_MODE (TREE_TYPE (TREE_OPERAND (in, 0)))))
        !           805:     in = TREE_OPERAND (in, 0);
        !           806: 
        !           807:   if (TREE_CODE (in) == code
        !           808:       || (TREE_CODE (TREE_TYPE (in)) != REAL_TYPE
        !           809:          /* We can associate addition and subtraction together
        !           810:             (even though the C standard doesn't say so)
        !           811:             for integers because the value is not affected.
        !           812:             For reals, the value might be affected, so we can't.  */
        !           813:          &&
        !           814:          ((code == PLUS_EXPR && TREE_CODE (in) == MINUS_EXPR)
        !           815:           || (code == MINUS_EXPR && TREE_CODE (in) == PLUS_EXPR))))
        !           816:     {
        !           817:       enum tree_code code = TREE_CODE (TREE_OPERAND (in, 0));
        !           818:       if (code == INTEGER_CST)
        !           819:        {
        !           820:          *conp = TREE_OPERAND (in, 0);
        !           821:          *varp = TREE_OPERAND (in, 1);
        !           822:          if (TYPE_MODE (TREE_TYPE (*varp)) != TYPE_MODE (outtype)
        !           823:              && TREE_TYPE (*varp) != outtype)
        !           824:            *varp = convert (outtype, *varp);
        !           825:          *varsignp = (TREE_CODE (in) == MINUS_EXPR) ? -1 : 1;
        !           826:          return 1;
        !           827:        }
        !           828:       if (TREE_CONSTANT (TREE_OPERAND (in, 1)))
        !           829:        {
        !           830:          *conp = TREE_OPERAND (in, 1);
        !           831:          *varp = TREE_OPERAND (in, 0);
        !           832:          *varsignp = 1;
        !           833:          if (TYPE_MODE (TREE_TYPE (*varp)) != TYPE_MODE (outtype)
        !           834:              && TREE_TYPE (*varp) != outtype)
        !           835:            *varp = convert (outtype, *varp);
        !           836:          if (TREE_CODE (in) == MINUS_EXPR)
        !           837:            {
        !           838:              /* If operation is subtraction and constant is second,
        !           839:                 must negate it to get an additive constant.
        !           840:                 And this cannot be done unless it is a manifest constant.
        !           841:                 It could also be the address of a static variable.
        !           842:                 We cannot negate that, so give up.  */
        !           843:              if (TREE_CODE (*conp) == INTEGER_CST)
        !           844:                /* Subtracting from integer_zero_node loses for long long.  */
        !           845:                *conp = fold (build1 (NEGATE_EXPR, TREE_TYPE (*conp), *conp));
        !           846:              else
        !           847:                return 0;
        !           848:            }
        !           849:          return 1;
        !           850:        }
        !           851:       if (TREE_CONSTANT (TREE_OPERAND (in, 0)))
        !           852:        {
        !           853:          *conp = TREE_OPERAND (in, 0);
        !           854:          *varp = TREE_OPERAND (in, 1);
        !           855:          if (TYPE_MODE (TREE_TYPE (*varp)) != TYPE_MODE (outtype)
        !           856:              && TREE_TYPE (*varp) != outtype)
        !           857:            *varp = convert (outtype, *varp);
        !           858:          *varsignp = (TREE_CODE (in) == MINUS_EXPR) ? -1 : 1;
        !           859:          return 1;
        !           860:        }
        !           861:     }
        !           862:   return 0;
        !           863: }
        !           864: 
        !           865: /* Combine two constants NUM and ARG2 under operation CODE
        !           866:    to produce a new constant.
        !           867:    We assume ARG1 and ARG2 have the same data type,
        !           868:    or at least are the same kind of constant and the same machine mode.  */
        !           869: 
        !           870: /* Handle floating overflow for `const_binop'.  */
        !           871: static jmp_buf const_binop_error;
        !           872: 
        !           873: static tree
        !           874: const_binop (code, arg1, arg2)
        !           875:      enum tree_code code;
        !           876:      register tree arg1, arg2;
        !           877: {
        !           878:   if (TREE_CODE (arg1) == INTEGER_CST)
        !           879:     {
        !           880:       register int int1l = TREE_INT_CST_LOW (arg1);
        !           881:       register int int1h = TREE_INT_CST_HIGH (arg1);
        !           882:       int int2l = TREE_INT_CST_LOW (arg2);
        !           883:       int int2h = TREE_INT_CST_HIGH (arg2);
        !           884:       int low, hi;
        !           885:       int garbagel, garbageh;
        !           886:       register tree t;
        !           887:       int uns = TREE_UNSIGNED (TREE_TYPE (arg1));
        !           888: 
        !           889:       switch (code)
        !           890:        {
        !           891:        case BIT_IOR_EXPR:
        !           892:          t = build_int_2 (int1l | int2l, int1h | int2h);
        !           893:          break;
        !           894: 
        !           895:        case BIT_XOR_EXPR:
        !           896:          t = build_int_2 (int1l ^ int2l, int1h ^ int2h);
        !           897:          break;
        !           898: 
        !           899:        case BIT_AND_EXPR:
        !           900:          t = build_int_2 (int1l & int2l, int1h & int2h);
        !           901:          break;
        !           902: 
        !           903:        case BIT_ANDTC_EXPR:
        !           904:          t = build_int_2 (int1l & ~int2l, int1h & ~int2h);
        !           905:          break;
        !           906: 
        !           907:        case RSHIFT_EXPR:
        !           908:          int2l = - int2l;
        !           909:        case LSHIFT_EXPR:
        !           910:          lshift_double (int1l, int1h, int2l,
        !           911:                         TYPE_PRECISION (TREE_TYPE (arg1)),
        !           912:                         &low, &hi,
        !           913:                         !uns);
        !           914:          t = build_int_2 (low, hi);
        !           915:          break;
        !           916: 
        !           917:        case RROTATE_EXPR:
        !           918:          int2l = - int2l;
        !           919:        case LROTATE_EXPR:
        !           920:          lrotate_double (int1l, int1h, int2l,
        !           921:                          TYPE_PRECISION (TREE_TYPE (arg1)),
        !           922:                          &low, &hi);
        !           923:          t = build_int_2 (low, hi);
        !           924:          break;
        !           925: 
        !           926:        case PLUS_EXPR:
        !           927:          if (int1h == 0)
        !           928:            {
        !           929:              int2l += int1l;
        !           930:              if ((unsigned) int2l < int1l)
        !           931:                int2h += 1;
        !           932:              t = build_int_2 (int2l, int2h);
        !           933:              break;
        !           934:            }
        !           935:          if (int2h == 0)
        !           936:            {
        !           937:              int1l += int2l;
        !           938:              if ((unsigned) int1l < int2l)
        !           939:                int1h += 1;
        !           940:              t = build_int_2 (int1l, int1h);
        !           941:              break;
        !           942:            }
        !           943:          add_double (int1l, int1h, int2l, int2h, &low, &hi);
        !           944:          t = build_int_2 (low, hi);
        !           945:          break;
        !           946: 
        !           947:        case MINUS_EXPR:
        !           948:          if (int2h == 0 && int2l == 0)
        !           949:            {
        !           950:              t = build_int_2 (int1l, int1h);
        !           951:              break;
        !           952:            }
        !           953:          neg_double (int2l, int2h, &int2l, &int2h);
        !           954:          add_double (int1l, int1h, int2l, int2h, &low, &hi);
        !           955:          t = build_int_2 (low, hi);
        !           956:          break;
        !           957: 
        !           958:        case MULT_EXPR:
        !           959:   /* Optimize simple cases.  */
        !           960:          if (int1h == 0)
        !           961:            {
        !           962:              unsigned temp;
        !           963: 
        !           964:              switch (int1l)
        !           965:                {
        !           966:                case 0:
        !           967:                  t = build_int_2 (0, 0);
        !           968:                  goto got_it;
        !           969:                case 1:
        !           970:                  t = build_int_2 (int2l, int2h);
        !           971:                  goto got_it;
        !           972:                case 2:
        !           973:                  temp = int2l + int2l;
        !           974:                  int2h = int2h * 2 + (temp < int2l);
        !           975:                  t = build_int_2 (temp, int2h);
        !           976:                  goto got_it;
        !           977:                case 3:
        !           978:                  temp = int2l + int2l + int2l;
        !           979:                  int2h = int2h * 3 + (temp < int2l);
        !           980:                  t = build_int_2 (temp, int2h);
        !           981:                  goto got_it;
        !           982:                case 4:
        !           983:                  temp = int2l + int2l;
        !           984:                  int2h = int2h * 4 + ((temp < int2l) << 1);
        !           985:                  int2l = temp;
        !           986:                  temp += temp;
        !           987:                  int2h += (temp < int2l);
        !           988:                  t = build_int_2 (temp, int2h);
        !           989:                  goto got_it;
        !           990:                case 8:
        !           991:                  temp = int2l + int2l;
        !           992:                  int2h = int2h * 8 + ((temp < int2l) << 2);
        !           993:                  int2l = temp;
        !           994:                  temp += temp;
        !           995:                  int2h += (temp < int2l) << 1;
        !           996:                  int2l = temp;
        !           997:                  temp += temp;
        !           998:                  int2h += (temp < int2l);
        !           999:                  t = build_int_2 (temp, int2h);
        !          1000:                  goto got_it;
        !          1001:                default:
        !          1002:                  break;
        !          1003:                }
        !          1004:            }
        !          1005: 
        !          1006:          if (int2h == 0)
        !          1007:            {
        !          1008:              if (int2l == 0)
        !          1009:                {
        !          1010:                  t = build_int_2 (0, 0);
        !          1011:                  break;
        !          1012:                }
        !          1013:              if (int2l == 1)
        !          1014:                {
        !          1015:                  t = build_int_2 (int1l, int1h);
        !          1016:                  break;
        !          1017:                }
        !          1018:            }
        !          1019: 
        !          1020:          mul_double (int1l, int1h, int2l, int2h, &low, &hi);
        !          1021:          t = build_int_2 (low, hi);
        !          1022:          break;
        !          1023: 
        !          1024:        case TRUNC_DIV_EXPR:
        !          1025:        case FLOOR_DIV_EXPR: case CEIL_DIV_EXPR:
        !          1026:        case EXACT_DIV_EXPR:
        !          1027:          /* This is a shortcut for a common special case.
        !          1028:             It reduces the number of tree nodes generated
        !          1029:             and saves time.  */
        !          1030:          if (int2h == 0 && int2l > 0
        !          1031:              && TREE_TYPE (arg1) == sizetype
        !          1032:              && int1h == 0 && int1l >= 0)
        !          1033:            {
        !          1034:              if (code == CEIL_DIV_EXPR)
        !          1035:                int1l += int2l-1;
        !          1036:              return size_int (int1l / int2l);
        !          1037:            }
        !          1038:        case ROUND_DIV_EXPR: 
        !          1039:          if (int2h == 0 && int2l == 1)
        !          1040:            {
        !          1041:              t = build_int_2 (int1l, int1h);
        !          1042:              break;
        !          1043:            }
        !          1044:          if (int1l == int2l && int1h == int2h)
        !          1045:            {
        !          1046:              if ((int1l | int1h) == 0)
        !          1047:                abort ();
        !          1048:              t = build_int_2 (1, 0);
        !          1049:              break;
        !          1050:            }
        !          1051:          div_and_round_double (code, uns, int1l, int1h, int2l, int2h,
        !          1052:                                &low, &hi, &garbagel, &garbageh);
        !          1053:          t = build_int_2 (low, hi);
        !          1054:          break;
        !          1055: 
        !          1056:        case TRUNC_MOD_EXPR: case ROUND_MOD_EXPR: 
        !          1057:        case FLOOR_MOD_EXPR: case CEIL_MOD_EXPR:
        !          1058:          div_and_round_double (code, uns, int1l, int1h, int2l, int2h,
        !          1059:                                &garbagel, &garbageh, &low, &hi);
        !          1060:          t = build_int_2 (low, hi);
        !          1061:          break;
        !          1062: 
        !          1063:        case MIN_EXPR:
        !          1064:        case MAX_EXPR:
        !          1065:          if (uns)
        !          1066:            {
        !          1067:              low = (((unsigned) int1h < (unsigned) int2h)
        !          1068:                     || (((unsigned) int1h == (unsigned) int2h)
        !          1069:                         && ((unsigned) int1l < (unsigned) int2l)));
        !          1070:            }
        !          1071:          else
        !          1072:            {
        !          1073:              low = ((int1h < int2h)
        !          1074:                     || ((int1h == int2h)
        !          1075:                         && ((unsigned) int1l < (unsigned) int2l)));
        !          1076:            }
        !          1077:          if (low == (code == MIN_EXPR))
        !          1078:            t = build_int_2 (int1l, int1h);
        !          1079:          else
        !          1080:            t = build_int_2 (int2l, int2h);
        !          1081:          break;
        !          1082: 
        !          1083:        default:
        !          1084:          abort ();
        !          1085:        }
        !          1086:     got_it:
        !          1087:       TREE_TYPE (t) = TREE_TYPE (arg1);
        !          1088:       force_fit_type (t);
        !          1089:       return t;
        !          1090:     }
        !          1091: #if ! defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
        !          1092:   if (TREE_CODE (arg1) == REAL_CST)
        !          1093:     {
        !          1094:       register REAL_VALUE_TYPE d1;
        !          1095:       register REAL_VALUE_TYPE d2;
        !          1096:       register REAL_VALUE_TYPE value;
        !          1097: 
        !          1098:       d1 = TREE_REAL_CST (arg1);
        !          1099:       d2 = TREE_REAL_CST (arg2);
        !          1100:       if (setjmp (const_binop_error))
        !          1101:        {
        !          1102:          warning ("floating overflow in constant folding");
        !          1103:          return build (code, TREE_TYPE (arg1), arg1, arg2);
        !          1104:        }
        !          1105:       set_float_handler (const_binop_error);
        !          1106: 
        !          1107: #ifdef REAL_ARITHMETIC
        !          1108:       REAL_ARITHMETIC (value, code, d1, d2);
        !          1109: #else
        !          1110:       switch (code)
        !          1111:        {
        !          1112:        case PLUS_EXPR:
        !          1113:          value = d1 + d2;
        !          1114:          break;
        !          1115: 
        !          1116:        case MINUS_EXPR:
        !          1117:          value = d1 - d2;
        !          1118:          break;
        !          1119: 
        !          1120:        case MULT_EXPR:
        !          1121:          value = d1 * d2;
        !          1122:          break;
        !          1123: 
        !          1124:        case RDIV_EXPR:
        !          1125: #ifndef REAL_INFINITY
        !          1126:          if (d2 == 0)
        !          1127:            abort ();
        !          1128: #endif
        !          1129: 
        !          1130:          value = d1 / d2;
        !          1131:          break;
        !          1132: 
        !          1133:        case MIN_EXPR:
        !          1134:          value = MIN (d1, d2);
        !          1135:          break;
        !          1136: 
        !          1137:        case MAX_EXPR:
        !          1138:          value = MAX (d1, d2);
        !          1139:          break;
        !          1140: 
        !          1141:        default:
        !          1142:          abort ();
        !          1143:        }
        !          1144: #endif /* no REAL_ARITHMETIC */
        !          1145:       set_float_handler (0);
        !          1146:       value = REAL_VALUE_TRUNCATE (TYPE_MODE (TREE_TYPE (arg1)), value);
        !          1147:       return build_real (TREE_TYPE (arg1), value);
        !          1148:     }
        !          1149: #endif /* not REAL_IS_NOT_DOUBLE, or REAL_ARITHMETIC */
        !          1150:   if (TREE_CODE (arg1) == COMPLEX_CST)
        !          1151:     {
        !          1152:       register tree r1 = TREE_REALPART (arg1);
        !          1153:       register tree i1 = TREE_IMAGPART (arg1);
        !          1154:       register tree r2 = TREE_REALPART (arg2);
        !          1155:       register tree i2 = TREE_IMAGPART (arg2);
        !          1156:       register tree t;
        !          1157: 
        !          1158:       switch (code)
        !          1159:        {
        !          1160:        case PLUS_EXPR:
        !          1161:          t = build_complex (const_binop (PLUS_EXPR, r1, r2),
        !          1162:                             const_binop (PLUS_EXPR, i1, i2));
        !          1163:          break;
        !          1164: 
        !          1165:        case MINUS_EXPR:
        !          1166:          t = build_complex (const_binop (MINUS_EXPR, r1, r2),
        !          1167:                             const_binop (MINUS_EXPR, i1, i2));
        !          1168:          break;
        !          1169: 
        !          1170:        case MULT_EXPR:
        !          1171:          t = build_complex (const_binop (MINUS_EXPR,
        !          1172:                                          const_binop (MULT_EXPR, r1, r2),
        !          1173:                                          const_binop (MULT_EXPR, i1, i2)),
        !          1174:                             const_binop (PLUS_EXPR,
        !          1175:                                          const_binop (MULT_EXPR, r1, i2),
        !          1176:                                          const_binop (MULT_EXPR, i1, r2)));
        !          1177:          break;
        !          1178: 
        !          1179:        case RDIV_EXPR:
        !          1180:          {
        !          1181:            register tree magsquared
        !          1182:              = const_binop (PLUS_EXPR,
        !          1183:                             const_binop (MULT_EXPR, r2, r2),
        !          1184:                             const_binop (MULT_EXPR, i2, i2));
        !          1185:            t = build_complex (const_binop (RDIV_EXPR,
        !          1186:                                            const_binop (PLUS_EXPR,
        !          1187:                                                         const_binop (MULT_EXPR, r1, r2),
        !          1188:                                                         const_binop (MULT_EXPR, i1, i2)),
        !          1189:                                            magsquared),
        !          1190:                               const_binop (RDIV_EXPR,
        !          1191:                                            const_binop (MINUS_EXPR,
        !          1192:                                                         const_binop (MULT_EXPR, i1, r2),
        !          1193:                                                         const_binop (MULT_EXPR, r1, i2)),
        !          1194:                                            magsquared));
        !          1195:          }
        !          1196:          break;
        !          1197: 
        !          1198:        default:
        !          1199:          abort ();
        !          1200:        }
        !          1201:       TREE_TYPE (t) = TREE_TYPE (arg1);
        !          1202:       return t;
        !          1203:     }
        !          1204:   return 0;
        !          1205: }
        !          1206: 
        !          1207: /* Return an INTEGER_CST with value V and type from `sizetype'.  */
        !          1208: 
        !          1209: tree
        !          1210: size_int (number)
        !          1211:      unsigned int number;
        !          1212: {
        !          1213:   register tree t;
        !          1214:   /* Type-size nodes already made for small sizes.  */
        !          1215:   static tree size_table[2*HOST_BITS_PER_INT+1];
        !          1216: 
        !          1217:   if (number >= 0 && number < 2*HOST_BITS_PER_INT+1 && size_table[number] != 0)
        !          1218:     return size_table[number];
        !          1219:   if (number >= 0 && number < 2*HOST_BITS_PER_INT+1)
        !          1220:     {
        !          1221:       int temp = allocation_temporary_p ();
        !          1222: 
        !          1223:       push_obstacks_nochange ();
        !          1224:       /* Make this a permanent node.  */
        !          1225:       if (temp)
        !          1226:        end_temporary_allocation ();
        !          1227:       t = build_int_2 (number, 0);
        !          1228:       TREE_TYPE (t) = sizetype;
        !          1229:       size_table[number] = t;
        !          1230:       pop_obstacks ();
        !          1231:     }
        !          1232:   else
        !          1233:     {
        !          1234:       t = build_int_2 (number, 0);
        !          1235:       TREE_TYPE (t) = sizetype;
        !          1236:     }
        !          1237:   return t;
        !          1238: }
        !          1239: 
        !          1240: /* Combine operands OP1 and OP2 with arithmetic operation CODE.
        !          1241:    CODE is a tree code.  Data type is taken from `sizetype',
        !          1242:    If the operands are constant, so is the result.  */
        !          1243: 
        !          1244: tree
        !          1245: size_binop (code, arg0, arg1)
        !          1246:      enum tree_code code;
        !          1247:      tree arg0, arg1;
        !          1248: {
        !          1249:   /* Handle the special case of two integer constants faster.  */
        !          1250:   if (TREE_CODE (arg0) == INTEGER_CST && TREE_CODE (arg1) == INTEGER_CST)
        !          1251:     {
        !          1252:       /* And some specific cases even faster than that.  */
        !          1253:       if (code == PLUS_EXPR
        !          1254:          && TREE_INT_CST_LOW (arg0) == 0
        !          1255:          && TREE_INT_CST_HIGH (arg0) == 0)
        !          1256:        return arg1;
        !          1257:       if (code == MINUS_EXPR
        !          1258:          && TREE_INT_CST_LOW (arg1) == 0
        !          1259:          && TREE_INT_CST_HIGH (arg1) == 0)
        !          1260:        return arg0;
        !          1261:       if (code == MULT_EXPR
        !          1262:          && TREE_INT_CST_LOW (arg0) == 1
        !          1263:          && TREE_INT_CST_HIGH (arg0) == 0)
        !          1264:        return arg1;
        !          1265:       /* Handle general case of two integer constants.  */
        !          1266:       return const_binop (code, arg0, arg1);
        !          1267:     }
        !          1268: 
        !          1269:   if (arg0 == error_mark_node || arg1 == error_mark_node)
        !          1270:     return error_mark_node;
        !          1271: 
        !          1272:   return fold (build (code, sizetype, arg0, arg1));
        !          1273: }
        !          1274: 
        !          1275: /* Given T, a tree representing type conversion of ARG1, a constant,
        !          1276:    return a constant tree representing the result of conversion.  */
        !          1277: 
        !          1278: static tree
        !          1279: fold_convert (t, arg1)
        !          1280:      register tree t;
        !          1281:      register tree arg1;
        !          1282: {
        !          1283:   register tree type = TREE_TYPE (t);
        !          1284: 
        !          1285:   if (TREE_CODE (type) == POINTER_TYPE
        !          1286:       || TREE_CODE (type) == INTEGER_TYPE
        !          1287:       || TREE_CODE (type) == ENUMERAL_TYPE)
        !          1288:     {
        !          1289:       if (TREE_CODE (arg1) == INTEGER_CST)
        !          1290:        {
        !          1291:          /* Given an integer constant, make new constant with new type,
        !          1292:             appropriately sign-extended or truncated.  */
        !          1293:          t = build_int_2 (TREE_INT_CST_LOW (arg1),
        !          1294:                           TREE_INT_CST_HIGH (arg1));
        !          1295:          TREE_TYPE (t) = type;
        !          1296:          force_fit_type (t);
        !          1297:        }
        !          1298: #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
        !          1299:       else if (TREE_CODE (arg1) == REAL_CST)
        !          1300:        {
        !          1301:          if (REAL_VALUES_LESS (real_value_from_int_cst (TYPE_MAX_VALUE (type)),
        !          1302:                                TREE_REAL_CST (arg1))
        !          1303:              || REAL_VALUES_LESS (TREE_REAL_CST (arg1),
        !          1304:                                   real_value_from_int_cst (TYPE_MIN_VALUE (type))))
        !          1305:            {
        !          1306:              warning ("real constant out of range for integer conversion");
        !          1307:              return t;
        !          1308:            }
        !          1309: #ifndef REAL_ARITHMETIC
        !          1310:          {
        !          1311:            REAL_VALUE_TYPE d;
        !          1312:            int low, high;
        !          1313:            int half_word = 1 << (HOST_BITS_PER_INT / 2);
        !          1314: 
        !          1315:            d = TREE_REAL_CST (arg1);
        !          1316:            if (d < 0)
        !          1317:              d = -d;
        !          1318: 
        !          1319:            high = (int) (d / half_word / half_word);
        !          1320:            d -= (REAL_VALUE_TYPE) high * half_word * half_word;
        !          1321:            low = (unsigned) d;
        !          1322:            if (TREE_REAL_CST (arg1) < 0)
        !          1323:              neg_double (low, high, &low, &high);
        !          1324:            t = build_int_2 (low, high);
        !          1325:          }
        !          1326: #else
        !          1327:          {
        !          1328:            int low, high;
        !          1329:            REAL_VALUE_TO_INT (low, high, TREE_REAL_CST (arg1));
        !          1330:            t = build_int_2 (low, high);
        !          1331:          }
        !          1332: #endif
        !          1333:          TREE_TYPE (t) = type;
        !          1334:          force_fit_type (t);
        !          1335:        }
        !          1336: #endif /* not REAL_IS_NOT_DOUBLE, or REAL_ARITHMETIC */
        !          1337:       TREE_TYPE (t) = type;
        !          1338:     }
        !          1339:   else if (TREE_CODE (type) == REAL_TYPE)
        !          1340:     {
        !          1341: #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
        !          1342:       if (TREE_CODE (arg1) == INTEGER_CST)
        !          1343:        return build_real_from_int_cst (type, arg1);
        !          1344: #endif /* not REAL_IS_NOT_DOUBLE, or REAL_ARITHMETIC */
        !          1345:       if (TREE_CODE (arg1) == REAL_CST)
        !          1346:        return build_real (type, REAL_VALUE_TRUNCATE (TYPE_MODE (type),
        !          1347:                                                      TREE_REAL_CST (arg1)));
        !          1348:     }
        !          1349:   TREE_CONSTANT (t) = 1;
        !          1350:   return t;
        !          1351: }
        !          1352: 
        !          1353: /* Return an expr equal to X but certainly not valid as an lvalue.  */
        !          1354: 
        !          1355: tree
        !          1356: non_lvalue (x)
        !          1357:      tree x;
        !          1358: {
        !          1359:   tree result;
        !          1360: 
        !          1361:   /* These things are certainly not lvalues.  */
        !          1362:   if (TREE_CODE (x) == NON_LVALUE_EXPR
        !          1363:       || TREE_CODE (x) == INTEGER_CST
        !          1364:       || TREE_CODE (x) == REAL_CST
        !          1365:       || TREE_CODE (x) == STRING_CST
        !          1366:       || TREE_CODE (x) == ADDR_EXPR)
        !          1367:     return x;
        !          1368: 
        !          1369:   result = build1 (NON_LVALUE_EXPR, TREE_TYPE (x), x);
        !          1370:   TREE_CONSTANT (result) = TREE_CONSTANT (x);
        !          1371:   return result;
        !          1372: }
        !          1373: 
        !          1374: /* Return nonzero if two operands are necessarily equal. 
        !          1375:    If ONLY_CONST is non-zero, only return non-zero for constants.  */
        !          1376: 
        !          1377: int
        !          1378: operand_equal_p (arg0, arg1, only_const)
        !          1379:      tree arg0, arg1;
        !          1380:      int only_const;
        !          1381: {
        !          1382:   /* If both types don't have the same signedness, then we can't consider
        !          1383:      them equal.  We must check this before the STRIP_NOPS calls
        !          1384:      because they may change the signedness of the arguments.  */
        !          1385:   if (TREE_UNSIGNED (TREE_TYPE (arg0)) != TREE_UNSIGNED (TREE_TYPE (arg1)))
        !          1386:     return 0;
        !          1387: 
        !          1388:   STRIP_NOPS (arg0);
        !          1389:   STRIP_NOPS (arg1);
        !          1390: 
        !          1391:   /* If ARG0 and ARG1 are the same SAVE_EXPR, they are necessarily equal.
        !          1392:      We don't care about side effects in that case because the SAVE_EXPR
        !          1393:      takes care of that for us.  */
        !          1394:   if (TREE_CODE (arg0) == SAVE_EXPR && arg0 == arg1)
        !          1395:     return ! only_const;
        !          1396: 
        !          1397:   if (TREE_SIDE_EFFECTS (arg0) || TREE_SIDE_EFFECTS (arg1))
        !          1398:     return 0;
        !          1399: 
        !          1400:   if (TREE_CODE (arg0) == TREE_CODE (arg1)
        !          1401:       && TREE_CODE (arg0) == ADDR_EXPR
        !          1402:       && TREE_OPERAND (arg0, 0) == TREE_OPERAND (arg1, 0))
        !          1403:     return 1;
        !          1404: 
        !          1405:   if (TREE_CODE (arg0) == TREE_CODE (arg1)
        !          1406:       && TREE_CODE (arg0) == INTEGER_CST
        !          1407:       && TREE_INT_CST_LOW (arg0) == TREE_INT_CST_LOW (arg1)
        !          1408:       && TREE_INT_CST_HIGH (arg0) == TREE_INT_CST_HIGH (arg1))
        !          1409:     return 1;
        !          1410: 
        !          1411:   if (TREE_CODE (arg0) == TREE_CODE (arg1)
        !          1412:       && TREE_CODE (arg0) == REAL_CST
        !          1413:       && REAL_VALUES_EQUAL (TREE_REAL_CST (arg0), TREE_REAL_CST (arg1)))
        !          1414:     return 1;
        !          1415: 
        !          1416:   if (only_const)
        !          1417:     return 0;
        !          1418: 
        !          1419:   if (arg0 == arg1)
        !          1420:     return 1;
        !          1421: 
        !          1422:   if (TREE_CODE (arg0) != TREE_CODE (arg1))
        !          1423:     return 0;
        !          1424:   /* This is needed for conversions and for COMPONENT_REF.
        !          1425:      Might as well play it safe and always test this.  */
        !          1426:   if (TYPE_MODE (TREE_TYPE (arg0)) != TYPE_MODE (TREE_TYPE (arg1)))
        !          1427:     return 0;
        !          1428: 
        !          1429:   switch (TREE_CODE_CLASS (TREE_CODE (arg0)))
        !          1430:     {
        !          1431:     case '1':
        !          1432:       /* Two conversions are equal only if signedness and modes match.  */
        !          1433:       if ((TREE_CODE (arg0) == NOP_EXPR || TREE_CODE (arg0) == CONVERT_EXPR)
        !          1434:          && (TREE_UNSIGNED (TREE_TYPE (arg0))
        !          1435:              != TREE_UNSIGNED (TREE_TYPE (arg1))))
        !          1436:        return 0;
        !          1437: 
        !          1438:       return operand_equal_p (TREE_OPERAND (arg0, 0),
        !          1439:                              TREE_OPERAND (arg1, 0), 0);
        !          1440: 
        !          1441:     case '<':
        !          1442:     case '2':
        !          1443:       return (operand_equal_p (TREE_OPERAND (arg0, 0),
        !          1444:                               TREE_OPERAND (arg1, 0), 0)
        !          1445:              && operand_equal_p (TREE_OPERAND (arg0, 1),
        !          1446:                                  TREE_OPERAND (arg1, 1), 0));
        !          1447: 
        !          1448:     case 'r':
        !          1449:       switch (TREE_CODE (arg0))
        !          1450:        {
        !          1451:        case INDIRECT_REF:
        !          1452:          return operand_equal_p (TREE_OPERAND (arg0, 0),
        !          1453:                                  TREE_OPERAND (arg1, 0), 0);
        !          1454: 
        !          1455:        case COMPONENT_REF:
        !          1456:        case ARRAY_REF:
        !          1457:          return (operand_equal_p (TREE_OPERAND (arg0, 0),
        !          1458:                                   TREE_OPERAND (arg1, 0), 0)
        !          1459:                  && operand_equal_p (TREE_OPERAND (arg0, 1),
        !          1460:                                      TREE_OPERAND (arg1, 1), 0));
        !          1461: 
        !          1462:        case BIT_FIELD_REF:
        !          1463:          return (operand_equal_p (TREE_OPERAND (arg0, 0),
        !          1464:                                   TREE_OPERAND (arg1, 0), 0)
        !          1465:                  && operand_equal_p (TREE_OPERAND (arg0, 1),
        !          1466:                                      TREE_OPERAND (arg1, 1), 0)
        !          1467:                  && operand_equal_p (TREE_OPERAND (arg0, 2),
        !          1468:                                      TREE_OPERAND (arg1, 2), 0));
        !          1469:        }
        !          1470:       break;
        !          1471:     }
        !          1472: 
        !          1473:   return 0;
        !          1474: }
        !          1475: 
        !          1476: /* Return nonzero if comparing COMP1 with COMP2
        !          1477:    gives the same result as comparing OP1 with OP2.
        !          1478:    When in doubt, return 0.  */
        !          1479: 
        !          1480: static int 
        !          1481: comparison_equiv_p (comp1, comp2, op1, op2)
        !          1482:      tree comp1, comp2, op1, op2;
        !          1483: {
        !          1484:   int unsignedp1, unsignedp2;
        !          1485:   tree primop1, primop2;
        !          1486:   int correct_width;
        !          1487: 
        !          1488:   if (operand_equal_p (comp1, op1, 0)
        !          1489:       && operand_equal_p (comp2, op2, 0))
        !          1490:     return 1;
        !          1491: 
        !          1492:   if (TREE_CODE (TREE_TYPE (op1)) != INTEGER_TYPE)
        !          1493:     return 0;
        !          1494: 
        !          1495:   if (TREE_TYPE (op1) != TREE_TYPE (op2))
        !          1496:     return 0;
        !          1497: 
        !          1498:   if (TREE_TYPE (comp1) != TREE_TYPE (comp2))
        !          1499:     return 0;
        !          1500: 
        !          1501:   /* Duplicate what shorten_compare does to the comparison operands,
        !          1502:      and see if that gives the actual comparison operands, COMP1 and COMP2.  */
        !          1503: 
        !          1504:   /* Throw away any conversions to wider types
        !          1505:      already present in the operands.  */
        !          1506:   primop1 = get_narrower (op1, &unsignedp1);
        !          1507:   primop2 = get_narrower (op2, &unsignedp2);
        !          1508: 
        !          1509:   correct_width = TYPE_PRECISION (TREE_TYPE (op2));
        !          1510:   if (unsignedp1 == unsignedp2
        !          1511:       && TYPE_PRECISION (TREE_TYPE (primop1)) < correct_width
        !          1512:       && TYPE_PRECISION (TREE_TYPE (primop2)) < correct_width)
        !          1513:     {
        !          1514:       tree type = TREE_TYPE (comp1);
        !          1515: 
        !          1516:       /* Make sure shorter operand is extended the right way
        !          1517:         to match the longer operand.  */
        !          1518:       primop1 = convert (signed_or_unsigned_type (unsignedp1, TREE_TYPE (primop1)),
        !          1519:                         primop1);
        !          1520:       primop2 = convert (signed_or_unsigned_type (unsignedp2, TREE_TYPE (primop2)),
        !          1521:                         primop2);
        !          1522: 
        !          1523:       primop1 = convert (type, primop1);
        !          1524:       primop2 = convert (type, primop2);
        !          1525: 
        !          1526:       if (operand_equal_p (comp1, primop1, 0)
        !          1527:          && operand_equal_p (comp2, primop2, 0))
        !          1528:        return 1;
        !          1529:     }
        !          1530: 
        !          1531:   return 0;
        !          1532: }
        !          1533: 
        !          1534: /* Return a tree for the case when the result of an expression is RESULT
        !          1535:    converted to TYPE and OMITTED was previously an operand of the expression
        !          1536:    but is now not needed (e.g., we folded OMITTED * 0).
        !          1537: 
        !          1538:    If OMITTED has side effects, we must evaluate it.  Otherwise, just do
        !          1539:    the conversion of RESULT to TYPE.  */
        !          1540: 
        !          1541: static tree
        !          1542: omit_one_operand (type, result, omitted)
        !          1543:      tree type, result, omitted;
        !          1544: {
        !          1545:   tree t = convert (type, result);
        !          1546: 
        !          1547:   if (TREE_SIDE_EFFECTS (omitted))
        !          1548:     return build (COMPOUND_EXPR, type, omitted, t);
        !          1549: 
        !          1550:   return t;
        !          1551: }
        !          1552: 
        !          1553: /* Return a simplified tree node for the truth-negation of ARG
        !          1554:    (perhaps by altering ARG).  It is known that ARG is an operation that
        !          1555:    returns a truth value (0 or 1).  */
        !          1556: 
        !          1557: tree
        !          1558: invert_truthvalue (arg)
        !          1559:      tree arg;
        !          1560: {
        !          1561:   tree type = TREE_TYPE (arg);
        !          1562: 
        !          1563:   /* For floating-point comparisons, it isn't safe to invert the condition.
        !          1564:      So just enclose a TRUTH_NOT_EXPR around what we have.  */
        !          1565:   if (TREE_CODE (type) == REAL_TYPE
        !          1566:       && TREE_CODE_CLASS (TREE_CODE (arg)) == '<')
        !          1567:     return build1 (TRUTH_NOT_EXPR, type, arg);
        !          1568: 
        !          1569:   switch (TREE_CODE (arg))
        !          1570:     {
        !          1571:     case NE_EXPR:
        !          1572:       TREE_SET_CODE (arg, EQ_EXPR);
        !          1573:       return arg;
        !          1574: 
        !          1575:     case EQ_EXPR:
        !          1576:       TREE_SET_CODE (arg, NE_EXPR);
        !          1577:       return arg;
        !          1578: 
        !          1579:     case GE_EXPR:
        !          1580:       TREE_SET_CODE (arg, LT_EXPR);
        !          1581:       return arg;
        !          1582: 
        !          1583:     case GT_EXPR:
        !          1584:       TREE_SET_CODE (arg, LE_EXPR);
        !          1585:       return arg;
        !          1586: 
        !          1587:     case LE_EXPR:
        !          1588:       TREE_SET_CODE (arg, GT_EXPR);
        !          1589:       return arg;
        !          1590: 
        !          1591:     case LT_EXPR:
        !          1592:       TREE_SET_CODE (arg, GE_EXPR);
        !          1593:       return arg;
        !          1594: 
        !          1595:     case INTEGER_CST:
        !          1596:       return convert (type, build_int_2 (TREE_INT_CST_LOW (arg) == 0
        !          1597:                                         && TREE_INT_CST_HIGH (arg) == 0, 0));
        !          1598: 
        !          1599:     case TRUTH_AND_EXPR:
        !          1600:       return build (TRUTH_OR_EXPR, type,
        !          1601:                    invert_truthvalue (TREE_OPERAND (arg, 0)),
        !          1602:                    invert_truthvalue (TREE_OPERAND (arg, 1)));
        !          1603: 
        !          1604:     case TRUTH_OR_EXPR:
        !          1605:       return build (TRUTH_AND_EXPR, type,
        !          1606:                    invert_truthvalue (TREE_OPERAND (arg, 0)),
        !          1607:                    invert_truthvalue (TREE_OPERAND (arg, 1)));
        !          1608: 
        !          1609:     case TRUTH_ANDIF_EXPR:
        !          1610:       return build (TRUTH_ORIF_EXPR, type,
        !          1611:                    invert_truthvalue (TREE_OPERAND (arg, 0)),
        !          1612:                    invert_truthvalue (TREE_OPERAND (arg, 1)));
        !          1613: 
        !          1614:     case TRUTH_ORIF_EXPR:
        !          1615:       return build (TRUTH_ANDIF_EXPR, type,
        !          1616:                    invert_truthvalue (TREE_OPERAND (arg, 0)),
        !          1617:                    invert_truthvalue (TREE_OPERAND (arg, 1)));
        !          1618: 
        !          1619:     case TRUTH_NOT_EXPR:
        !          1620:       return TREE_OPERAND (arg, 0);
        !          1621: 
        !          1622:     case COND_EXPR:
        !          1623:       return build (COND_EXPR, type, TREE_OPERAND (arg, 0),
        !          1624:                    invert_truthvalue (TREE_OPERAND (arg, 1)),
        !          1625:                    invert_truthvalue (TREE_OPERAND (arg, 2)));
        !          1626: 
        !          1627:     case NON_LVALUE_EXPR:
        !          1628:       return invert_truthvalue (TREE_OPERAND (arg, 0));
        !          1629: 
        !          1630:     case NOP_EXPR:
        !          1631:     case CONVERT_EXPR:
        !          1632:     case FLOAT_EXPR:
        !          1633:       return build1 (TREE_CODE (arg), type,
        !          1634:                     invert_truthvalue (TREE_OPERAND (arg, 0)));
        !          1635: 
        !          1636:     case BIT_AND_EXPR:
        !          1637:       if (! integer_onep (TREE_OPERAND (arg, 1)))
        !          1638:        abort ();
        !          1639:       return build (EQ_EXPR, type, arg, convert (type, integer_zero_node));
        !          1640:     }
        !          1641: 
        !          1642:   abort ();
        !          1643: }
        !          1644: 
        !          1645: /* Given a bit-wise operation CODE applied to ARG0 and ARG1, see if both
        !          1646:    operands are another bit-wise operation with a common input.  If so,
        !          1647:    distribute the bit operations to save an operation and possibly two if
        !          1648:    constants are involved.  For example, convert
        !          1649:        (A | B) & (A | C) into A | (B & C)
        !          1650:    Further simplification will occur if B and C are constants.
        !          1651: 
        !          1652:    If this optimization cannot be done, 0 will be returned.  */
        !          1653: 
        !          1654: static tree
        !          1655: distribute_bit_expr (code, type, arg0, arg1)
        !          1656:      enum tree_code code;
        !          1657:      tree type;
        !          1658:      tree arg0, arg1;
        !          1659: {
        !          1660:   tree common;
        !          1661:   tree left, right;
        !          1662: 
        !          1663:   if (TREE_CODE (arg0) != TREE_CODE (arg1)
        !          1664:       || TREE_CODE (arg0) == code
        !          1665:       || (TREE_CODE (arg0) != BIT_AND_EXPR
        !          1666:          && TREE_CODE (arg0) != BIT_IOR_EXPR))
        !          1667:     return 0;
        !          1668: 
        !          1669:   if (operand_equal_p (TREE_OPERAND (arg0, 0), TREE_OPERAND (arg1, 0), 0))
        !          1670:     {
        !          1671:       common = TREE_OPERAND (arg0, 0);
        !          1672:       left = TREE_OPERAND (arg0, 1);
        !          1673:       right = TREE_OPERAND (arg1, 1);
        !          1674:     }
        !          1675:   else if (operand_equal_p (TREE_OPERAND (arg0, 0), TREE_OPERAND (arg1, 1), 0))
        !          1676:     {
        !          1677:       common = TREE_OPERAND (arg0, 0);
        !          1678:       left = TREE_OPERAND (arg0, 1);
        !          1679:       right = TREE_OPERAND (arg1, 0);
        !          1680:     }
        !          1681:   else if (operand_equal_p (TREE_OPERAND (arg0, 1), TREE_OPERAND (arg1, 0), 0))
        !          1682:     {
        !          1683:       common = TREE_OPERAND (arg0, 1);
        !          1684:       left = TREE_OPERAND (arg0, 0);
        !          1685:       right = TREE_OPERAND (arg1, 1);
        !          1686:     }
        !          1687:   else if (operand_equal_p (TREE_OPERAND (arg0, 1), TREE_OPERAND (arg1, 1), 0))
        !          1688:     {
        !          1689:       common = TREE_OPERAND (arg0, 1);
        !          1690:       left = TREE_OPERAND (arg0, 0);
        !          1691:       right = TREE_OPERAND (arg1, 0);
        !          1692:     }
        !          1693:   else
        !          1694:     return 0;
        !          1695: 
        !          1696:   return fold (build (TREE_CODE (arg0), type, common,
        !          1697:                      fold (build (code, type, left, right))));
        !          1698: }
        !          1699: 
        !          1700: /* Return a BIT_FIELD_REF of type TYPE to refer to BITSIZE bits of INNER
        !          1701:    starting at BITPOS.  The field is unsigned if UNSIGNEDP is non-zero.  */
        !          1702: 
        !          1703: static tree
        !          1704: make_bit_field_ref (inner, type, bitsize, bitpos, unsignedp)
        !          1705:      tree inner;
        !          1706:      tree type;
        !          1707:      int bitsize, bitpos;
        !          1708:      int unsignedp;
        !          1709: {
        !          1710:   tree result = build (BIT_FIELD_REF, type, inner,
        !          1711:                       size_int (bitsize), size_int (bitpos));
        !          1712: 
        !          1713:   TREE_UNSIGNED (result) = unsignedp;
        !          1714: 
        !          1715:   return result;
        !          1716: }
        !          1717: 
        !          1718: /* Optimize a bit-field compare.
        !          1719: 
        !          1720:    There are two cases:  First is a compare against a constant and the
        !          1721:    second is a comparison of two items where the fields are at the same
        !          1722:    bit position relative to the start of a chunk (byte, halfword, word)
        !          1723:    large enough to contain it.  In these cases we can avoid the shift
        !          1724:    implicit in bitfield extractions.
        !          1725: 
        !          1726:    For constants, we emit a compare of the shifted constant with the
        !          1727:    BIT_AND_EXPR of a mask and a byte, halfword, or word of the operand being
        !          1728:    compared.  For two fields at the same position, we do the ANDs with the
        !          1729:    similar mask and compare the result of the ANDs.
        !          1730: 
        !          1731:    CODE is the comparison code, known to be either NE_EXPR or EQ_EXPR.
        !          1732:    COMPARE_TYPE is the type of the comparison, and LHS and RHS
        !          1733:    are the left and right operands of the comparison, respectively.
        !          1734: 
        !          1735:    If the optimization described above can be done, we return the resuling
        !          1736:    tree.  Otherwise we return zero.  */
        !          1737: 
        !          1738: static tree
        !          1739: optimize_bit_field_compare (code, compare_type, lhs, rhs)
        !          1740:      enum tree_code code;
        !          1741:      tree compare_type;
        !          1742:      tree lhs, rhs;
        !          1743: {
        !          1744:   int lbitpos, lbitsize, rbitpos, rbitsize;
        !          1745:   int lnbitpos, lnbitsize, rnbitpos, rnbitsize;
        !          1746:   tree type = TREE_TYPE (lhs);
        !          1747:   tree signed_type, unsigned_type;
        !          1748:   int const_p = TREE_CODE (rhs) == INTEGER_CST;
        !          1749:   enum machine_mode lmode, rmode, lnmode, rnmode;
        !          1750:   int lunsignedp, runsignedp;
        !          1751:   int lvolatilep = 0, rvolatilep = 0;
        !          1752:   tree linner, rinner;
        !          1753:   tree mask;
        !          1754: 
        !          1755:   /* Get all the information about the extractions being done.  If the bit size
        !          1756:      if the same as the size of the underlying object, we aren't doing an
        !          1757:      extraction at all and so can do nothing.  */
        !          1758:   linner = get_inner_reference (lhs, &lbitsize, &lbitpos, &lmode,
        !          1759:                                &lunsignedp, &lvolatilep);
        !          1760:   if (lbitsize == GET_MODE_BITSIZE (lmode))
        !          1761:     return 0;
        !          1762: 
        !          1763:  if (!const_p)
        !          1764:    {
        !          1765:      /* If this is not a constant, we can only do something if bit positions,
        !          1766:        sizes, and signedness are the same.   */
        !          1767:      rinner = get_inner_reference (rhs, &rbitsize, &rbitpos,
        !          1768:                                   &rmode, &runsignedp, &rvolatilep);
        !          1769: 
        !          1770:      if (lbitpos != rbitpos || lbitsize != rbitsize
        !          1771:         || lunsignedp != runsignedp)
        !          1772:        return 0;
        !          1773:    }
        !          1774: 
        !          1775:   /* See if we can find a mode to refer to this field.  We should be able to,
        !          1776:      but fail if we can't.  */
        !          1777:   lnmode = get_best_mode (lbitsize, lbitpos,
        !          1778:                          TYPE_ALIGN (TREE_TYPE (linner)), word_mode,
        !          1779:                          lvolatilep);
        !          1780:   if (lnmode == VOIDmode)
        !          1781:     return 0;
        !          1782: 
        !          1783:   /* Set signed and unsigned types of the precision of this mode for the
        !          1784:      shifts below.  */
        !          1785:   signed_type = type_for_mode (lnmode, 0);
        !          1786:   unsigned_type = type_for_mode (lnmode, 1);
        !          1787: 
        !          1788:   if (! const_p)
        !          1789:     {
        !          1790:       rnmode = get_best_mode (rbitsize, rbitpos, 
        !          1791:                              TYPE_ALIGN (TREE_TYPE (rinner)), word_mode,
        !          1792:                              rvolatilep);
        !          1793:       if (rnmode == VOIDmode)
        !          1794:        return 0;
        !          1795:     }
        !          1796:     
        !          1797:   /* Compute the bit position and size for the new reference and our offset
        !          1798:      within it. If the new reference is the same size as the original, we
        !          1799:      won't optimize anything, so return zero.  */
        !          1800:   lnbitsize = GET_MODE_BITSIZE (lnmode);
        !          1801:   lnbitpos = lbitpos & ~ (lnbitsize - 1);
        !          1802:   lbitpos -= lnbitpos;
        !          1803:   if (lnbitsize == lbitsize)
        !          1804:     return 0;
        !          1805: 
        !          1806:   if (! const_p)
        !          1807:     {
        !          1808:       rnbitsize = GET_MODE_BITSIZE (rnmode);
        !          1809:       rnbitpos = rbitpos & ~ (rnbitsize - 1);
        !          1810:       rbitpos -= rnbitpos;
        !          1811:       if (rnbitsize == rbitsize)
        !          1812:        return 0;
        !          1813:     }
        !          1814: 
        !          1815: #if BYTES_BIG_ENDIAN
        !          1816:   lbitpos = lnbitsize - lbitsize - lbitpos;
        !          1817:   rbitpos = rnbitsize - rbitsize - rbitpos;
        !          1818: #endif
        !          1819: 
        !          1820:   /* Make the mask to be used against the extracted field.  */
        !          1821:   mask = convert (unsigned_type, build_int_2 (~0, ~0));
        !          1822:   mask = const_binop (LSHIFT_EXPR, mask, size_int (lnbitsize - lbitsize));
        !          1823:   mask = const_binop (RSHIFT_EXPR, mask,
        !          1824:                      size_int (lnbitsize - lbitsize - lbitpos));
        !          1825: 
        !          1826:   if (! const_p)
        !          1827:     /* If not comparing with constant, just rework the comparison
        !          1828:        and return.  */
        !          1829:     return build (code, compare_type,
        !          1830:                  build (BIT_AND_EXPR, type,
        !          1831:                         make_bit_field_ref (linner, type,
        !          1832:                                             lnbitsize, lnbitpos, lunsignedp),
        !          1833:                         mask),
        !          1834:                  build (BIT_AND_EXPR, type,
        !          1835:                         make_bit_field_ref (rinner, type,
        !          1836:                                             rnbitsize, rnbitpos, runsignedp),
        !          1837:                         mask));
        !          1838: 
        !          1839:   /* Otherwise, we are handling the constant case. See if the constant is too
        !          1840:      big for the field.  Warn and return a tree of for 0 (false) if so.  We do
        !          1841:      this not only for its own sake, but to avoid having to test for this
        !          1842:      error case below.  If we didn't, we might generate wrong code.
        !          1843: 
        !          1844:      For unsigned fields, the constant shifted right by the field length should
        !          1845:      be all zero.  For signed fields, the high-order bits should agree with 
        !          1846:      the sign bit.  */
        !          1847: 
        !          1848:   if (lunsignedp)
        !          1849:     {
        !          1850:       if (! integer_zerop (const_binop (RSHIFT_EXPR,
        !          1851:                                        convert (unsigned_type, rhs),
        !          1852:                                        size_int (lbitsize))))
        !          1853:        {
        !          1854:          warning ("comparison is always %s due to width of bitfield",
        !          1855:                   code == NE_EXPR ? "one" : "zero");
        !          1856:          return convert (compare_type,
        !          1857:                          (code == NE_EXPR
        !          1858:                           ? integer_one_node : integer_zero_node));
        !          1859:        }
        !          1860:     }
        !          1861:   else
        !          1862:     {
        !          1863:       tree tem = const_binop (RSHIFT_EXPR, convert (signed_type, rhs),
        !          1864:                              size_int (lbitsize - 1));
        !          1865:       if (! integer_zerop (tem) && ! integer_all_onesp (tem))
        !          1866:        {
        !          1867:          warning ("comparison is always %s due to width of bitfield",
        !          1868:                   code == NE_EXPR ? "one" : "zero");
        !          1869:          return convert (compare_type,
        !          1870:                          (code == NE_EXPR
        !          1871:                           ? integer_one_node : integer_zero_node));
        !          1872:        }
        !          1873:     }
        !          1874: 
        !          1875:   /* Single-bit compares should always be against zero.  */
        !          1876:   if (lbitsize == 1 && ! integer_zerop (rhs))
        !          1877:     {
        !          1878:       code = code == EQ_EXPR ? NE_EXPR : EQ_EXPR;
        !          1879:       rhs = convert (type, integer_zero_node);
        !          1880:     }
        !          1881: 
        !          1882:   /* Make a new bitfield reference, shift the constant over the
        !          1883:      appropriate number of bits and mask it with the computed mask
        !          1884:      (in case this was a signed field).  If we changed it, make a new one.  */
        !          1885:   lhs = make_bit_field_ref (linner, TREE_TYPE (lhs), lnbitsize, lnbitpos, 
        !          1886:                            lunsignedp);
        !          1887: 
        !          1888:   rhs = fold (build1 (NOP_EXPR, type,
        !          1889:                      const_binop (BIT_AND_EXPR,
        !          1890:                                   const_binop (LSHIFT_EXPR,
        !          1891:                                                convert (unsigned_type, rhs),
        !          1892:                                                size_int (lbitpos)), mask)));
        !          1893: 
        !          1894:   return build (code, compare_type,
        !          1895:                build (BIT_AND_EXPR, type, lhs, mask),
        !          1896:                rhs);
        !          1897: }
        !          1898: 
        !          1899: /* Subroutine for the following routine: decode a field reference.
        !          1900: 
        !          1901:    If EXP is a comparison reference, we return the innermost reference.
        !          1902: 
        !          1903:    *PBITSIZE is set to the number of bits in the reference, *PBITPOS is
        !          1904:    set to the starting bit number.
        !          1905: 
        !          1906:    If the innermost field can be completely contained in a mode-sized
        !          1907:    unit, *PMODE is set to that mode.  Otherwise, it is set to VOIDmode.
        !          1908: 
        !          1909:    *PVOLATILEP is set to 1 if the any expression encountered is volatile;
        !          1910:    otherwise it is not changed.
        !          1911: 
        !          1912:    *PUNSIGNEDP is set to the signedness of the field.
        !          1913: 
        !          1914:    *PMASK is set to the mask used.  This is either contained in a
        !          1915:    BIT_AND_EXPR or derived from the width of the field.
        !          1916: 
        !          1917:    Return 0 if this is not a component reference or is one that we can't
        !          1918:    do anything with.  */
        !          1919: 
        !          1920: static tree
        !          1921: decode_field_reference (exp, pbitsize, pbitpos, pmode, punsignedp,
        !          1922:                        pvolatilep, pmask)
        !          1923:      tree exp;
        !          1924:      int *pbitsize, *pbitpos;
        !          1925:      enum machine_mode *pmode;
        !          1926:      int *punsignedp, *pvolatilep;
        !          1927:      tree *pmask;
        !          1928: {
        !          1929:   tree mask = 0;
        !          1930:   tree inner;
        !          1931: 
        !          1932:   STRIP_NOPS (exp);
        !          1933: 
        !          1934:   if (TREE_CODE (exp) == BIT_AND_EXPR)
        !          1935:     {
        !          1936:       mask = TREE_OPERAND (exp, 1);
        !          1937:       exp = TREE_OPERAND (exp, 0);
        !          1938:       STRIP_NOPS (exp); STRIP_NOPS (mask);
        !          1939:       if (TREE_CODE (mask) != INTEGER_CST)
        !          1940:        return 0;
        !          1941:     }
        !          1942: 
        !          1943:   if (TREE_CODE (exp) != COMPONENT_REF && TREE_CODE (exp) != ARRAY_REF
        !          1944:       && TREE_CODE (exp) != BIT_FIELD_REF)
        !          1945:     return 0;
        !          1946: 
        !          1947:   inner = get_inner_reference (exp, pbitsize, pbitpos, pmode,
        !          1948:                               punsignedp, pvolatilep);
        !          1949:   
        !          1950:   if (mask == 0)
        !          1951:     {
        !          1952:       tree unsigned_type = type_for_size (*pbitsize, 1);
        !          1953:       int precision = TYPE_PRECISION (unsigned_type);
        !          1954: 
        !          1955:       mask = convert (unsigned_type, build_int_2 (~0, ~0));
        !          1956:       mask = const_binop (LSHIFT_EXPR, mask, size_int (precision - *pbitsize));
        !          1957:       mask = const_binop (RSHIFT_EXPR, mask, size_int (precision - *pbitsize));
        !          1958:     }
        !          1959: 
        !          1960:   *pmask = mask;
        !          1961:   return inner;
        !          1962: }
        !          1963: 
        !          1964: /* Return non-zero if MASK respresents a mask of SIZE ones in the low-order
        !          1965:    bit positions.  */
        !          1966: 
        !          1967: static int
        !          1968: all_ones_mask_p (mask, size)
        !          1969:      tree mask;
        !          1970:      int size;
        !          1971: {
        !          1972:   tree type = TREE_TYPE (mask);
        !          1973:   int precision = TYPE_PRECISION (type);
        !          1974: 
        !          1975:   return
        !          1976:     operand_equal_p (mask, 
        !          1977:                     const_binop (RSHIFT_EXPR,
        !          1978:                                  const_binop (LSHIFT_EXPR,
        !          1979:                                               convert (signed_type (type),
        !          1980:                                                        build_int_2 (~0, ~0)),
        !          1981:                                               size_int (precision - size)),
        !          1982:                                  size_int (precision - size)), 0);
        !          1983: }
        !          1984: 
        !          1985: /* Try to merge two comparisons to the same innermost item.
        !          1986: 
        !          1987:    For example, if we have p->a == 2 && p->b == 4 and we can make an
        !          1988:    object large enough to span both A and B, we can do this with a comparison
        !          1989:    against the object ANDed with the a mask.
        !          1990: 
        !          1991:    If we have p->a == q->a && p->b == q->b, we may be able to use bit masking
        !          1992:    operations to do this with one comparison.
        !          1993: 
        !          1994:    We check for both normal comparisons and the BIT_AND_EXPRs made this by
        !          1995:    function and the one above.
        !          1996: 
        !          1997:    CODE is the logical operation being done.  It can be TRUTH_ANDIF_EXPR,
        !          1998:    TRUTH_AND_EXPR, TRUTH_ORIF_EXPR, or TRUTH_OR_EXPR.
        !          1999: 
        !          2000:    TRUTH_TYPE is the type of the logical operand and LHS and RHS are its
        !          2001:    two operands.
        !          2002: 
        !          2003:    We return the simplified tree or 0 if no optimization is possible.  */
        !          2004: 
        !          2005: static tree
        !          2006: merge_component_references (code, truth_type, lhs, rhs)
        !          2007:      enum tree_code code;
        !          2008:      tree truth_type, lhs, rhs;
        !          2009: {
        !          2010:   /* If this is the "or" of two comparisons, we can do something if we
        !          2011:      the comparisons are NE_EXPR.  If this is the "and", we can do something
        !          2012:      if the comparisons are EQ_EXPR.  I.e., 
        !          2013:        (a->b == 2 && a->c == 4) can become (a->new == NEW).
        !          2014: 
        !          2015:      WANTED_CODE is this operation code.  For single bit fields, we can
        !          2016:      convert EQ_EXPR to NE_EXPR so we need not reject the "wrong"
        !          2017:      comparison for one-bit fields.  */
        !          2018: 
        !          2019:   enum tree_code wanted_code
        !          2020:     = (code == TRUTH_AND_EXPR || code == TRUTH_ANDIF_EXPR) ? EQ_EXPR : NE_EXPR;
        !          2021:   enum tree_code lcode, rcode;
        !          2022:   tree ll_inner, lr_inner, rl_inner, rr_inner;
        !          2023:   int ll_bitsize, ll_bitpos, lr_bitsize, lr_bitpos;
        !          2024:   int rl_bitsize, rl_bitpos, rr_bitsize, rr_bitpos;
        !          2025:   int xll_bitpos, xlr_bitpos, xrl_bitpos, xrr_bitpos;
        !          2026:   int lnbitsize, lnbitpos, rnbitsize, rnbitpos;
        !          2027:   int ll_unsignedp, lr_unsignedp, rl_unsignedp, rr_unsignedp;
        !          2028:   enum machine_mode ll_mode, lr_mode, rl_mode, rr_mode;
        !          2029:   enum machine_mode lnmode, rnmode;
        !          2030:   tree ll_mask, lr_mask, rl_mask, rr_mask;
        !          2031:   tree l_const = 0, r_const = 0;
        !          2032:   tree type, result;
        !          2033:   int first_bit, end_bit;
        !          2034:   int volatilep = 0;
        !          2035: 
        !          2036:   /* Start by getting the comparison codes and seeing if we may be able
        !          2037:      to do something.  Then get all the parameters for each side.  Fail
        !          2038:      if anything is volatile.  */
        !          2039: 
        !          2040:   lcode = TREE_CODE (lhs);
        !          2041:   rcode = TREE_CODE (rhs);
        !          2042:   if ((lcode != EQ_EXPR && lcode != NE_EXPR)
        !          2043:       || (rcode != EQ_EXPR && rcode != NE_EXPR)
        !          2044:       || TREE_SIDE_EFFECTS (lhs) || TREE_SIDE_EFFECTS (rhs))
        !          2045:     return 0;
        !          2046: 
        !          2047:   ll_inner = decode_field_reference (TREE_OPERAND (lhs, 0),
        !          2048:                                     &ll_bitsize, &ll_bitpos, &ll_mode,
        !          2049:                                     &ll_unsignedp, &volatilep, &ll_mask);
        !          2050:   lr_inner = decode_field_reference (TREE_OPERAND (lhs, 1),
        !          2051:                                     &lr_bitsize, &lr_bitpos, &lr_mode,
        !          2052:                                     &lr_unsignedp, &volatilep, &lr_mask);
        !          2053:   rl_inner = decode_field_reference (TREE_OPERAND (rhs, 0),
        !          2054:                                     &rl_bitsize, &rl_bitpos, &rl_mode,
        !          2055:                                     &rl_unsignedp, &volatilep, &rl_mask);
        !          2056:   rr_inner = decode_field_reference (TREE_OPERAND (rhs, 1),
        !          2057:                                     &rr_bitsize, &rr_bitpos, &rr_mode,
        !          2058:                                     &rr_unsignedp, &volatilep, &rr_mask);
        !          2059: 
        !          2060:   /* It must be true that the inner operation on the lhs of each
        !          2061:      comparison must be the same if we are to be able to do anything.
        !          2062:      Then see if we have constants.  If not, the same must be true for
        !          2063:      the rhs's.  */
        !          2064:   if (volatilep || ll_inner == 0 || rl_inner == 0
        !          2065:       || ! operand_equal_p (ll_inner, rl_inner, 0))
        !          2066:     return 0;
        !          2067: 
        !          2068:   if (TREE_CODE (TREE_OPERAND (lhs, 1)) == INTEGER_CST
        !          2069:       && TREE_CODE (TREE_OPERAND (rhs, 1)) == INTEGER_CST)
        !          2070:     l_const = TREE_OPERAND (lhs, 1), r_const = TREE_OPERAND (rhs, 1);
        !          2071:   else if (lr_inner == 0 || rr_inner == 0
        !          2072:           || ! operand_equal_p (lr_inner, rr_inner, 0))
        !          2073:     return 0;
        !          2074: 
        !          2075:   /* If either comparison code is not correct for our logical operation,
        !          2076:      fail.  However, we can convert a one-bit comparison against zero into
        !          2077:      the opposite comparison against that bit being set in the field.  */
        !          2078:   if (lcode != wanted_code)
        !          2079:     {
        !          2080:       if (l_const && integer_zerop (l_const) && integer_pow2p (ll_mask))
        !          2081:        l_const = ll_mask;
        !          2082:       else
        !          2083:        return 0;
        !          2084:     }
        !          2085: 
        !          2086:   if (rcode != wanted_code)
        !          2087:     {
        !          2088:       if (r_const && integer_zerop (r_const) && integer_pow2p (rl_mask))
        !          2089:        r_const = rl_mask;
        !          2090:       else
        !          2091:        return 0;
        !          2092:     }
        !          2093: 
        !          2094:   /* See if we can find a mode that contains both fields being compared on
        !          2095:      the left.  If we can't, fail.  Otherwise, update all constants and masks
        !          2096:      to be relative to a field of that size.  */
        !          2097:   first_bit = MIN (ll_bitpos, rl_bitpos);
        !          2098:   end_bit = MAX (ll_bitpos + ll_bitsize, rl_bitpos + rl_bitsize);
        !          2099:   lnmode = get_best_mode (end_bit - first_bit, first_bit,
        !          2100:                          TYPE_ALIGN (TREE_TYPE (ll_inner)), word_mode,
        !          2101:                          volatilep);
        !          2102:   if (lnmode == VOIDmode)
        !          2103:     return 0;
        !          2104: 
        !          2105:   lnbitsize = GET_MODE_BITSIZE (lnmode);
        !          2106:   lnbitpos = first_bit & ~ (lnbitsize - 1);
        !          2107:   type = type_for_size (lnbitsize, 1);
        !          2108:   xll_bitpos = ll_bitpos - lnbitpos, xrl_bitpos = rl_bitpos - lnbitpos;
        !          2109: 
        !          2110: #if BYTES_BIG_ENDIAN
        !          2111:   xll_bitpos = lnbitsize - xll_bitpos - ll_bitsize;
        !          2112:   xrl_bitpos = lnbitsize - xrl_bitpos - rl_bitsize;
        !          2113: #endif
        !          2114: 
        !          2115:   ll_mask = const_binop (LSHIFT_EXPR, convert (type, ll_mask),
        !          2116:                         size_int (xll_bitpos));
        !          2117:   rl_mask = const_binop (LSHIFT_EXPR, convert (type, rl_mask),
        !          2118:                         size_int (xrl_bitpos));
        !          2119: 
        !          2120:   /* Make sure the constants are interpreted as unsigned, so we
        !          2121:      don't have sign bits outside the range of their type.  */
        !          2122: 
        !          2123:   if (l_const)
        !          2124:     {
        !          2125:       l_const = convert (unsigned_type (TREE_TYPE (l_const)), l_const);
        !          2126:       l_const = const_binop (LSHIFT_EXPR, convert (type, l_const),
        !          2127:                             size_int (xll_bitpos));
        !          2128:     }
        !          2129:   if (r_const)
        !          2130:     {
        !          2131:       r_const = convert (unsigned_type (TREE_TYPE (r_const)), r_const);
        !          2132:       r_const = const_binop (LSHIFT_EXPR, convert (type, r_const),
        !          2133:                             size_int (xrl_bitpos));
        !          2134:     }
        !          2135: 
        !          2136:   /* If the right sides are not constant, do the same for it.  Also,
        !          2137:      disallow this optimization if a size or signedness mismatch occurs
        !          2138:      between the left and right sides.  */
        !          2139:   if (l_const == 0)
        !          2140:     {
        !          2141:       if (ll_bitsize != lr_bitsize || rl_bitsize != rr_bitsize
        !          2142:          || ll_unsignedp != lr_unsignedp || rl_unsignedp != rr_unsignedp)
        !          2143:        return 0;
        !          2144: 
        !          2145:       first_bit = MIN (lr_bitpos, rr_bitpos);
        !          2146:       end_bit = MAX (lr_bitpos + lr_bitsize, rr_bitpos + rr_bitsize);
        !          2147:       rnmode = get_best_mode (end_bit - first_bit, first_bit,
        !          2148:                              TYPE_ALIGN (TREE_TYPE (lr_inner)), word_mode,
        !          2149:                              volatilep);
        !          2150:       if (rnmode == VOIDmode)
        !          2151:        return 0;
        !          2152: 
        !          2153:       rnbitsize = GET_MODE_BITSIZE (rnmode);
        !          2154:       rnbitpos = first_bit & ~ (rnbitsize - 1);
        !          2155:       xlr_bitpos = lr_bitpos - rnbitpos, xrr_bitpos = rr_bitpos - rnbitpos;
        !          2156: 
        !          2157: #if BYTES_BIG_ENDIAN
        !          2158:       xlr_bitpos = rnbitsize - xlr_bitpos - lr_bitsize;
        !          2159:       xrr_bitpos = rnbitsize - xrr_bitpos - rr_bitsize;
        !          2160: #endif
        !          2161: 
        !          2162:       lr_mask = const_binop (LSHIFT_EXPR, convert (type, lr_mask),
        !          2163:                             size_int (xlr_bitpos));
        !          2164:       rr_mask = const_binop (LSHIFT_EXPR, convert (type, rr_mask),
        !          2165:                             size_int (xrr_bitpos));
        !          2166: 
        !          2167:       /* Make a mask that corresponds to both fields being compared.
        !          2168:         Do this for both items being compared.  If the masks agree,
        !          2169:         we can do this by masking both and comparing the masked
        !          2170:         results.  */
        !          2171:       ll_mask = const_binop (BIT_IOR_EXPR, ll_mask, rl_mask);
        !          2172:       lr_mask = const_binop (BIT_IOR_EXPR, lr_mask, rr_mask);
        !          2173:       if (operand_equal_p (ll_mask, lr_mask, 0) && lnbitsize == rnbitsize)
        !          2174:        {
        !          2175:          lhs = make_bit_field_ref (ll_inner, type, lnbitsize, lnbitpos,
        !          2176:                                    ll_unsignedp || rl_unsignedp);
        !          2177:          rhs = make_bit_field_ref (lr_inner, type, rnbitsize, rnbitpos,
        !          2178:                                    lr_unsignedp || rr_unsignedp);
        !          2179:          if (! all_ones_mask_p (ll_mask, lnbitsize))
        !          2180:            {
        !          2181:              lhs = build (BIT_AND_EXPR, type, lhs, ll_mask);
        !          2182:              rhs = build (BIT_AND_EXPR, type, rhs, ll_mask);
        !          2183:            }
        !          2184:          return build (wanted_code, truth_type, lhs, rhs);
        !          2185:        }
        !          2186: 
        !          2187:       /* There is still another way we can do something:  If both pairs of
        !          2188:         fields being compared are adjacent, we may be able to make a wider
        !          2189:         field containing them both.  */
        !          2190:       if ((ll_bitsize + ll_bitpos == rl_bitpos
        !          2191:           && lr_bitsize + lr_bitpos == rr_bitpos)
        !          2192:          || (ll_bitpos == rl_bitpos + rl_bitsize
        !          2193:              && lr_bitpos == rr_bitpos + rr_bitsize))
        !          2194:        return build (wanted_code, truth_type,
        !          2195:                      make_bit_field_ref (ll_inner, type,
        !          2196:                                          ll_bitsize + rl_bitsize,
        !          2197:                                          MIN (ll_bitpos, rl_bitpos),
        !          2198:                                          ll_unsignedp),
        !          2199:                      make_bit_field_ref (lr_inner, type,
        !          2200:                                          lr_bitsize + rr_bitsize,
        !          2201:                                          MIN (lr_bitpos, rr_bitpos),
        !          2202:                                          lr_unsignedp));
        !          2203: 
        !          2204:       return 0;
        !          2205:     }
        !          2206: 
        !          2207:   /* Handle the case of comparisons with constants.  If there is something in
        !          2208:      common between the masks, those bits of the constants must be the same.
        !          2209:      If not, the condition is always false.  Test for this to avoid generating
        !          2210:      incorrect code below.  */
        !          2211:   result = const_binop (BIT_AND_EXPR, ll_mask, rl_mask);
        !          2212:   if (! integer_zerop (result)
        !          2213:       && simple_cst_equal (const_binop (BIT_AND_EXPR, result, l_const),
        !          2214:                           const_binop (BIT_AND_EXPR, result, r_const)) != 1)
        !          2215:     {
        !          2216:       if (wanted_code == NE_EXPR)
        !          2217:        {
        !          2218:          warning ("`or' of unmatched not-equal tests is always 1");
        !          2219:          return convert (truth_type, integer_one_node);
        !          2220:        }
        !          2221:       else
        !          2222:        {
        !          2223:          warning ("`and' of mutually exclusive equal-tests is always zero");
        !          2224:          return convert (truth_type, integer_zero_node);
        !          2225:        }
        !          2226:     }
        !          2227: 
        !          2228:   /* Construct the expression we will return.  First get the component
        !          2229:      reference we will make.  Unless the mask is all ones the width of
        !          2230:      that field, perform the mask operation.  Then compare with the
        !          2231:      merged constant.  */
        !          2232:   result = make_bit_field_ref (ll_inner, type, lnbitsize, lnbitpos,
        !          2233:                               ll_unsignedp || rl_unsignedp);
        !          2234: 
        !          2235:   ll_mask = const_binop (BIT_IOR_EXPR, ll_mask, rl_mask);
        !          2236:   if (! all_ones_mask_p (ll_mask, lnbitsize))
        !          2237:     result = build (BIT_AND_EXPR, type, result, ll_mask);
        !          2238: 
        !          2239:   return build (wanted_code, truth_type, result,
        !          2240:                const_binop (BIT_IOR_EXPR, l_const, r_const));
        !          2241: }
        !          2242: 
        !          2243: /* Perform constant folding and related simplification of EXPR.
        !          2244:    The related simplifications include x*1 => x, x*0 => 0, etc.,
        !          2245:    and application of the associative law.
        !          2246:    NOP_EXPR conversions may be removed freely (as long as we
        !          2247:    are careful not to change the C type of the overall expression)
        !          2248:    We cannot simplify through a CONVERT_EXPR, FIX_EXPR or FLOAT_EXPR,
        !          2249:    but we can constant-fold them if they have constant operands.  */
        !          2250: 
        !          2251: tree
        !          2252: fold (expr) 
        !          2253:      tree expr;
        !          2254: {
        !          2255:   register tree t = expr;
        !          2256:   tree t1 = NULL_TREE;
        !          2257:   tree type = TREE_TYPE (expr);
        !          2258:   register tree arg0, arg1;
        !          2259:   register enum tree_code code = TREE_CODE (t);
        !          2260:   register int kind;
        !          2261: 
        !          2262:   /* WINS will be nonzero when the switch is done
        !          2263:      if all operands are constant.  */
        !          2264: 
        !          2265:   int wins = 1;
        !          2266: 
        !          2267:   /* Return right away if already constant.  */
        !          2268:   if (TREE_CONSTANT (t))
        !          2269:     {
        !          2270:       if (code == CONST_DECL)
        !          2271:        return DECL_INITIAL (t);
        !          2272:       return t;
        !          2273:     }
        !          2274:   
        !          2275:   kind = TREE_CODE_CLASS (code);
        !          2276:   if (kind == 'e' || kind == '<' || kind == '1' || kind == '2' || kind == 'r')
        !          2277:     {
        !          2278:       register int len = tree_code_length[(int) code];
        !          2279:       register int i;
        !          2280:       for (i = 0; i < len; i++)
        !          2281:        {
        !          2282:          tree op = TREE_OPERAND (t, i);
        !          2283: 
        !          2284:          if (op == 0)
        !          2285:            continue;           /* Valid for CALL_EXPR, at least.  */
        !          2286: 
        !          2287:          /* Strip any conversions that don't change the mode.  */
        !          2288:          STRIP_NOPS (op);
        !          2289:          
        !          2290:          if (TREE_CODE (op) != INTEGER_CST
        !          2291: #if ! defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
        !          2292:              && TREE_CODE (op) != REAL_CST
        !          2293: #endif /* not REAL_IS_NOT_DOUBLE, or REAL_ARITHMETIC */
        !          2294:              )
        !          2295:            /* Note that TREE_CONSTANT isn't enough:
        !          2296:               static var addresses are constant but we can't
        !          2297:               do arithmetic on them.  */
        !          2298:            wins = 0;
        !          2299: 
        !          2300:          if (i == 0)
        !          2301:            arg0 = op;
        !          2302:          else if (i == 1)
        !          2303:            arg1 = op;
        !          2304:        }
        !          2305:     }
        !          2306: 
        !          2307:   /* If this is a commutative operation, and ARG0 is a constant, move it
        !          2308:      to ARG1 to reduce the number of tests below.  */
        !          2309:   if ((code == PLUS_EXPR || code == MULT_EXPR || code == MIN_EXPR
        !          2310:        || code == MAX_EXPR || code == BIT_IOR_EXPR || code == BIT_XOR_EXPR
        !          2311:        || code == BIT_AND_EXPR)
        !          2312:       && (TREE_CODE (arg0) == INTEGER_CST || TREE_CODE (arg0) == REAL_CST))
        !          2313:     {
        !          2314:       tree tem = arg0;
        !          2315:       arg0 = arg1; arg1 = tem;
        !          2316: 
        !          2317:       TREE_OPERAND (t, 0) = arg0;
        !          2318:       TREE_OPERAND (t, 1) = arg1;
        !          2319:     }
        !          2320: 
        !          2321:   /* Now WINS is set as described above,
        !          2322:      ARG0 is the first operand of EXPR,
        !          2323:      and ARG1 is the second operand (if it has more than one operand).
        !          2324: 
        !          2325:      First check for cases where an arithmetic operation is applied to a
        !          2326:      compound, conditional, or comparison operation.  Push the arithmetic
        !          2327:      operation inside the compound or conditional to see if any folding
        !          2328:      can then be done.  Convert comparison to conditional for this purpose.
        !          2329:      The also optimizes non-constant cases that used to be done in
        !          2330:      expand_expr.  */
        !          2331:   if (TREE_CODE_CLASS (code) == '1')
        !          2332:     {
        !          2333:       if (TREE_CODE (arg0) == COMPOUND_EXPR)
        !          2334:        return build (COMPOUND_EXPR, type, TREE_OPERAND (arg0, 0),
        !          2335:                      fold (build1 (code, type, TREE_OPERAND (arg0, 1))));
        !          2336:       else if (TREE_CODE (arg0) == COND_EXPR)
        !          2337:        return fold (build (COND_EXPR, type, TREE_OPERAND (arg0, 0),
        !          2338:                            fold (build1 (code, type, TREE_OPERAND (arg0, 1))),
        !          2339:                            fold (build1 (code, type, TREE_OPERAND (arg0, 2)))));
        !          2340:       else if (TREE_CODE_CLASS (TREE_CODE (arg0)) == '<') 
        !          2341:        return fold (build (COND_EXPR, type, arg0,
        !          2342:                            fold (build1 (code, type, integer_one_node)),
        !          2343:                            fold (build1 (code, type, integer_zero_node))));
        !          2344:    }
        !          2345:   else if (TREE_CODE_CLASS (code) == '2')
        !          2346:     {
        !          2347:       if (TREE_CODE (arg1) == COMPOUND_EXPR)
        !          2348:        return build (COMPOUND_EXPR, type, TREE_OPERAND (arg1, 0),
        !          2349:                      fold (build (code, type, arg0, TREE_OPERAND (arg1, 1))));
        !          2350:       else if (TREE_CODE (arg1) == COND_EXPR
        !          2351:               || TREE_CODE_CLASS (TREE_CODE (arg1)) == '<')
        !          2352:        {
        !          2353:          tree test, true_value, false_value;
        !          2354: 
        !          2355:          if (TREE_CODE (arg1) == COND_EXPR)
        !          2356:            {
        !          2357:              test = TREE_OPERAND (arg1, 0);
        !          2358:              true_value = TREE_OPERAND (arg1, 1);
        !          2359:              false_value = TREE_OPERAND (arg1, 2);
        !          2360:            }
        !          2361:          else
        !          2362:            {
        !          2363:              test = arg1;
        !          2364:              true_value = integer_one_node;
        !          2365:              false_value = integer_zero_node;
        !          2366:            }
        !          2367: 
        !          2368:          if (TREE_CODE (arg0) != VAR_DECL && TREE_CODE (arg0) != PARM_DECL)
        !          2369:            arg0 = save_expr (arg0);
        !          2370:          test = fold (build (COND_EXPR, type, test,
        !          2371:                              fold (build (code, type, arg0, true_value)),
        !          2372:                              fold (build (code, type, arg0, false_value))));
        !          2373:          if (TREE_CODE (arg0) == SAVE_EXPR)
        !          2374:            return build (COMPOUND_EXPR, type,
        !          2375:                          convert (void_type_node, arg0), test);
        !          2376:          else
        !          2377:            return convert (type, test);
        !          2378:        }
        !          2379: 
        !          2380:       else if (TREE_CODE (arg0) == COMPOUND_EXPR)
        !          2381:        return build (COMPOUND_EXPR, type, TREE_OPERAND (arg0, 0),
        !          2382:                      fold (build (code, type, TREE_OPERAND (arg0, 1), arg1)));
        !          2383:       else if (TREE_CODE (arg0) == COND_EXPR
        !          2384:               || TREE_CODE_CLASS (TREE_CODE (arg0)) == '<')
        !          2385:        {
        !          2386:          tree test, true_value, false_value;
        !          2387: 
        !          2388:          if (TREE_CODE (arg0) == COND_EXPR)
        !          2389:            {
        !          2390:              test = TREE_OPERAND (arg0, 0);
        !          2391:              true_value = TREE_OPERAND (arg0, 1);
        !          2392:              false_value = TREE_OPERAND (arg0, 2);
        !          2393:            }
        !          2394:          else
        !          2395:            {
        !          2396:              test = arg0;
        !          2397:              true_value = integer_one_node;
        !          2398:              false_value = integer_zero_node;
        !          2399:            }
        !          2400: 
        !          2401:          if (TREE_CODE (arg1) != VAR_DECL && TREE_CODE (arg1) != PARM_DECL)
        !          2402:            arg1 = save_expr (arg1);
        !          2403:          test = fold (build (COND_EXPR, type, test,
        !          2404:                              fold (build (code, type, true_value, arg1)),
        !          2405:                              fold (build (code, type, false_value, arg1))));
        !          2406:          if (TREE_CODE (arg1) == SAVE_EXPR)
        !          2407:            return build (COMPOUND_EXPR, type,
        !          2408:                          convert (void_type_node, arg1), test);
        !          2409:          else
        !          2410:            return convert (type, test);
        !          2411:        }
        !          2412:     }
        !          2413:          
        !          2414:   switch (code)
        !          2415:     {
        !          2416:     case INTEGER_CST:
        !          2417:     case REAL_CST:
        !          2418:     case STRING_CST:
        !          2419:     case COMPLEX_CST:
        !          2420:     case CONSTRUCTOR:
        !          2421:       return t;
        !          2422: 
        !          2423:     case CONST_DECL:
        !          2424:       return fold (DECL_INITIAL (t));
        !          2425: 
        !          2426:     case NOP_EXPR:
        !          2427:     case FLOAT_EXPR:
        !          2428:     case CONVERT_EXPR:
        !          2429:     case FIX_TRUNC_EXPR:
        !          2430:       /* Other kinds of FIX are not handled properly by fold_convert.  */
        !          2431:       /* Two conversions in a row are not needed unless:
        !          2432:         - the intermediate type is narrower than both initial and final, or
        !          2433:         - the initial type is a pointer type and the precisions of the
        !          2434:           intermediate and final types differ, or
        !          2435:         - the final type is a pointer type and the precisions of the 
        !          2436:          initial and intermediate types differ.  */
        !          2437:       if ((TREE_CODE (TREE_OPERAND (t, 0)) == NOP_EXPR
        !          2438:           || TREE_CODE (TREE_OPERAND (t, 0)) == CONVERT_EXPR)
        !          2439:          && (TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (t, 0)))
        !          2440:              > TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (t, 0), 0)))
        !          2441:              ||
        !          2442:              TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (t, 0)))
        !          2443:              > TYPE_PRECISION (TREE_TYPE (t)))
        !          2444:          && ((TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (t, 0)))
        !          2445:               && (TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (t, 0)))
        !          2446:                   > TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (t, 0), 0)))))
        !          2447:              ==
        !          2448:              (TREE_UNSIGNED (TREE_TYPE (t))
        !          2449:               && (TYPE_PRECISION (TREE_TYPE (t))
        !          2450:                   > TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (t, 0))))))
        !          2451:          && ! ((TREE_CODE (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (t, 0), 0)))
        !          2452:                 == POINTER_TYPE)
        !          2453:                && (TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (t, 0)))
        !          2454:                    != TYPE_PRECISION (TREE_TYPE (t))))
        !          2455:          && ! (TREE_CODE (TREE_TYPE (t)) == POINTER_TYPE
        !          2456:                && (TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (t, 0), 0)))
        !          2457:                    != TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (t, 0))))))
        !          2458:        return convert (TREE_TYPE (t), TREE_OPERAND (TREE_OPERAND (t, 0), 0));
        !          2459: 
        !          2460:       if (TREE_CODE (TREE_OPERAND (t, 0)) == MODIFY_EXPR
        !          2461:          && TREE_CONSTANT (TREE_OPERAND (TREE_OPERAND (t, 0), 1)))
        !          2462:        {
        !          2463:          /* Don't leave an assignment inside a conversion.  */
        !          2464:          tree prev = TREE_OPERAND (t, 0);
        !          2465:          TREE_OPERAND (t, 0) = TREE_OPERAND (prev, 1);
        !          2466:          /* First do the assignment, then return converted constant.  */
        !          2467:          t = build (COMPOUND_EXPR, TREE_TYPE (t), prev, fold (t));
        !          2468:          TREE_USED (t) = 1;
        !          2469:          return t;
        !          2470:        }
        !          2471:       if (!wins)
        !          2472:        {
        !          2473:          TREE_CONSTANT (t) = TREE_CONSTANT (arg0);
        !          2474:          return t;
        !          2475:        }
        !          2476:       return fold_convert (t, arg0);
        !          2477: 
        !          2478: #if 0  /* This loses on &"foo"[0].  */
        !          2479:     case ARRAY_REF:
        !          2480:        {
        !          2481:          int i;
        !          2482: 
        !          2483:          /* Fold an expression like: "foo"[2] */
        !          2484:          if (TREE_CODE (arg0) == STRING_CST
        !          2485:              && TREE_CODE (arg1) == INTEGER_CST
        !          2486:              && !TREE_INT_CST_HIGH (arg1)
        !          2487:              && (i = TREE_INT_CST_LOW (arg1)) < TREE_STRING_LENGTH (arg0))
        !          2488:            {
        !          2489:              t = build_int_2 (TREE_STRING_POINTER (arg0)[i], 0);
        !          2490:              TREE_TYPE (t) = TREE_TYPE (TREE_TYPE (arg0));
        !          2491:              force_fit_type (t);
        !          2492:            }
        !          2493:        }
        !          2494:       return t;
        !          2495: #endif /* 0 */
        !          2496: 
        !          2497:     case RANGE_EXPR:
        !          2498:       TREE_CONSTANT (t) = wins;
        !          2499:       return t;
        !          2500: 
        !          2501:     case NEGATE_EXPR:
        !          2502:       if (wins)
        !          2503:        {
        !          2504:          if (TREE_CODE (arg0) == INTEGER_CST)
        !          2505:            {
        !          2506:              if (TREE_INT_CST_LOW (arg0) == 0)
        !          2507:                t = build_int_2 (0, - TREE_INT_CST_HIGH (arg0));
        !          2508:              else
        !          2509:                t = build_int_2 (- TREE_INT_CST_LOW (arg0),
        !          2510:                                 ~ TREE_INT_CST_HIGH (arg0));
        !          2511:              TREE_TYPE (t) = type;
        !          2512:              force_fit_type (t);
        !          2513:            }
        !          2514:          else if (TREE_CODE (arg0) == REAL_CST)
        !          2515:            t = build_real (type, REAL_VALUE_NEGATE (TREE_REAL_CST (arg0)));
        !          2516:          TREE_TYPE (t) = type;
        !          2517:        }
        !          2518:       else if (TREE_CODE (arg0) == NEGATE_EXPR)
        !          2519:        return TREE_OPERAND (arg0, 0);
        !          2520: 
        !          2521:       /* Convert - (a - b) to (b - a) for non-floating-point.  */
        !          2522:       else if (TREE_CODE (arg0) == MINUS_EXPR && TREE_CODE (type) != REAL_TYPE)
        !          2523:        return build (MINUS_EXPR, type, TREE_OPERAND (arg0, 1),
        !          2524:                      TREE_OPERAND (arg0, 0));
        !          2525: 
        !          2526:       return t;
        !          2527: 
        !          2528:     case ABS_EXPR:
        !          2529:       if (wins)
        !          2530:        {
        !          2531:          if (TREE_CODE (arg0) == INTEGER_CST)
        !          2532:            {
        !          2533:              if (! TREE_UNSIGNED (type)
        !          2534:                  && TREE_INT_CST_HIGH (arg0) < 0)
        !          2535:                {
        !          2536:                  if (TREE_INT_CST_LOW (arg0) == 0)
        !          2537:                    t = build_int_2 (0, - TREE_INT_CST_HIGH (arg0));
        !          2538:                  else
        !          2539:                    t = build_int_2 (- TREE_INT_CST_LOW (arg0),
        !          2540:                                     ~ TREE_INT_CST_HIGH (arg0));
        !          2541:                }
        !          2542:            }
        !          2543:          else if (TREE_CODE (arg0) == REAL_CST)
        !          2544:            {
        !          2545:              if (REAL_VALUES_LESS (TREE_REAL_CST (arg0), dconst0))
        !          2546:                t = build_real (type,
        !          2547:                                REAL_VALUE_NEGATE (TREE_REAL_CST (arg0)));
        !          2548:            }
        !          2549:          TREE_TYPE (t) = type;
        !          2550:        }
        !          2551:       else if (TREE_CODE (arg0) == ABS_EXPR || TREE_CODE (arg0) == NEGATE_EXPR)
        !          2552:        return build1 (ABS_EXPR, type, TREE_OPERAND (arg0, 0));
        !          2553:       return t;
        !          2554: 
        !          2555:     case BIT_NOT_EXPR:
        !          2556:       if (wins)
        !          2557:        {
        !          2558:          if (TREE_CODE (arg0) == INTEGER_CST)
        !          2559:            t = build_int_2 (~ TREE_INT_CST_LOW (arg0),
        !          2560:                             ~ TREE_INT_CST_HIGH (arg0));
        !          2561:          TREE_TYPE (t) = type;
        !          2562:          force_fit_type (t);
        !          2563:        }
        !          2564:       else if (TREE_CODE (arg0) == BIT_NOT_EXPR)
        !          2565:        return TREE_OPERAND (arg0, 0);
        !          2566:       return t;
        !          2567: 
        !          2568:     case PLUS_EXPR:
        !          2569:       /* A + (-B) -> A - B */
        !          2570:       if (TREE_CODE (arg1) == NEGATE_EXPR)
        !          2571:        return fold (build (MINUS_EXPR, type, arg0, TREE_OPERAND (arg1, 0)));
        !          2572:       else if (TREE_CODE (type) != REAL_TYPE)
        !          2573:        {
        !          2574:          if (integer_zerop (arg1))
        !          2575:            return non_lvalue (convert (type, arg0));
        !          2576: 
        !          2577:          /* If we are adding two BIT_AND_EXPR's, both of which are and'ing
        !          2578:             with a constant, and the two constants have no bits in common,
        !          2579:             we should treat this as a BIT_IOR_EXPR since this may produce more
        !          2580:             simplifications.  */
        !          2581:          if (TREE_CODE (arg0) == BIT_AND_EXPR
        !          2582:              && TREE_CODE (arg1) == BIT_AND_EXPR
        !          2583:              && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST
        !          2584:              && TREE_CODE (TREE_OPERAND (arg1, 1)) == INTEGER_CST
        !          2585:              && integer_zerop (const_binop (BIT_AND_EXPR,
        !          2586:                                             TREE_OPERAND (arg0, 1),
        !          2587:                                             TREE_OPERAND (arg1, 1))))
        !          2588:            {
        !          2589:              code = BIT_IOR_EXPR;
        !          2590:              goto bit_ior;
        !          2591:            }
        !          2592:        }
        !          2593:       /* In IEEE floating point, x+0 may not equal x.  */
        !          2594:       else if (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT
        !          2595:               && real_zerop (arg1))
        !          2596:        return non_lvalue (convert (type, arg0));
        !          2597:     associate:
        !          2598:       /* In most languages, can't associate operations on floats
        !          2599:         through parentheses.  Rather than remember where the parentheses
        !          2600:         were, we don't associate floats at all.  It shouldn't matter much.  */
        !          2601:       if (TREE_CODE (type) == REAL_TYPE)
        !          2602:        goto binary;
        !          2603:       /* The varsign == -1 cases happen only for addition and subtraction.
        !          2604:         It says that the arg that was split was really CON minus VAR.
        !          2605:         The rest of the code applies to all associative operations.  */
        !          2606:       if (!wins)
        !          2607:        {
        !          2608:          tree var, con, tem;
        !          2609:          int varsign;
        !          2610: 
        !          2611:          if (split_tree (arg0, code, &var, &con, &varsign))
        !          2612:            {
        !          2613:              if (varsign == -1)
        !          2614:                {
        !          2615:                  /* EXPR is (CON-VAR) +- ARG1.  */
        !          2616:                  /* If it is + and VAR==ARG1, return just CONST.  */
        !          2617:                  if (code == PLUS_EXPR && operand_equal_p (var, arg1, 0))
        !          2618:                    return convert (TREE_TYPE (t), con);
        !          2619:                    
        !          2620:                  /* Otherwise return (CON +- ARG1) - VAR.  */
        !          2621:                  TREE_SET_CODE (t, MINUS_EXPR);
        !          2622:                  TREE_OPERAND (t, 1) = var;
        !          2623:                  TREE_OPERAND (t, 0)
        !          2624:                    = fold (build (code, TREE_TYPE (t), con, arg1));
        !          2625:                }
        !          2626:              else
        !          2627:                {
        !          2628:                  /* EXPR is (VAR+CON) +- ARG1.  */
        !          2629:                  /* If it is - and VAR==ARG1, return just CONST.  */
        !          2630:                  if (code == MINUS_EXPR && operand_equal_p (var, arg1, 0))
        !          2631:                    return convert (TREE_TYPE (t), con);
        !          2632:                    
        !          2633:                  /* Otherwise return VAR +- (ARG1 +- CON).  */
        !          2634:                  TREE_OPERAND (t, 1) = tem
        !          2635:                    = fold (build (code, TREE_TYPE (t), arg1, con));
        !          2636:                  TREE_OPERAND (t, 0) = var;
        !          2637:                  if (integer_zerop (tem)
        !          2638:                      && (code == PLUS_EXPR || code == MINUS_EXPR))
        !          2639:                    return convert (type, var);
        !          2640:                  /* If we have x +/- (c - d) [c an explicit integer]
        !          2641:                     change it to x -/+ (d - c) since if d is relocatable
        !          2642:                     then the latter can be a single immediate insn
        !          2643:                     and the former cannot.  */
        !          2644:                  if (TREE_CODE (tem) == MINUS_EXPR
        !          2645:                      && TREE_CODE (TREE_OPERAND (tem, 0)) == INTEGER_CST)
        !          2646:                    {
        !          2647:                      tree tem1 = TREE_OPERAND (tem, 1);
        !          2648:                      TREE_OPERAND (tem, 1) = TREE_OPERAND (tem, 0);
        !          2649:                      TREE_OPERAND (tem, 0) = tem1;
        !          2650:                      TREE_SET_CODE (t,
        !          2651:                                     (code == PLUS_EXPR ? MINUS_EXPR : PLUS_EXPR));
        !          2652:                    }
        !          2653:                }
        !          2654:              return t;
        !          2655:            }
        !          2656: 
        !          2657:          if (split_tree (arg1, code, &var, &con, &varsign))
        !          2658:            {
        !          2659:              /* EXPR is ARG0 +- (CON +- VAR).  */
        !          2660:              if (varsign == -1)
        !          2661:                TREE_SET_CODE (t,
        !          2662:                               (code == PLUS_EXPR ? MINUS_EXPR : PLUS_EXPR));
        !          2663:              if (TREE_CODE (t) == MINUS_EXPR
        !          2664:                  && operand_equal_p (var, arg0, 0))
        !          2665:                {
        !          2666:                  /* If VAR and ARG0 cancel, return just CON or -CON.  */
        !          2667:                  if (code == PLUS_EXPR)
        !          2668:                    return convert (TREE_TYPE (t), con);
        !          2669:                  return fold (build1 (NEGATE_EXPR, TREE_TYPE (t),
        !          2670:                                       convert (TREE_TYPE (t), con)));
        !          2671:                }
        !          2672:              TREE_OPERAND (t, 0)
        !          2673:                = fold (build (code, TREE_TYPE (t), arg0, con));
        !          2674:              TREE_OPERAND (t, 1) = var;
        !          2675:              if (integer_zerop (TREE_OPERAND (t, 0))
        !          2676:                  && TREE_CODE (t) == PLUS_EXPR)
        !          2677:                return convert (TREE_TYPE (t), var);
        !          2678:              return t;
        !          2679:            }
        !          2680:        }
        !          2681:     binary:
        !          2682: #if defined (REAL_IS_NOT_DOUBLE) && ! defined (REAL_ARITHMETIC)
        !          2683:       if (TREE_CODE (arg1) == REAL_CST)
        !          2684:        return t;
        !          2685: #endif /* REAL_IS_NOT_DOUBLE, and no REAL_ARITHMETIC */
        !          2686:       if (wins)
        !          2687:        t1 = const_binop (code, arg0, arg1);
        !          2688:       if (t1 != NULL_TREE)
        !          2689:        {
        !          2690:          /* The return value should always have
        !          2691:             the same type as the original expression.  */
        !          2692:          TREE_TYPE (t1) = TREE_TYPE (t);
        !          2693:          return t1;
        !          2694:        }
        !          2695:       return t;
        !          2696: 
        !          2697:     case MINUS_EXPR:
        !          2698:       if (TREE_CODE (type) != REAL_TYPE)
        !          2699:        {
        !          2700:          if (! wins && integer_zerop (arg0))
        !          2701:            return build1 (NEGATE_EXPR, type, arg1);
        !          2702:          if (integer_zerop (arg1))
        !          2703:            return non_lvalue (convert (type, arg0));
        !          2704:        }
        !          2705:       /* Convert A - (-B) to A + B.  */
        !          2706:       else if (TREE_CODE (arg1) == NEGATE_EXPR)
        !          2707:        return fold (build (PLUS_EXPR, type, arg0, TREE_OPERAND (arg1, 0)));
        !          2708:       else
        !          2709:        {
        !          2710:          if (! wins && real_zerop (arg0))
        !          2711:            return build1 (NEGATE_EXPR, type, arg1);
        !          2712:          /* In IEEE floating point, x-0 may not equal x.  */
        !          2713:          if (real_zerop (arg1) && TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT)
        !          2714:            return non_lvalue (convert (type, arg0));
        !          2715:        }
        !          2716:       /* Fold &x - &x.  This can happen from &x.foo - &x. 
        !          2717:         Note that can't be done for certain floats even in non-IEEE formats.
        !          2718:         Also note that operand_equal_p is always false is an operand
        !          2719:         is volatile.  */
        !          2720: 
        !          2721:       if (operand_equal_p (arg0, arg1,
        !          2722:                           TREE_CODE (type) == REAL_TYPE))
        !          2723:        return convert (type, integer_zero_node);
        !          2724:       goto associate;
        !          2725: 
        !          2726:     case MULT_EXPR:
        !          2727:       if (TREE_CODE (type) != REAL_TYPE)
        !          2728:        {
        !          2729:          if (integer_zerop (arg1))
        !          2730:            return omit_one_operand (type, arg1, arg0);
        !          2731:          if (integer_onep (arg1))
        !          2732:            return non_lvalue (convert (type, arg0));
        !          2733: 
        !          2734:          /* (a * (1 << b)) is (a << b)  */
        !          2735:          if (TREE_CODE (arg1) == LSHIFT_EXPR
        !          2736:              && integer_onep (TREE_OPERAND (arg1, 0)))
        !          2737:            return fold (build (LSHIFT_EXPR, type, arg0,
        !          2738:                                TREE_OPERAND (arg1, 1)));
        !          2739:          if (TREE_CODE (arg0) == LSHIFT_EXPR
        !          2740:              && integer_onep (TREE_OPERAND (arg0, 0)))
        !          2741:            return fold (build (LSHIFT_EXPR, type, arg1,
        !          2742:                                TREE_OPERAND (arg0, 1)));
        !          2743:        }
        !          2744:       /* In IEEE floating point, these optimizations are not correct.  */
        !          2745:       else
        !          2746:        {
        !          2747:          if (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT
        !          2748:              && real_zerop (arg1))
        !          2749:            return omit_one_operand (type, arg1, arg0);
        !          2750:          /* In IEEE floating point, x*1 is not equivalent to x for nans.
        !          2751:             However, ANSI says we can drop signals,
        !          2752:             so we can do this anyway.  */
        !          2753:          if (real_onep (arg1))
        !          2754:            return non_lvalue (convert (type, arg0));
        !          2755:          /* x*2 is x+x */
        !          2756:          if (! wins && real_twop (arg1))
        !          2757:            {
        !          2758:              tree arg = save_expr (arg0);
        !          2759:              return build (PLUS_EXPR, type, arg, arg);
        !          2760:            }
        !          2761:        }
        !          2762:       goto associate;
        !          2763: 
        !          2764:     case BIT_IOR_EXPR:
        !          2765:     bit_ior:
        !          2766:       if (integer_all_onesp (arg1))
        !          2767:        return omit_one_operand (type, arg1, arg0);
        !          2768:       if (integer_zerop (arg1))
        !          2769:        return non_lvalue (convert (type, arg0));
        !          2770:       t1 = distribute_bit_expr (code, type, arg0, arg1);
        !          2771:       if (t1 != NULL_TREE)
        !          2772:        return t1;
        !          2773:       goto associate;
        !          2774: 
        !          2775:     case BIT_XOR_EXPR:
        !          2776:       if (integer_zerop (arg1))
        !          2777:        return non_lvalue (convert (type, arg0));
        !          2778:       if (integer_all_onesp (arg1))
        !          2779:        return fold (build1 (BIT_NOT_EXPR, type, arg0));
        !          2780:       goto associate;
        !          2781: 
        !          2782:     case BIT_AND_EXPR:
        !          2783:     bit_and:
        !          2784:       if (integer_all_onesp (arg1))
        !          2785:        return non_lvalue (convert (type, arg0));
        !          2786:       if (integer_zerop (arg1))
        !          2787:        return omit_one_operand (type, arg1, arg0);
        !          2788:       t1 = distribute_bit_expr (code, type, arg0, arg1);
        !          2789:       if (t1 != NULL_TREE)
        !          2790:        return t1;
        !          2791:       /* Simplify ((int)c & 0x377) into (int)c, if c is unsigned char.  */
        !          2792:       if (TREE_CODE (arg0) == INTEGER_CST && TREE_CODE (arg1) == NOP_EXPR
        !          2793:          && TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (arg1, 0))))
        !          2794:        {
        !          2795:          int prec = TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg1, 0)));
        !          2796:          if (prec < BITS_PER_WORD && prec < HOST_BITS_PER_INT
        !          2797:              && (~TREE_INT_CST_LOW (arg0) & ((1 << prec) - 1)) == 0)
        !          2798:            return build1 (NOP_EXPR, type, TREE_OPERAND (arg1, 0));
        !          2799:        }
        !          2800:       if (TREE_CODE (arg1) == INTEGER_CST && TREE_CODE (arg0) == NOP_EXPR
        !          2801:          && TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (arg0, 0))))
        !          2802:        {
        !          2803:          int prec = TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg0, 0)));
        !          2804:          if (prec < BITS_PER_WORD && prec < HOST_BITS_PER_INT
        !          2805:              && (~TREE_INT_CST_LOW (arg1) & ((1 << prec) - 1)) == 0)
        !          2806:            return build1 (NOP_EXPR, type, TREE_OPERAND (arg0, 0));
        !          2807:        }
        !          2808:       goto associate;
        !          2809: 
        !          2810:     case BIT_ANDTC_EXPR:
        !          2811:       if (integer_all_onesp (arg0))
        !          2812:        return non_lvalue (convert (type, arg1));
        !          2813:       if (integer_zerop (arg0))
        !          2814:        return omit_one_operand (type, arg0, arg1);
        !          2815:       if (TREE_CODE (arg1) == INTEGER_CST)
        !          2816:        {
        !          2817:          arg1 = fold (build1 (BIT_NOT_EXPR, type, arg1));
        !          2818:          code = BIT_AND_EXPR;
        !          2819:          goto bit_and;
        !          2820:        }
        !          2821:       goto binary;
        !          2822: 
        !          2823:     case TRUNC_DIV_EXPR:
        !          2824:     case ROUND_DIV_EXPR:
        !          2825:     case FLOOR_DIV_EXPR:
        !          2826:     case CEIL_DIV_EXPR:
        !          2827:     case EXACT_DIV_EXPR:
        !          2828:     case RDIV_EXPR:
        !          2829:       if (integer_onep (arg1))
        !          2830:        return non_lvalue (convert (type, arg0));
        !          2831:       if (integer_zerop (arg1))
        !          2832:        return t;
        !          2833: #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
        !          2834: #ifndef REAL_INFINITY
        !          2835:       if (TREE_CODE (arg1) == REAL_CST
        !          2836:          && real_zerop (arg1))
        !          2837:        return t;
        !          2838: #endif
        !          2839: #endif /* not REAL_IS_NOT_DOUBLE, or REAL_ARITHMETIC */
        !          2840: 
        !          2841:       goto binary;
        !          2842: 
        !          2843:     case CEIL_MOD_EXPR:
        !          2844:     case FLOOR_MOD_EXPR:
        !          2845:     case ROUND_MOD_EXPR:
        !          2846:     case TRUNC_MOD_EXPR:
        !          2847:       if (integer_onep (arg1))
        !          2848:        return omit_one_operand (type, integer_zero_node, arg0);
        !          2849:       if (integer_zerop (arg1))
        !          2850:        return t;
        !          2851:       goto binary;
        !          2852: 
        !          2853:     case LSHIFT_EXPR:
        !          2854:     case RSHIFT_EXPR:
        !          2855:     case LROTATE_EXPR:
        !          2856:     case RROTATE_EXPR:
        !          2857:       if (integer_zerop (arg1))
        !          2858:        return non_lvalue (convert (type, arg0));
        !          2859:       /* Since negative shift count is not well-defined,
        !          2860:         don't try to compute it in the compiler.  */
        !          2861:       if (tree_int_cst_lt (arg1, integer_zero_node))
        !          2862:        return t;
        !          2863:       goto binary;
        !          2864: 
        !          2865:     case MIN_EXPR:
        !          2866:       if (operand_equal_p (arg0, arg1, 0))
        !          2867:        return arg0;
        !          2868:       if (TREE_CODE (type) == INTEGER_TYPE
        !          2869:          && operand_equal_p (arg1, TYPE_MIN_VALUE (type), 1))
        !          2870:        return omit_one_operand (type, arg1, arg0);
        !          2871:       goto associate;
        !          2872: 
        !          2873:     case MAX_EXPR:
        !          2874:       if (operand_equal_p (arg0, arg1, 0))
        !          2875:        return arg0;
        !          2876:       if (TREE_CODE (type) == INTEGER_TYPE
        !          2877:          && operand_equal_p (arg1, TYPE_MAX_VALUE (type), 1))
        !          2878:        return omit_one_operand (type, arg1, arg0);
        !          2879:       goto associate;
        !          2880: 
        !          2881:     case TRUTH_NOT_EXPR:
        !          2882:       /* Note that the operand of this must be an int
        !          2883:         and its values must be 0 or 1.
        !          2884:         ("true" is a fixed value perhaps depending on the language,
        !          2885:         but we don't handle values other than 1 correctly yet.)  */
        !          2886:       return invert_truthvalue (arg0);
        !          2887: 
        !          2888:     case TRUTH_ANDIF_EXPR:
        !          2889:       /* Note that the operands of this must be ints
        !          2890:         and their values must be 0 or 1.
        !          2891:         ("true" is a fixed value perhaps depending on the language.)  */
        !          2892:       /* If first arg is constant zero, return it.  */
        !          2893:       if (TREE_CODE (arg0) == INTEGER_CST && integer_zerop (arg0))
        !          2894:        return arg0;
        !          2895:     case TRUTH_AND_EXPR:
        !          2896:       /* If either arg is constant true, drop it.  */
        !          2897:       if (TREE_CODE (arg0) == INTEGER_CST && ! integer_zerop (arg0))
        !          2898:        return non_lvalue (arg1);
        !          2899:       if (TREE_CODE (arg1) == INTEGER_CST && ! integer_zerop (arg1))
        !          2900:        return non_lvalue (arg0);
        !          2901:       /* Both known to be zero => return zero.  */
        !          2902:       if (TREE_CODE (arg0) == INTEGER_CST && TREE_CODE (arg1) == INTEGER_CST)
        !          2903:        return arg0;
        !          2904: 
        !          2905:     truth_andor:
        !          2906:       /* Check for the possibility of merging component references.  If our
        !          2907:         lhs is another similar operation, try to merge its rhs with our
        !          2908:         rhs.  Then try to merge our lhs and rhs.  */
        !          2909:       if (optimize)
        !          2910:        {
        !          2911:          tree tem;
        !          2912: 
        !          2913:          if (TREE_CODE (arg0) == code)
        !          2914:            {
        !          2915:              tem = merge_component_references (code, type,
        !          2916:                                                TREE_OPERAND (arg0, 1), arg1);
        !          2917:              if (tem)
        !          2918:                return fold (build (code, type, TREE_OPERAND (arg0, 0), tem));
        !          2919:            }
        !          2920: 
        !          2921:          tem = merge_component_references (code, type, arg0, arg1);
        !          2922:          if (tem)
        !          2923:            return tem;
        !          2924:        }
        !          2925:       return t;
        !          2926: 
        !          2927:     case TRUTH_ORIF_EXPR:
        !          2928:       /* Note that the operands of this must be ints
        !          2929:         and their values must be 0 or true.
        !          2930:         ("true" is a fixed value perhaps depending on the language.)  */
        !          2931:       /* If first arg is constant true, return it.  */
        !          2932:       if (TREE_CODE (arg0) == INTEGER_CST && ! integer_zerop (arg0))
        !          2933:        return arg0;
        !          2934:     case TRUTH_OR_EXPR:
        !          2935:       /* If either arg is constant zero, drop it.  */
        !          2936:       if (TREE_CODE (arg0) == INTEGER_CST && integer_zerop (arg0))
        !          2937:        return non_lvalue (arg1);
        !          2938:       if (TREE_CODE (arg1) == INTEGER_CST && integer_zerop (arg1))
        !          2939:        return non_lvalue (arg0);
        !          2940:       /* Both known to be true => return true.  */
        !          2941:       if (TREE_CODE (arg0) == INTEGER_CST && TREE_CODE (arg1) == INTEGER_CST)
        !          2942:        return arg0;
        !          2943:       goto truth_andor;
        !          2944: 
        !          2945:     case EQ_EXPR:
        !          2946:     case NE_EXPR:
        !          2947:     case LT_EXPR:
        !          2948:     case GT_EXPR:
        !          2949:     case LE_EXPR:
        !          2950:     case GE_EXPR:
        !          2951:       /* If one arg is a constant integer, put it last.  */
        !          2952:       if (TREE_CODE (arg0) == INTEGER_CST
        !          2953:          && TREE_CODE (arg1) != INTEGER_CST)
        !          2954:        {
        !          2955:          TREE_OPERAND (t, 0) = arg1;
        !          2956:          TREE_OPERAND (t, 1) = arg0;
        !          2957:          arg0 = TREE_OPERAND (t, 0);
        !          2958:          arg1 = TREE_OPERAND (t, 1);
        !          2959:          switch (code)
        !          2960:            {
        !          2961:            case GT_EXPR:
        !          2962:              code = LT_EXPR;
        !          2963:              break;
        !          2964:            case GE_EXPR:
        !          2965:              code = LE_EXPR;
        !          2966:              break;
        !          2967:            case LT_EXPR:
        !          2968:              code = GT_EXPR;
        !          2969:              break;
        !          2970:            case LE_EXPR:
        !          2971:              code = GE_EXPR;
        !          2972:              break;
        !          2973:            }
        !          2974:          TREE_SET_CODE (t, code);
        !          2975:        }
        !          2976: 
        !          2977:       /* Convert foo++ == CONST into ++foo == CONST + INCR.
        !          2978:         First, see if one arg is constant; find the constant arg
        !          2979:         and the other one.  */
        !          2980:       {
        !          2981:        tree constop = 0, varop;
        !          2982:        tree *constoploc;
        !          2983: 
        !          2984:        if (TREE_CONSTANT (arg1))
        !          2985:          constoploc = &TREE_OPERAND (t, 1), constop = arg1, varop = arg0;
        !          2986:        if (TREE_CONSTANT (arg0))
        !          2987:          constoploc = &TREE_OPERAND (t, 0), constop = arg0, varop = arg1;
        !          2988: 
        !          2989:        if (constop && TREE_CODE (varop) == POSTINCREMENT_EXPR)
        !          2990:          {
        !          2991:            tree newconst
        !          2992:              = fold (build (PLUS_EXPR, TREE_TYPE (varop),
        !          2993:                             constop, TREE_OPERAND (varop, 1)));
        !          2994:            /* This optimization is invalid for ordered comparisons
        !          2995:               if CONST+INCR overflows or if foo+incr might overflow.
        !          2996:               For pointer types we assume overflow doesn't happen.  */
        !          2997:            if (TREE_CODE (TREE_TYPE (varop)) == POINTER_TYPE
        !          2998:                || code == EQ_EXPR || code == NE_EXPR)
        !          2999:              {
        !          3000:                /* This optimization is invalid for floating point
        !          3001:                   if adding one to the constant does not change it.  */
        !          3002:                if (TREE_CODE (TREE_TYPE (newconst)) != REAL_TYPE
        !          3003:                    || !REAL_VALUES_EQUAL (TREE_REAL_CST (newconst),
        !          3004:                                           TREE_REAL_CST (constop)))
        !          3005:                  {
        !          3006:                    TREE_SET_CODE (varop, PREINCREMENT_EXPR);
        !          3007:                    *constoploc = newconst;
        !          3008:                    return t;
        !          3009:                  }
        !          3010:              }
        !          3011:          }
        !          3012:        else if (constop && TREE_CODE (varop) == POSTDECREMENT_EXPR)
        !          3013:          {
        !          3014:            tree newconst
        !          3015:              = fold (build (MINUS_EXPR, TREE_TYPE (varop),
        !          3016:                             constop, TREE_OPERAND (varop, 1)));
        !          3017:            if (TREE_CODE (TREE_TYPE (varop)) == POINTER_TYPE
        !          3018:                || code == EQ_EXPR || code == NE_EXPR)
        !          3019:              {
        !          3020:                if (TREE_CODE (TREE_TYPE (newconst)) != REAL_TYPE
        !          3021:                    || !REAL_VALUES_EQUAL (TREE_REAL_CST (newconst),
        !          3022:                                           TREE_REAL_CST (constop)))
        !          3023:                  {
        !          3024:                    TREE_SET_CODE (varop, PREDECREMENT_EXPR);
        !          3025:                    *constoploc = newconst;
        !          3026:                    return t;
        !          3027:                  }
        !          3028:              }
        !          3029:          }
        !          3030:       }
        !          3031: 
        !          3032:       /* Change X >= CST to X > (CST - 1) if CST is positive.  */
        !          3033:       if (TREE_CODE (arg1) == INTEGER_CST
        !          3034:          && TREE_CODE (arg0) != INTEGER_CST
        !          3035:          && ! tree_int_cst_lt (arg1, integer_one_node))
        !          3036:        {
        !          3037:          switch (TREE_CODE (t))
        !          3038:            {
        !          3039:            case GE_EXPR:
        !          3040:              code = GT_EXPR;
        !          3041:              TREE_SET_CODE (t, code);
        !          3042:              arg1 = const_binop (MINUS_EXPR, arg1, integer_one_node);
        !          3043:              TREE_OPERAND (t, 1) = arg1;
        !          3044:              break;
        !          3045: 
        !          3046:            case LT_EXPR:
        !          3047:              code = LE_EXPR;
        !          3048:              TREE_SET_CODE (t, code);
        !          3049:              arg1 = const_binop (MINUS_EXPR, arg1, integer_one_node);
        !          3050:              TREE_OPERAND (t, 1) = arg1;
        !          3051:            }
        !          3052:        }
        !          3053: 
        !          3054:       /* If we are comparing the result of a comparison to a constant,
        !          3055:         we can often simplify this, since the comparison result is known to
        !          3056:         be either 0 or 1.  We can ignore conversions if the LHS is a
        !          3057:         comparison.  */
        !          3058: 
        !          3059:       if (TREE_CODE (arg1) == INTEGER_CST)
        !          3060:        {
        !          3061:          tree comparison = arg0;
        !          3062: 
        !          3063:          while (TREE_CODE (comparison) == NOP_EXPR
        !          3064:                 || TREE_CODE (comparison) == CONVERT_EXPR)
        !          3065:            comparison = TREE_OPERAND (comparison, 0);
        !          3066: 
        !          3067:          if (TREE_CODE_CLASS (TREE_CODE (comparison)) == '<'
        !          3068:              || TREE_CODE (comparison) == TRUTH_ANDIF_EXPR
        !          3069:              || TREE_CODE (comparison) == TRUTH_ORIF_EXPR
        !          3070:              || TREE_CODE (comparison) == TRUTH_AND_EXPR
        !          3071:              || TREE_CODE (comparison) == TRUTH_OR_EXPR
        !          3072:              || TREE_CODE (comparison) == TRUTH_NOT_EXPR)
        !          3073:            {
        !          3074:              /* We do different things depending on whether the
        !          3075:                 constant being compared against is < 0, == 0, == 1, or > 1.
        !          3076:                 Each of those cases, in order, corresponds to one
        !          3077:                 character in a string.  The value of the character is
        !          3078:                 the result to return.  A '0' or '1' means return always true
        !          3079:                 or always false, respectively; 'c' means return the result
        !          3080:                 of the comparison, and 'i' means return the result of the
        !          3081:                 inverted comparison.  */
        !          3082: 
        !          3083:              char *actions, action;
        !          3084: 
        !          3085:              switch (code)
        !          3086:                {
        !          3087:                case EQ_EXPR:
        !          3088:                  actions = "0ic0";
        !          3089:                  break;
        !          3090:                case NE_EXPR:
        !          3091:                  actions = "1ci1";
        !          3092:                  break;
        !          3093:                case LE_EXPR:
        !          3094:                  actions = "0i11";
        !          3095:                  break;
        !          3096:                case LT_EXPR:
        !          3097:                  actions = "00i1";
        !          3098:                  break;
        !          3099:                case GE_EXPR:
        !          3100:                  actions = "11c0";
        !          3101:                  break;
        !          3102:                case GT_EXPR:
        !          3103:                  actions = "1c00";
        !          3104:                  break;
        !          3105:                }
        !          3106: 
        !          3107:              if (tree_int_cst_lt (arg1, integer_zero_node))
        !          3108:                action = actions[0];
        !          3109:              else if (integer_zerop (arg1))
        !          3110:                action = actions[1];
        !          3111:              else if (integer_onep (arg1))
        !          3112:                action = actions[2];
        !          3113:              else
        !          3114:                action = actions[3];
        !          3115: 
        !          3116:              switch (action)
        !          3117:                {
        !          3118:                case '0':
        !          3119:                  return omit_one_operand (type, integer_zero_node,
        !          3120:                                           comparison);
        !          3121: 
        !          3122:                case '1':
        !          3123:                  return omit_one_operand (type, integer_one_node, comparison);
        !          3124: 
        !          3125:                case 'c':
        !          3126:                  return convert (type, comparison);
        !          3127: 
        !          3128:                case 'i':
        !          3129:                  return convert (type, invert_truthvalue (comparison));
        !          3130:                  
        !          3131:                default:
        !          3132:                  abort ();
        !          3133:                }
        !          3134:            }
        !          3135:        }
        !          3136:                     
        !          3137:       /* If this is an EQ or NE comparison with zero and ARG0 is
        !          3138:         (1 << foo) & bar, convert it to (bar >> foo) & 1.  Both require
        !          3139:         two operations, but the latter can be done in one less insn
        !          3140:         one machine that have only two-operand insns or on which a
        !          3141:         constant cannot be the first operand.  */
        !          3142:       if (integer_zerop (arg1) && (code == EQ_EXPR || code == NE_EXPR)
        !          3143:          && TREE_CODE (arg0) == BIT_AND_EXPR)
        !          3144:        {
        !          3145:          if (TREE_CODE (TREE_OPERAND (arg0, 0)) == LSHIFT_EXPR
        !          3146:              && integer_onep (TREE_OPERAND (TREE_OPERAND (arg0, 0), 0)))
        !          3147:            return
        !          3148:              fold (build (code, type,
        !          3149:                           build (BIT_AND_EXPR, TREE_TYPE (arg0),
        !          3150:                                  build (RSHIFT_EXPR,
        !          3151:                                         TREE_TYPE (TREE_OPERAND (arg0, 0)),
        !          3152:                                         TREE_OPERAND (arg0, 1),
        !          3153:                                         TREE_OPERAND (TREE_OPERAND (arg0, 0), 1)),
        !          3154:                                  convert (TREE_TYPE (arg0),
        !          3155:                                           integer_one_node)),
        !          3156:                           arg1));
        !          3157:          else if (TREE_CODE (TREE_OPERAND (arg0, 1)) == LSHIFT_EXPR
        !          3158:                   && integer_onep (TREE_OPERAND (TREE_OPERAND (arg0, 1), 0)))
        !          3159:            return
        !          3160:              fold (build (code, type,
        !          3161:                           build (BIT_AND_EXPR, TREE_TYPE (arg0),
        !          3162:                                  build (RSHIFT_EXPR,
        !          3163:                                         TREE_TYPE (TREE_OPERAND (arg0, 1)),
        !          3164:                                         TREE_OPERAND (arg0, 0),
        !          3165:                                         TREE_OPERAND (TREE_OPERAND (arg0, 1), 1)),
        !          3166:                                  convert (TREE_TYPE (arg0),
        !          3167:                                           integer_one_node)),
        !          3168:                           arg1));
        !          3169:        }
        !          3170: 
        !          3171:       /* If this is an NE comparison of zero with an AND of one, remove the
        !          3172:         comparison since the AND will give the correct value.  */
        !          3173:       if (code == NE_EXPR && integer_zerop (arg1)
        !          3174:          && TREE_CODE (arg0) == BIT_AND_EXPR
        !          3175:          && integer_onep (TREE_OPERAND (arg0, 1)))
        !          3176:        return convert (type, arg0);
        !          3177: 
        !          3178:       /* If we have (A & C) == C where C is a power of 2, convert this into
        !          3179:         (A & C) != 0.  Similarly for NE_EXPR.  */
        !          3180:       if ((code == EQ_EXPR || code == NE_EXPR)
        !          3181:          && TREE_CODE (arg0) == BIT_AND_EXPR
        !          3182:          && integer_pow2p (TREE_OPERAND (arg0, 1))
        !          3183:          && operand_equal_p (TREE_OPERAND (arg0, 1), arg1, 0))
        !          3184:        return build (code == EQ_EXPR ? NE_EXPR : EQ_EXPR, type,
        !          3185:                      arg0, integer_zero_node);
        !          3186: 
        !          3187:       /* Simplify comparison of an integer with itself.
        !          3188:         (This may not be safe with IEEE floats if they are nans.)  */
        !          3189:       if (operand_equal_p (arg0, arg1, 0)
        !          3190:          && TREE_CODE (TREE_TYPE (arg1)) == INTEGER_TYPE)
        !          3191:        {
        !          3192:          switch (code)
        !          3193:            {
        !          3194:            case EQ_EXPR:
        !          3195:            case GE_EXPR:
        !          3196:            case LE_EXPR:
        !          3197:              t = build_int_2 (1, 0);
        !          3198:              TREE_TYPE (t) = type;
        !          3199:              return t;
        !          3200:            case NE_EXPR:
        !          3201:            case GT_EXPR:
        !          3202:            case LT_EXPR:
        !          3203:              t = build_int_2 (0, 0);
        !          3204:              TREE_TYPE (t) = type;
        !          3205:              return t;
        !          3206:            }
        !          3207:        }
        !          3208: 
        !          3209:       /* An unsigned comparison against 0 can be simplified.  */
        !          3210:       if (integer_zerop (arg1)
        !          3211:          && (TREE_CODE (TREE_TYPE (arg1)) == INTEGER_TYPE
        !          3212:              || TREE_CODE (TREE_TYPE (arg1)) == POINTER_TYPE)
        !          3213:          && TREE_UNSIGNED (TREE_TYPE (arg1)))
        !          3214:        {
        !          3215:          switch (TREE_CODE (t))
        !          3216:            {
        !          3217:            case GT_EXPR:
        !          3218:              TREE_SET_CODE (t, NE_EXPR);
        !          3219:              break;
        !          3220:            case LE_EXPR:
        !          3221:              TREE_SET_CODE (t, EQ_EXPR);
        !          3222:              break;
        !          3223:            case GE_EXPR:
        !          3224:              return omit_one_operand (integer_type_node,
        !          3225:                                       integer_one_node, arg0);
        !          3226:            case LT_EXPR:
        !          3227:              return omit_one_operand (integer_type_node,
        !          3228:                                       integer_zero_node, arg0);
        !          3229:            }
        !          3230:        }
        !          3231: 
        !          3232:       /* To compute GT, swap the arguments and do LT.
        !          3233:         To compute GE, do LT and invert the result.
        !          3234:         To compute LE, swap the arguments, do LT and invert the result.
        !          3235:         To compute NE, do EQ and invert the result.  */
        !          3236:       if (code == LE_EXPR || code == GT_EXPR)
        !          3237:        {
        !          3238:          register tree temp = arg0;
        !          3239:          arg0 = arg1;
        !          3240:          arg1 = temp;
        !          3241:        }
        !          3242: 
        !          3243:       /* Compute a result for LT or EQ if args permit;
        !          3244:         otherwise return T.  */
        !          3245:       if (TREE_CODE (arg0) == INTEGER_CST
        !          3246:          && TREE_CODE (arg1) == INTEGER_CST)
        !          3247:        {
        !          3248:          if (code == EQ_EXPR || code == NE_EXPR)
        !          3249:            t = build_int_2
        !          3250:              (TREE_INT_CST_LOW (arg0) == TREE_INT_CST_LOW (arg1)
        !          3251:               && TREE_INT_CST_HIGH (arg0) == TREE_INT_CST_HIGH (arg1),
        !          3252:               0);
        !          3253:          else
        !          3254:            t = build_int_2 ((TREE_UNSIGNED (TREE_TYPE (arg0))
        !          3255:                              ? INT_CST_LT_UNSIGNED (arg0, arg1)
        !          3256:                              : INT_CST_LT (arg0, arg1)),
        !          3257:                             0);
        !          3258:        }
        !          3259:       /* Assume a nonexplicit constant cannot equal an explicit one,
        !          3260:         since such code would be undefined anyway.
        !          3261:         Exception: on sysvr4, using #pragma weak,
        !          3262:         a label can come out as 0.  */
        !          3263:       else if (TREE_CODE (arg1) == INTEGER_CST
        !          3264:               && !integer_zerop (arg1)
        !          3265:               && TREE_CONSTANT (arg0)
        !          3266:               && TREE_CODE (arg0) == ADDR_EXPR
        !          3267:               && (code == EQ_EXPR || code == NE_EXPR))
        !          3268:        {
        !          3269:          t = build_int_2 (0, 0);
        !          3270:        }
        !          3271:       /* Two real constants can be compared explicitly.  */
        !          3272:       else if (TREE_CODE (arg0) == REAL_CST
        !          3273:               && TREE_CODE (arg1) == REAL_CST)
        !          3274:        {
        !          3275:          if (code == EQ_EXPR || code == NE_EXPR)
        !          3276:            t = build_int_2 (REAL_VALUES_EQUAL (TREE_REAL_CST (arg0),
        !          3277:                                                TREE_REAL_CST (arg1)),
        !          3278:                             0);
        !          3279:          else
        !          3280:            t = build_int_2 (REAL_VALUES_LESS (TREE_REAL_CST (arg0),
        !          3281:                                               TREE_REAL_CST (arg1)),
        !          3282:                             0);
        !          3283:        }
        !          3284:       else if ((TREE_CODE (arg0) == COMPONENT_REF
        !          3285:                || TREE_CODE (arg0) == BIT_FIELD_REF)
        !          3286:               && (code == EQ_EXPR || code == NE_EXPR)
        !          3287:               /* Handle the constant case even without -O
        !          3288:                  to make sure the warnings are given.  */
        !          3289:               && (optimize || TREE_CODE (arg1) == INTEGER_CST))
        !          3290:        {
        !          3291:          tree tem = optimize_bit_field_compare (code, type, arg0, arg1);
        !          3292:          return tem ? tem : t;
        !          3293:        }
        !          3294: 
        !          3295:       /* If what we want is other than LT or EQ, invert the result.  */
        !          3296:       if (code == GE_EXPR || code == LE_EXPR || code == NE_EXPR)
        !          3297:        TREE_INT_CST_LOW (t) ^= 1;
        !          3298:       TREE_TYPE (t) = type;
        !          3299:       return t;
        !          3300: 
        !          3301:     case COND_EXPR:
        !          3302:       if (TREE_CODE (arg0) == INTEGER_CST)
        !          3303:        return TREE_OPERAND (t, (integer_zerop (arg0) ? 2 : 1));
        !          3304:       else if (operand_equal_p (arg1, TREE_OPERAND (expr, 2), 0))
        !          3305:        return omit_one_operand (type, arg1, arg0);
        !          3306:       else if (integer_onep (TREE_OPERAND (t, 1))
        !          3307:               && integer_zerop (TREE_OPERAND (t, 2))
        !          3308:               /* If we try to convert TREE_OPERAND (t, 0) to our type, the
        !          3309:                  call to fold will try to move the conversion inside 
        !          3310:                  a COND, which will recurse.  In that case, the COND_EXPR
        !          3311:                  is probably the best choice, so leave it alone.  */
        !          3312:               && type == TREE_TYPE (arg0))
        !          3313:        return arg0;
        !          3314:       else if (integer_zerop (arg1) && integer_onep (TREE_OPERAND (t, 2)))
        !          3315:        return convert (type, invert_truthvalue (arg0));
        !          3316: 
        !          3317:       /* If we have (a >= 0 ? a : -a) or the same with ">", this is an
        !          3318:         absolute value expression.  */
        !          3319: 
        !          3320:       if ((TREE_CODE (arg0) == GE_EXPR || TREE_CODE (arg0) == GT_EXPR)
        !          3321:          && integer_zerop (TREE_OPERAND (arg0, 1))
        !          3322:          && TREE_CODE (TREE_OPERAND (t, 2)) == NEGATE_EXPR
        !          3323:          && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0)
        !          3324:          && operand_equal_p (TREE_OPERAND (TREE_OPERAND (t, 2), 0), arg1, 0))
        !          3325:        return fold (build1 (ABS_EXPR, type, arg1));
        !          3326: 
        !          3327:       /* Similarly for (a <= 0 ? -a : a).  */
        !          3328: 
        !          3329:       if ((TREE_CODE (arg0) == LE_EXPR || TREE_CODE (arg0) == LT_EXPR)
        !          3330:          && integer_zerop (TREE_OPERAND (arg0, 1))
        !          3331:          && TREE_CODE (arg1) == NEGATE_EXPR
        !          3332:          && operand_equal_p (TREE_OPERAND (arg0, 0), TREE_OPERAND (t, 2), 0)
        !          3333:          && operand_equal_p (TREE_OPERAND (arg1, 0), TREE_OPERAND (t, 2), 0))
        !          3334:        return fold (build1 (ABS_EXPR, type, TREE_OPERAND (t, 2)));
        !          3335: 
        !          3336:       /* If we have a GT, GE, LT, or LE comparison, this might be a MIN or
        !          3337:         MAX test.  If so, make a MIN_EXPR or MAX_EXPR.  */
        !          3338: 
        !          3339:       if (TREE_CODE (arg0) == GT_EXPR || TREE_CODE (arg0) == GE_EXPR
        !          3340:          || TREE_CODE (arg0) == LT_EXPR || TREE_CODE (arg0) == LE_EXPR)
        !          3341:        {
        !          3342:          tree hi_true, lo_true;
        !          3343: 
        !          3344:          if (TREE_CODE (arg0) == GT_EXPR || TREE_CODE (arg0) == GE_EXPR)
        !          3345:            hi_true = TREE_OPERAND (arg0, 0), lo_true = TREE_OPERAND (arg0, 1);
        !          3346:          else
        !          3347:            hi_true = TREE_OPERAND (arg0, 1), lo_true = TREE_OPERAND (arg0, 0);
        !          3348: 
        !          3349:          if (comparison_equiv_p (hi_true, lo_true, arg1, TREE_OPERAND (t, 2)))
        !          3350:            /* We use arg1 and the other arg because they must have the same
        !          3351:               type as the intended result.
        !          3352:               The values being compared might have a narrower type.  */
        !          3353:            return fold (build (MAX_EXPR, type, arg1, TREE_OPERAND (t, 2)));
        !          3354:          else if (comparison_equiv_p (lo_true, hi_true,
        !          3355:                                       arg1, TREE_OPERAND (t, 2)))
        !          3356:            return fold (build (MIN_EXPR, type, arg1, TREE_OPERAND (t, 2)));
        !          3357:        }
        !          3358: 
        !          3359:       /* Look for cases when we are comparing some expression A for equality
        !          3360:         with zero and the result is to be zero if A is zero.  In that case,
        !          3361:         check to see if the value of A is the same as the value to be
        !          3362:         returned when A is non-zero.
        !          3363: 
        !          3364:         There are two cases:  One is where we have (A ? A : 0) and the
        !          3365:         other is when a single bit is tested (e.g., A & 2 ? 2 : 0).
        !          3366:         In these cases, the result of the conditional is simply A. 
        !          3367: 
        !          3368:         Start by setting ARG1 to be the true value and ARG0 to be the thing
        !          3369:         compared with zero.  Then check for the two cases above.  */
        !          3370: 
        !          3371:       if (integer_zerop (TREE_OPERAND (t, 2))
        !          3372:          && TREE_CODE (arg0) == NE_EXPR
        !          3373:          && integer_zerop (TREE_OPERAND (arg0, 1))
        !          3374:          && ! TREE_SIDE_EFFECTS (arg1))
        !          3375:        ;
        !          3376:       else if (integer_zerop (arg1)
        !          3377:               && TREE_CODE (arg0) == EQ_EXPR
        !          3378:               && integer_zerop (TREE_OPERAND (arg0, 1))
        !          3379:               && ! TREE_SIDE_EFFECTS (TREE_OPERAND (t, 2)))
        !          3380:        arg1 = TREE_OPERAND (t, 2);
        !          3381:       else
        !          3382:        return t;
        !          3383: 
        !          3384:       arg0 = TREE_OPERAND (arg0, 0);
        !          3385: 
        !          3386:       STRIP_NOPS (arg1);
        !          3387:       if (operand_equal_p (arg0, arg1, 0)
        !          3388:          || (TREE_CODE (arg1) == INTEGER_CST
        !          3389:              && integer_pow2p (arg1)
        !          3390:              && TREE_CODE (arg0) == BIT_AND_EXPR
        !          3391:              && operand_equal_p (TREE_OPERAND (arg0, 1), arg1, 0)))
        !          3392:        return convert (type, arg0);
        !          3393:       return t;
        !          3394: 
        !          3395:     case COMPOUND_EXPR:
        !          3396:       if (!TREE_SIDE_EFFECTS (arg0))
        !          3397:        return arg1;
        !          3398:       return t;
        !          3399: 
        !          3400:     default:
        !          3401:       return t;
        !          3402:     } /* switch (code) */
        !          3403: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.