Annotation of researchv10dc/cmd/gcc/fold-const.c, revision 1.1.1.1

1.1       root        1: /*@@ Fix lossage on folding division of big integers.  */
                      2: 
                      3: /*@@ This file should be rewritten to use an arbitary precision
                      4:   @@ representation for "struct tree_int_cst" and "struct tree_real_cst".
                      5:   @@ Perhaps the routines could also be used for bc/dc, and made a lib.
                      6:   @@ The routines that translate from the ap rep should
                      7:   @@ warn if precision et. al. is lost.
                      8:   @@ This would also make life easier when this technology is used
                      9:   @@ for cross-compilers.  */
                     10: 
                     11: /* Fold a constant sub-tree into a single node for C-compiler
                     12:    Copyright (C) 1987, 1988 Free Software Foundation, Inc.
                     13: 
                     14: This file is part of GNU CC.
                     15: 
                     16: GNU CC is distributed in the hope that it will be useful,
                     17: but WITHOUT ANY WARRANTY.  No author or distributor
                     18: accepts responsibility to anyone for the consequences of using it
                     19: or for whether it serves any particular purpose or works at all,
                     20: unless he says so in writing.  Refer to the GNU CC General Public
                     21: License for full details.
                     22: 
                     23: Everyone is granted permission to copy, modify and redistribute
                     24: GNU CC, but only under the conditions described in the
                     25: GNU CC General Public License.   A copy of this license is
                     26: supposed to have been given to you along with GNU CC so you
                     27: can know your rights and responsibilities.  It should be in a
                     28: file named COPYING.  Among other things, the copyright notice
                     29: and this notice must be preserved on all copies.  */
                     30: 
                     31: 
                     32: /* There are only two entry points in this file:
                     33:    fold and combine.
                     34: 
                     35:    fold takes a tree as argument and returns a simplified tree.
                     36: 
                     37:    combine takes a tree code for an arithmetic operation
                     38:    and two operands that are trees for constant values
                     39:    and returns the result of the specified operation on those values,
                     40:    also as a tree.  */
                     41:    
                     42: #include <stdio.h>
                     43: #include "config.h"
                     44: #include "tree.h"
                     45: 
                     46: static void lshift_double ();
                     47: static void rshift_double ();
                     48: static void lrotate_double ();
                     49: static void rrotate_double ();
                     50: 
                     51: /* To do constant folding on INTEGER_CST nodes requires 64-bit arithmetic.
                     52:    We do that by representing the 64-bit integer as 8 shorts,
                     53:    with only 8 bits stored in each short, as a positive number.  */
                     54: 
                     55: /* Unpack a 64-bit integer into 8 shorts.
                     56:    LOW and HI are the integer, as two `int' pieces.
                     57:    SHORTS points to the array of shorts.  */
                     58: 
                     59: static void
                     60: encode (shorts, low, hi)
                     61:      short *shorts;
                     62:      int low, hi;
                     63: {
                     64:   shorts[0] = low & 0xff;
                     65:   shorts[1] = (low >> 8) & 0xff;
                     66:   shorts[2] = (low >> 16) & 0xff;
                     67:   shorts[3] = (low >> 24) & 0xff;
                     68:   shorts[4] = hi & 0xff;
                     69:   shorts[5] = (hi >> 8) & 0xff;
                     70:   shorts[6] = (hi >> 16) & 0xff;
                     71:   shorts[7] = (hi >> 24) & 0xff;
                     72: }
                     73: 
                     74: /* Pack an array of 8 shorts into a 64-bit integer.
                     75:    SHORTS points to the array of shorts.
                     76:    The integer is stored into *LOW and *HI as two `int' pieces.  */
                     77: 
                     78: static void
                     79: decode (shorts, low, hi)
                     80:      short *shorts;
                     81:      int *low, *hi;
                     82: {
                     83:   *low = (shorts[3] << 24) | (shorts[2] << 16) | (shorts[1] << 8) | shorts[0];
                     84:   *hi = (shorts[7] << 24) | (shorts[6] << 16) | (shorts[5] << 8) | shorts[4];
                     85: }
                     86: 
                     87: /* Make the integer constant T valid for its type
                     88:    by setting to 0 or 1 all the bits in the constant
                     89:    that don't belong in the type.  */
                     90: 
                     91: static void
                     92: force_fit_type (t)
                     93:      tree t;
                     94: {
                     95:   register int prec = TYPE_PRECISION (TREE_TYPE (t));
                     96: 
                     97:   if (TREE_CODE (TREE_TYPE (t)) == POINTER_TYPE)
                     98:     prec = BITS_PER_WORD;
                     99: 
                    100:   /* First clear all bits that are beyond the type's precision.  */
                    101: 
                    102:   if (prec > HOST_BITS_PER_INT)
                    103:     {
                    104:       TREE_INT_CST_HIGH (t)
                    105:        &= ~((-1) << (prec - HOST_BITS_PER_INT));
                    106:     }
                    107:   else
                    108:     {
                    109:       TREE_INT_CST_HIGH (t) = 0;
                    110:       if (prec < HOST_BITS_PER_INT)
                    111:        TREE_INT_CST_LOW (t)
                    112:          &= ~((-1) << prec);
                    113:     }
                    114: 
                    115:   /* If it's a signed type and value's sign bit is set, extend the sign.  */
                    116: 
                    117:   if (! TREE_UNSIGNED (TREE_TYPE (t))
                    118:       && (prec > HOST_BITS_PER_INT
                    119:          ? TREE_INT_CST_HIGH (t) & (1 << (prec - HOST_BITS_PER_INT - 1))
                    120:          : TREE_INT_CST_LOW (t) & (1 << (prec - 1))))
                    121:     {
                    122:       /* Value is negative:
                    123:         set to 1 all the bits that are outside this type's precision.  */
                    124:       if (prec > HOST_BITS_PER_INT)
                    125:        {
                    126:          TREE_INT_CST_HIGH (t)
                    127:            |= ((-1) << (prec - HOST_BITS_PER_INT));
                    128:        }
                    129:       else
                    130:        {
                    131:          TREE_INT_CST_HIGH (t) = -1;
                    132:          if (prec < HOST_BITS_PER_INT)
                    133:            TREE_INT_CST_LOW (t)
                    134:              |= ((-1) << prec);
                    135:        }
                    136:     }
                    137: }
                    138: 
                    139: /* Add two 64-bit integers with 64-bit result.
                    140:    Each argument is given as two `int' pieces.
                    141:    One argument is L1 and H1; the other, L2 and H2.
                    142:    The value is stored as two `int' pieces in *LV and *HV.
                    143:    We use the 8-shorts representation internally.  */
                    144: 
                    145: static void
                    146: add_double (l1, h1, l2, h2, lv, hv)
                    147:      int l1, h1, l2, h2;
                    148:      int *lv, *hv;
                    149: {
                    150:   short arg1[8];
                    151:   short arg2[8];
                    152:   register int carry = 0;
                    153:   register int i;
                    154: 
                    155:   encode (arg1, l1, h1);
                    156:   encode (arg2, l2, h2);
                    157: 
                    158:   for (i = 0; i < 8; i++)
                    159:     {
                    160:       carry += arg1[i] + arg2[i];
                    161:       arg1[i] = carry & 0xff;
                    162:       carry >>= 8;
                    163:     }
                    164: 
                    165:   decode (arg1, lv, hv);
                    166: }
                    167: 
                    168: /* Negate a 64-bit integers with 64-bit result.
                    169:    The argument is given as two `int' pieces in L1 and H1.
                    170:    The value is stored as two `int' pieces in *LV and *HV.
                    171:    We use the 8-shorts representation internally.  */
                    172: 
                    173: static void
                    174: neg_double (l1, h1, lv, hv)
                    175:      int l1, h1;
                    176:      int *lv, *hv;
                    177: {
                    178:   if (l1 == 0)
                    179:     {
                    180:       *lv = 0;
                    181:       *hv = - h1;
                    182:     }
                    183:   else
                    184:     {
                    185:       *lv = - l1;
                    186:       *hv = ~ h1;
                    187:     }
                    188: }
                    189: 
                    190: /* Multiply two 64-bit integers with 64-bit result.
                    191:    Each argument is given as two `int' pieces.
                    192:    One argument is L1 and H1; the other, L2 and H2.
                    193:    The value is stored as two `int' pieces in *LV and *HV.
                    194:    We use the 8-shorts representation internally.  */
                    195: 
                    196: static void
                    197: mul_double (l1, h1, l2, h2, lv, hv)
                    198:      int l1, h1, l2, h2;
                    199:      int *lv, *hv;
                    200: {
                    201:   short arg1[8];
                    202:   short arg2[8];
                    203:   short prod[16];
                    204:   register int carry = 0;
                    205:   register int i, j, k;
                    206: 
                    207:   encode (arg1, l1, h1);
                    208:   encode (arg2, l2, h2);
                    209: 
                    210:   bzero (prod, sizeof prod);
                    211: 
                    212:   for (i = 0; i < 8; i++)
                    213:     for (j = 0; j < 8; j++)
                    214:       {
                    215:        k = i + j;
                    216:        carry = arg1[i] * arg2[j];
                    217:        while (carry)
                    218:          {
                    219:            carry += prod[k];
                    220:            prod[k] = carry & 0xff;
                    221:            carry >>= 8;
                    222:            k++;
                    223:          }
                    224:       }
                    225: 
                    226:   decode (prod, lv, hv);       /* @@decode ignores prod[8] -> prod[15] */
                    227: }
                    228: 
                    229: /* Shift the 64-bit integer in L1, H1 left by COUNT places
                    230:    keeping only PREC bits of result.
                    231:    Shift right if COUNT is negative.
                    232:    ARITH nonzero specifies arithmetic shifting; otherwise use logical shift.
                    233:    Store the value as two `int' pieces in *LV and *HV.  */
                    234: 
                    235: static void
                    236: lshift_double (l1, h1, count, prec, lv, hv, arith)
                    237:      int l1, h1, count, prec;
                    238:      int *lv, *hv;
                    239:      int arith;
                    240: {
                    241:   short arg1[8];
                    242:   register int i;
                    243:   register int carry;
                    244: 
                    245:   if (count < 0)
                    246:     {
                    247:       rshift_double (l1, h1, - count, prec, lv, hv, arith);
                    248:       return;
                    249:     }
                    250: 
                    251:   encode (arg1, l1, h1);
                    252:   if (prec < HOST_BITS_PER_INT)
                    253:     count &= (1 << prec) - 1;
                    254: 
                    255:   while (count > 0)
                    256:     {
                    257:       carry = 0;
                    258:       for (i = 0; i < 8; i++)
                    259:        {
                    260:          carry += arg1[i] << 1;
                    261:          arg1[i] = carry & 0xff;
                    262:          carry >>= 8;
                    263:        }
                    264:       count--;
                    265:     }
                    266: 
                    267:   decode (arg1, lv, hv);
                    268: }
                    269: 
                    270: /* Shift the 64-bit integer in L1, H1 right by COUNT places
                    271:    keeping only PREC bits of result.  COUNT must be positive.
                    272:    ARITH nonzero specifies arithmetic shifting; otherwise use logical shift.
                    273:    Store the value as two `int' pieces in *LV and *HV.  */
                    274: 
                    275: static void
                    276: rshift_double (l1, h1, count, prec, lv, hv, arith)
                    277:      int l1, h1, count, prec;
                    278:      int *lv, *hv;
                    279:      int arith;
                    280: {
                    281:   short arg1[8];
                    282:   register int i;
                    283:   register int carry;
                    284: 
                    285:   encode (arg1, l1, h1);
                    286:   if (prec < HOST_BITS_PER_INT)
                    287:     count &= (1 << prec) - 1;
                    288: 
                    289:   carry = arith && arg1[7] >> 7;
                    290:   while (count > 0)
                    291:     {
                    292:       for (i = 7; i >= 0; i--)
                    293:        {
                    294:          carry <<= 8;
                    295:          carry += arg1[i];
                    296:          arg1[i] = (carry >> 1) & 0xff;
                    297:        }
                    298:       count--;
                    299:     }
                    300: 
                    301:   decode (arg1, lv, hv);
                    302: }
                    303: 
                    304: /* Rotate the 64-bit integer in L1, H1 left by COUNT places
                    305:    keeping only PREC bits of result.
                    306:    Rotate right if COUNT is negative.
                    307:    Store the value as two `int' pieces in *LV and *HV.  */
                    308: 
                    309: static void
                    310: lrotate_double (l1, h1, count, prec, lv, hv)
                    311:      int l1, h1, count, prec;
                    312:      int *lv, *hv;
                    313: {
                    314:   short arg1[8];
                    315:   register int i;
                    316:   register int carry;
                    317: 
                    318:   if (count < 0)
                    319:     {
                    320:       rrotate_double (l1, h1, - count, prec, lv, hv);
                    321:       return;
                    322:     }
                    323: 
                    324:   encode (arg1, l1, h1);
                    325:   if (prec < HOST_BITS_PER_INT)
                    326:     count &= (1 << prec) - 1;
                    327: 
                    328:   carry = arg1[7] >> 7;
                    329:   while (count > 0)
                    330:     {
                    331:       for (i = 0; i < 8; i++)
                    332:        {
                    333:          carry += arg1[i] << 1;
                    334:          arg1[i] = carry & 0xff;
                    335:          carry >>= 8;
                    336:        }
                    337:       count--;
                    338:     }
                    339: 
                    340:   decode (arg1, lv, hv);
                    341: }
                    342: 
                    343: /* Rotate the 64-bit integer in L1, H1 left by COUNT places
                    344:    keeping only PREC bits of result.  COUNT must be positive.
                    345:    Store the value as two `int' pieces in *LV and *HV.  */
                    346: 
                    347: static void
                    348: rrotate_double (l1, h1, count, prec, lv, hv)
                    349:      int l1, h1, count, prec;
                    350:      int *lv, *hv;
                    351: {
                    352:   short arg1[8];
                    353:   register int i;
                    354:   register int carry;
                    355: 
                    356:   encode (arg1, l1, h1);
                    357:   if (prec < HOST_BITS_PER_INT)
                    358:     count &= (1 << prec) - 1;
                    359: 
                    360:   carry = arg1[0] & 1;
                    361:   while (count > 0)
                    362:     {
                    363:       for (i = 7; i >= 0; i--)
                    364:        {
                    365:          carry <<= 8;
                    366:          carry += arg1[i];
                    367:          arg1[i] = (carry >> 1) & 0xff;
                    368:        }
                    369:       count--;
                    370:     }
                    371: 
                    372:   decode (arg1, lv, hv);
                    373: }
                    374: 
                    375: /* Divide 64 bit integer LNUM, HNUM by 64 bit integer LDEN, HDEN
                    376:    for a quotient (stored in *LQUO, *HQUO) and remainder (in *LREM, *HREM).
                    377:    CODE is a tree code for a kind of division, one of
                    378:    TRUNC_DIV_EXPR, FLOOR_DIV_EXPR, CEIL_DIV_EXPR and ROUND_DIV_EXPR.
                    379:    It controls how the quotient is rounded to a integer.
                    380:    UNS nonzero says do unsigned division.  */
                    381: 
                    382: static void
                    383: div_and_round_double (code, uns,
                    384:                      lnum_orig, hnum_orig, lden_orig, hden_orig,
                    385:                      lquo, hquo, lrem, hrem)
                    386:      enum tree_code code;
                    387:      int uns;
                    388:      int lnum_orig, hnum_orig;         /* num == numerator == dividend */
                    389:      int lden_orig, hden_orig;         /* den == denominator == divisor */
                    390:      int *lquo, *hquo, *lrem, *hrem;
                    391: {
                    392:   int quo_neg = 0;
                    393:   short num[9], den[8], quo[8];        /* extra element for scaling.  */
                    394:   register int i, j, work;
                    395:   register int carry = 0;
                    396:   int lnum = lnum_orig, hnum = hnum_orig;
                    397:   int lden = lden_orig, hden = hden_orig;
                    398: 
                    399:   if ((hden == 0) && (lden == 0)) {
                    400:     *hquo = *lquo = *hrem = *lrem = 0;
                    401:     error
                    402:       ("divide by 0 in constant folding - quotient and remainder set to 0.");
                    403:     return;
                    404:   }
                    405: 
                    406:   /* calculate quotient sign and convert operands to unsigned.  */
                    407:   if (!uns) 
                    408:     {
                    409:       if (hden < 0) 
                    410:        {
                    411:          quo_neg = ~ quo_neg;
                    412:          neg_double (lden, hden, &lden, &hden);
                    413:        }
                    414:       if (hnum < 0)
                    415:        {
                    416:          quo_neg = ~ quo_neg;
                    417:          neg_double (lnum, hnum, &lnum, &hnum);
                    418:        }
                    419:     }
                    420: 
                    421:   if (hnum == 0 && hden == 0)
                    422:     {                          /* single precision */
                    423:       *hquo = *hrem = 0;
                    424:       *lquo = (unsigned) lnum / lden;  /* rounds toward zero since positive args */
                    425:       goto finish_up;
                    426:     }
                    427: 
                    428:   if (hnum == 0)
                    429:     {                          /* trivial case: dividend < divisor */
                    430:       /* hden != 0 already checked.  */
                    431:       *hquo = *lquo = 0;
                    432:       *hrem = hnum;
                    433:       *lrem = lnum;
                    434:       goto finish_up;
                    435:     }
                    436: 
                    437:   bzero (quo, sizeof quo);
                    438: 
                    439:   bzero (num, sizeof num);     /* to zero 9th element */
                    440:   bzero (den, sizeof den);
                    441: 
                    442:   encode (num, lnum, hnum); 
                    443:   encode (den, lden, hden);
                    444: 
                    445:   if (hden == 0)
                    446:     {                          /* simpler algorithm */
                    447:       /* hnum != 0 already checked.  */
                    448:       for (i = 7; i >= 0; i--)
                    449:        {
                    450:          work = num[i] + (carry << 8);
                    451:          quo[i] = work / lden;
                    452:          carry = work % lden;
                    453:        }
                    454:     }
                    455:   else {                       /* full double precision,
                    456:                                   with thanks to Don Knuth's
                    457:                                   "Semi-Numericial Algorithms".  */
                    458: #define BASE 256
                    459:     int quo_est, scale, num_hi_sig, den_hi_sig, quo_hi_sig;
                    460: 
                    461:     /* Find the highest non-zero divisor digit.  */
                    462:     for (i = 7; ; i--)
                    463:       if (den[i] != 0) {
                    464:        den_hi_sig = i;
                    465:        break;
                    466:       }
                    467:     for (i = 7; ; i--)
                    468:       if (num[i] != 0) {
                    469:        num_hi_sig = i;
                    470:        break;
                    471:       }
                    472:     quo_hi_sig = num_hi_sig - den_hi_sig + 1;
                    473: 
                    474:     /* Insure that the first digit of the divisor is at least BASE/2.
                    475:        This is required by the quotient digit estimation algorithm.  */
                    476: 
                    477:     scale = BASE / (den[den_hi_sig] + 1);
                    478:     if (scale > 1) {           /* scale divisor and dividend */
                    479:       carry = 0;
                    480:       for (i = 0; i <= 8; i++) {
                    481:        work = (num[i] * scale) + carry;
                    482:        num[i] = work & 0xff;
                    483:        carry = work >> 8;
                    484:        if (num[i] != 0) num_hi_sig = i;
                    485:       }
                    486:       carry = 0;
                    487:       for (i = 0; i <= 7; i++) {
                    488:        work = (den[i] * scale) + carry;
                    489:        den[i] = work & 0xff;
                    490:        carry = work >> 8;
                    491:        if (den[i] != 0) den_hi_sig = i;
                    492:       }
                    493:     }
                    494: 
                    495:     /* Main loop */
                    496:     for (i = quo_hi_sig; i > 0; i--) {
                    497:       /* quess the next quotient digit, quo_est, by dividing the first
                    498:         two remaining dividend digits by the high order quotient digit.
                    499:         quo_est is never low and is at most 2 high.  */
                    500: 
                    501:       int num_hi;              /* index of highest remaining dividend digit */
                    502: 
                    503:       num_hi = i + den_hi_sig;
                    504: 
                    505:       work = (num[num_hi] * BASE) + (num_hi ? 0 : num[num_hi - 1]);
                    506:       if (num[num_hi] != den[den_hi_sig]) {
                    507:        quo_est = work / den[den_hi_sig];
                    508:       }
                    509:       else {
                    510:        quo_est = BASE - 1;
                    511:       }
                    512: 
                    513:       /* refine quo_est so it's usually correct, and at most one high.   */
                    514:       while ((den[den_hi_sig - 1] * quo_est)
                    515:             > (((work - (quo_est * den[den_hi_sig])) * BASE)
                    516:                 + ((num_hi - 1) ? 0 : num[num_hi - 2]))) {
                    517:        quo_est--;
                    518:       }
                    519: 
                    520:       /* try quo_est as the quotient digit, by multiplying the
                    521:          divisor by quo_est and subtracting from the remaining dividend.  */
                    522: 
                    523:       carry = 0;
                    524: 
                    525:       for (j = 0; j <= den_hi_sig; j++) {
                    526:        int digit;
                    527: 
                    528:        work = num[i + j] - (quo_est * den[j]) + carry;
                    529:        digit = work & 0xff;
                    530:        carry = work >> 8;
                    531:        if (digit < 0) {
                    532:          digit += BASE;
                    533:          carry--;
                    534:        }
                    535:        num[i + j] = digit;
                    536:       }
                    537: 
                    538:       /* if quo_est was high by one, then num[i] went negative and
                    539:         we need to correct things.  */
                    540: 
                    541:       if (num[num_hi] < 0) {
                    542:        quo_est--;
                    543:        carry = 0;              /* add divisor back in */
                    544:        for (j = 0; j <= den_hi_sig; j++) {
                    545:          work = num[i + j] + den[j] + carry;
                    546:          if (work > BASE) {
                    547:            work -= BASE;
                    548:            carry = 1;
                    549:          }
                    550:          else {
                    551:            carry = 0;
                    552:          }
                    553:          num[i + j] = work;
                    554:        }
                    555:        num [num_hi] += carry;
                    556:       }
                    557: 
                    558:       /* store the quotient digit.  */
                    559:       quo[i - 1] = quo_est;
                    560:     }
                    561:   }
                    562: 
                    563:   decode (quo, lquo, hquo);
                    564: 
                    565:  finish_up:
                    566:   /* if result is negative, make it so.  */
                    567:   if (quo_neg)
                    568:     neg_double (*lquo, *hquo, lquo, hquo);
                    569: 
                    570:   /* compute trial remainder:  rem = num - (quo * den)  */
                    571:   mul_double (*lquo, *hquo, lden_orig, hden_orig, lrem, hrem);
                    572:   neg_double (*lrem, *hrem, lrem, hrem);
                    573:   add_double (lnum_orig, hnum_orig, *lrem, *hrem, lrem, hrem);
                    574: 
                    575:   switch (code)
                    576:     {
                    577:     case TRUNC_DIV_EXPR:
                    578:     case TRUNC_MOD_EXPR:       /* round toward zero */
                    579:       return;
                    580: 
                    581:     case FLOOR_DIV_EXPR:
                    582:     case FLOOR_MOD_EXPR:       /* round toward negative infinity */
                    583:       if (quo_neg && (*lrem != 0 || *hrem != 0))   /* ratio < 0 && rem != 0 */
                    584:        {
                    585:          /* quo = quo - 1;  */
                    586:          add_double (*lquo, *hquo, -1, -1, lquo, hquo);
                    587:        }
                    588:       else return;
                    589:       break;
                    590: 
                    591:     case CEIL_DIV_EXPR:
                    592:     case CEIL_MOD_EXPR:                /* round toward positive infinity */
                    593:       if (!quo_neg && (*lrem != 0 || *hrem != 0))  /* ratio > 0 && rem != 0 */
                    594:        {
                    595:          add_double (*lquo, *hquo, 1, 0, lquo, hquo);
                    596:        }
                    597:       else return;
                    598:       break;
                    599:     
                    600:     case ROUND_DIV_EXPR:
                    601:     case ROUND_MOD_EXPR:       /* round to closest integer */
                    602:       {
                    603:        int labs_rem = *lrem, habs_rem = *hrem;
                    604:        int labs_den = lden, habs_den = hden, ltwice, htwice;
                    605: 
                    606:        /* get absolute values */
                    607:        if (*hrem < 0) neg_double(*lrem, *hrem, &labs_rem, &habs_rem);
                    608:        if (hden < 0) neg_double(lden, hden, &labs_den, &habs_den);
                    609: 
                    610:        /* if (2 * abs (lrem) >= abs (lden)) */
                    611:        mul_double(2, 0, labs_rem, habs_rem, &ltwice, &htwice);
                    612:        if (((unsigned) habs_den < (unsigned) htwice)
                    613:            || (((unsigned) habs_den == (unsigned) htwice)
                    614:                && ((unsigned) labs_den < (unsigned) ltwice)))
                    615:          {
                    616:            if (*hquo < 0)
                    617:              /* quo = quo - 1;  */
                    618:              add_double (*lquo, *hquo, -1, -1, lquo, hquo);
                    619:            else
                    620:              /* quo = quo + 1; */
                    621:              add_double (*lquo, *hquo, 1, 0, lquo, hquo);
                    622:          }
                    623:        else return;
                    624:       }
                    625:       break;
                    626: 
                    627:     default:
                    628:       abort ();
                    629:     }
                    630: 
                    631:   /* compute true 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: 
                    637: /* Split a tree IN into a constant and a variable part
                    638:    that could be combined with CODE to make IN.
                    639:    CODE must be a commutative arithmetic operation.
                    640:    Store the constant part into *CONP and the variable in &VARP.
                    641:    Return 1 if this was done; zero means the tree IN did not decompose
                    642:    this way.
                    643: 
                    644:    If CODE is PLUS_EXPR we also split trees that use MINUS_EXPR.
                    645:    Therefore, we must tell the caller whether the variable part
                    646:    was subtracted.  We do this by storing 1 or -1 into *VARSIGNP.
                    647:    The value stored is the coefficient for the variable term.
                    648:    The constant term we return should always be added;
                    649:    we negate it if necessary.  */
                    650: 
                    651: static int
                    652: split_tree (in, code, varp, conp, varsignp)
                    653:      tree in;
                    654:      enum tree_code code;
                    655:      tree *varp, *conp;
                    656:      int *varsignp;
                    657: {
                    658:   register tree outtype = TREE_TYPE (in);
                    659:   *varp = 0;
                    660:   *conp = 0;
                    661: 
                    662:   /* Strip any conversions that don't change the machine mode.  */
                    663:   while ((TREE_CODE (in) == NOP_EXPR
                    664:          || TREE_CODE (in) == CONVERT_EXPR)
                    665:         && (TYPE_MODE (TREE_TYPE (in))
                    666:             == TYPE_MODE (TREE_TYPE (TREE_OPERAND (in, 0)))))
                    667:     in = TREE_OPERAND (in, 0);
                    668: 
                    669:   if (TREE_CODE (in) == code
                    670:       || (TREE_CODE (TREE_TYPE (in)) != REAL_TYPE
                    671:          /* We can associate addition and subtraction together
                    672:             (even though the C standard doesn't say so)
                    673:             for integers because the value is not affected.
                    674:             For reals, the value might be affected, so we can't.  */
                    675:          &&
                    676:          ((code == PLUS_EXPR && TREE_CODE (in) == MINUS_EXPR)
                    677:           || (code == MINUS_EXPR && TREE_CODE (in) == PLUS_EXPR))))
                    678:     {
                    679:       enum tree_code code = TREE_CODE (TREE_OPERAND (in, 0));
                    680:       if (code == INTEGER_CST || code == REAL_CST)
                    681:        {
                    682:          *conp = TREE_OPERAND (in, 0);
                    683:          *varp = TREE_OPERAND (in, 1);
                    684:          if (TREE_TYPE (*varp) != outtype)
                    685:            *varp = convert (outtype, *varp);
                    686:          *varsignp = (TREE_CODE (in) == MINUS_EXPR) ? -1 : 1;
                    687:          return 1;
                    688:        }
                    689:       if (TREE_LITERAL (TREE_OPERAND (in, 1)))
                    690:        {
                    691:          *conp = TREE_OPERAND (in, 1);
                    692:          *varp = TREE_OPERAND (in, 0);
                    693:          *varsignp = 1;
                    694:          if (TREE_TYPE (*varp) != outtype)
                    695:            *varp = convert (outtype, *varp);
                    696:          if (TREE_CODE (in) == MINUS_EXPR)
                    697:            {
                    698:              /* If operation is subtraction and constant is second,
                    699:                 must negate it to get an additive constant.
                    700:                 And this cannot be done unless it is a manifest constant.
                    701:                 It could also be the address of a static variable.
                    702:                 We cannot negate that, so give up.  */
                    703:              if (TREE_CODE (*conp) == INTEGER_CST
                    704:                  || TREE_CODE (*conp) == REAL_CST)
                    705:                *conp = combine (MINUS_EXPR, integer_zero_node, *conp);
                    706:              else
                    707:                return 0;
                    708:            }
                    709:          return 1;
                    710:        }
                    711:       if (TREE_LITERAL (TREE_OPERAND (in, 0)))
                    712:        {
                    713:          *conp = TREE_OPERAND (in, 0);
                    714:          *varp = TREE_OPERAND (in, 1);
                    715:          if (TREE_TYPE (*varp) != outtype)
                    716:            *varp = convert (outtype, *varp);
                    717:          *varsignp = (TREE_CODE (in) == MINUS_EXPR) ? -1 : 1;
                    718:          return 1;
                    719:        }
                    720:     }
                    721:   return 0;
                    722: }
                    723: 
                    724: /* Combine two constants NUM and ARG2 under operation CODE
                    725:    to produce a new constant.
                    726:    We assume ARG1 and ARG2 have the same data type,
                    727:    or at least are the same kind of constant and the same machine mode.  */
                    728: 
                    729: tree
                    730: combine (code, arg1, arg2)
                    731:      enum tree_code code;
                    732:      register tree arg1, arg2;
                    733: {
                    734:   if (TREE_CODE (arg1) == INTEGER_CST)
                    735:     {
                    736:       register int int1l = TREE_INT_CST_LOW (arg1);
                    737:       register int int1h = TREE_INT_CST_HIGH (arg1);
                    738:       int int2l = TREE_INT_CST_LOW (arg2);
                    739:       int int2h = TREE_INT_CST_HIGH (arg2);
                    740:       int low, hi;
                    741:       int garbagel, garbageh;
                    742:       register tree t;
                    743:       int uns = TREE_UNSIGNED (TREE_TYPE (arg1));
                    744: 
                    745:       switch (code)
                    746:        {
                    747:        case BIT_IOR_EXPR:
                    748:          t = build_int_2 (int1l | int2l, int1h | int2h);
                    749:          break;
                    750: 
                    751:        case BIT_XOR_EXPR:
                    752:          t = build_int_2 (int1l ^ int2l, int1h ^ int2h);
                    753:          break;
                    754: 
                    755:        case BIT_AND_EXPR:
                    756:          t = build_int_2 (int1l & int2l, int1h & int2h);
                    757:          break;
                    758: 
                    759:        case BIT_ANDTC_EXPR:
                    760:          t = build_int_2 (int1l & ~int2l, int1h & ~int2h);
                    761:          break;
                    762: 
                    763:        case RSHIFT_EXPR:
                    764:          int2l = - int2l;
                    765:        case LSHIFT_EXPR:
                    766:          lshift_double (int1l, int1h, int2l,
                    767:                         TYPE_PRECISION (TREE_TYPE (arg1)),
                    768:                         &low, &hi,
                    769:                         !uns);
                    770:          t = build_int_2 (low, hi);
                    771:          break;
                    772: 
                    773:        case RROTATE_EXPR:
                    774:          int2l = - int2l;
                    775:        case LROTATE_EXPR:
                    776:          lrotate_double (int1l, int1h, int2l,
                    777:                          TYPE_PRECISION (TREE_TYPE (arg1)),
                    778:                          &low, &hi);
                    779:          t = build_int_2 (low, hi);
                    780:          break;
                    781: 
                    782:        case PLUS_EXPR:
                    783:          add_double (int1l, int1h, int2l, int2h, &low, &hi);
                    784:          t = build_int_2 (low, hi);
                    785:          break;
                    786: 
                    787:        case MINUS_EXPR:
                    788:          neg_double (int2l, int2h, &int2l, &int2h);
                    789:          add_double (int1l, int1h, int2l, int2h, &low, &hi);
                    790:          t = build_int_2 (low, hi);
                    791:          break;
                    792: 
                    793:        case MULT_EXPR:
                    794:          mul_double (int1l, int1h, int2l, int2h, &low, &hi);
                    795:          t = build_int_2 (low, hi);
                    796:          break;
                    797: 
                    798:        case TRUNC_DIV_EXPR: case ROUND_DIV_EXPR: 
                    799:        case FLOOR_DIV_EXPR: case CEIL_DIV_EXPR:
                    800:          div_and_round_double (code, uns, int1l, int1h, int2l, int2h,
                    801:                                &low, &hi, &garbagel, &garbageh);
                    802:          t = build_int_2 (low, hi);
                    803:          break;
                    804: 
                    805:        case TRUNC_MOD_EXPR: case ROUND_MOD_EXPR: 
                    806:        case FLOOR_MOD_EXPR: case CEIL_MOD_EXPR:
                    807:          div_and_round_double (code, uns, int1l, int1h, int2l, int2h,
                    808:                                &garbagel, &garbageh, &low, &hi);
                    809:          t = build_int_2 (low, hi);
                    810:          break;
                    811: 
                    812:        case MIN_EXPR:
                    813:        case MAX_EXPR:
                    814:          if (uns)
                    815:            {
                    816:              low = (((unsigned) int1h < (unsigned) int2h)
                    817:                     || (((unsigned) int1h == (unsigned) int2h)
                    818:                         && ((unsigned) int1l < (unsigned) int2l)));
                    819:            }
                    820:          else
                    821:            {
                    822:              low = ((int1h < int2h)
                    823:                     || ((int1h == int2h)
                    824:                         && ((unsigned) int1l < (unsigned) int2l)));
                    825:            }
                    826:          if (low == (code == MIN_EXPR))
                    827:            t = build_int_2 (int1l, int1h);
                    828:          else
                    829:            t = build_int_2 (int2l, int2h);
                    830:          break;
                    831: 
                    832:        default:
                    833:          abort ();
                    834:        }
                    835:       TREE_TYPE (t) = TREE_TYPE (arg1);
                    836:       force_fit_type (t);
                    837:       return t;
                    838:     }
                    839:   if (TREE_CODE (arg1) == REAL_CST)
                    840:     {
                    841:       register double d1 = TREE_REAL_CST (arg1);
                    842:       register double d2 = TREE_REAL_CST (arg2);
                    843:       register tree t;
                    844: 
                    845:       switch (code)
                    846:        {
                    847:        case PLUS_EXPR:
                    848:          t = build_real (d1 + d2);
                    849:          break;
                    850: 
                    851:        case MINUS_EXPR:
                    852:          t = build_real (d1 - d2);
                    853:          break;
                    854: 
                    855:        case MULT_EXPR:
                    856:          t = build_real (d1 * d2);
                    857:          break;
                    858: 
                    859:        case RDIV_EXPR:
                    860:          if (d2 == 0)
                    861:            return 0;
                    862: 
                    863:          t = build_real (d1 / d2);
                    864:          break;
                    865: 
                    866:        case MIN_EXPR:
                    867:          if (d1 < d2)
                    868:            t = build_real (d1);
                    869:          else
                    870:            t = build_real (d2);
                    871:          break;
                    872: 
                    873:        case MAX_EXPR:
                    874:          if (d1 > d2)
                    875:            t = build_real (d1);
                    876:          else
                    877:            t = build_real (d2);
                    878:          break;
                    879: 
                    880:        default:
                    881:          abort ();
                    882:        }
                    883:       TREE_TYPE (t) = TREE_TYPE (arg1);
                    884:       return t;
                    885:     }
                    886:   if (TREE_CODE (arg1) == COMPLEX_CST)
                    887:     {
                    888:       register tree r1 = TREE_REALPART (arg1);
                    889:       register tree i1 = TREE_IMAGPART (arg1);
                    890:       register tree r2 = TREE_REALPART (arg2);
                    891:       register tree i2 = TREE_IMAGPART (arg2);
                    892:       register tree t;
                    893: 
                    894:       switch (code)
                    895:        {
                    896:        case PLUS_EXPR:
                    897:          t = build_complex (combine (PLUS_EXPR, r1, r2),
                    898:                             combine (PLUS_EXPR, i1, i2));
                    899:          break;
                    900: 
                    901:        case MINUS_EXPR:
                    902:          t = build_complex (combine (MINUS_EXPR, r1, r2),
                    903:                             combine (MINUS_EXPR, i1, i2));
                    904:          break;
                    905: 
                    906:        case MULT_EXPR:
                    907:          t = build_complex (combine (MINUS_EXPR,
                    908:                                      combine (MULT_EXPR, r1, r2),
                    909:                                      combine (MULT_EXPR, i1, i2)),
                    910:                             combine (PLUS_EXPR,
                    911:                                      combine (MULT_EXPR, r1, i2),
                    912:                                      combine (MULT_EXPR, i1, r2)));
                    913:          break;
                    914: 
                    915:        case RDIV_EXPR:
                    916:          {
                    917:            register tree magsquared
                    918:              = combine (PLUS_EXPR,
                    919:                         combine (MULT_EXPR, r2, r2),
                    920:                         combine (MULT_EXPR, i2, i2));
                    921:            t = build_complex (combine (RDIV_EXPR,
                    922:                                        combine (PLUS_EXPR,
                    923:                                                 combine (MULT_EXPR, r1, r2),
                    924:                                                 combine (MULT_EXPR, i1, i2)),
                    925:                                        magsquared),
                    926:                               combine (RDIV_EXPR,
                    927:                                        combine (MINUS_EXPR,
                    928:                                                 combine (MULT_EXPR, i1, r2),
                    929:                                                 combine (MULT_EXPR, r1, i2)),
                    930:                                        magsquared));
                    931:          }
                    932:          break;
                    933: 
                    934:        default:
                    935:          abort ();
                    936:        }
                    937:       TREE_TYPE (t) = TREE_TYPE (arg1);
                    938:       return t;
                    939:     }
                    940:   return 0;
                    941: }
                    942: 
                    943: /* Given T, a tree representing type conversion of a constant,
                    944:    return a constant tree representing the result of conversion.  */
                    945: 
                    946: static tree
                    947: fold_convert (t)
                    948:      register tree t;
                    949: {
                    950:   register tree arg1 = TREE_OPERAND (t, 0);
                    951:   register tree type = TREE_TYPE (t);
                    952: 
                    953:   if (TREE_CODE (type) == POINTER_TYPE
                    954:       || TREE_CODE (type) == INTEGER_TYPE
                    955:       || TREE_CODE (type) == ENUMERAL_TYPE)
                    956:     {
                    957:       if (TREE_CODE (arg1) == INTEGER_CST)
                    958:        {
                    959:          /* Given an integer constant, make new constant with new type,
                    960:             appropriately sign-extended or truncated.  */
                    961:          register int inprec;
                    962:          register int outprec;
                    963: 
                    964:          if (TREE_CODE (TREE_TYPE (arg1)) == POINTER_TYPE)
                    965:            inprec = BITS_PER_WORD;
                    966:          else
                    967:            inprec = TYPE_PRECISION (TREE_TYPE (arg1));
                    968:          if (TREE_CODE (type) == POINTER_TYPE)
                    969:            outprec = BITS_PER_WORD;
                    970:          else
                    971:            outprec = TYPE_PRECISION (type);
                    972: 
                    973:          t = build_int_2 (TREE_INT_CST_LOW (arg1),
                    974:                           TREE_INT_CST_HIGH (arg1));
                    975:          TREE_TYPE (t) = type;
                    976:          force_fit_type (t);
                    977:        }
                    978:       else if (TREE_CODE (arg1) == REAL_CST)
                    979:        t = build_int_2 ((int) TREE_REAL_CST (arg1),
                    980:                         (int) (TREE_REAL_CST (arg1) / 0x10000 / 0x10000));
                    981:     }
                    982:   else if (TREE_CODE (type) == REAL_TYPE)
                    983:     {
                    984:       if (TREE_CODE (arg1) == INTEGER_CST)
                    985:        t = build_real_from_int_cst (arg1);
                    986:       else if (TREE_CODE (arg1) == REAL_CST)
                    987:        t = build_real (TREE_REAL_CST (arg1));
                    988:     }
                    989:   TREE_TYPE (t) = type;
                    990:   TREE_LITERAL (t) = 1;
                    991:   return t;
                    992: }
                    993: 
                    994: /* Return nonzero if two constants (that are not manifest constants)
                    995:    are necessarily equal.  It detects only the easiest, common case of
                    996:    equality.  */
                    997: 
                    998: static int
                    999: operand_equal_p (arg0, arg1)
                   1000:      tree arg0, arg1;
                   1001: {
                   1002:   while ((TREE_CODE (arg0) == NOP_EXPR
                   1003:          || TREE_CODE (arg0) == CONVERT_EXPR)
                   1004:         && TYPE_MODE (TREE_TYPE (arg0)) == TYPE_MODE (TREE_TYPE (TREE_OPERAND (arg0, 0))))
                   1005:     arg0 = TREE_OPERAND (arg0, 0);
                   1006:   while ((TREE_CODE (arg1) == NOP_EXPR
                   1007:          || TREE_CODE (arg1) == CONVERT_EXPR)
                   1008:         && TYPE_MODE (TREE_TYPE (arg1)) == TYPE_MODE (TREE_TYPE (TREE_OPERAND (arg1, 0))))
                   1009:     arg1 = TREE_OPERAND (arg1, 0);
                   1010: 
                   1011:   if (TREE_CODE (arg0) == TREE_CODE (arg1)
                   1012:       && TREE_CODE (arg0) == ADDR_EXPR
                   1013:       && TREE_OPERAND (arg0, 0) == TREE_OPERAND (arg1, 0))
                   1014:     return 1;
                   1015:   return 0;
                   1016: }
                   1017: 
                   1018: /* Perform constant folding and related simplification of EXPR.
                   1019:    The related simplifications include x*1 => x, x*0 => 0, etc.,
                   1020:    and application of the associative law.
                   1021:    NOP_EXPR conversions may be removed freely (as long as we
                   1022:    are careful not to change the C type of the overall expression)
                   1023:    We cannot simplify through a CONVERT_EXPR, FIX_EXPR or FLOAT_EXPR,
                   1024:    but we can constant-fold them if they have constant operands.  */
                   1025: 
                   1026: tree
                   1027: fold (expr) 
                   1028:      tree expr;
                   1029: {
                   1030:   register tree t = expr;
                   1031:   register tree arg0, arg1;
                   1032:   register enum tree_code code = TREE_CODE (t);
                   1033:   register int kind;
                   1034: 
                   1035:   /* WINS will be nonzero when the switch is done
                   1036:      if all operands are constant.
                   1037: 
                   1038:      LOSES will be nonzero when the switch is done
                   1039:      if any operand is volatile.
                   1040:      This inhibits optimizations such as  (foo () * 0) => 0.
                   1041:      But identity-element optimizations such as
                   1042:      (foo () * 1) => (foo ()) can be done even if LOSES is set.  */
                   1043: 
                   1044:   int wins = 1;
                   1045:   int loses = 0;
                   1046: 
                   1047:   /* Return right away if already constant.  */
                   1048:   if (TREE_LITERAL (t))
                   1049:     {
                   1050:       if (code == CONST_DECL)
                   1051:        return DECL_INITIAL (t);
                   1052:       return t;
                   1053:     }
                   1054:   
                   1055:   kind = *tree_code_type[(int) code];
                   1056:   if (kind == 'e' || kind == 'r')
                   1057:     {
                   1058:       register int len = tree_code_length[(int) code];
                   1059:       register int i;
                   1060:       for (i = 0; i < len; i++)
                   1061:        {
                   1062:          if (TREE_OPERAND (t, i) == 0)
                   1063:            continue;           /* Valid for CALL_EXPR, at least.  */
                   1064:          if (TREE_CODE (TREE_OPERAND (t, i)) != INTEGER_CST
                   1065:              && TREE_CODE (TREE_OPERAND (t, i)) != REAL_CST)
                   1066:            /* Note that TREE_LITERAL isn't enough:
                   1067:               static var addresses are constant but we can't
                   1068:               do arithmetic on them.  */
                   1069:            wins = 0;
                   1070:          if (TREE_VOLATILE (TREE_OPERAND (t, i)))
                   1071:            loses = 1;
                   1072:        }
                   1073:       arg0 = TREE_OPERAND (t, 0);
                   1074:       if (len > 1)
                   1075:        arg1 = TREE_OPERAND (t, 1);
                   1076:     }
                   1077: 
                   1078:   /* Now WINS and LOSES are set as described above,
                   1079:      ARG0 is the first operand of EXPR,
                   1080:      and ARG1 is the second operand (if it has more than one operand).  */
                   1081: 
                   1082:   switch (code)
                   1083:     {
                   1084:     case INTEGER_CST:
                   1085:     case REAL_CST:
                   1086:     case STRING_CST:
                   1087:     case COMPLEX_CST:
                   1088:     case CONSTRUCTOR:
                   1089:       return t;
                   1090: 
                   1091:     case CONST_DECL:
                   1092:       return fold (DECL_INITIAL (t));
                   1093: 
                   1094:     case NOP_EXPR:
                   1095:     case FLOAT_EXPR:
                   1096:     case CONVERT_EXPR:
                   1097:     case FIX_TRUNC_EXPR:
                   1098:       /* Other kinds of FIX are not handled properly by fold_convert.  */
                   1099:       if (!wins)
                   1100:        {
                   1101:          TREE_LITERAL (t) = TREE_LITERAL (arg0);
                   1102:          return t;
                   1103:        }
                   1104:       return fold_convert (t);
                   1105: 
                   1106:     case RANGE_EXPR:
                   1107:       TREE_LITERAL (t) = wins;
                   1108:       return t;
                   1109: 
                   1110:     case NEGATE_EXPR:
                   1111:       if (wins)
                   1112:        {
                   1113:          if (TREE_CODE (arg0) == INTEGER_CST)
                   1114:            {
                   1115:              if (TREE_INT_CST_LOW (arg0) == 0)
                   1116:                t = build_int_2 (0, - TREE_INT_CST_HIGH (arg0));
                   1117:              else
                   1118:                t = build_int_2 (- TREE_INT_CST_LOW (arg0),
                   1119:                                 ~ TREE_INT_CST_HIGH (arg0));
                   1120:              force_fit_type (t);
                   1121:            }
                   1122:          else if (TREE_CODE (arg0) == REAL_CST)
                   1123:            t = build_real (- TREE_REAL_CST (arg0));
                   1124:          TREE_TYPE (t) = TREE_TYPE (expr);
                   1125:        }
                   1126:       return t;
                   1127: 
                   1128:     case ABS_EXPR:
                   1129:       if (wins)
                   1130:        {
                   1131:          if (TREE_CODE (arg0) == INTEGER_CST)
                   1132:            {
                   1133:              if (! TREE_UNSIGNED (TREE_TYPE (expr))
                   1134:                  || TREE_INT_CST_HIGH (arg0) < 0)
                   1135:                {
                   1136:                  if (TREE_INT_CST_LOW (arg0) == 0)
                   1137:                    t = build_int_2 (0, - TREE_INT_CST_HIGH (arg0));
                   1138:                  else
                   1139:                    t = build_int_2 (- TREE_INT_CST_LOW (arg0),
                   1140:                                     ~ TREE_INT_CST_HIGH (arg0));
                   1141:                }
                   1142:            }
                   1143:          else if (TREE_CODE (arg0) == REAL_CST)
                   1144:            {
                   1145:              if (TREE_REAL_CST (arg0) < 0)
                   1146:                t = build_real (- TREE_REAL_CST (arg0));
                   1147:            }
                   1148:          TREE_TYPE (t) = TREE_TYPE (expr);
                   1149:        }
                   1150:       return t;
                   1151: 
                   1152:     case BIT_NOT_EXPR:
                   1153:       if (wins)
                   1154:        {
                   1155:          if (TREE_CODE (arg0) == INTEGER_CST)
                   1156:            t = build_int_2 (~ TREE_INT_CST_LOW (arg0),
                   1157:                             ~ TREE_INT_CST_HIGH (arg0));
                   1158:          TREE_TYPE (t) = TREE_TYPE (expr);
                   1159:          force_fit_type (t);
                   1160:        }
                   1161:       return t;
                   1162: 
                   1163:     case PLUS_EXPR:
                   1164:       if (integer_zerop (arg0))
                   1165:        return convert (TREE_TYPE (expr), arg1);
                   1166:       if (integer_zerop (arg1))
                   1167:        return convert (TREE_TYPE (expr), arg0);
                   1168:     associate:
                   1169:       /* In most languages, can't associate operations on floats
                   1170:         through parentheses.  Rather than remember where the parentheses
                   1171:         were, we don't associate floats at all.  It shouldn't matter much.  */
                   1172:       if (TREE_CODE (TREE_TYPE (expr)) == REAL_TYPE)
                   1173:        goto binary;
                   1174:       /* The varsign == -1 cases happen only for addition and subtraction.
                   1175:         It says that the arg that was split was really CON minus VAR.
                   1176:         The rest of the code applies to all associative operations.  */
                   1177:       if (!wins)
                   1178:        {
                   1179:          tree var, con, tem;
                   1180:          int varsign;
                   1181:          tree inner_arg;
                   1182: 
                   1183:          if (split_tree (arg0, code, &var, &con, &varsign))
                   1184:            {
                   1185:              if (varsign == -1)
                   1186:                {
                   1187:                  /* EXPR is (CON-VAR) +- ARG1.  */
                   1188:                  /* If it is + and VAR==ARG1, return just CONST.  */
                   1189:                  if (code == PLUS_EXPR && operand_equal_p (var, arg1))
                   1190:                    return con;
                   1191:                    
                   1192:                  /* Otherwise return (CON +- ARG1) - VAR.  */
                   1193:                  TREE_SET_CODE (t, MINUS_EXPR);
                   1194:                  TREE_OPERAND (t, 1) = var;
                   1195:                  TREE_OPERAND (t, 0)
                   1196:                    = fold (build (code, TREE_TYPE (t), con, arg1));
                   1197:                }
                   1198:              else
                   1199:                {
                   1200:                  /* EXPR is (VAR+CON) +- ARG1.  */
                   1201:                  /* If it is - and VAR==ARG1, return just CONST.  */
                   1202:                  if (code == MINUS_EXPR && operand_equal_p (var, arg1))
                   1203:                    return con;
                   1204:                    
                   1205:                  /* Otherwise return VAR +- (ARG1 +- CON).  */
                   1206:                  TREE_OPERAND (t, 1) = tem
                   1207:                    = fold (build (code, TREE_TYPE (t), arg1, con));
                   1208:                  TREE_OPERAND (t, 0) = var;
                   1209:                  if (integer_zerop (tem)
                   1210:                      && (code == PLUS_EXPR || code == MINUS_EXPR))
                   1211:                    return var;
                   1212:                  /* If we have x +/- (c - d) [c an explicit integer]
                   1213:                     change it to x -/+ (d - c) since if d is relocatable
                   1214:                     then the latter can be a single immediate insn
                   1215:                     and the former cannot.  */
                   1216:                  if (TREE_CODE (tem) == MINUS_EXPR
                   1217:                      && TREE_CODE (TREE_OPERAND (tem, 0)) == INTEGER_CST)
                   1218:                    {
                   1219:                      tree tem1 = TREE_OPERAND (tem, 1);
                   1220:                      TREE_OPERAND (tem, 1) = TREE_OPERAND (tem, 0);
                   1221:                      TREE_OPERAND (tem, 0) = tem1;
                   1222:                      TREE_SET_CODE (t,
                   1223:                                     (code == PLUS_EXPR ? MINUS_EXPR : PLUS_EXPR));
                   1224:                    }
                   1225:                }
                   1226:              return t;
                   1227:            }
                   1228: 
                   1229:          if (split_tree (arg1, code, &var, &con, &varsign))
                   1230:            {
                   1231:              /* EXPR is ARG0 +- (CON +- VAR).  */
                   1232:              if (varsign == -1)
                   1233:                TREE_SET_CODE (t,
                   1234:                               (code == PLUS_EXPR ? MINUS_EXPR : PLUS_EXPR));
                   1235:              if (TREE_CODE (t) == MINUS_EXPR && operand_equal_p (var, arg0))
                   1236:                return con;
                   1237:              TREE_OPERAND (t, 0)
                   1238:                = fold (build (code, TREE_TYPE (t), arg0, con));
                   1239:              TREE_OPERAND (t, 1) = var;
                   1240:              if (integer_zerop (TREE_OPERAND (t, 0))
                   1241:                  && TREE_CODE (t) == PLUS_EXPR)
                   1242:                return var;
                   1243:              return t;
                   1244:            }
                   1245:        }
                   1246:     binary:
                   1247:       {
                   1248:        register tree t1 = NULL_TREE;
                   1249:        if (wins)
                   1250:          t1 = combine (code, arg0, arg1);
                   1251:        if (t1 != NULL_TREE) return t1;
                   1252:        return t;
                   1253:       }
                   1254: 
                   1255:     case MINUS_EXPR:
                   1256:       if (! wins && integer_zerop (arg0))
                   1257:        return build (NEGATE_EXPR, TREE_TYPE (expr), arg1);
                   1258:       if (integer_zerop (arg1))
                   1259:        return convert (TREE_TYPE (expr), arg0);
                   1260:       /* Fold &x - &x.  This can happen from &x.foo - &x.  */
                   1261:       if (operand_equal_p (arg0, arg1))
                   1262:        return convert (TREE_TYPE (t), integer_zero_node);
                   1263:       goto associate;
                   1264: 
                   1265:     case MULT_EXPR:
                   1266:       if (!loses && integer_zerop (arg0))
                   1267:        return convert (TREE_TYPE (expr), arg0);
                   1268:       if (!loses && integer_zerop (arg1))
                   1269:        return convert (TREE_TYPE (expr), arg1);
                   1270:       if (integer_onep (arg0))
                   1271:        return convert (TREE_TYPE (expr), arg1);
                   1272:       if (integer_onep (arg1))
                   1273:        return convert (TREE_TYPE (expr), arg0);
                   1274:       goto associate;
                   1275: 
                   1276:     case BIT_IOR_EXPR:
                   1277:       if (!loses && integer_all_onesp (arg0))
                   1278:        return convert (TREE_TYPE (expr), arg0);
                   1279:       if (!loses && integer_all_onesp (arg1))
                   1280:        return convert (TREE_TYPE (expr), arg1);
                   1281:     case BIT_XOR_EXPR:
                   1282:       if (integer_zerop (arg0))
                   1283:        return convert (TREE_TYPE (expr), arg1);
                   1284:       if (integer_zerop (arg1))
                   1285:        return convert (TREE_TYPE (expr), arg0);
                   1286:       goto associate;
                   1287: 
                   1288:     case BIT_AND_EXPR:
                   1289:       if (integer_all_onesp (arg0))
                   1290:        return convert (TREE_TYPE (expr), arg1);
                   1291:       if (integer_all_onesp (arg1))
                   1292:        return convert (TREE_TYPE (expr), arg0);
                   1293:       if (!loses && integer_zerop (arg0))
                   1294:        return convert (TREE_TYPE (expr), arg0);
                   1295:       if (!loses && integer_zerop (arg1))
                   1296:        return convert (TREE_TYPE (expr), arg1);
                   1297:       /* Simplify (int)((unsigned char)x & 0x377) into (int)(unsigned char)x.  */
                   1298:       if (TREE_CODE (arg0) == INTEGER_CST && TREE_CODE (arg1) == NOP_EXPR
                   1299:          && TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (arg1, 0))))
                   1300:        {
                   1301:          int prec = TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg1, 0)));
                   1302:          if (prec < BITS_PER_WORD && prec < HOST_BITS_PER_INT
                   1303:              && (~TREE_INT_CST_LOW (arg0) & ((1 << prec) - 1)) == 0)
                   1304:            return convert (TREE_TYPE (expr), arg1);
                   1305:        }
                   1306:       if (TREE_CODE (arg1) == INTEGER_CST && TREE_CODE (arg0) == NOP_EXPR
                   1307:          && TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (arg0, 0))))
                   1308:        {
                   1309:          int prec = TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg0, 0)));
                   1310:          if (prec < BITS_PER_WORD && prec < HOST_BITS_PER_INT
                   1311:              && (~TREE_INT_CST_LOW (arg1) & ((1 << prec) - 1)) == 0)
                   1312:            return convert (TREE_TYPE (expr), arg0);
                   1313:        }
                   1314:       goto associate;
                   1315: 
                   1316:     case BIT_ANDTC_EXPR:
                   1317:       if (integer_all_onesp (arg0))
                   1318:        return convert (TREE_TYPE (expr), arg1);
                   1319:       if (integer_zerop (arg1))
                   1320:        return convert (TREE_TYPE (expr), arg0);
                   1321:       if (!loses && integer_zerop (arg0))
                   1322:        return convert (TREE_TYPE (expr), arg0);
                   1323:       if (!loses && integer_all_onesp (arg1))
                   1324:        return combine (code, arg1, arg1);
                   1325:       goto binary;
                   1326: 
                   1327:     case TRUNC_DIV_EXPR:
                   1328:     case ROUND_DIV_EXPR:
                   1329:     case FLOOR_DIV_EXPR:
                   1330:     case CEIL_DIV_EXPR:
                   1331:     case RDIV_EXPR:
                   1332:       if (integer_onep (arg1))
                   1333:        return convert (TREE_TYPE (expr), arg0);
                   1334:       goto binary;
                   1335: 
                   1336:     case CEIL_MOD_EXPR:
                   1337:     case FLOOR_MOD_EXPR:
                   1338:     case ROUND_MOD_EXPR:
                   1339:     case TRUNC_MOD_EXPR:
                   1340:       if (!loses && integer_onep (arg1))
                   1341:        return combine (code, arg1, arg1);
                   1342:       goto binary;
                   1343: 
                   1344:     case LSHIFT_EXPR:
                   1345:     case RSHIFT_EXPR:
                   1346:     case LROTATE_EXPR:
                   1347:     case RROTATE_EXPR:
                   1348:       if (integer_zerop (arg1))
                   1349:        return convert (TREE_TYPE (expr), arg0);
                   1350:       goto binary;
                   1351: 
                   1352:     case MIN_EXPR: case MAX_EXPR:
                   1353:       goto associate;
                   1354: 
                   1355:     case TRUTH_NOT_EXPR:
                   1356:       if (wins)
                   1357:        {
                   1358:          if (TREE_CODE (arg0) == INTEGER_CST)
                   1359:            {
                   1360:              t = build_int_2 ((TREE_INT_CST_LOW (arg0) == 0
                   1361:                                && TREE_INT_CST_HIGH (arg0) == 0),
                   1362:                               0);
                   1363:              TREE_TYPE (t) = integer_type_node;
                   1364:            }
                   1365:          if (TREE_CODE (arg0) == REAL_CST)
                   1366:            {
                   1367:              t = build_int_2 (TREE_REAL_CST (arg0) == 0, 0);
                   1368:              TREE_TYPE (t) = integer_type_node;
                   1369:            }
                   1370:        }
                   1371:       return t;
                   1372: 
                   1373:     case TRUTH_AND_EXPR:
                   1374:     case TRUTH_ANDIF_EXPR:
                   1375:       if (wins)
                   1376:        {
                   1377:          if (TREE_CODE (arg0) == INTEGER_CST
                   1378:              && TREE_CODE (arg1) == INTEGER_CST)
                   1379:            t = build_int_2 (((TREE_INT_CST_LOW (arg0) || TREE_INT_CST_HIGH (arg0))
                   1380:                              && (TREE_INT_CST_LOW (arg1) || TREE_INT_CST_HIGH (arg1))),
                   1381:                             0);
                   1382:          if (TREE_CODE (arg0) == REAL_CST
                   1383:              && TREE_CODE (arg1) == REAL_CST)
                   1384:            t = build_int_2 ((TREE_REAL_CST (arg0) && TREE_REAL_CST (arg1)),
                   1385:                             0);
                   1386:          TREE_TYPE (t) = TREE_TYPE (expr);
                   1387:        }
                   1388:       return t;
                   1389: 
                   1390:     case TRUTH_OR_EXPR:
                   1391:     case TRUTH_ORIF_EXPR:
                   1392:       if (wins)
                   1393:        {
                   1394:          if (TREE_CODE (arg0) == INTEGER_CST
                   1395:              && TREE_CODE (arg1) == INTEGER_CST)
                   1396:            t = build_int_2 (((TREE_INT_CST_LOW (arg0) || TREE_INT_CST_HIGH (arg0))
                   1397:                              || (TREE_INT_CST_LOW (arg1) || TREE_INT_CST_HIGH (arg1))),
                   1398:                             0);
                   1399:          if (TREE_CODE (arg0) == REAL_CST && TREE_CODE (arg1) == REAL_CST)
                   1400:            t = build_int_2 ((TREE_REAL_CST (arg0) || TREE_REAL_CST (arg1)),
                   1401:                             0);
                   1402:          TREE_TYPE (t) = TREE_TYPE (expr);
                   1403:        }
                   1404:       return t;
                   1405: 
                   1406:     case EQ_EXPR:
                   1407:     case NE_EXPR:
                   1408:     case LT_EXPR:
                   1409:     case GT_EXPR:
                   1410:     case LE_EXPR:
                   1411:     case GE_EXPR:
                   1412:       /* Convert foo++ == CONST into ++foo == CONST + INCR.
                   1413:         First, see if one arg is constant; find the constant arg
                   1414:         and the other one.  */
                   1415:       {
                   1416:        tree constop = 0, varop;
                   1417:        tree *constoploc;
                   1418: 
                   1419:        if (TREE_LITERAL (arg1))
                   1420:          constoploc = &TREE_OPERAND (t, 1), constop = arg1, varop = arg0;
                   1421:        if (TREE_LITERAL (arg0))
                   1422:          constoploc = &TREE_OPERAND (t, 0), constop = arg0, varop = arg1;
                   1423: 
                   1424:        if (constop && TREE_CODE (varop) == POSTINCREMENT_EXPR)
                   1425:          {
                   1426:            tree newconst
                   1427:              = fold (build (PLUS_EXPR, TREE_TYPE (t),
                   1428:                             constop, TREE_OPERAND (varop, 1)));
                   1429:            /* This optimization is invalid for ordered comparisons
                   1430:               if CONST+INCR overflows!
                   1431:               We can assume that address + integer will not overflow.  */
                   1432:            if (TREE_CODE (newconst) != INTEGER_CST
                   1433:                || ! tree_int_cst_lt (newconst, constop)
                   1434:                || code == EQ_EXPR || code == NE_EXPR)
                   1435:              {
                   1436:                TREE_CODE (varop) = PREINCREMENT_EXPR;
                   1437:                *constoploc = newconst;
                   1438:                return t;
                   1439:              }
                   1440:          }
                   1441:        else if (constop && TREE_CODE (varop) == POSTDECREMENT_EXPR)
                   1442:          {
                   1443:            tree newconst
                   1444:              = fold (build (MINUS_EXPR, TREE_TYPE (t),
                   1445:                             constop, TREE_OPERAND (varop, 1)));
                   1446:            if (TREE_CODE (newconst) != INTEGER_CST
                   1447:                || tree_int_cst_lt (newconst, constop)
                   1448:                || code == EQ_EXPR || code == NE_EXPR)
                   1449:              {
                   1450:                TREE_CODE (varop) = PREDECREMENT_EXPR;
                   1451:                *constoploc = newconst;
                   1452:                return t;
                   1453:              }
                   1454:          }
                   1455:       }
                   1456: 
                   1457:       /* An unsigned comparison against 0 can be simplified.  */
                   1458:       if (integer_zerop (arg0)
                   1459:          && (TREE_CODE (TREE_TYPE (arg0)) == INTEGER_TYPE
                   1460:              || TREE_CODE (TREE_TYPE (arg0)) == POINTER_TYPE)
                   1461:          && TREE_UNSIGNED (TREE_TYPE (arg0)))
                   1462:        {
                   1463:          switch (TREE_CODE (t))
                   1464:            {
                   1465:            case LT_EXPR:
                   1466:              TREE_CODE (t) = NE_EXPR;
                   1467:              break;
                   1468:            case GE_EXPR:
                   1469:              TREE_CODE (t) = EQ_EXPR;
                   1470:              break;
                   1471:            case LE_EXPR:
                   1472:              return build (COMPOUND_EXPR, integer_type_node,
                   1473:                            arg1, integer_one_node);
                   1474:            case GT_EXPR:
                   1475:              return build (COMPOUND_EXPR, integer_type_node,
                   1476:                            arg1, integer_zero_node);
                   1477:            }
                   1478:        }
                   1479: 
                   1480:       /* An unsigned comparison against 0 can be simplified.  */
                   1481:       if (integer_zerop (arg1)
                   1482:          && (TREE_CODE (TREE_TYPE (arg1)) == INTEGER_TYPE
                   1483:              || TREE_CODE (TREE_TYPE (arg1)) == POINTER_TYPE)
                   1484:          && TREE_UNSIGNED (TREE_TYPE (arg1)))
                   1485:        {
                   1486:          switch (TREE_CODE (t))
                   1487:            {
                   1488:            case GT_EXPR:
                   1489:              TREE_CODE (t) = NE_EXPR;
                   1490:              break;
                   1491:            case LE_EXPR:
                   1492:              TREE_CODE (t) = EQ_EXPR;
                   1493:              break;
                   1494:            case GE_EXPR:
                   1495:              return build (COMPOUND_EXPR, integer_type_node,
                   1496:                            arg0, integer_one_node);
                   1497:            case LT_EXPR:
                   1498:              return build (COMPOUND_EXPR, integer_type_node,
                   1499:                            arg0, integer_zero_node);
                   1500:            }
                   1501:        }
                   1502: 
                   1503:       /* To compute GT, swap the arguments and do LT.
                   1504:         To compute GE, do LT and invert the result.
                   1505:         To compute LE, swap the arguments, do LT and invert the result.
                   1506:         To compute NE, do EQ and invert the result.  */
                   1507:       if (code == LE_EXPR || code == GT_EXPR)
                   1508:        {
                   1509:          register tree temp = arg0;
                   1510:          arg0 = arg1;
                   1511:          arg1 = temp;
                   1512:        }
                   1513: 
                   1514:       /* Compute a result for LT or EQ if args permit.  */
                   1515:       if (TREE_CODE (arg0) == INTEGER_CST
                   1516:          && TREE_CODE (arg1) == INTEGER_CST)
                   1517:        {
                   1518:          if (code == EQ_EXPR || code == NE_EXPR)
                   1519:            t = build_int_2
                   1520:              (TREE_INT_CST_LOW (arg0) == TREE_INT_CST_LOW (arg1)
                   1521:               && TREE_INT_CST_HIGH (arg0) == TREE_INT_CST_HIGH (arg1),
                   1522:               0);
                   1523:          else
                   1524:            t = build_int_2 ((TREE_UNSIGNED (TREE_TYPE (arg0))
                   1525:                              ? INT_CST_LT_UNSIGNED (arg0, arg1)
                   1526:                              : INT_CST_LT (arg0, arg1)),
                   1527:                             0);
                   1528:        }
                   1529:       else if (TREE_CODE (arg0) == REAL_CST
                   1530:               && TREE_CODE (arg1) == REAL_CST)
                   1531:        {
                   1532:          if (code == EQ_EXPR || code == NE_EXPR)
                   1533:            t = build_int_2 (TREE_REAL_CST (arg0) == TREE_REAL_CST (arg1), 0);
                   1534:          else
                   1535:            t = build_int_2 (TREE_REAL_CST (arg0) < TREE_REAL_CST (arg1), 0);
                   1536:        }
                   1537:       else
                   1538:        return t;
                   1539: 
                   1540:       /* If we wanted ...-or-equal, invert the result.  */
                   1541:       if (code == GE_EXPR || code == LE_EXPR || code == NE_EXPR)
                   1542:        TREE_INT_CST_LOW (t) ^= 1;
                   1543:       TREE_TYPE (t) = TREE_TYPE (expr);
                   1544:       return t;
                   1545: 
                   1546:     COND_EXPR:
                   1547:       if (TREE_LITERAL (arg0))
                   1548:        return TREE_OPERAND (expr, (integer_zerop (arg0) ? 2 : 1));
                   1549:       return t;
                   1550: 
                   1551:     default:
                   1552:       return t;
                   1553:     } /* switch (code) */
                   1554: }

unix.superglobalmegacorp.com

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