Annotation of gcc/expmed.c, revision 1.1.1.7

1.1       root        1: /* Medium-level subroutines: convert bit-field store and extract
                      2:    and shifts, multiplies and divides to rtl instructions.
1.1.1.7 ! root        3:    Copyright (C) 1987, 88, 89, 92, 93, 1994 Free Software Foundation, Inc.
1.1       root        4: 
                      5: This file is part of GNU CC.
                      6: 
                      7: GNU CC is free software; you can redistribute it and/or modify
                      8: it under the terms of the GNU General Public License as published by
                      9: the Free Software Foundation; either version 2, or (at your option)
                     10: any later version.
                     11: 
                     12: GNU CC is distributed in the hope that it will be useful,
                     13: but WITHOUT ANY WARRANTY; without even the implied warranty of
                     14: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     15: GNU General Public License for more details.
                     16: 
                     17: You should have received a copy of the GNU General Public License
                     18: along with GNU CC; see the file COPYING.  If not, write to
                     19: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
                     20: 
                     21: 
                     22: #include "config.h"
                     23: #include "rtl.h"
                     24: #include "tree.h"
                     25: #include "flags.h"
                     26: #include "insn-flags.h"
                     27: #include "insn-codes.h"
                     28: #include "insn-config.h"
                     29: #include "expr.h"
                     30: #include "real.h"
                     31: #include "recog.h"
                     32: 
1.1.1.7 ! root       33: static void store_fixed_bit_field      PROTO((rtx, int, int, int, rtx, int));
        !            34: static void store_split_bit_field      PROTO((rtx, int, int, rtx, int));
        !            35: static rtx extract_fixed_bit_field     PROTO((enum machine_mode, rtx, int,
        !            36:                                               int, int, rtx, int, int));
        !            37: static rtx mask_rtx                    PROTO((enum machine_mode, int,
        !            38:                                               int, int));
        !            39: static rtx lshift_value                        PROTO((enum machine_mode, rtx,
        !            40:                                               int, int));
        !            41: static rtx extract_split_bit_field     PROTO((rtx, int, int, int, int));
1.1       root       42: 
                     43: #define CEIL(x,y) (((x) + (y) - 1) / (y))
                     44: 
                     45: /* Non-zero means divides or modulus operations are relatively cheap for
                     46:    powers of two, so don't use branches; emit the operation instead. 
                     47:    Usually, this will mean that the MD file will emit non-branch
                     48:    sequences.  */
                     49: 
                     50: static int sdiv_pow2_cheap, smod_pow2_cheap;
                     51: 
1.1.1.6   root       52: #ifndef SLOW_UNALIGNED_ACCESS
                     53: #define SLOW_UNALIGNED_ACCESS STRICT_ALIGNMENT
                     54: #endif
                     55: 
1.1.1.5   root       56: /* For compilers that support multiple targets with different word sizes,
                     57:    MAX_BITS_PER_WORD contains the biggest value of BITS_PER_WORD.  An example
                     58:    is the H8/300(H) compiler.  */
                     59: 
                     60: #ifndef MAX_BITS_PER_WORD
                     61: #define MAX_BITS_PER_WORD BITS_PER_WORD
                     62: #endif
1.1       root       63: 
1.1.1.5   root       64: /* Cost of various pieces of RTL.  */
1.1.1.6   root       65: static int add_cost, negate_cost, zero_cost;
1.1.1.5   root       66: static int shift_cost[MAX_BITS_PER_WORD];
                     67: static int shiftadd_cost[MAX_BITS_PER_WORD];
                     68: static int shiftsub_cost[MAX_BITS_PER_WORD];
1.1       root       69: 
                     70: void
                     71: init_expmed ()
                     72: {
1.1.1.5   root       73:   char *free_point;
1.1       root       74:   /* This is "some random pseudo register" for purposes of calling recog
                     75:      to see what insns exist.  */
1.1.1.6   root       76:   rtx reg = gen_rtx (REG, word_mode, 10000);
1.1.1.5   root       77:   rtx shift_insn, shiftadd_insn, shiftsub_insn;
1.1.1.4   root       78:   int dummy;
1.1.1.5   root       79:   int m;
1.1       root       80: 
1.1.1.5   root       81:   start_sequence ();
                     82: 
                     83:   /* Since we are on the permanent obstack, we must be sure we save this
                     84:      spot AFTER we call start_sequence, since it will reuse the rtl it
                     85:      makes.  */
                     86: 
                     87:   free_point = (char *) oballoc (0);
                     88: 
                     89:   zero_cost = rtx_cost (const0_rtx, 0);
1.1.1.3   root       90:   add_cost = rtx_cost (gen_rtx (PLUS, word_mode, reg, reg), SET);
1.1.1.5   root       91: 
                     92:   shift_insn = emit_insn (gen_rtx (SET, VOIDmode, reg,
                     93:                                   gen_rtx (ASHIFT, word_mode, reg,
                     94:                                            const0_rtx)));
                     95: 
                     96:   shiftadd_insn = emit_insn (gen_rtx (SET, VOIDmode, reg,
                     97:                                      gen_rtx (PLUS, word_mode,
                     98:                                               gen_rtx (MULT, word_mode,
                     99:                                                        reg, const0_rtx),
                    100:                                               reg)));
                    101: 
                    102:   shiftsub_insn = emit_insn (gen_rtx (SET, VOIDmode, reg,
                    103:                                      gen_rtx (MINUS, word_mode,
                    104:                                               gen_rtx (MULT, word_mode,
                    105:                                                         reg, const0_rtx),
                    106:                                                reg)));
                    107: 
                    108:   init_recog ();
                    109: 
                    110:   shift_cost[0] = 0;
                    111:   shiftadd_cost[0] = shiftsub_cost[0] = add_cost;
                    112: 
                    113:   for (m = 1; m < BITS_PER_WORD; m++)
                    114:     {
                    115:       shift_cost[m] = shiftadd_cost[m] = shiftsub_cost[m] = 32000;
                    116: 
                    117:       XEXP (SET_SRC (PATTERN (shift_insn)), 1) = GEN_INT (m);
                    118:       if (recog (PATTERN (shift_insn), shift_insn, &dummy) >= 0)
                    119:        shift_cost[m] = rtx_cost (SET_SRC (PATTERN (shift_insn)), SET);
                    120: 
                    121:       XEXP (XEXP (SET_SRC (PATTERN (shiftadd_insn)), 0), 1)
                    122:        = GEN_INT ((HOST_WIDE_INT) 1 << m);
                    123:       if (recog (PATTERN (shiftadd_insn), shiftadd_insn, &dummy) >= 0)
                    124:        shiftadd_cost[m] = rtx_cost (SET_SRC (PATTERN (shiftadd_insn)), SET);
                    125: 
                    126:       XEXP (XEXP (SET_SRC (PATTERN (shiftsub_insn)), 0), 1)
                    127:        = GEN_INT ((HOST_WIDE_INT) 1 << m);
                    128:       if (recog (PATTERN (shiftsub_insn), shiftsub_insn, &dummy) >= 0)
                    129:        shiftsub_cost[m] = rtx_cost (SET_SRC (PATTERN (shiftsub_insn)), SET);
                    130:     }
                    131: 
1.1.1.3   root      132:   negate_cost = rtx_cost (gen_rtx (NEG, word_mode, reg), SET);
1.1       root      133: 
                    134:   sdiv_pow2_cheap
1.1.1.5   root      135:     = (rtx_cost (gen_rtx (DIV, word_mode, reg, GEN_INT (32)), SET)
                    136:        <= 2 * add_cost);
1.1       root      137:   smod_pow2_cheap
1.1.1.5   root      138:     = (rtx_cost (gen_rtx (MOD, word_mode, reg, GEN_INT (32)), SET)
                    139:        <= 2 * add_cost);
1.1       root      140: 
                    141:   /* Free the objects we just allocated.  */
1.1.1.5   root      142:   end_sequence ();
1.1       root      143:   obfree (free_point);
                    144: }
                    145: 
                    146: /* Return an rtx representing minus the value of X.
                    147:    MODE is the intended mode of the result,
                    148:    useful if X is a CONST_INT.  */
                    149: 
                    150: rtx
                    151: negate_rtx (mode, x)
                    152:      enum machine_mode mode;
                    153:      rtx x;
                    154: {
                    155:   if (GET_CODE (x) == CONST_INT)
                    156:     {
1.1.1.4   root      157:       HOST_WIDE_INT val = - INTVAL (x);
                    158:       if (GET_MODE_BITSIZE (mode) < HOST_BITS_PER_WIDE_INT)
1.1       root      159:        {
                    160:          /* Sign extend the value from the bits that are significant.  */
1.1.1.4   root      161:          if (val & ((HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE (mode) - 1)))
                    162:            val |= (HOST_WIDE_INT) (-1) << GET_MODE_BITSIZE (mode);
1.1       root      163:          else
1.1.1.4   root      164:            val &= ((HOST_WIDE_INT) 1 << GET_MODE_BITSIZE (mode)) - 1;
1.1       root      165:        }
1.1.1.4   root      166:       return GEN_INT (val);
1.1       root      167:     }
                    168:   else
1.1.1.4   root      169:     return expand_unop (GET_MODE (x), neg_optab, x, NULL_RTX, 0);
1.1       root      170: }
                    171: 
                    172: /* Generate code to store value from rtx VALUE
                    173:    into a bit-field within structure STR_RTX
                    174:    containing BITSIZE bits starting at bit BITNUM.
                    175:    FIELDMODE is the machine-mode of the FIELD_DECL node for this field.
                    176:    ALIGN is the alignment that STR_RTX is known to have, measured in bytes.
                    177:    TOTAL_SIZE is the size of the structure in bytes, or -1 if varying.  */
                    178: 
                    179: /* ??? Note that there are two different ideas here for how
                    180:    to determine the size to count bits within, for a register.
                    181:    One is BITS_PER_WORD, and the other is the size of operand 3
                    182:    of the insv pattern.  (The latter assumes that an n-bit machine
                    183:    will be able to insert bit fields up to n bits wide.)
                    184:    It isn't certain that either of these is right.
                    185:    extract_bit_field has the same quandary.  */
                    186: 
                    187: rtx
                    188: store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, align, total_size)
                    189:      rtx str_rtx;
                    190:      register int bitsize;
                    191:      int bitnum;
                    192:      enum machine_mode fieldmode;
                    193:      rtx value;
                    194:      int align;
                    195:      int total_size;
                    196: {
                    197:   int unit = (GET_CODE (str_rtx) == MEM) ? BITS_PER_UNIT : BITS_PER_WORD;
                    198:   register int offset = bitnum / unit;
                    199:   register int bitpos = bitnum % unit;
                    200:   register rtx op0 = str_rtx;
                    201: 
                    202:   if (GET_CODE (str_rtx) == MEM && ! MEM_IN_STRUCT_P (str_rtx))
                    203:     abort ();
                    204: 
                    205:   /* Discount the part of the structure before the desired byte.
                    206:      We need to know how many bytes are safe to reference after it.  */
                    207:   if (total_size >= 0)
                    208:     total_size -= (bitpos / BIGGEST_ALIGNMENT
                    209:                   * (BIGGEST_ALIGNMENT / BITS_PER_UNIT));
                    210: 
                    211:   while (GET_CODE (op0) == SUBREG)
                    212:     {
                    213:       /* The following line once was done only if WORDS_BIG_ENDIAN,
                    214:         but I think that is a mistake.  WORDS_BIG_ENDIAN is
                    215:         meaningful at a much higher level; when structures are copied
                    216:         between memory and regs, the higher-numbered regs
                    217:         always get higher addresses.  */
                    218:       offset += SUBREG_WORD (op0);
                    219:       /* We used to adjust BITPOS here, but now we do the whole adjustment
                    220:         right after the loop.  */
                    221:       op0 = SUBREG_REG (op0);
                    222:     }
                    223: 
                    224: #if BYTES_BIG_ENDIAN
                    225:   /* If OP0 is a register, BITPOS must count within a word.
                    226:      But as we have it, it counts within whatever size OP0 now has.
                    227:      On a bigendian machine, these are not the same, so convert.  */
                    228:   if (GET_CODE (op0) != MEM && unit > GET_MODE_BITSIZE (GET_MODE (op0)))
                    229:     bitpos += unit - GET_MODE_BITSIZE (GET_MODE (op0));
                    230: #endif
                    231: 
                    232:   value = protect_from_queue (value, 0);
                    233: 
                    234:   if (flag_force_mem)
                    235:     value = force_not_mem (value);
                    236: 
                    237:   /* Note that the adjustment of BITPOS above has no effect on whether
                    238:      BITPOS is 0 in a REG bigger than a word.  */
1.1.1.3   root      239:   if (GET_MODE_SIZE (fieldmode) >= UNITS_PER_WORD
1.1.1.6   root      240:       && (GET_CODE (op0) != MEM
                    241:          || ! SLOW_UNALIGNED_ACCESS
                    242:          || (offset * BITS_PER_UNIT % bitsize == 0
                    243:              && align % GET_MODE_SIZE (fieldmode) == 0))
1.1       root      244:       && bitpos == 0 && bitsize == GET_MODE_BITSIZE (fieldmode))
                    245:     {
                    246:       /* Storing in a full-word or multi-word field in a register
                    247:         can be done with just SUBREG.  */
                    248:       if (GET_MODE (op0) != fieldmode)
1.1.1.6   root      249:        {
                    250:          if (GET_CODE (op0) == REG)
                    251:            op0 = gen_rtx (SUBREG, fieldmode, op0, offset);
                    252:          else
                    253:            op0 = change_address (op0, fieldmode,
                    254:                                  plus_constant (XEXP (op0, 0), offset));
                    255:        }
1.1       root      256:       emit_move_insn (op0, value);
                    257:       return value;
                    258:     }
                    259: 
                    260:   /* Storing an lsb-aligned field in a register
                    261:      can be done with a movestrict instruction.  */
                    262: 
                    263:   if (GET_CODE (op0) != MEM
                    264: #if BYTES_BIG_ENDIAN
                    265:       && bitpos + bitsize == unit
                    266: #else
                    267:       && bitpos == 0
                    268: #endif
                    269:       && bitsize == GET_MODE_BITSIZE (fieldmode)
                    270:       && (GET_MODE (op0) == fieldmode
                    271:          || (movstrict_optab->handlers[(int) fieldmode].insn_code
                    272:              != CODE_FOR_nothing)))
                    273:     {
                    274:       /* Get appropriate low part of the value being stored.  */
                    275:       if (GET_CODE (value) == CONST_INT || GET_CODE (value) == REG)
                    276:        value = gen_lowpart (fieldmode, value);
                    277:       else if (!(GET_CODE (value) == SYMBOL_REF
                    278:                 || GET_CODE (value) == LABEL_REF
                    279:                 || GET_CODE (value) == CONST))
                    280:        value = convert_to_mode (fieldmode, value, 0);
                    281: 
                    282:       if (GET_MODE (op0) == fieldmode)
                    283:        emit_move_insn (op0, value);
                    284:       else
                    285:        {
                    286:          int icode = movstrict_optab->handlers[(int) fieldmode].insn_code;
                    287:          if(! (*insn_operand_predicate[icode][1]) (value, fieldmode))
                    288:            value = copy_to_mode_reg (fieldmode, value);
                    289:          emit_insn (GEN_FCN (icode)
                    290:                   (gen_rtx (SUBREG, fieldmode, op0, offset), value));
                    291:        }
                    292:       return value;
                    293:     }
                    294: 
                    295:   /* Handle fields bigger than a word.  */
                    296: 
                    297:   if (bitsize > BITS_PER_WORD)
                    298:     {
                    299:       /* Here we transfer the words of the field
                    300:         in the order least significant first.
                    301:         This is because the most significant word is the one which may
1.1.1.7 ! root      302:         be less than full.
        !           303:         However, only do that if the value is not BLKmode.  */
        !           304: 
        !           305:       int backwards = WORDS_BIG_ENDIAN && fieldmode != BLKmode;
1.1       root      306: 
                    307:       int nwords = (bitsize + (BITS_PER_WORD - 1)) / BITS_PER_WORD;
                    308:       int i;
                    309: 
                    310:       /* This is the mode we must force value to, so that there will be enough
                    311:         subwords to extract.  Note that fieldmode will often (always?) be
                    312:         VOIDmode, because that is what store_field uses to indicate that this
                    313:         is a bit field, but passing VOIDmode to operand_subword_force will
                    314:         result in an abort.  */
                    315:       fieldmode = mode_for_size (nwords * BITS_PER_WORD, MODE_INT, 0);
                    316: 
                    317:       for (i = 0; i < nwords; i++)
                    318:        {
                    319:          /* If I is 0, use the low-order word in both field and target;
                    320:             if I is 1, use the next to lowest word; and so on.  */
1.1.1.7 ! root      321:          int wordnum = (backwards ? nwords - i - 1 : i);
        !           322:          int bit_offset = (backwards
1.1       root      323:                            ? MAX (bitsize - (i + 1) * BITS_PER_WORD, 0)
                    324:                            : i * BITS_PER_WORD);
                    325:          store_bit_field (op0, MIN (BITS_PER_WORD,
                    326:                                     bitsize - i * BITS_PER_WORD),
                    327:                           bitnum + bit_offset, word_mode,
1.1.1.6   root      328:                           operand_subword_force (value, wordnum,
                    329:                                                  (GET_MODE (value) == VOIDmode
                    330:                                                   ? fieldmode
                    331:                                                   : GET_MODE (value))),
1.1       root      332:                           align, total_size);
                    333:        }
                    334:       return value;
                    335:     }
                    336: 
                    337:   /* From here on we can assume that the field to be stored in is
                    338:      a full-word (whatever type that is), since it is shorter than a word.  */
                    339: 
                    340:   /* OFFSET is the number of words or bytes (UNIT says which)
                    341:      from STR_RTX to the first word or byte containing part of the field.  */
                    342: 
                    343:   if (GET_CODE (op0) == REG)
                    344:     {
                    345:       if (offset != 0
                    346:          || GET_MODE_SIZE (GET_MODE (op0)) > UNITS_PER_WORD)
                    347:        op0 = gen_rtx (SUBREG, TYPE_MODE (type_for_size (BITS_PER_WORD, 0)),
                    348:                       op0, offset);
                    349:       offset = 0;
                    350:     }
                    351:   else
                    352:     {
                    353:       op0 = protect_from_queue (op0, 1);
                    354:     }
                    355: 
1.1.1.7 ! root      356:   /* If VALUE is a floating-point mode, access it as an integer of the
        !           357:      corresponding size.  This can occur on a machine with 64 bit registers
        !           358:      that uses SFmode for float.  This can also occur for unaligned float
        !           359:      structure fields.  */
        !           360:   if (GET_MODE_CLASS (GET_MODE (value)) == MODE_FLOAT)
        !           361:     {
        !           362:       if (GET_CODE (value) != REG)
        !           363:        value = copy_to_reg (value);
        !           364:       value = gen_rtx (SUBREG, word_mode, value, 0);
        !           365:     }
        !           366: 
1.1       root      367:   /* Now OFFSET is nonzero only if OP0 is memory
                    368:      and is therefore always measured in bytes.  */
                    369: 
                    370: #ifdef HAVE_insv
                    371:   if (HAVE_insv
                    372:       && !(bitsize == 1 && GET_CODE (value) == CONST_INT)
                    373:       /* Ensure insv's size is wide enough for this field.  */
                    374:       && (GET_MODE_BITSIZE (insn_operand_mode[(int) CODE_FOR_insv][3])
1.1.1.7 ! root      375:          >= bitsize)
        !           376:       && ! ((GET_CODE (op0) == REG || GET_CODE (op0) == SUBREG)
        !           377:            && (bitsize + bitpos
        !           378:                > GET_MODE_BITSIZE (insn_operand_mode[(int) CODE_FOR_insv][3]))))
1.1       root      379:     {
                    380:       int xbitpos = bitpos;
                    381:       rtx value1;
                    382:       rtx xop0 = op0;
                    383:       rtx last = get_last_insn ();
                    384:       rtx pat;
                    385:       enum machine_mode maxmode
                    386:        = insn_operand_mode[(int) CODE_FOR_insv][3];
                    387: 
                    388:       int save_volatile_ok = volatile_ok;
                    389:       volatile_ok = 1;
                    390: 
                    391:       /* If this machine's insv can only insert into a register, or if we
                    392:         are to force MEMs into a register, copy OP0 into a register and
                    393:         save it back later.  */
                    394:       if (GET_CODE (op0) == MEM
                    395:          && (flag_force_mem
                    396:              || ! ((*insn_operand_predicate[(int) CODE_FOR_insv][0])
                    397:                    (op0, VOIDmode))))
                    398:        {
                    399:          rtx tempreg;
                    400:          enum machine_mode bestmode;
                    401: 
                    402:          /* Get the mode to use for inserting into this field.  If OP0 is
                    403:             BLKmode, get the smallest mode consistent with the alignment. If
                    404:             OP0 is a non-BLKmode object that is no wider than MAXMODE, use its
                    405:             mode. Otherwise, use the smallest mode containing the field.  */
                    406: 
                    407:          if (GET_MODE (op0) == BLKmode
                    408:              || GET_MODE_SIZE (GET_MODE (op0)) > GET_MODE_SIZE (maxmode))
                    409:            bestmode
1.1.1.3   root      410:              = get_best_mode (bitsize, bitnum, align * BITS_PER_UNIT, maxmode,
                    411:                               MEM_VOLATILE_P (op0));
1.1       root      412:          else
                    413:            bestmode = GET_MODE (op0);
                    414: 
1.1.1.6   root      415:          if (bestmode == VOIDmode
                    416:              || (STRICT_ALIGNMENT && GET_MODE_SIZE (bestmode) > align))
1.1       root      417:            goto insv_loses;
                    418: 
                    419:          /* Adjust address to point to the containing unit of that mode.  */
                    420:          unit = GET_MODE_BITSIZE (bestmode);
                    421:          /* Compute offset as multiple of this unit, counting in bytes.  */
                    422:          offset = (bitnum / unit) * GET_MODE_SIZE (bestmode);
                    423:          bitpos = bitnum % unit;
                    424:          op0 = change_address (op0, bestmode, 
                    425:                                plus_constant (XEXP (op0, 0), offset));
                    426: 
                    427:          /* Fetch that unit, store the bitfield in it, then store the unit.  */
                    428:          tempreg = copy_to_reg (op0);
                    429:          store_bit_field (tempreg, bitsize, bitpos, fieldmode, value,
                    430:                           align, total_size);
                    431:          emit_move_insn (op0, tempreg);
                    432:          return value;
                    433:        }
                    434:       volatile_ok = save_volatile_ok;
                    435: 
                    436:       /* Add OFFSET into OP0's address.  */
                    437:       if (GET_CODE (xop0) == MEM)
                    438:        xop0 = change_address (xop0, byte_mode,
                    439:                               plus_constant (XEXP (xop0, 0), offset));
                    440: 
                    441:       /* If xop0 is a register, we need it in MAXMODE
                    442:         to make it acceptable to the format of insv.  */
                    443:       if (GET_CODE (xop0) == SUBREG)
1.1.1.7 ! root      444:        /* We can't just change the mode, because this might clobber op0,
        !           445:           and we will need the original value of op0 if insv fails.  */
        !           446:        xop0 = gen_rtx (SUBREG, maxmode, SUBREG_REG (xop0), SUBREG_WORD (xop0));
1.1       root      447:       if (GET_CODE (xop0) == REG && GET_MODE (xop0) != maxmode)
                    448:        xop0 = gen_rtx (SUBREG, maxmode, xop0, 0);
                    449: 
                    450:       /* On big-endian machines, we count bits from the most significant.
                    451:         If the bit field insn does not, we must invert.  */
                    452: 
                    453: #if BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN
                    454:       xbitpos = unit - bitsize - xbitpos;
                    455: #endif
                    456:       /* We have been counting XBITPOS within UNIT.
                    457:         Count instead within the size of the register.  */
                    458: #if BITS_BIG_ENDIAN
                    459:       if (GET_CODE (xop0) != MEM)
                    460:        xbitpos += GET_MODE_BITSIZE (maxmode) - unit;
                    461: #endif
                    462:       unit = GET_MODE_BITSIZE (maxmode);
                    463: 
                    464:       /* Convert VALUE to maxmode (which insv insn wants) in VALUE1.  */
                    465:       value1 = value;
                    466:       if (GET_MODE (value) != maxmode)
                    467:        {
                    468:          if (GET_MODE_BITSIZE (GET_MODE (value)) >= bitsize)
                    469:            {
                    470:              /* Optimization: Don't bother really extending VALUE
1.1.1.4   root      471:                 if it has all the bits we will actually use.  However,
                    472:                 if we must narrow it, be sure we do it correctly.  */
1.1       root      473: 
1.1.1.4   root      474:              if (GET_MODE_SIZE (GET_MODE (value)) < GET_MODE_SIZE (maxmode))
                    475:                {
                    476:                  /* Avoid making subreg of a subreg, or of a mem.  */
                    477:                  if (GET_CODE (value1) != REG)
1.1       root      478:                value1 = copy_to_reg (value1);
1.1.1.4   root      479:                  value1 = gen_rtx (SUBREG, maxmode, value1, 0);
                    480:                }
                    481:              else
                    482:                value1 = gen_lowpart (maxmode, value1);
1.1       root      483:            }
                    484:          else if (!CONSTANT_P (value))
                    485:            /* Parse phase is supposed to make VALUE's data type
                    486:               match that of the component reference, which is a type
                    487:               at least as wide as the field; so VALUE should have
                    488:               a mode that corresponds to that type.  */
                    489:            abort ();
                    490:        }
                    491: 
                    492:       /* If this machine's insv insists on a register,
                    493:         get VALUE1 into a register.  */
                    494:       if (! ((*insn_operand_predicate[(int) CODE_FOR_insv][3])
                    495:             (value1, maxmode)))
                    496:        value1 = force_reg (maxmode, value1);
                    497: 
1.1.1.4   root      498:       pat = gen_insv (xop0, GEN_INT (bitsize), GEN_INT (xbitpos), value1);
1.1       root      499:       if (pat)
                    500:        emit_insn (pat);
                    501:       else
                    502:         {
                    503:          delete_insns_since (last);
                    504:          store_fixed_bit_field (op0, offset, bitsize, bitpos, value, align);
                    505:        }
                    506:     }
                    507:   else
                    508:     insv_loses:
                    509: #endif
                    510:     /* Insv is not available; store using shifts and boolean ops.  */
                    511:     store_fixed_bit_field (op0, offset, bitsize, bitpos, value, align);
                    512:   return value;
                    513: }
                    514: 
                    515: /* Use shifts and boolean operations to store VALUE
                    516:    into a bit field of width BITSIZE
                    517:    in a memory location specified by OP0 except offset by OFFSET bytes.
                    518:      (OFFSET must be 0 if OP0 is a register.)
                    519:    The field starts at position BITPOS within the byte.
                    520:     (If OP0 is a register, it may be a full word or a narrower mode,
                    521:      but BITPOS still counts within a full word,
                    522:      which is significant on bigendian machines.)
                    523:    STRUCT_ALIGN is the alignment the structure is known to have (in bytes).
                    524: 
                    525:    Note that protect_from_queue has already been done on OP0 and VALUE.  */
                    526: 
                    527: static void
                    528: store_fixed_bit_field (op0, offset, bitsize, bitpos, value, struct_align)
                    529:      register rtx op0;
                    530:      register int offset, bitsize, bitpos;
                    531:      register rtx value;
                    532:      int struct_align;
                    533: {
                    534:   register enum machine_mode mode;
                    535:   int total_bits = BITS_PER_WORD;
                    536:   rtx subtarget, temp;
                    537:   int all_zero = 0;
                    538:   int all_one = 0;
                    539: 
                    540:   /* There is a case not handled here:
                    541:      a structure with a known alignment of just a halfword
                    542:      and a field split across two aligned halfwords within the structure.
                    543:      Or likewise a structure with a known alignment of just a byte
                    544:      and a field split across two bytes.
                    545:      Such cases are not supposed to be able to occur.  */
                    546: 
                    547:   if (GET_CODE (op0) == REG || GET_CODE (op0) == SUBREG)
                    548:     {
                    549:       if (offset != 0)
                    550:        abort ();
                    551:       /* Special treatment for a bit field split across two registers.  */
                    552:       if (bitsize + bitpos > BITS_PER_WORD)
                    553:        {
1.1.1.6   root      554:          store_split_bit_field (op0, bitsize, bitpos,
                    555:                                 value, BITS_PER_WORD);
1.1       root      556:          return;
                    557:        }
                    558:     }
                    559:   else
                    560:     {
                    561:       /* Get the proper mode to use for this field.  We want a mode that
                    562:         includes the entire field.  If such a mode would be larger than
                    563:         a word, we won't be doing the extraction the normal way.  */
                    564: 
                    565:       mode = get_best_mode (bitsize, bitpos + offset * BITS_PER_UNIT,
                    566:                            struct_align * BITS_PER_UNIT, word_mode,
                    567:                            GET_CODE (op0) == MEM && MEM_VOLATILE_P (op0));
                    568: 
                    569:       if (mode == VOIDmode)
                    570:        {
                    571:          /* The only way this should occur is if the field spans word
                    572:             boundaries.  */
1.1.1.6   root      573:          store_split_bit_field (op0,
                    574:                                 bitsize, bitpos + offset * BITS_PER_UNIT,
1.1       root      575:                                 value, struct_align);
                    576:          return;
                    577:        }
                    578: 
                    579:       total_bits = GET_MODE_BITSIZE (mode);
                    580: 
1.1.1.7 ! root      581:       /* Make sure bitpos is valid for the chosen mode.  Adjust BITPOS to
        !           582:         be be in the range 0 to total_bits-1, and put any excess bytes in
        !           583:         OFFSET.  */
        !           584:       if (bitpos >= total_bits)
        !           585:        {
        !           586:          offset += (bitpos / total_bits) * (total_bits / BITS_PER_UNIT);
        !           587:          bitpos -= ((bitpos / total_bits) * (total_bits / BITS_PER_UNIT)
        !           588:                     * BITS_PER_UNIT);
        !           589:        }
        !           590: 
1.1       root      591:       /* Get ref to an aligned byte, halfword, or word containing the field.
                    592:         Adjust BITPOS to be position within a word,
                    593:         and OFFSET to be the offset of that word.
                    594:         Then alter OP0 to refer to that word.  */
                    595:       bitpos += (offset % (total_bits / BITS_PER_UNIT)) * BITS_PER_UNIT;
                    596:       offset -= (offset % (total_bits / BITS_PER_UNIT));
                    597:       op0 = change_address (op0, mode,
                    598:                            plus_constant (XEXP (op0, 0), offset));
                    599:     }
                    600: 
                    601:   mode = GET_MODE (op0);
                    602: 
                    603:   /* Now MODE is either some integral mode for a MEM as OP0,
                    604:      or is a full-word for a REG as OP0.  TOTAL_BITS corresponds.
                    605:      The bit field is contained entirely within OP0.
                    606:      BITPOS is the starting bit number within OP0.
                    607:      (OP0's mode may actually be narrower than MODE.)  */
                    608: 
                    609: #if BYTES_BIG_ENDIAN
                    610:   /* BITPOS is the distance between our msb
                    611:      and that of the containing datum.
                    612:      Convert it to the distance from the lsb.  */
                    613: 
                    614:   bitpos = total_bits - bitsize - bitpos;
                    615: #endif
                    616:   /* Now BITPOS is always the distance between our lsb
                    617:      and that of OP0.  */
                    618: 
                    619:   /* Shift VALUE left by BITPOS bits.  If VALUE is not constant,
                    620:      we must first convert its mode to MODE.  */
                    621: 
                    622:   if (GET_CODE (value) == CONST_INT)
                    623:     {
1.1.1.4   root      624:       register HOST_WIDE_INT v = INTVAL (value);
1.1       root      625: 
1.1.1.4   root      626:       if (bitsize < HOST_BITS_PER_WIDE_INT)
                    627:        v &= ((HOST_WIDE_INT) 1 << bitsize) - 1;
1.1       root      628: 
                    629:       if (v == 0)
                    630:        all_zero = 1;
1.1.1.4   root      631:       else if ((bitsize < HOST_BITS_PER_WIDE_INT
                    632:                && v == ((HOST_WIDE_INT) 1 << bitsize) - 1)
                    633:               || (bitsize == HOST_BITS_PER_WIDE_INT && v == -1))
1.1       root      634:        all_one = 1;
                    635: 
                    636:       value = lshift_value (mode, value, bitpos, bitsize);
                    637:     }
                    638:   else
                    639:     {
                    640:       int must_and = (GET_MODE_BITSIZE (GET_MODE (value)) != bitsize
                    641:                      && bitpos + bitsize != GET_MODE_BITSIZE (mode));
                    642: 
                    643:       if (GET_MODE (value) != mode)
                    644:        {
                    645:          if ((GET_CODE (value) == REG || GET_CODE (value) == SUBREG)
                    646:              && GET_MODE_SIZE (mode) < GET_MODE_SIZE (GET_MODE (value)))
                    647:            value = gen_lowpart (mode, value);
                    648:          else
                    649:            value = convert_to_mode (mode, value, 1);
                    650:        }
                    651: 
                    652:       if (must_and)
                    653:        value = expand_binop (mode, and_optab, value,
                    654:                              mask_rtx (mode, 0, bitsize, 0),
1.1.1.4   root      655:                              NULL_RTX, 1, OPTAB_LIB_WIDEN);
1.1       root      656:       if (bitpos > 0)
                    657:        value = expand_shift (LSHIFT_EXPR, mode, value,
1.1.1.4   root      658:                              build_int_2 (bitpos, 0), NULL_RTX, 1);
1.1       root      659:     }
                    660: 
                    661:   /* Now clear the chosen bits in OP0,
                    662:      except that if VALUE is -1 we need not bother.  */
                    663: 
                    664:   subtarget = (GET_CODE (op0) == REG || ! flag_force_mem) ? op0 : 0;
                    665: 
                    666:   if (! all_one)
                    667:     {
                    668:       temp = expand_binop (mode, and_optab, op0,
                    669:                           mask_rtx (mode, bitpos, bitsize, 1),
                    670:                           subtarget, 1, OPTAB_LIB_WIDEN);
                    671:       subtarget = temp;
                    672:     }
                    673:   else
                    674:     temp = op0;
                    675: 
                    676:   /* Now logical-or VALUE into OP0, unless it is zero.  */
                    677: 
                    678:   if (! all_zero)
                    679:     temp = expand_binop (mode, ior_optab, temp, value,
                    680:                         subtarget, 1, OPTAB_LIB_WIDEN);
                    681:   if (op0 != temp)
                    682:     emit_move_insn (op0, temp);
                    683: }
                    684: 
1.1.1.6   root      685: /* Store a bit field that is split across multiple accessible memory objects.
1.1       root      686: 
1.1.1.6   root      687:    OP0 is the REG, SUBREG or MEM rtx for the first of the objects.
1.1       root      688:    BITSIZE is the field width; BITPOS the position of its first bit
                    689:    (within the word).
1.1.1.6   root      690:    VALUE is the value to store.
                    691:    ALIGN is the known alignment of OP0, measured in bytes.
                    692:    This is also the size of the memory objects to be used.
                    693: 
                    694:    This does not yet handle fields wider than BITS_PER_WORD.  */
1.1       root      695: 
                    696: static void
                    697: store_split_bit_field (op0, bitsize, bitpos, value, align)
                    698:      rtx op0;
                    699:      int bitsize, bitpos;
                    700:      rtx value;
                    701:      int align;
                    702: {
1.1.1.7 ! root      703:   int unit;
        !           704:   int bitsdone = 0;
        !           705: 
1.1.1.6   root      706:   /* Make sure UNIT isn't larger than BITS_PER_WORD, we can only handle that
                    707:      much at a time.  */
1.1.1.7 ! root      708:   if (GET_CODE (op0) == REG || GET_CODE (op0) == SUBREG)
        !           709:     unit = BITS_PER_WORD;
        !           710:   else
        !           711:     unit = MIN (align * BITS_PER_UNIT, BITS_PER_WORD);
1.1.1.6   root      712: 
                    713:   /* If VALUE is a constant other than a CONST_INT, get it into a register in
                    714:      WORD_MODE.  If we can do this using gen_lowpart_common, do so.  Note
                    715:      that VALUE might be a floating-point constant.  */
                    716:   if (CONSTANT_P (value) && GET_CODE (value) != CONST_INT)
                    717:     {
                    718:       rtx word = gen_lowpart_common (word_mode, value);
1.1       root      719: 
1.1.1.7 ! root      720:       if (word && (value != word))
1.1.1.6   root      721:        value = word;
                    722:       else
                    723:        value = gen_lowpart_common (word_mode,
                    724:                                    force_reg (GET_MODE (value), value));
                    725:     }
1.1       root      726: 
1.1.1.6   root      727:   while (bitsdone < bitsize)
                    728:     {
                    729:       int thissize;
                    730:       rtx part, word;
                    731:       int thispos;
                    732:       int offset;
1.1.1.5   root      733: 
1.1.1.6   root      734:       offset = (bitpos + bitsdone) / unit;
                    735:       thispos = (bitpos + bitsdone) % unit;
1.1.1.5   root      736: 
1.1.1.6   root      737:       /* THISSIZE must not overrun a word boundary.  Otherwise,
                    738:         store_fixed_bit_field will call us again, and we will mutually
                    739:         recurse forever.  */
                    740:       thissize = MIN (bitsize - bitsdone, BITS_PER_WORD);
                    741:       thissize = MIN (thissize, unit - thispos);
1.1       root      742: 
                    743: #if BYTES_BIG_ENDIAN
1.1.1.6   root      744:       /* Fetch successively less significant portions.  */
                    745:       if (GET_CODE (value) == CONST_INT)
                    746:        part = GEN_INT (((unsigned HOST_WIDE_INT) (INTVAL (value))
                    747:                         >> (bitsize - bitsdone - thissize))
                    748:                        & (((HOST_WIDE_INT) 1 << thissize) - 1));
                    749:       else
1.1.1.7 ! root      750:        /* The args are chosen so that the last part includes the lsb.
        !           751:           Give extract_bit_field the value it needs (with endianness
        !           752:           compensation) to fetch the piece we want.  */
1.1.1.6   root      753:        part = extract_fixed_bit_field (word_mode, value, 0, thissize,
1.1.1.7 ! root      754:                                        GET_MODE_BITSIZE (GET_MODE (value))
        !           755:                                        - bitsize + bitsdone,
1.1.1.6   root      756:                                        NULL_RTX, 1, align);
1.1       root      757: #else
1.1.1.6   root      758:       /* Fetch successively more significant portions.  */
                    759:       if (GET_CODE (value) == CONST_INT)
                    760:        part = GEN_INT (((unsigned HOST_WIDE_INT) (INTVAL (value)) >> bitsdone)
                    761:                        & (((HOST_WIDE_INT) 1 << thissize) - 1));
                    762:       else
                    763:        part = extract_fixed_bit_field (word_mode, value, 0, thissize,
                    764:                                        bitsdone, NULL_RTX, 1, align);
1.1       root      765: #endif
                    766: 
1.1.1.6   root      767:       /* If OP0 is a register, then handle OFFSET here.
1.1.1.7 ! root      768: 
        !           769:         When handling multiword bitfields, extract_bit_field may pass
        !           770:         down a word_mode SUBREG of a larger REG for a bitfield that actually
        !           771:         crosses a word boundary.  Thus, for a SUBREG, we must find
        !           772:         the current word starting from the base register.  */
        !           773:       if (GET_CODE (op0) == SUBREG)
        !           774:        {
        !           775:          word = operand_subword_force (SUBREG_REG (op0),
        !           776:                                        SUBREG_WORD (op0) + offset,
        !           777:                                        GET_MODE (SUBREG_REG (op0)));
        !           778:          offset = 0;
        !           779:        }
        !           780:       else if (GET_CODE (op0) == REG)
1.1.1.6   root      781:        {
1.1.1.7 ! root      782:          word = operand_subword_force (op0, offset, GET_MODE (op0));
1.1.1.6   root      783:          offset = 0;
                    784:        }
                    785:       else
                    786:        word = op0;
1.1       root      787: 
1.1.1.6   root      788:       /* OFFSET is in UNITs, and UNIT is in bits.
                    789:          store_fixed_bit_field wants offset in bytes.  */
                    790:       store_fixed_bit_field (word, offset * unit / BITS_PER_UNIT,
                    791:                             thissize, thispos, part, align);
                    792:       bitsdone += thissize;
                    793:     }
1.1       root      794: }
                    795: 
                    796: /* Generate code to extract a byte-field from STR_RTX
                    797:    containing BITSIZE bits, starting at BITNUM,
                    798:    and put it in TARGET if possible (if TARGET is nonzero).
                    799:    Regardless of TARGET, we return the rtx for where the value is placed.
                    800:    It may be a QUEUED.
                    801: 
                    802:    STR_RTX is the structure containing the byte (a REG or MEM).
                    803:    UNSIGNEDP is nonzero if this is an unsigned bit field.
                    804:    MODE is the natural mode of the field value once extracted.
                    805:    TMODE is the mode the caller would like the value to have;
                    806:    but the value may be returned with type MODE instead.
                    807: 
                    808:    ALIGN is the alignment that STR_RTX is known to have, measured in bytes.
                    809:    TOTAL_SIZE is the size in bytes of the containing structure,
                    810:    or -1 if varying.
                    811: 
                    812:    If a TARGET is specified and we can store in it at no extra cost,
                    813:    we do so, and return TARGET.
                    814:    Otherwise, we return a REG of mode TMODE or MODE, with TMODE preferred
                    815:    if they are equally easy.  */
                    816: 
                    817: rtx
                    818: extract_bit_field (str_rtx, bitsize, bitnum, unsignedp,
                    819:                   target, mode, tmode, align, total_size)
                    820:      rtx str_rtx;
                    821:      register int bitsize;
                    822:      int bitnum;
                    823:      int unsignedp;
                    824:      rtx target;
                    825:      enum machine_mode mode, tmode;
                    826:      int align;
                    827:      int total_size;
                    828: {
                    829:   int unit = (GET_CODE (str_rtx) == MEM) ? BITS_PER_UNIT : BITS_PER_WORD;
                    830:   register int offset = bitnum / unit;
                    831:   register int bitpos = bitnum % unit;
                    832:   register rtx op0 = str_rtx;
                    833:   rtx spec_target = target;
                    834:   rtx spec_target_subreg = 0;
                    835: 
                    836:   if (GET_CODE (str_rtx) == MEM && ! MEM_IN_STRUCT_P (str_rtx))
                    837:     abort ();
                    838: 
                    839:   /* Discount the part of the structure before the desired byte.
                    840:      We need to know how many bytes are safe to reference after it.  */
                    841:   if (total_size >= 0)
                    842:     total_size -= (bitpos / BIGGEST_ALIGNMENT
                    843:                   * (BIGGEST_ALIGNMENT / BITS_PER_UNIT));
                    844: 
                    845:   if (tmode == VOIDmode)
                    846:     tmode = mode;
                    847:   while (GET_CODE (op0) == SUBREG)
                    848:     {
                    849:       offset += SUBREG_WORD (op0);
                    850:       op0 = SUBREG_REG (op0);
                    851:     }
                    852:   
                    853: #if BYTES_BIG_ENDIAN
                    854:   /* If OP0 is a register, BITPOS must count within a word.
                    855:      But as we have it, it counts within whatever size OP0 now has.
                    856:      On a bigendian machine, these are not the same, so convert.  */
                    857:   if (GET_CODE (op0) != MEM && unit > GET_MODE_BITSIZE (GET_MODE (op0)))
                    858:     bitpos += unit - GET_MODE_BITSIZE (GET_MODE (op0));
                    859: #endif
                    860: 
                    861:   /* Extracting a full-word or multi-word value
1.1.1.6   root      862:      from a structure in a register or aligned memory.
1.1       root      863:      This can be done with just SUBREG.
                    864:      So too extracting a subword value in
                    865:      the least significant part of the register.  */
                    866: 
1.1.1.6   root      867:   if ((GET_CODE (op0) == REG
                    868:        || (GET_CODE (op0) == MEM
                    869:           && (! SLOW_UNALIGNED_ACCESS
                    870:               || (offset * BITS_PER_UNIT % bitsize == 0
                    871:                   && align * BITS_PER_UNIT % bitsize == 0))))
1.1       root      872:       && ((bitsize >= BITS_PER_WORD && bitsize == GET_MODE_BITSIZE (mode)
                    873:           && bitpos % BITS_PER_WORD == 0)
                    874:          || (mode_for_size (bitsize, GET_MODE_CLASS (tmode), 0) != BLKmode
                    875: #if BYTES_BIG_ENDIAN
                    876:              && bitpos + bitsize == BITS_PER_WORD
                    877: #else
                    878:              && bitpos == 0
                    879: #endif
                    880:              )))
                    881:     {
                    882:       enum machine_mode mode1
                    883:        = mode_for_size (bitsize, GET_MODE_CLASS (tmode), 0);
                    884: 
                    885:       if (mode1 != GET_MODE (op0))
1.1.1.6   root      886:        {
                    887:          if (GET_CODE (op0) == REG)
                    888:            op0 = gen_rtx (SUBREG, mode1, op0, offset);
                    889:          else
                    890:            op0 = change_address (op0, mode1,
                    891:                                  plus_constant (XEXP (op0, 0), offset));
                    892:        }
1.1       root      893:       if (mode1 != mode)
                    894:        return convert_to_mode (tmode, op0, unsignedp);
                    895:       return op0;
                    896:     }
                    897: 
                    898:   /* Handle fields bigger than a word.  */
                    899:   
                    900:   if (bitsize > BITS_PER_WORD)
                    901:     {
                    902:       /* Here we transfer the words of the field
                    903:         in the order least significant first.
                    904:         This is because the most significant word is the one which may
                    905:         be less than full.  */
                    906: 
                    907:       int nwords = (bitsize + (BITS_PER_WORD - 1)) / BITS_PER_WORD;
                    908:       int i;
                    909: 
                    910:       if (target == 0 || GET_CODE (target) != REG)
                    911:        target = gen_reg_rtx (mode);
                    912: 
                    913:       for (i = 0; i < nwords; i++)
                    914:        {
                    915:          /* If I is 0, use the low-order word in both field and target;
                    916:             if I is 1, use the next to lowest word; and so on.  */
                    917:          int wordnum = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i);
                    918:          int bit_offset = (WORDS_BIG_ENDIAN
                    919:                            ? MAX (0, bitsize - (i + 1) * BITS_PER_WORD)
                    920:                            : i * BITS_PER_WORD);
                    921:          rtx target_part = operand_subword (target, wordnum, 1, VOIDmode);
                    922:          rtx result_part
                    923:            = extract_bit_field (op0, MIN (BITS_PER_WORD,
                    924:                                           bitsize - i * BITS_PER_WORD),
                    925:                                 bitnum + bit_offset,
                    926:                                 1, target_part, mode, word_mode,
                    927:                                 align, total_size);
                    928: 
                    929:          if (target_part == 0)
                    930:            abort ();
                    931: 
                    932:          if (result_part != target_part)
                    933:            emit_move_insn (target_part, result_part);
                    934:        }
                    935: 
1.1.1.7 ! root      936:       if (unsignedp)
        !           937:        return target;
        !           938:       /* Signed bit field: sign-extend with two arithmetic shifts.  */
        !           939:       target = expand_shift (LSHIFT_EXPR, mode, target,
        !           940:                             build_int_2 (GET_MODE_BITSIZE (mode) - bitsize, 0),
        !           941:                             NULL_RTX, 0);
        !           942:       return expand_shift (RSHIFT_EXPR, mode, target,
        !           943:                           build_int_2 (GET_MODE_BITSIZE (mode) - bitsize, 0),
        !           944:                           NULL_RTX, 0);
1.1       root      945:     }
                    946:   
                    947:   /* From here on we know the desired field is smaller than a word
                    948:      so we can assume it is an integer.  So we can safely extract it as one
                    949:      size of integer, if necessary, and then truncate or extend
                    950:      to the size that is wanted.  */
                    951: 
                    952:   /* OFFSET is the number of words or bytes (UNIT says which)
                    953:      from STR_RTX to the first word or byte containing part of the field.  */
                    954: 
                    955:   if (GET_CODE (op0) == REG)
                    956:     {
                    957:       if (offset != 0
                    958:          || GET_MODE_SIZE (GET_MODE (op0)) > UNITS_PER_WORD)
                    959:        op0 = gen_rtx (SUBREG, TYPE_MODE (type_for_size (BITS_PER_WORD, 0)),
                    960:                       op0, offset);
                    961:       offset = 0;
                    962:     }
                    963:   else
                    964:     {
                    965:       op0 = protect_from_queue (str_rtx, 1);
                    966:     }
                    967: 
                    968:   /* Now OFFSET is nonzero only for memory operands.  */
                    969: 
                    970:   if (unsignedp)
                    971:     {
                    972: #ifdef HAVE_extzv
                    973:       if (HAVE_extzv
                    974:          && (GET_MODE_BITSIZE (insn_operand_mode[(int) CODE_FOR_extzv][0])
1.1.1.7 ! root      975:              >= bitsize)
        !           976:          && ! ((GET_CODE (op0) == REG || GET_CODE (op0) == SUBREG)
        !           977:                && (bitsize + bitpos
        !           978:                    > GET_MODE_BITSIZE (insn_operand_mode[(int) CODE_FOR_extzv][0]))))
1.1       root      979:        {
                    980:          int xbitpos = bitpos, xoffset = offset;
                    981:          rtx bitsize_rtx, bitpos_rtx;
                    982:          rtx last = get_last_insn();
                    983:          rtx xop0 = op0;
                    984:          rtx xtarget = target;
                    985:          rtx xspec_target = spec_target;
                    986:          rtx xspec_target_subreg = spec_target_subreg;
                    987:          rtx pat;
                    988:          enum machine_mode maxmode
                    989:            = insn_operand_mode[(int) CODE_FOR_extzv][0];
                    990: 
                    991:          if (GET_CODE (xop0) == MEM)
                    992:            {
                    993:              int save_volatile_ok = volatile_ok;
                    994:              volatile_ok = 1;
                    995: 
                    996:              /* Is the memory operand acceptable?  */
                    997:              if (flag_force_mem
                    998:                  || ! ((*insn_operand_predicate[(int) CODE_FOR_extzv][1])
                    999:                        (xop0, GET_MODE (xop0))))
                   1000:                {
                   1001:                  /* No, load into a reg and extract from there.  */
                   1002:                  enum machine_mode bestmode;
                   1003: 
                   1004:                  /* Get the mode to use for inserting into this field.  If
                   1005:                     OP0 is BLKmode, get the smallest mode consistent with the
                   1006:                     alignment. If OP0 is a non-BLKmode object that is no
                   1007:                     wider than MAXMODE, use its mode. Otherwise, use the
                   1008:                     smallest mode containing the field.  */
                   1009: 
                   1010:                  if (GET_MODE (xop0) == BLKmode
                   1011:                      || (GET_MODE_SIZE (GET_MODE (op0))
                   1012:                          > GET_MODE_SIZE (maxmode)))
                   1013:                    bestmode = get_best_mode (bitsize, bitnum,
                   1014:                                              align * BITS_PER_UNIT, maxmode,
1.1.1.3   root     1015:                                              MEM_VOLATILE_P (xop0));
1.1       root     1016:                  else
                   1017:                    bestmode = GET_MODE (xop0);
                   1018: 
1.1.1.6   root     1019:                  if (bestmode == VOIDmode
                   1020:                      || (STRICT_ALIGNMENT && GET_MODE_SIZE (bestmode) > align))
1.1       root     1021:                    goto extzv_loses;
                   1022: 
                   1023:                  /* Compute offset as multiple of this unit,
                   1024:                     counting in bytes.  */
                   1025:                  unit = GET_MODE_BITSIZE (bestmode);
                   1026:                  xoffset = (bitnum / unit) * GET_MODE_SIZE (bestmode);
                   1027:                  xbitpos = bitnum % unit;
                   1028:                  xop0 = change_address (xop0, bestmode,
                   1029:                                         plus_constant (XEXP (xop0, 0),
                   1030:                                                        xoffset));
                   1031:                  /* Fetch it to a register in that size.  */
                   1032:                  xop0 = force_reg (bestmode, xop0);
                   1033: 
                   1034:                  /* XBITPOS counts within UNIT, which is what is expected.  */
                   1035:                }
                   1036:              else
                   1037:                /* Get ref to first byte containing part of the field.  */
                   1038:                xop0 = change_address (xop0, byte_mode,
                   1039:                                       plus_constant (XEXP (xop0, 0), xoffset));
                   1040: 
                   1041:              volatile_ok = save_volatile_ok;
                   1042:            }
                   1043: 
                   1044:          /* If op0 is a register, we need it in MAXMODE (which is usually
                   1045:             SImode). to make it acceptable to the format of extzv.  */
                   1046:          if (GET_CODE (xop0) == SUBREG && GET_MODE (xop0) != maxmode)
                   1047:            abort ();
                   1048:          if (GET_CODE (xop0) == REG && GET_MODE (xop0) != maxmode)
                   1049:            xop0 = gen_rtx (SUBREG, maxmode, xop0, 0);
                   1050: 
                   1051:          /* On big-endian machines, we count bits from the most significant.
                   1052:             If the bit field insn does not, we must invert.  */
                   1053: #if BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN
                   1054:          xbitpos = unit - bitsize - xbitpos;
                   1055: #endif
                   1056:          /* Now convert from counting within UNIT to counting in MAXMODE.  */
                   1057: #if BITS_BIG_ENDIAN
                   1058:          if (GET_CODE (xop0) != MEM)
                   1059:            xbitpos += GET_MODE_BITSIZE (maxmode) - unit;
                   1060: #endif
                   1061:          unit = GET_MODE_BITSIZE (maxmode);
                   1062: 
                   1063:          if (xtarget == 0
                   1064:              || (flag_force_mem && GET_CODE (xtarget) == MEM))
                   1065:            xtarget = xspec_target = gen_reg_rtx (tmode);
                   1066: 
                   1067:          if (GET_MODE (xtarget) != maxmode)
                   1068:            {
                   1069:              if (GET_CODE (xtarget) == REG)
1.1.1.3   root     1070:                {
                   1071:                  int wider = (GET_MODE_SIZE (maxmode)
                   1072:                               > GET_MODE_SIZE (GET_MODE (xtarget)));
                   1073:                  xtarget = gen_lowpart (maxmode, xtarget);
                   1074:                  if (wider)
                   1075:                    xspec_target_subreg = xtarget;
                   1076:                }
1.1       root     1077:              else
                   1078:                xtarget = gen_reg_rtx (maxmode);
                   1079:            }
                   1080: 
                   1081:          /* If this machine's extzv insists on a register target,
                   1082:             make sure we have one.  */
                   1083:          if (! ((*insn_operand_predicate[(int) CODE_FOR_extzv][0])
                   1084:                 (xtarget, maxmode)))
                   1085:            xtarget = gen_reg_rtx (maxmode);
                   1086: 
1.1.1.4   root     1087:          bitsize_rtx = GEN_INT (bitsize);
                   1088:          bitpos_rtx = GEN_INT (xbitpos);
1.1       root     1089: 
                   1090:          pat = gen_extzv (protect_from_queue (xtarget, 1),
                   1091:                           xop0, bitsize_rtx, bitpos_rtx);
                   1092:          if (pat)
                   1093:            {
                   1094:              emit_insn (pat);
                   1095:              target = xtarget;
                   1096:              spec_target = xspec_target;
                   1097:              spec_target_subreg = xspec_target_subreg;
                   1098:            }
                   1099:          else
                   1100:            {
                   1101:              delete_insns_since (last);
                   1102:              target = extract_fixed_bit_field (tmode, op0, offset, bitsize,
                   1103:                                                bitpos, target, 1, align);
                   1104:            }
                   1105:        }
                   1106:       else
                   1107:         extzv_loses:
                   1108: #endif
                   1109:        target = extract_fixed_bit_field (tmode, op0, offset, bitsize, bitpos,
                   1110:                                          target, 1, align);
                   1111:     }
                   1112:   else
                   1113:     {
                   1114: #ifdef HAVE_extv
                   1115:       if (HAVE_extv
                   1116:          && (GET_MODE_BITSIZE (insn_operand_mode[(int) CODE_FOR_extv][0])
1.1.1.7 ! root     1117:              >= bitsize)
        !          1118:          && ! ((GET_CODE (op0) == REG || GET_CODE (op0) == SUBREG)
        !          1119:                && (bitsize + bitpos
        !          1120:                    > GET_MODE_BITSIZE (insn_operand_mode[(int) CODE_FOR_extv][0]))))
1.1       root     1121:        {
                   1122:          int xbitpos = bitpos, xoffset = offset;
                   1123:          rtx bitsize_rtx, bitpos_rtx;
                   1124:          rtx last = get_last_insn();
                   1125:          rtx xop0 = op0, xtarget = target;
                   1126:          rtx xspec_target = spec_target;
                   1127:          rtx xspec_target_subreg = spec_target_subreg;
                   1128:          rtx pat;
                   1129:          enum machine_mode maxmode
                   1130:            = insn_operand_mode[(int) CODE_FOR_extv][0];
                   1131: 
                   1132:          if (GET_CODE (xop0) == MEM)
                   1133:            {
                   1134:              /* Is the memory operand acceptable?  */
                   1135:              if (! ((*insn_operand_predicate[(int) CODE_FOR_extv][1])
                   1136:                     (xop0, GET_MODE (xop0))))
                   1137:                {
                   1138:                  /* No, load into a reg and extract from there.  */
                   1139:                  enum machine_mode bestmode;
                   1140: 
                   1141:                  /* Get the mode to use for inserting into this field.  If
                   1142:                     OP0 is BLKmode, get the smallest mode consistent with the
                   1143:                     alignment. If OP0 is a non-BLKmode object that is no
                   1144:                     wider than MAXMODE, use its mode. Otherwise, use the
                   1145:                     smallest mode containing the field.  */
                   1146: 
                   1147:                  if (GET_MODE (xop0) == BLKmode
                   1148:                      || (GET_MODE_SIZE (GET_MODE (op0))
                   1149:                          > GET_MODE_SIZE (maxmode)))
                   1150:                    bestmode = get_best_mode (bitsize, bitnum,
                   1151:                                              align * BITS_PER_UNIT, maxmode,
1.1.1.3   root     1152:                                              MEM_VOLATILE_P (xop0));
1.1       root     1153:                  else
                   1154:                    bestmode = GET_MODE (xop0);
                   1155: 
1.1.1.6   root     1156:                  if (bestmode == VOIDmode
                   1157:                      || (STRICT_ALIGNMENT && GET_MODE_SIZE (bestmode) > align))
1.1       root     1158:                    goto extv_loses;
                   1159: 
                   1160:                  /* Compute offset as multiple of this unit,
                   1161:                     counting in bytes.  */
                   1162:                  unit = GET_MODE_BITSIZE (bestmode);
                   1163:                  xoffset = (bitnum / unit) * GET_MODE_SIZE (bestmode);
                   1164:                  xbitpos = bitnum % unit;
                   1165:                  xop0 = change_address (xop0, bestmode,
                   1166:                                         plus_constant (XEXP (xop0, 0),
                   1167:                                                        xoffset));
                   1168:                  /* Fetch it to a register in that size.  */
                   1169:                  xop0 = force_reg (bestmode, xop0);
                   1170: 
                   1171:                  /* XBITPOS counts within UNIT, which is what is expected.  */
                   1172:                }
                   1173:              else
                   1174:                /* Get ref to first byte containing part of the field.  */
                   1175:                xop0 = change_address (xop0, byte_mode,
                   1176:                                       plus_constant (XEXP (xop0, 0), xoffset));
                   1177:            }
                   1178: 
                   1179:          /* If op0 is a register, we need it in MAXMODE (which is usually
                   1180:             SImode) to make it acceptable to the format of extv.  */
                   1181:          if (GET_CODE (xop0) == SUBREG && GET_MODE (xop0) != maxmode)
                   1182:            abort ();
                   1183:          if (GET_CODE (xop0) == REG && GET_MODE (xop0) != maxmode)
                   1184:            xop0 = gen_rtx (SUBREG, maxmode, xop0, 0);
                   1185: 
                   1186:          /* On big-endian machines, we count bits from the most significant.
                   1187:             If the bit field insn does not, we must invert.  */
                   1188: #if BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN
                   1189:          xbitpos = unit - bitsize - xbitpos;
                   1190: #endif
                   1191:          /* XBITPOS counts within a size of UNIT.
                   1192:             Adjust to count within a size of MAXMODE.  */
                   1193: #if BITS_BIG_ENDIAN
                   1194:          if (GET_CODE (xop0) != MEM)
                   1195:            xbitpos += (GET_MODE_BITSIZE (maxmode) - unit);
                   1196: #endif
                   1197:          unit = GET_MODE_BITSIZE (maxmode);
                   1198: 
                   1199:          if (xtarget == 0
                   1200:              || (flag_force_mem && GET_CODE (xtarget) == MEM))
                   1201:            xtarget = xspec_target = gen_reg_rtx (tmode);
                   1202: 
                   1203:          if (GET_MODE (xtarget) != maxmode)
                   1204:            {
                   1205:              if (GET_CODE (xtarget) == REG)
1.1.1.3   root     1206:                {
                   1207:                  int wider = (GET_MODE_SIZE (maxmode)
                   1208:                               > GET_MODE_SIZE (GET_MODE (xtarget)));
                   1209:                  xtarget = gen_lowpart (maxmode, xtarget);
                   1210:                  if (wider)
                   1211:                    xspec_target_subreg = xtarget;
                   1212:                }
1.1       root     1213:              else
                   1214:                xtarget = gen_reg_rtx (maxmode);
                   1215:            }
                   1216: 
                   1217:          /* If this machine's extv insists on a register target,
                   1218:             make sure we have one.  */
                   1219:          if (! ((*insn_operand_predicate[(int) CODE_FOR_extv][0])
                   1220:                 (xtarget, maxmode)))
                   1221:            xtarget = gen_reg_rtx (maxmode);
                   1222: 
1.1.1.4   root     1223:          bitsize_rtx = GEN_INT (bitsize);
                   1224:          bitpos_rtx = GEN_INT (xbitpos);
1.1       root     1225: 
                   1226:          pat = gen_extv (protect_from_queue (xtarget, 1),
                   1227:                          xop0, bitsize_rtx, bitpos_rtx);
                   1228:          if (pat)
                   1229:            {
                   1230:              emit_insn (pat);
                   1231:              target = xtarget;
                   1232:              spec_target = xspec_target;
                   1233:              spec_target_subreg = xspec_target_subreg;
                   1234:            }
                   1235:          else
                   1236:            {
                   1237:              delete_insns_since (last);
                   1238:              target = extract_fixed_bit_field (tmode, op0, offset, bitsize,
                   1239:                                                bitpos, target, 0, align);
                   1240:            }
                   1241:        } 
                   1242:       else
                   1243:        extv_loses:
                   1244: #endif
                   1245:        target = extract_fixed_bit_field (tmode, op0, offset, bitsize, bitpos,
                   1246:                                          target, 0, align);
                   1247:     }
                   1248:   if (target == spec_target)
                   1249:     return target;
                   1250:   if (target == spec_target_subreg)
                   1251:     return spec_target;
                   1252:   if (GET_MODE (target) != tmode && GET_MODE (target) != mode)
                   1253:     {
                   1254:       /* If the target mode is floating-point, first convert to the
                   1255:         integer mode of that size and then access it as a floating-point
                   1256:         value via a SUBREG.  */
                   1257:       if (GET_MODE_CLASS (tmode) == MODE_FLOAT)
                   1258:        {
                   1259:          target = convert_to_mode (mode_for_size (GET_MODE_BITSIZE (tmode),
                   1260:                                                   MODE_INT, 0),
                   1261:                                    target, unsignedp);
                   1262:          if (GET_CODE (target) != REG)
                   1263:            target = copy_to_reg (target);
                   1264:          return gen_rtx (SUBREG, tmode, target, 0);
                   1265:        }
                   1266:       else
                   1267:        return convert_to_mode (tmode, target, unsignedp);
                   1268:     }
                   1269:   return target;
                   1270: }
                   1271: 
                   1272: /* Extract a bit field using shifts and boolean operations
                   1273:    Returns an rtx to represent the value.
                   1274:    OP0 addresses a register (word) or memory (byte).
                   1275:    BITPOS says which bit within the word or byte the bit field starts in.
                   1276:    OFFSET says how many bytes farther the bit field starts;
                   1277:     it is 0 if OP0 is a register.
                   1278:    BITSIZE says how many bits long the bit field is.
                   1279:     (If OP0 is a register, it may be narrower than a full word,
                   1280:      but BITPOS still counts within a full word,
                   1281:      which is significant on bigendian machines.)
                   1282: 
                   1283:    UNSIGNEDP is nonzero for an unsigned bit field (don't sign-extend value).
                   1284:    If TARGET is nonzero, attempts to store the value there
                   1285:    and return TARGET, but this is not guaranteed.
                   1286:    If TARGET is not used, create a pseudo-reg of mode TMODE for the value.
                   1287: 
                   1288:    ALIGN is the alignment that STR_RTX is known to have, measured in bytes.  */
                   1289: 
                   1290: static rtx
                   1291: extract_fixed_bit_field (tmode, op0, offset, bitsize, bitpos,
                   1292:                         target, unsignedp, align)
                   1293:      enum machine_mode tmode;
                   1294:      register rtx op0, target;
                   1295:      register int offset, bitsize, bitpos;
                   1296:      int unsignedp;
                   1297:      int align;
                   1298: {
                   1299:   int total_bits = BITS_PER_WORD;
                   1300:   enum machine_mode mode;
                   1301: 
                   1302:   if (GET_CODE (op0) == SUBREG || GET_CODE (op0) == REG)
                   1303:     {
                   1304:       /* Special treatment for a bit field split across two registers.  */
                   1305:       if (bitsize + bitpos > BITS_PER_WORD)
                   1306:        return extract_split_bit_field (op0, bitsize, bitpos,
                   1307:                                        unsignedp, align);
                   1308:     }
                   1309:   else
                   1310:     {
                   1311:       /* Get the proper mode to use for this field.  We want a mode that
                   1312:         includes the entire field.  If such a mode would be larger than
                   1313:         a word, we won't be doing the extraction the normal way.  */
                   1314: 
                   1315:       mode = get_best_mode (bitsize, bitpos + offset * BITS_PER_UNIT,
                   1316:                            align * BITS_PER_UNIT, word_mode,
                   1317:                            GET_CODE (op0) == MEM && MEM_VOLATILE_P (op0));
                   1318: 
                   1319:       if (mode == VOIDmode)
                   1320:        /* The only way this should occur is if the field spans word
                   1321:           boundaries.  */
                   1322:        return extract_split_bit_field (op0, bitsize,
                   1323:                                        bitpos + offset * BITS_PER_UNIT,
                   1324:                                        unsignedp, align);
                   1325: 
                   1326:       total_bits = GET_MODE_BITSIZE (mode);
                   1327: 
1.1.1.5   root     1328:       /* Make sure bitpos is valid for the chosen mode.  Adjust BITPOS to
                   1329:         be be in the range 0 to total_bits-1, and put any excess bytes in
                   1330:         OFFSET.  */
                   1331:       if (bitpos >= total_bits)
                   1332:        {
                   1333:          offset += (bitpos / total_bits) * (total_bits / BITS_PER_UNIT);
                   1334:          bitpos -= ((bitpos / total_bits) * (total_bits / BITS_PER_UNIT)
                   1335:                     * BITS_PER_UNIT);
                   1336:        }
                   1337: 
1.1       root     1338:       /* Get ref to an aligned byte, halfword, or word containing the field.
                   1339:         Adjust BITPOS to be position within a word,
                   1340:         and OFFSET to be the offset of that word.
                   1341:         Then alter OP0 to refer to that word.  */
                   1342:       bitpos += (offset % (total_bits / BITS_PER_UNIT)) * BITS_PER_UNIT;
                   1343:       offset -= (offset % (total_bits / BITS_PER_UNIT));
                   1344:       op0 = change_address (op0, mode,
                   1345:                            plus_constant (XEXP (op0, 0), offset));
                   1346:     }
                   1347: 
                   1348:   mode = GET_MODE (op0);
                   1349: 
                   1350: #if BYTES_BIG_ENDIAN
                   1351:   /* BITPOS is the distance between our msb and that of OP0.
                   1352:      Convert it to the distance from the lsb.  */
                   1353: 
                   1354:   bitpos = total_bits - bitsize - bitpos;
                   1355: #endif
                   1356:   /* Now BITPOS is always the distance between the field's lsb and that of OP0.
                   1357:      We have reduced the big-endian case to the little-endian case.  */
                   1358: 
                   1359:   if (unsignedp)
                   1360:     {
                   1361:       if (bitpos)
                   1362:        {
                   1363:          /* If the field does not already start at the lsb,
                   1364:             shift it so it does.  */
                   1365:          tree amount = build_int_2 (bitpos, 0);
                   1366:          /* Maybe propagate the target for the shift.  */
                   1367:          /* But not if we will return it--could confuse integrate.c.  */
                   1368:          rtx subtarget = (target != 0 && GET_CODE (target) == REG
                   1369:                           && !REG_FUNCTION_VALUE_P (target)
                   1370:                           ? target : 0);
                   1371:          if (tmode != mode) subtarget = 0;
                   1372:          op0 = expand_shift (RSHIFT_EXPR, mode, op0, amount, subtarget, 1);
                   1373:        }
                   1374:       /* Convert the value to the desired mode.  */
                   1375:       if (mode != tmode)
                   1376:        op0 = convert_to_mode (tmode, op0, 1);
                   1377: 
                   1378:       /* Unless the msb of the field used to be the msb when we shifted,
                   1379:         mask out the upper bits.  */
                   1380: 
                   1381:       if (GET_MODE_BITSIZE (mode) != bitpos + bitsize
                   1382: #if 0
                   1383: #ifdef SLOW_ZERO_EXTEND
                   1384:          /* Always generate an `and' if
                   1385:             we just zero-extended op0 and SLOW_ZERO_EXTEND, since it
                   1386:             will combine fruitfully with the zero-extend. */
                   1387:          || tmode != mode
                   1388: #endif
                   1389: #endif
                   1390:          )
                   1391:        return expand_binop (GET_MODE (op0), and_optab, op0,
                   1392:                             mask_rtx (GET_MODE (op0), 0, bitsize, 0),
                   1393:                             target, 1, OPTAB_LIB_WIDEN);
                   1394:       return op0;
                   1395:     }
                   1396: 
                   1397:   /* To extract a signed bit-field, first shift its msb to the msb of the word,
                   1398:      then arithmetic-shift its lsb to the lsb of the word.  */
                   1399:   op0 = force_reg (mode, op0);
                   1400:   if (mode != tmode)
                   1401:     target = 0;
                   1402: 
                   1403:   /* Find the narrowest integer mode that contains the field.  */
                   1404: 
                   1405:   for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT); mode != VOIDmode;
                   1406:        mode = GET_MODE_WIDER_MODE (mode))
                   1407:     if (GET_MODE_BITSIZE (mode) >= bitsize + bitpos)
                   1408:       {
                   1409:        op0 = convert_to_mode (mode, op0, 0);
                   1410:        break;
                   1411:       }
                   1412: 
                   1413:   if (GET_MODE_BITSIZE (mode) != (bitsize + bitpos))
                   1414:     {
                   1415:       tree amount = build_int_2 (GET_MODE_BITSIZE (mode) - (bitsize + bitpos), 0);
                   1416:       /* Maybe propagate the target for the shift.  */
                   1417:       /* But not if we will return the result--could confuse integrate.c.  */
                   1418:       rtx subtarget = (target != 0 && GET_CODE (target) == REG
                   1419:                       && ! REG_FUNCTION_VALUE_P (target)
                   1420:                       ? target : 0);
                   1421:       op0 = expand_shift (LSHIFT_EXPR, mode, op0, amount, subtarget, 1);
                   1422:     }
                   1423: 
                   1424:   return expand_shift (RSHIFT_EXPR, mode, op0,
                   1425:                       build_int_2 (GET_MODE_BITSIZE (mode) - bitsize, 0), 
                   1426:                       target, 0);
                   1427: }
                   1428: 
                   1429: /* Return a constant integer (CONST_INT or CONST_DOUBLE) mask value
                   1430:    of mode MODE with BITSIZE ones followed by BITPOS zeros, or the
                   1431:    complement of that if COMPLEMENT.  The mask is truncated if
                   1432:    necessary to the width of mode MODE.  */
                   1433: 
                   1434: static rtx
                   1435: mask_rtx (mode, bitpos, bitsize, complement)
                   1436:      enum machine_mode mode;
                   1437:      int bitpos, bitsize, complement;
                   1438: {
1.1.1.4   root     1439:   HOST_WIDE_INT masklow, maskhigh;
1.1       root     1440: 
1.1.1.4   root     1441:   if (bitpos < HOST_BITS_PER_WIDE_INT)
                   1442:     masklow = (HOST_WIDE_INT) -1 << bitpos;
1.1       root     1443:   else
                   1444:     masklow = 0;
                   1445: 
1.1.1.4   root     1446:   if (bitpos + bitsize < HOST_BITS_PER_WIDE_INT)
                   1447:     masklow &= ((unsigned HOST_WIDE_INT) -1
                   1448:                >> (HOST_BITS_PER_WIDE_INT - bitpos - bitsize));
1.1       root     1449:   
1.1.1.4   root     1450:   if (bitpos <= HOST_BITS_PER_WIDE_INT)
1.1       root     1451:     maskhigh = -1;
                   1452:   else
1.1.1.4   root     1453:     maskhigh = (HOST_WIDE_INT) -1 << (bitpos - HOST_BITS_PER_WIDE_INT);
1.1       root     1454: 
1.1.1.4   root     1455:   if (bitpos + bitsize > HOST_BITS_PER_WIDE_INT)
                   1456:     maskhigh &= ((unsigned HOST_WIDE_INT) -1
                   1457:                 >> (2 * HOST_BITS_PER_WIDE_INT - bitpos - bitsize));
1.1       root     1458:   else
                   1459:     maskhigh = 0;
                   1460: 
                   1461:   if (complement)
                   1462:     {
                   1463:       maskhigh = ~maskhigh;
                   1464:       masklow = ~masklow;
                   1465:     }
                   1466: 
                   1467:   return immed_double_const (masklow, maskhigh, mode);
                   1468: }
                   1469: 
                   1470: /* Return a constant integer (CONST_INT or CONST_DOUBLE) rtx with the value
                   1471:    VALUE truncated to BITSIZE bits and then shifted left BITPOS bits.  */
                   1472: 
                   1473: static rtx
                   1474: lshift_value (mode, value, bitpos, bitsize)
                   1475:      enum machine_mode mode;
                   1476:      rtx value;
                   1477:      int bitpos, bitsize;
                   1478: {
1.1.1.4   root     1479:   unsigned HOST_WIDE_INT v = INTVAL (value);
                   1480:   HOST_WIDE_INT low, high;
1.1       root     1481: 
1.1.1.4   root     1482:   if (bitsize < HOST_BITS_PER_WIDE_INT)
                   1483:     v &= ~((HOST_WIDE_INT) -1 << bitsize);
1.1       root     1484: 
1.1.1.4   root     1485:   if (bitpos < HOST_BITS_PER_WIDE_INT)
1.1       root     1486:     {
                   1487:       low = v << bitpos;
1.1.1.4   root     1488:       high = (bitpos > 0 ? (v >> (HOST_BITS_PER_WIDE_INT - bitpos)) : 0);
1.1       root     1489:     }
                   1490:   else
                   1491:     {
                   1492:       low = 0;
1.1.1.4   root     1493:       high = v << (bitpos - HOST_BITS_PER_WIDE_INT);
1.1       root     1494:     }
                   1495: 
                   1496:   return immed_double_const (low, high, mode);
                   1497: }
                   1498: 
                   1499: /* Extract a bit field that is split across two words
                   1500:    and return an RTX for the result.
                   1501: 
                   1502:    OP0 is the REG, SUBREG or MEM rtx for the first of the two words.
                   1503:    BITSIZE is the field width; BITPOS, position of its first bit, in the word.
1.1.1.6   root     1504:    UNSIGNEDP is 1 if should zero-extend the contents; else sign-extend.
                   1505: 
                   1506:    ALIGN is the known alignment of OP0, measured in bytes.
                   1507:    This is also the size of the memory objects to be used.  */
1.1       root     1508: 
                   1509: static rtx
                   1510: extract_split_bit_field (op0, bitsize, bitpos, unsignedp, align)
                   1511:      rtx op0;
                   1512:      int bitsize, bitpos, unsignedp, align;
                   1513: {
1.1.1.7 ! root     1514:   int unit;
1.1.1.6   root     1515:   int bitsdone = 0;
                   1516:   rtx result;
                   1517:   int first = 1;
                   1518: 
1.1.1.7 ! root     1519:   /* Make sure UNIT isn't larger than BITS_PER_WORD, we can only handle that
        !          1520:      much at a time.  */
        !          1521:   if (GET_CODE (op0) == REG || GET_CODE (op0) == SUBREG)
        !          1522:     unit = BITS_PER_WORD;
        !          1523:   else
        !          1524:     unit = MIN (align * BITS_PER_UNIT, BITS_PER_WORD);
        !          1525: 
1.1.1.6   root     1526:   while (bitsdone < bitsize)
                   1527:     {
                   1528:       int thissize;
                   1529:       rtx part, word;
                   1530:       int thispos;
                   1531:       int offset;
                   1532: 
                   1533:       offset = (bitpos + bitsdone) / unit;
                   1534:       thispos = (bitpos + bitsdone) % unit;
                   1535: 
                   1536:       /* THISSIZE must not overrun a word boundary.  Otherwise,
                   1537:         extract_fixed_bit_field will call us again, and we will mutually
                   1538:         recurse forever.  */
                   1539:       thissize = MIN (bitsize - bitsdone, BITS_PER_WORD);
                   1540:       thissize = MIN (thissize, unit - thispos);
                   1541: 
                   1542:       /* If OP0 is a register, then handle OFFSET here.
1.1.1.7 ! root     1543: 
        !          1544:         When handling multiword bitfields, extract_bit_field may pass
        !          1545:         down a word_mode SUBREG of a larger REG for a bitfield that actually
        !          1546:         crosses a word boundary.  Thus, for a SUBREG, we must find
        !          1547:         the current word starting from the base register.  */
        !          1548:       if (GET_CODE (op0) == SUBREG)
        !          1549:        {
        !          1550:          word = operand_subword_force (SUBREG_REG (op0),
        !          1551:                                        SUBREG_WORD (op0) + offset,
        !          1552:                                        GET_MODE (SUBREG_REG (op0)));
        !          1553:          offset = 0;
        !          1554:        }
        !          1555:       else if (GET_CODE (op0) == REG)
1.1.1.6   root     1556:        {
                   1557:          word = operand_subword_force (op0, offset, GET_MODE (op0));
                   1558:          offset = 0;
                   1559:        }
                   1560:       else
                   1561:        word = op0;
1.1       root     1562: 
1.1.1.6   root     1563:       /* Extract the parts in bit-counting order,
                   1564:         whose meaning is determined by BYTES_PER_UNIT.
                   1565:         OFFSET is in UNITs, and UNIT is in bits.
                   1566:         extract_fixed_bit_field wants offset in bytes.  */
                   1567:       part = extract_fixed_bit_field (word_mode, word,
                   1568:                                      offset * unit / BITS_PER_UNIT,
                   1569:                                      thissize, thispos, 0, 1, align);
                   1570:       bitsdone += thissize;
1.1       root     1571: 
1.1.1.6   root     1572:       /* Shift this part into place for the result.  */
1.1       root     1573: #if BYTES_BIG_ENDIAN
1.1.1.6   root     1574:       if (bitsize != bitsdone)
                   1575:        part = expand_shift (LSHIFT_EXPR, word_mode, part,
                   1576:                             build_int_2 (bitsize - bitsdone, 0), 0, 1);
1.1       root     1577: #else
1.1.1.6   root     1578:       if (bitsdone != thissize)
                   1579:        part = expand_shift (LSHIFT_EXPR, word_mode, part,
                   1580:                             build_int_2 (bitsdone - thissize, 0), 0, 1);
1.1       root     1581: #endif
                   1582: 
1.1.1.6   root     1583:       if (first)
                   1584:        result = part;
                   1585:       else
                   1586:        /* Combine the parts with bitwise or.  This works
                   1587:           because we extracted each part as an unsigned bit field.  */
                   1588:        result = expand_binop (word_mode, ior_optab, part, result, NULL_RTX, 1,
                   1589:                               OPTAB_LIB_WIDEN);
                   1590: 
                   1591:       first = 0;
                   1592:     }
1.1       root     1593: 
                   1594:   /* Unsigned bit field: we are done.  */
                   1595:   if (unsignedp)
                   1596:     return result;
                   1597:   /* Signed bit field: sign-extend with two arithmetic shifts.  */
                   1598:   result = expand_shift (LSHIFT_EXPR, word_mode, result,
1.1.1.4   root     1599:                         build_int_2 (BITS_PER_WORD - bitsize, 0),
                   1600:                         NULL_RTX, 0);
1.1       root     1601:   return expand_shift (RSHIFT_EXPR, word_mode, result,
1.1.1.4   root     1602:                       build_int_2 (BITS_PER_WORD - bitsize, 0), NULL_RTX, 0);
1.1       root     1603: }
                   1604: 
                   1605: /* Add INC into TARGET.  */
                   1606: 
                   1607: void
                   1608: expand_inc (target, inc)
                   1609:      rtx target, inc;
                   1610: {
                   1611:   rtx value = expand_binop (GET_MODE (target), add_optab,
                   1612:                            target, inc,
                   1613:                            target, 0, OPTAB_LIB_WIDEN);
                   1614:   if (value != target)
                   1615:     emit_move_insn (target, value);
                   1616: }
                   1617: 
1.1.1.2   root     1618: /* Subtract DEC from TARGET.  */
1.1       root     1619: 
                   1620: void
                   1621: expand_dec (target, dec)
                   1622:      rtx target, dec;
                   1623: {
                   1624:   rtx value = expand_binop (GET_MODE (target), sub_optab,
                   1625:                            target, dec,
                   1626:                            target, 0, OPTAB_LIB_WIDEN);
                   1627:   if (value != target)
                   1628:     emit_move_insn (target, value);
                   1629: }
                   1630: 
                   1631: /* Output a shift instruction for expression code CODE,
                   1632:    with SHIFTED being the rtx for the value to shift,
                   1633:    and AMOUNT the tree for the amount to shift by.
                   1634:    Store the result in the rtx TARGET, if that is convenient.
                   1635:    If UNSIGNEDP is nonzero, do a logical shift; otherwise, arithmetic.
                   1636:    Return the rtx for where the value is.  */
                   1637: 
                   1638: rtx
                   1639: expand_shift (code, mode, shifted, amount, target, unsignedp)
                   1640:      enum tree_code code;
                   1641:      register enum machine_mode mode;
                   1642:      rtx shifted;
                   1643:      tree amount;
                   1644:      register rtx target;
                   1645:      int unsignedp;
                   1646: {
                   1647:   register rtx op1, temp = 0;
                   1648:   register int left = (code == LSHIFT_EXPR || code == LROTATE_EXPR);
                   1649:   register int rotate = (code == LROTATE_EXPR || code == RROTATE_EXPR);
                   1650:   int try;
                   1651: 
                   1652:   /* Previously detected shift-counts computed by NEGATE_EXPR
                   1653:      and shifted in the other direction; but that does not work
                   1654:      on all machines.  */
                   1655: 
1.1.1.4   root     1656:   op1 = expand_expr (amount, NULL_RTX, VOIDmode, 0);
1.1       root     1657: 
1.1.1.7 ! root     1658: #if 0 && SHIFT_COUNT_TRUNCATED
        !          1659:   if (SHIFT_COUNT_TRUNCATED
        !          1660:       && GET_CODE (op1) == CONST_INT
        !          1661:       && (unsigned HOST_WIDE_INT) INTVAL (op1) >= GET_MODE_BITSIZE (mode))
        !          1662:     op1 = GEN_INT ((unsigned HOST_WIDE_INT) INTVAL (op1)
        !          1663:                   % GET_MODE_BITSIZE (mode));
        !          1664: #endif
        !          1665: 
1.1       root     1666:   if (op1 == const0_rtx)
                   1667:     return shifted;
                   1668: 
                   1669:   for (try = 0; temp == 0 && try < 3; try++)
                   1670:     {
                   1671:       enum optab_methods methods;
                   1672: 
                   1673:       if (try == 0)
                   1674:        methods = OPTAB_DIRECT;
                   1675:       else if (try == 1)
                   1676:        methods = OPTAB_WIDEN;
                   1677:       else
                   1678:        methods = OPTAB_LIB_WIDEN;
                   1679: 
                   1680:       if (rotate)
                   1681:        {
                   1682:          /* Widening does not work for rotation.  */
                   1683:          if (methods == OPTAB_WIDEN)
                   1684:            continue;
                   1685:          else if (methods == OPTAB_LIB_WIDEN)
1.1.1.5   root     1686:            {
1.1.1.7 ! root     1687:              /* If we have been unable to open-code this by a rotation,
1.1.1.5   root     1688:                 do it as the IOR of two shifts.  I.e., to rotate A
                   1689:                 by N bits, compute (A << N) | ((unsigned) A >> (C - N))
                   1690:                 where C is the bitsize of A.
                   1691: 
                   1692:                 It is theoretically possible that the target machine might
                   1693:                 not be able to perform either shift and hence we would
                   1694:                 be making two libcalls rather than just the one for the
                   1695:                 shift (similarly if IOR could not be done).  We will allow
                   1696:                 this extremely unlikely lossage to avoid complicating the
                   1697:                 code below.  */
                   1698: 
1.1.1.7 ! root     1699:              rtx subtarget = target == shifted ? 0 : target;
        !          1700:              rtx temp1;
        !          1701:              tree type = TREE_TYPE (amount);
        !          1702:              tree new_amount = make_tree (type, op1);
        !          1703:              tree other_amount
        !          1704:                = fold (build (MINUS_EXPR, type,
        !          1705:                               convert (type,
        !          1706:                                        build_int_2 (GET_MODE_BITSIZE (mode),
        !          1707:                                                     0)),
        !          1708:                               amount));
        !          1709: 
        !          1710:              shifted = force_reg (mode, shifted);
        !          1711: 
        !          1712:              temp = expand_shift (left ? LSHIFT_EXPR : RSHIFT_EXPR,
        !          1713:                                   mode, shifted, new_amount, subtarget, 1);
        !          1714:              temp1 = expand_shift (left ? RSHIFT_EXPR : LSHIFT_EXPR,
        !          1715:                                    mode, shifted, other_amount, 0, 1);
        !          1716:              return expand_binop (mode, ior_optab, temp, temp1, target,
        !          1717:                                   unsignedp, methods);
1.1.1.5   root     1718:            }
1.1       root     1719: 
                   1720:          temp = expand_binop (mode,
                   1721:                               left ? rotl_optab : rotr_optab,
                   1722:                               shifted, op1, target, unsignedp, methods);
1.1.1.5   root     1723: 
                   1724:          /* If we don't have the rotate, but we are rotating by a constant
                   1725:             that is in range, try a rotate in the opposite direction.  */
                   1726: 
                   1727:          if (temp == 0 && GET_CODE (op1) == CONST_INT
                   1728:              && INTVAL (op1) > 0 && INTVAL (op1) < GET_MODE_BITSIZE (mode))
                   1729:            temp = expand_binop (mode,
                   1730:                                 left ? rotr_optab : rotl_optab,
                   1731:                                 shifted, 
                   1732:                                 GEN_INT (GET_MODE_BITSIZE (mode)
                   1733:                                          - INTVAL (op1)),
                   1734:                                 target, unsignedp, methods);
1.1       root     1735:        }
                   1736:       else if (unsignedp)
1.1.1.7 ! root     1737:        temp = expand_binop (mode,
        !          1738:                             left ? ashl_optab : lshr_optab,
        !          1739:                             shifted, op1, target, unsignedp, methods);
1.1       root     1740: 
                   1741:       /* Do arithmetic shifts.
                   1742:         Also, if we are going to widen the operand, we can just as well
                   1743:         use an arithmetic right-shift instead of a logical one.  */
                   1744:       if (temp == 0 && ! rotate
                   1745:          && (! unsignedp || (! left && methods == OPTAB_WIDEN)))
                   1746:        {
                   1747:          enum optab_methods methods1 = methods;
                   1748: 
                   1749:          /* If trying to widen a log shift to an arithmetic shift,
                   1750:             don't accept an arithmetic shift of the same size.  */
                   1751:          if (unsignedp)
                   1752:            methods1 = OPTAB_MUST_WIDEN;
                   1753: 
                   1754:          /* Arithmetic shift */
                   1755: 
                   1756:          temp = expand_binop (mode,
                   1757:                               left ? ashl_optab : ashr_optab,
                   1758:                               shifted, op1, target, unsignedp, methods1);
                   1759:        }
                   1760: 
1.1.1.7 ! root     1761:       /* We used to try extzv here for logical right shifts, but that was
        !          1762:         only useful for one machine, the VAX, and caused poor code 
        !          1763:         generation there for lshrdi3, so the code was deleted and a
        !          1764:         define_expand for lshrsi3 was added to vax.md.  */
1.1       root     1765:     }
                   1766: 
                   1767:   if (temp == 0)
                   1768:     abort ();
                   1769:   return temp;
                   1770: }
                   1771: 
1.1.1.5   root     1772: enum alg_code { alg_zero, alg_m, alg_shift,
                   1773:                  alg_add_t_m2, alg_sub_t_m2,
                   1774:                  alg_add_factor, alg_sub_factor,
                   1775:                  alg_add_t2_m, alg_sub_t2_m,
                   1776:                  alg_add, alg_subtract, alg_factor, alg_shiftop };
1.1       root     1777: 
                   1778: /* This structure records a sequence of operations.
                   1779:    `ops' is the number of operations recorded.
                   1780:    `cost' is their total cost.
                   1781:    The operations are stored in `op' and the corresponding
1.1.1.5   root     1782:    logarithms of the integer coefficients in `log'.
                   1783: 
1.1       root     1784:    These are the operations:
1.1.1.5   root     1785:    alg_zero            total := 0;
                   1786:    alg_m               total := multiplicand;
                   1787:    alg_shift           total := total * coeff
                   1788:    alg_add_t_m2                total := total + multiplicand * coeff;
                   1789:    alg_sub_t_m2                total := total - multiplicand * coeff;
                   1790:    alg_add_factor      total := total * coeff + total;
                   1791:    alg_sub_factor      total := total * coeff - total;
                   1792:    alg_add_t2_m                total := total * coeff + multiplicand;
                   1793:    alg_sub_t2_m                total := total * coeff - multiplicand;
1.1       root     1794: 
1.1.1.5   root     1795:    The first operand must be either alg_zero or alg_m.  */
1.1       root     1796: 
                   1797: struct algorithm
                   1798: {
1.1.1.5   root     1799:   short cost;
                   1800:   short ops;
                   1801:   /* The size of the OP and LOG fields are not directly related to the
                   1802:      word size, but the worst-case algorithms will be if we have few
                   1803:      consecutive ones or zeros, i.e., a multiplicand like 10101010101...
                   1804:      In that case we will generate shift-by-2, add, shift-by-2, add,...,
                   1805:      in total wordsize operations.  */
1.1       root     1806:   enum alg_code op[MAX_BITS_PER_WORD];
1.1.1.5   root     1807:   char log[MAX_BITS_PER_WORD];
1.1       root     1808: };
                   1809: 
                   1810: /* Compute and return the best algorithm for multiplying by T.
1.1.1.5   root     1811:    The algorithm must cost less than cost_limit
                   1812:    If retval.cost >= COST_LIMIT, no algorithm was found and all
                   1813:    other field of the returned struct are undefined.  */
1.1       root     1814: 
1.1.1.6   root     1815: static void
                   1816: synth_mult (alg_out, t, cost_limit)
                   1817:      struct algorithm *alg_out;
1.1.1.4   root     1818:      unsigned HOST_WIDE_INT t;
1.1.1.5   root     1819:      int cost_limit;
1.1       root     1820: {
1.1.1.5   root     1821:   int m;
1.1.1.7 ! root     1822:   struct algorithm *alg_in, *best_alg;
1.1       root     1823:   unsigned int cost;
1.1.1.5   root     1824:   unsigned HOST_WIDE_INT q;
1.1       root     1825: 
1.1.1.5   root     1826:   /* Indicate that no algorithm is yet found.  If no algorithm
                   1827:      is found, this value will be returned and indicate failure.  */
1.1.1.6   root     1828:   alg_out->cost = cost_limit;
1.1       root     1829: 
1.1.1.5   root     1830:   if (cost_limit <= 0)
1.1.1.6   root     1831:     return;
1.1       root     1832: 
1.1.1.5   root     1833:   /* t == 1 can be done in zero cost.  */
                   1834:   if (t == 1)
1.1       root     1835:     {
1.1.1.6   root     1836:       alg_out->ops = 1;
                   1837:       alg_out->cost = 0;
                   1838:       alg_out->op[0] = alg_m;
                   1839:       return;
1.1       root     1840:     }
                   1841: 
1.1.1.5   root     1842:   /* t == 0 sometimes has a cost.  If it does and it exceeds our limit,
                   1843:      fail now.  */
1.1.1.6   root     1844:   if (t == 0)
1.1       root     1845:     {
1.1.1.5   root     1846:       if (zero_cost >= cost_limit)
1.1.1.6   root     1847:        return;
1.1.1.5   root     1848:       else
1.1       root     1849:        {
1.1.1.6   root     1850:          alg_out->ops = 1;
                   1851:          alg_out->cost = zero_cost;
                   1852:          alg_out->op[0] = alg_zero;
                   1853:          return;
1.1       root     1854:        }
1.1.1.5   root     1855:     }
1.1       root     1856: 
1.1.1.7 ! root     1857:   /* We'll be needing a couple extra algorithm structures now.  */
        !          1858: 
        !          1859:   alg_in = (struct algorithm *)alloca (sizeof (struct algorithm));
        !          1860:   best_alg = (struct algorithm *)alloca (sizeof (struct algorithm));
        !          1861: 
1.1.1.5   root     1862:   /* If we have a group of zero bits at the low-order part of T, try
                   1863:      multiplying by the remaining bits and then doing a shift.  */
1.1       root     1864: 
1.1.1.5   root     1865:   if ((t & 1) == 0)
                   1866:     {
                   1867:       m = floor_log2 (t & -t); /* m = number of low zero bits */
                   1868:       q = t >> m;
                   1869:       cost = shift_cost[m];
1.1.1.6   root     1870:       synth_mult (alg_in, q, cost_limit - cost);
                   1871: 
                   1872:       cost += alg_in->cost;
1.1.1.5   root     1873:       if (cost < cost_limit)
                   1874:        {
1.1.1.6   root     1875:          struct algorithm *x;
                   1876:          x = alg_in, alg_in = best_alg, best_alg = x;
                   1877:          best_alg->log[best_alg->ops] = m;
                   1878:          best_alg->op[best_alg->ops] = alg_shift;
                   1879:          cost_limit = cost;
1.1       root     1880:        }
                   1881:     }
                   1882: 
1.1.1.5   root     1883:   /* If we have an odd number, add or subtract one.  */
                   1884:   if ((t & 1) != 0)
1.1.1.6   root     1885:     {
                   1886:       unsigned HOST_WIDE_INT w;
1.1       root     1887: 
1.1.1.6   root     1888:       for (w = 1; (w & t) != 0; w <<= 1)
                   1889:        ;
                   1890:       if (w > 2
                   1891:          /* Reject the case where t is 3.
                   1892:             Thus we prefer addition in that case.  */
                   1893:          && t != 3)
                   1894:        {
                   1895:          /* T ends with ...111.  Multiply by (T + 1) and subtract 1.  */
1.1       root     1896: 
1.1.1.6   root     1897:          cost = add_cost;
                   1898:          synth_mult (alg_in, t + 1, cost_limit - cost);
1.1       root     1899: 
1.1.1.6   root     1900:          cost += alg_in->cost;
                   1901:          if (cost < cost_limit)
                   1902:            {
                   1903:              struct algorithm *x;
                   1904:              x = alg_in, alg_in = best_alg, best_alg = x;
                   1905:              best_alg->log[best_alg->ops] = 0;
                   1906:              best_alg->op[best_alg->ops] = alg_sub_t_m2;
                   1907:              cost_limit = cost;
                   1908:            }
                   1909:        }
                   1910:       else
                   1911:        {
                   1912:          /* T ends with ...01 or ...011.  Multiply by (T - 1) and add 1.  */
1.1       root     1913: 
1.1.1.6   root     1914:          cost = add_cost;
                   1915:          synth_mult (alg_in, t - 1, cost_limit - cost);
1.1.1.5   root     1916: 
1.1.1.6   root     1917:          cost += alg_in->cost;
                   1918:          if (cost < cost_limit)
                   1919:            {
                   1920:              struct algorithm *x;
                   1921:              x = alg_in, alg_in = best_alg, best_alg = x;
                   1922:              best_alg->log[best_alg->ops] = 0;
                   1923:              best_alg->op[best_alg->ops] = alg_add_t_m2;
                   1924:              cost_limit = cost;
                   1925:            }
                   1926:        }
                   1927:     }
1.1       root     1928: 
1.1.1.5   root     1929:   /* Look for factors of t of the form
                   1930:      t = q(2**m +- 1), 2 <= m <= floor(log2(t - 1)).
                   1931:      If we find such a factor, we can multiply by t using an algorithm that
                   1932:      multiplies by q, shift the result by m and add/subtract it to itself.
1.1       root     1933: 
1.1.1.5   root     1934:      We search for large factors first and loop down, even if large factors
                   1935:      are less probable than small; if we find a large factor we will find a
                   1936:      good sequence quickly, and therefore be able to prune (by decreasing
                   1937:      COST_LIMIT) the search.  */
1.1       root     1938: 
1.1.1.5   root     1939:   for (m = floor_log2 (t - 1); m >= 2; m--)
                   1940:     {
                   1941:       unsigned HOST_WIDE_INT d;
1.1       root     1942: 
1.1.1.5   root     1943:       d = ((unsigned HOST_WIDE_INT) 1 << m) + 1;
                   1944:       if (t % d == 0 && t > d)
                   1945:        {
                   1946:          cost = MIN (shiftadd_cost[m], add_cost + shift_cost[m]);
1.1.1.6   root     1947:          synth_mult (alg_in, t / d, cost_limit - cost);
1.1       root     1948: 
1.1.1.5   root     1949:          cost += alg_in->cost;
1.1.1.6   root     1950:          if (cost < cost_limit)
1.1.1.5   root     1951:            {
                   1952:              struct algorithm *x;
                   1953:              x = alg_in, alg_in = best_alg, best_alg = x;
                   1954:              best_alg->log[best_alg->ops] = m;
1.1.1.6   root     1955:              best_alg->op[best_alg->ops] = alg_add_factor;
                   1956:              cost_limit = cost;
1.1.1.5   root     1957:            }
1.1.1.6   root     1958:          /* Other factors will have been taken care of in the recursion.  */
                   1959:          break;
1.1.1.5   root     1960:        }
1.1       root     1961: 
1.1.1.5   root     1962:       d = ((unsigned HOST_WIDE_INT) 1 << m) - 1;
                   1963:       if (t % d == 0 && t > d)
                   1964:        {
                   1965:          cost = MIN (shiftsub_cost[m], add_cost + shift_cost[m]);
1.1.1.6   root     1966:          synth_mult (alg_in, t / d, cost_limit - cost);
1.1       root     1967: 
1.1.1.5   root     1968:          cost += alg_in->cost;
1.1.1.6   root     1969:          if (cost < cost_limit)
1.1.1.5   root     1970:            {
                   1971:              struct algorithm *x;
                   1972:              x = alg_in, alg_in = best_alg, best_alg = x;
                   1973:              best_alg->log[best_alg->ops] = m;
1.1.1.6   root     1974:              best_alg->op[best_alg->ops] = alg_sub_factor;
                   1975:              cost_limit = cost;
1.1.1.5   root     1976:            }
1.1.1.6   root     1977:          break;
1.1.1.5   root     1978:        }
                   1979:     }
1.1       root     1980: 
1.1.1.5   root     1981:   /* Try shift-and-add (load effective address) instructions,
                   1982:      i.e. do a*3, a*5, a*9.  */
                   1983:   if ((t & 1) != 0)
                   1984:     {
                   1985:       q = t - 1;
                   1986:       q = q & -q;
                   1987:       m = exact_log2 (q);
                   1988:       if (m >= 0)
                   1989:        {
                   1990:          cost = shiftadd_cost[m];
1.1.1.6   root     1991:          synth_mult (alg_in, (t - 1) >> m, cost_limit - cost);
1.1.1.5   root     1992: 
                   1993:          cost += alg_in->cost;
1.1.1.6   root     1994:          if (cost < cost_limit)
1.1.1.5   root     1995:            {
                   1996:              struct algorithm *x;
                   1997:              x = alg_in, alg_in = best_alg, best_alg = x;
                   1998:              best_alg->log[best_alg->ops] = m;
1.1.1.6   root     1999:              best_alg->op[best_alg->ops] = alg_add_t2_m;
                   2000:              cost_limit = cost;
1.1.1.5   root     2001:            }
                   2002:        }
1.1       root     2003: 
1.1.1.5   root     2004:       q = t + 1;
                   2005:       q = q & -q;
                   2006:       m = exact_log2 (q);
                   2007:       if (m >= 0)
                   2008:        {
                   2009:          cost = shiftsub_cost[m];
1.1.1.6   root     2010:          synth_mult (alg_in, (t + 1) >> m, cost_limit - cost);
1.1       root     2011: 
1.1.1.5   root     2012:          cost += alg_in->cost;
1.1.1.6   root     2013:          if (cost < cost_limit)
1.1.1.5   root     2014:            {
                   2015:              struct algorithm *x;
                   2016:              x = alg_in, alg_in = best_alg, best_alg = x;
                   2017:              best_alg->log[best_alg->ops] = m;
1.1.1.6   root     2018:              best_alg->op[best_alg->ops] = alg_sub_t2_m;
                   2019:              cost_limit = cost;
1.1.1.5   root     2020:            }
                   2021:        }
                   2022:     }
1.1       root     2023: 
1.1.1.6   root     2024:   /* If cost_limit has not decreased since we stored it in alg_out->cost,
                   2025:      we have not found any algorithm.  */
                   2026:   if (cost_limit == alg_out->cost)
                   2027:     return;
                   2028: 
1.1.1.7 ! root     2029:   /* If we are getting a too long sequence for `struct algorithm'
        !          2030:      to record, make this search fail.  */
        !          2031:   if (best_alg->ops == MAX_BITS_PER_WORD)
        !          2032:     return;
        !          2033: 
1.1.1.6   root     2034:   /* Copy the algorithm from temporary space to the space at alg_out.
                   2035:      We avoid using structure assignment because the majority of
                   2036:      best_alg is normally undefined, and this is a critical function.  */
                   2037:   alg_out->ops = best_alg->ops + 1;
                   2038:   alg_out->cost = cost_limit;
1.1.1.7 ! root     2039:   bcopy ((char *) best_alg->op, (char *) alg_out->op,
        !          2040:         alg_out->ops * sizeof *alg_out->op);
        !          2041:   bcopy ((char *) best_alg->log, (char *) alg_out->log,
        !          2042:         alg_out->ops * sizeof *alg_out->log);
1.1       root     2043: }
                   2044: 
                   2045: /* Perform a multiplication and return an rtx for the result.
                   2046:    MODE is mode of value; OP0 and OP1 are what to multiply (rtx's);
                   2047:    TARGET is a suggestion for where to store the result (an rtx).
                   2048: 
                   2049:    We check specially for a constant integer as OP1.
                   2050:    If you want this check for OP0 as well, then before calling
                   2051:    you should swap the two operands if OP0 would be constant.  */
                   2052: 
                   2053: rtx
                   2054: expand_mult (mode, op0, op1, target, unsignedp)
                   2055:      enum machine_mode mode;
                   2056:      register rtx op0, op1, target;
                   2057:      int unsignedp;
                   2058: {
                   2059:   rtx const_op1 = op1;
                   2060: 
1.1.1.7 ! root     2061:   /* synth_mult does an `unsigned int' multiply.  As long as the mode is
        !          2062:      less than or equal in size to `unsigned int' this doesn't matter.
        !          2063:      If the mode is larger than `unsigned int', then synth_mult works only
        !          2064:      if the constant value exactly fits in an `unsigned int' without any
        !          2065:      truncation.  This means that multiplying by negative values does
        !          2066:      not work; results are off by 2^32 on a 32 bit machine.  */
        !          2067: 
1.1       root     2068:   /* If we are multiplying in DImode, it may still be a win
                   2069:      to try to work with shifts and adds.  */
                   2070:   if (GET_CODE (op1) == CONST_DOUBLE
                   2071:       && GET_MODE_CLASS (GET_MODE (op1)) == MODE_INT
1.1.1.7 ! root     2072:       && HOST_BITS_PER_INT >= BITS_PER_WORD
        !          2073:       && CONST_DOUBLE_HIGH (op1) == 0)
        !          2074:     const_op1 = GEN_INT (CONST_DOUBLE_LOW (op1));
        !          2075:   else if (HOST_BITS_PER_INT < GET_MODE_BITSIZE (mode)
        !          2076:           && GET_CODE (op1) == CONST_INT
        !          2077:           && INTVAL (op1) < 0)
        !          2078:     const_op1 = 0;
1.1       root     2079: 
1.1.1.3   root     2080:   /* We used to test optimize here, on the grounds that it's better to
                   2081:      produce a smaller program when -O is not used.
                   2082:      But this causes such a terrible slowdown sometimes
                   2083:      that it seems better to use synth_mult always.  */
1.1.1.5   root     2084: 
1.1.1.7 ! root     2085:   if (const_op1 && GET_CODE (const_op1) == CONST_INT)
1.1       root     2086:     {
                   2087:       struct algorithm alg;
1.1.1.7 ! root     2088:       struct algorithm alg2;
1.1.1.5   root     2089:       HOST_WIDE_INT val = INTVAL (op1);
                   2090:       HOST_WIDE_INT val_so_far;
                   2091:       rtx insn;
1.1.1.6   root     2092:       int mult_cost;
1.1.1.7 ! root     2093:       enum {basic_variant, negate_variant, add_variant} variant = basic_variant;
1.1       root     2094: 
1.1.1.7 ! root     2095:       /* Try to do the computation three ways: multiply by the negative of OP1
        !          2096:         and then negate, do the multiplication directly, or do multiplication
        !          2097:         by OP1 - 1.  */
1.1       root     2098: 
1.1.1.6   root     2099:       mult_cost = rtx_cost (gen_rtx (MULT, mode, op0, op1), SET);
                   2100:       mult_cost = MIN (12 * add_cost, mult_cost);
                   2101: 
                   2102:       synth_mult (&alg, val, mult_cost);
1.1       root     2103: 
1.1.1.7 ! root     2104:       /* This works only if the inverted value actually fits in an
        !          2105:         `unsigned int' */
        !          2106:       if (HOST_BITS_PER_INT >= GET_MODE_BITSIZE (mode))
        !          2107:        {
        !          2108:          synth_mult (&alg2, - val,
        !          2109:                      (alg.cost < mult_cost ? alg.cost : mult_cost) - negate_cost);
        !          2110:          if (alg2.cost + negate_cost < alg.cost)
        !          2111:            alg = alg2, variant = negate_variant;
        !          2112:        }
        !          2113: 
        !          2114:       /* This proves very useful for division-by-constant.  */
        !          2115:       synth_mult (&alg2, val - 1,
        !          2116:                  (alg.cost < mult_cost ? alg.cost : mult_cost) - add_cost);
        !          2117:       if (alg2.cost + add_cost < alg.cost)
        !          2118:        alg = alg2, variant = add_variant;
1.1       root     2119: 
1.1.1.5   root     2120:       if (alg.cost < mult_cost)
1.1       root     2121:        {
1.1.1.5   root     2122:          /* We found something cheaper than a multiply insn.  */
                   2123:          int opno;
1.1       root     2124:          rtx accum, tem;
                   2125: 
                   2126:          op0 = protect_from_queue (op0, 0);
                   2127: 
                   2128:          /* Avoid referencing memory over and over.
                   2129:             For speed, but also for correctness when mem is volatile.  */
                   2130:          if (GET_CODE (op0) == MEM)
                   2131:            op0 = force_reg (mode, op0);
                   2132: 
1.1.1.5   root     2133:          /* ACCUM starts out either as OP0 or as a zero, depending on
                   2134:             the first operation.  */
                   2135: 
                   2136:          if (alg.op[0] == alg_zero)
                   2137:            {
                   2138:              accum = copy_to_mode_reg (mode, const0_rtx);
                   2139:              val_so_far = 0;
                   2140:            }
                   2141:          else if (alg.op[0] == alg_m)
                   2142:            {
1.1.1.6   root     2143:              accum = copy_to_mode_reg (mode, op0);
1.1.1.5   root     2144:              val_so_far = 1;
                   2145:            }
1.1       root     2146:          else
1.1.1.5   root     2147:            abort ();
                   2148: 
                   2149:          for (opno = 1; opno < alg.ops; opno++)
1.1       root     2150:            {
1.1.1.5   root     2151:              int log = alg.log[opno];
1.1.1.7 ! root     2152:              int preserve = preserve_subexpressions_p ();
        !          2153:              rtx shift_subtarget = preserve ? 0 : accum;
        !          2154:              rtx add_target
        !          2155:                = (opno == alg.ops - 1 && target != 0 && variant != add_variant
        !          2156:                  ? target : 0);
        !          2157:              rtx accum_target = preserve ? 0 : accum;
        !          2158:              
1.1       root     2159:              switch (alg.op[opno])
                   2160:                {
1.1.1.5   root     2161:                case alg_shift:
                   2162:                  accum = expand_shift (LSHIFT_EXPR, mode, accum,
                   2163:                                        build_int_2 (log, 0), NULL_RTX, 0);
                   2164:                  val_so_far <<= log;
1.1       root     2165:                  break;
                   2166: 
1.1.1.5   root     2167:                case alg_add_t_m2:
                   2168:                  tem = expand_shift (LSHIFT_EXPR, mode, op0,
                   2169:                                      build_int_2 (log, 0), NULL_RTX, 0);
                   2170:                  accum = force_operand (gen_rtx (PLUS, mode, accum, tem),
1.1.1.7 ! root     2171:                                         add_target ? add_target : accum_target);
1.1.1.5   root     2172:                  val_so_far += (HOST_WIDE_INT) 1 << log;
                   2173:                  break;
                   2174: 
                   2175:                case alg_sub_t_m2:
                   2176:                  tem = expand_shift (LSHIFT_EXPR, mode, op0,
                   2177:                                      build_int_2 (log, 0), NULL_RTX, 0);
                   2178:                  accum = force_operand (gen_rtx (MINUS, mode, accum, tem),
1.1.1.7 ! root     2179:                                         add_target ? add_target : accum_target);
1.1.1.5   root     2180:                  val_so_far -= (HOST_WIDE_INT) 1 << log;
                   2181:                  break;
                   2182: 
                   2183:                case alg_add_t2_m:
                   2184:                  accum = expand_shift (LSHIFT_EXPR, mode, accum,
1.1.1.7 ! root     2185:                                        build_int_2 (log, 0), shift_subtarget,
        !          2186:                                        0);
1.1.1.5   root     2187:                  accum = force_operand (gen_rtx (PLUS, mode, accum, op0),
1.1.1.7 ! root     2188:                                         add_target ? add_target : accum_target);
1.1.1.5   root     2189:                  val_so_far = (val_so_far << log) + 1;
                   2190:                  break;
                   2191: 
                   2192:                case alg_sub_t2_m:
                   2193:                  accum = expand_shift (LSHIFT_EXPR, mode, accum,
1.1.1.7 ! root     2194:                                        build_int_2 (log, 0), shift_subtarget,
        !          2195:                                        0);
1.1.1.5   root     2196:                  accum = force_operand (gen_rtx (MINUS, mode, accum, op0),
1.1.1.7 ! root     2197:                                         add_target ? add_target : accum_target);
1.1.1.5   root     2198:                  val_so_far = (val_so_far << log) - 1;
                   2199:                  break;
1.1       root     2200: 
1.1.1.5   root     2201:                case alg_add_factor:
                   2202:                  tem = expand_shift (LSHIFT_EXPR, mode, accum,
                   2203:                                      build_int_2 (log, 0), NULL_RTX, 0);
                   2204:                  accum = force_operand (gen_rtx (PLUS, mode, accum, tem),
1.1.1.7 ! root     2205:                                         add_target ? add_target : accum_target);
1.1.1.5   root     2206:                  val_so_far += val_so_far << log;
1.1       root     2207:                  break;
                   2208: 
1.1.1.5   root     2209:                case alg_sub_factor:
1.1       root     2210:                  tem = expand_shift (LSHIFT_EXPR, mode, accum,
1.1.1.4   root     2211:                                      build_int_2 (log, 0), NULL_RTX, 0);
1.1.1.5   root     2212:                  accum = force_operand (gen_rtx (MINUS, mode, tem, accum),
1.1.1.7 ! root     2213:                                         (add_target ? add_target
        !          2214:                                          : preserve ? 0 : tem));
1.1.1.5   root     2215:                  val_so_far = (val_so_far << log) - val_so_far;
                   2216:                  break;
1.1       root     2217: 
1.1.1.5   root     2218:                default:
                   2219:                  abort ();;
1.1       root     2220:                }
                   2221: 
1.1.1.5   root     2222:              /* Write a REG_EQUAL note on the last insn so that we can cse
                   2223:                 multiplication sequences.  */
1.1       root     2224: 
1.1.1.5   root     2225:              insn = get_last_insn ();
                   2226:              REG_NOTES (insn)
                   2227:                = gen_rtx (EXPR_LIST, REG_EQUAL,
                   2228:                           gen_rtx (MULT, mode, op0, GEN_INT (val_so_far)),
                   2229:                           REG_NOTES (insn));
                   2230:            }
1.1       root     2231: 
1.1.1.7 ! root     2232:          if (variant == negate_variant)
1.1       root     2233:            {
1.1.1.5   root     2234:              val_so_far = - val_so_far;
                   2235:              accum = expand_unop (mode, neg_optab, accum, target, 0);
1.1       root     2236:            }
1.1.1.7 ! root     2237:          else if (variant == add_variant)
        !          2238:            {
        !          2239:              val_so_far = val_so_far + 1;
        !          2240:              accum = force_operand (gen_rtx (PLUS, mode, accum, op0), target);
        !          2241:            }
1.1       root     2242: 
1.1.1.5   root     2243:          if (val != val_so_far)
                   2244:            abort ();
                   2245: 
                   2246:          return accum;
1.1       root     2247:        }
                   2248:     }
                   2249: 
1.1.1.6   root     2250:   /* This used to use umul_optab if unsigned, but for non-widening multiply
                   2251:      there is no difference between signed and unsigned.  */
1.1       root     2252:   op0 = expand_binop (mode, smul_optab,
                   2253:                      op0, op1, target, unsignedp, OPTAB_LIB_WIDEN);
                   2254:   if (op0 == 0)
                   2255:     abort ();
                   2256:   return op0;
                   2257: }
                   2258: 
1.1.1.7 ! root     2259: /* Return the smallest n such that 2**n >= X.  */
        !          2260: 
        !          2261: int
        !          2262: ceil_log2 (x)
        !          2263:      unsigned HOST_WIDE_INT x;
        !          2264: {
        !          2265:   return floor_log2 (x - 1) + 1;
        !          2266: }
        !          2267: 
        !          2268: /* Choose a minimal N + 1 bit approximation to 1/D that can be used to
        !          2269:    replace division by D, and put the least significant N bits of the result
        !          2270:    in *MULTIPLIER_PTR and return the most significant bit.
        !          2271: 
        !          2272:    The width of operations is N (should be <= HOST_BITS_PER_WIDE_INT), the
        !          2273:    needed precision is in PRECISION (should be <= N).
        !          2274: 
        !          2275:    PRECISION should be as small as possible so this function can choose
        !          2276:    multiplier more freely.
        !          2277: 
        !          2278:    The rounded-up logarithm of D is placed in *lgup_ptr.  A shift count that
        !          2279:    is to be used for a final right shift is placed in *POST_SHIFT_PTR.
        !          2280: 
        !          2281:    Using this function, x/D will be equal to (x * m) >> (*POST_SHIFT_PTR),
        !          2282:    where m is the full HOST_BITS_PER_WIDE_INT + 1 bit multiplier.  */
        !          2283: 
        !          2284: static
        !          2285: unsigned HOST_WIDE_INT
        !          2286: choose_multiplier (d, n, precision, multiplier_ptr, post_shift_ptr, lgup_ptr)
        !          2287:      unsigned HOST_WIDE_INT d;
        !          2288:      int n;
        !          2289:      int precision;
        !          2290:      unsigned HOST_WIDE_INT *multiplier_ptr;
        !          2291:      int *post_shift_ptr;
        !          2292:      int *lgup_ptr;
        !          2293: {
        !          2294:   unsigned HOST_WIDE_INT mhigh_hi, mhigh_lo;
        !          2295:   unsigned HOST_WIDE_INT mlow_hi, mlow_lo;
        !          2296:   int lgup, post_shift;
        !          2297:   int pow, pow2;
        !          2298:   unsigned HOST_WIDE_INT nh, nl, dummy1, dummy2;
        !          2299: 
        !          2300:   /* lgup = ceil(log2(divisor)); */
        !          2301:   lgup = ceil_log2 (d);
        !          2302: 
        !          2303:   if (lgup > n)
        !          2304:     abort ();
        !          2305: 
        !          2306:   pow = n + lgup;
        !          2307:   pow2 = n + lgup - precision;
        !          2308: 
        !          2309:   if (pow == 2 * HOST_BITS_PER_WIDE_INT)
        !          2310:     {
        !          2311:       /* We could handle this with some effort, but this case is much better
        !          2312:         handled directly with a scc insn, so rely on caller using that.  */
        !          2313:       abort ();
        !          2314:     }
        !          2315: 
        !          2316:   /* mlow = 2^(N + lgup)/d */
        !          2317:  if (pow >= HOST_BITS_PER_WIDE_INT)
        !          2318:     {
        !          2319:       nh = (unsigned HOST_WIDE_INT) 1 << (pow - HOST_BITS_PER_WIDE_INT);
        !          2320:       nl = 0;
        !          2321:     }
        !          2322:   else
        !          2323:     {
        !          2324:       nh = 0;
        !          2325:       nl = (unsigned HOST_WIDE_INT) 1 << pow;
        !          2326:     }
        !          2327:   div_and_round_double (TRUNC_DIV_EXPR, 1, nl, nh, d, (HOST_WIDE_INT) 0,
        !          2328:                        &mlow_lo, &mlow_hi, &dummy1, &dummy2);
        !          2329: 
        !          2330:   /* mhigh = (2^(N + lgup) + 2^N + lgup - precision)/d */
        !          2331:   if (pow2 >= HOST_BITS_PER_WIDE_INT)
        !          2332:     nh |= (unsigned HOST_WIDE_INT) 1 << (pow2 - HOST_BITS_PER_WIDE_INT);
        !          2333:   else
        !          2334:     nl |= (unsigned HOST_WIDE_INT) 1 << pow2;
        !          2335:   div_and_round_double (TRUNC_DIV_EXPR, 1, nl, nh, d, (HOST_WIDE_INT) 0,
        !          2336:                        &mhigh_lo, &mhigh_hi, &dummy1, &dummy2);
        !          2337: 
        !          2338:   if (mhigh_hi && nh - d >= d)
        !          2339:     abort ();
        !          2340:   if (mhigh_hi > 1 || mlow_hi > 1)
        !          2341:     abort ();
        !          2342:   /* assert that mlow < mhigh.  */
        !          2343:   if (! (mlow_hi < mhigh_hi || (mlow_hi == mhigh_hi && mlow_lo < mhigh_lo)))
        !          2344:     abort();
        !          2345: 
        !          2346:   /* If precision == N, then mlow, mhigh exceed 2^N
        !          2347:      (but they do not exceed 2^(N+1)).  */
        !          2348: 
        !          2349:   /* Reduce to lowest terms */
        !          2350:   for (post_shift = lgup; post_shift > 0; post_shift--)
        !          2351:     {
        !          2352:       unsigned HOST_WIDE_INT ml_lo = (mlow_hi << (HOST_BITS_PER_WIDE_INT - 1)) | (mlow_lo >> 1);
        !          2353:       unsigned HOST_WIDE_INT mh_lo = (mhigh_hi << (HOST_BITS_PER_WIDE_INT - 1)) | (mhigh_lo >> 1);
        !          2354:       if (ml_lo >= mh_lo)
        !          2355:        break;
        !          2356: 
        !          2357:       mlow_hi = 0;
        !          2358:       mlow_lo = ml_lo;
        !          2359:       mhigh_hi = 0;
        !          2360:       mhigh_lo = mh_lo;
        !          2361:     }
        !          2362: 
        !          2363:   *post_shift_ptr = post_shift;
        !          2364:   *lgup_ptr = lgup;
        !          2365:   if (n < HOST_BITS_PER_WIDE_INT)
        !          2366:     {
        !          2367:       unsigned HOST_WIDE_INT mask = ((unsigned HOST_WIDE_INT) 1 << n) - 1;
        !          2368:       *multiplier_ptr = mhigh_lo & mask;
        !          2369:       return mhigh_lo >= mask;
        !          2370:     }
        !          2371:   else
        !          2372:     {
        !          2373:       *multiplier_ptr = mhigh_lo;
        !          2374:       return mhigh_hi;
        !          2375:     }
        !          2376: }
        !          2377: 
        !          2378: /* Compute the inverse of X mod 2**n, i.e., find Y such that X * Y is
        !          2379:    congruent to 1 (mod 2**N).  */
        !          2380: 
        !          2381: static unsigned HOST_WIDE_INT
        !          2382: invert_mod2n (x, n)
        !          2383:      unsigned HOST_WIDE_INT x;
        !          2384:      int n;
        !          2385: {
        !          2386:   /* Solve x*y == 1 (mod 2^n), where x is odd.  Return y. */
        !          2387: 
        !          2388:   /* The algorithm notes that the choice y = x satisfies
        !          2389:      x*y == 1 mod 2^3, since x is assumed odd.
        !          2390:      Each iteration doubles the number of bits of significance in y.  */
        !          2391: 
        !          2392:   unsigned HOST_WIDE_INT mask;
        !          2393:   unsigned HOST_WIDE_INT y = x;
        !          2394:   int nbit = 3;
        !          2395: 
        !          2396:   mask = (n == HOST_BITS_PER_WIDE_INT
        !          2397:          ? ~(unsigned HOST_WIDE_INT) 0
        !          2398:          : ((unsigned HOST_WIDE_INT) 1 << n) - 1);
        !          2399: 
        !          2400:   while (nbit < n)
        !          2401:     {
        !          2402:       y = y * (2 - x*y) & mask;                /* Modulo 2^N */
        !          2403:       nbit *= 2;
        !          2404:     }
        !          2405:   return y;
        !          2406: }
        !          2407: 
        !          2408: /* Emit code to adjust ADJ_OPERAND after multiplication of wrong signedness
        !          2409:    flavor of OP0 and OP1.  ADJ_OPERAND is already the high half of the
        !          2410:    product OP0 x OP1.  If UNSIGNEDP is nonzero, adjust the signed product
        !          2411:    to become unsigned, if UNSIGNEDP is zero, adjust the unsigned product to
        !          2412:    become signed.
        !          2413: 
        !          2414:    The result is put in TARGET if that is convenient.
        !          2415: 
        !          2416:    MODE is the mode of operation.  */
        !          2417: 
        !          2418: rtx
        !          2419: expand_mult_highpart_adjust (mode, adj_operand, op0, op1, target, unsignedp)
        !          2420:      enum machine_mode mode;
        !          2421:      register rtx adj_operand, op0, op1, target;
        !          2422:      int unsignedp;
        !          2423: {
        !          2424:   rtx tem;
        !          2425:   enum rtx_code adj_code = unsignedp ? PLUS : MINUS;
        !          2426: 
        !          2427:   tem = expand_shift (RSHIFT_EXPR, mode, op0,
        !          2428:                      build_int_2 (GET_MODE_BITSIZE (mode) - 1, 0),
        !          2429:                      NULL_RTX, 0);
        !          2430:   tem = expand_and (tem, op1, NULL_RTX);
        !          2431:   adj_operand = force_operand (gen_rtx (adj_code, mode, adj_operand, tem),
        !          2432:                               adj_operand);
        !          2433: 
        !          2434:   tem = expand_shift (RSHIFT_EXPR, mode, op1,
        !          2435:                      build_int_2 (GET_MODE_BITSIZE (mode) - 1, 0),
        !          2436:                      NULL_RTX, 0);
        !          2437:   tem = expand_and (tem, op0, NULL_RTX);
        !          2438:   target = force_operand (gen_rtx (adj_code, mode, adj_operand, tem), target);
        !          2439: 
        !          2440:   return target;
        !          2441: }
        !          2442: 
        !          2443: /* Emit code to multiply OP0 and CNST1, putting the high half of the result
        !          2444:    in TARGET if that is convenient, and return where the result is.  If the
        !          2445:    operation can not be performed, 0 is returned.
        !          2446: 
        !          2447:    MODE is the mode of operation and result.
        !          2448: 
        !          2449:    UNSIGNEDP nonzero means unsigned multiply.  */
        !          2450: 
        !          2451: rtx
        !          2452: expand_mult_highpart (mode, op0, cnst1, target, unsignedp)
        !          2453:      enum machine_mode mode;
        !          2454:      register rtx op0, target;
        !          2455:      unsigned HOST_WIDE_INT cnst1;
        !          2456:      int unsignedp;
        !          2457: {
        !          2458:   enum machine_mode wider_mode = GET_MODE_WIDER_MODE (mode);
        !          2459:   optab mul_highpart_optab;
        !          2460:   optab moptab;
        !          2461:   rtx tem;
        !          2462:   int size = GET_MODE_BITSIZE (mode);
        !          2463:   rtx op1, wide_op1;
        !          2464: 
        !          2465:   /* We can't support modes wider than HOST_BITS_PER_INT.  */
        !          2466:   if (size > HOST_BITS_PER_WIDE_INT)
        !          2467:     abort ();
        !          2468: 
        !          2469:   op1 = GEN_INT (cnst1);
        !          2470: 
        !          2471:   if (GET_MODE_BITSIZE (wider_mode) <= HOST_BITS_PER_INT)
        !          2472:     wide_op1 = op1;
        !          2473:   else
        !          2474:     wide_op1
        !          2475:       = immed_double_const (cnst1,
        !          2476:                            (unsignedp
        !          2477:                             ? (HOST_WIDE_INT) 0
        !          2478:                             : -(cnst1 >> (HOST_BITS_PER_WIDE_INT - 1))),
        !          2479:                            wider_mode);
        !          2480: 
        !          2481:   /* expand_mult handles constant multiplication of word_mode
        !          2482:      or narrower.  It does a poor job for large modes.  */
        !          2483:   if (size < BITS_PER_WORD)
        !          2484:     {
        !          2485:       /* We have to do this, since expand_binop doesn't do conversion for
        !          2486:         multiply.  Maybe change expand_binop to handle widening multiply?  */
        !          2487:       op0 = convert_to_mode (wider_mode, op0, unsignedp);
        !          2488: 
        !          2489:       tem = expand_mult (wider_mode, op0, wide_op1, NULL_RTX, unsignedp);
        !          2490:       tem = expand_shift (RSHIFT_EXPR, wider_mode, tem,
        !          2491:                          build_int_2 (size, 0), NULL_RTX, 1);
        !          2492:       return gen_lowpart (mode, tem);
        !          2493:     }
        !          2494: 
        !          2495:   if (target == 0)
        !          2496:     target = gen_reg_rtx (mode);
        !          2497: 
        !          2498:   /* Firstly, try using a multiplication insn that only generates the needed
        !          2499:      high part of the product, and in the sign flavor of unsignedp.  */
        !          2500:   mul_highpart_optab = unsignedp ? umul_highpart_optab : smul_highpart_optab;
        !          2501:   target = expand_binop (mode, mul_highpart_optab,
        !          2502:                         op0, op1, target, unsignedp, OPTAB_DIRECT);
        !          2503:   if (target)
        !          2504:     return target;
        !          2505: 
        !          2506:   /* Secondly, same as above, but use sign flavor opposite of unsignedp.
        !          2507:      Need to adjust the result after the multiplication.  */
        !          2508:   mul_highpart_optab = unsignedp ? smul_highpart_optab : umul_highpart_optab;
        !          2509:   target = expand_binop (mode, mul_highpart_optab,
        !          2510:                         op0, op1, target, unsignedp, OPTAB_DIRECT);
        !          2511:   if (target)
        !          2512:     /* We used the wrong signedness.  Adjust the result.  */
        !          2513:     return expand_mult_highpart_adjust (mode, target, op0,
        !          2514:                                        op1, target, unsignedp);
        !          2515: 
        !          2516:   /* Thirdly, we try to use a widening multiplication, or a wider mode
        !          2517:      multiplication.  */
        !          2518: 
        !          2519:   moptab = unsignedp ? umul_widen_optab : smul_widen_optab;
        !          2520:   if (moptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing)
        !          2521:     ;
        !          2522:   else if (smul_optab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing)
        !          2523:     moptab = smul_optab;
        !          2524:   else
        !          2525:     {
        !          2526:       /* Try widening multiplication of opposite signedness, and adjust.  */
        !          2527:       moptab = unsignedp ? smul_widen_optab : umul_widen_optab;
        !          2528:       if (moptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing)
        !          2529:        {
        !          2530:          tem = expand_binop (wider_mode, moptab, op0, wide_op1,
        !          2531:                              NULL_RTX, ! unsignedp, OPTAB_WIDEN);
        !          2532:          if (tem != 0)
        !          2533:            {
        !          2534:              /* Extract the high half of the just generated product.  */
        !          2535:              tem = expand_shift (RSHIFT_EXPR, wider_mode, tem,
        !          2536:                                  build_int_2 (size, 0), NULL_RTX, 1);
        !          2537:              tem = gen_lowpart (mode, tem);
        !          2538:              /* We used the wrong signedness.  Adjust the result.  */
        !          2539:              return expand_mult_highpart_adjust (mode, tem, op0, op1,
        !          2540:                                                  target, unsignedp);
        !          2541:            }
        !          2542:        }
        !          2543: 
        !          2544:       /* As a last resort, try widening the mode and perform a
        !          2545:         non-widening multiplication.  */
        !          2546:       moptab = smul_optab;
        !          2547:     }
        !          2548: 
        !          2549:   /* Pass NULL_RTX as target since TARGET has wrong mode.  */
        !          2550:   tem = expand_binop (wider_mode, moptab, op0, wide_op1,
        !          2551:                      NULL_RTX, unsignedp, OPTAB_WIDEN);
        !          2552:   if (tem == 0)
        !          2553:     return 0;
        !          2554: 
        !          2555:   /* Extract the high half of the just generated product.  */
        !          2556:   tem = expand_shift (RSHIFT_EXPR, wider_mode, tem,
        !          2557:                      build_int_2 (size, 0), NULL_RTX, 1);
        !          2558:   return gen_lowpart (mode, tem);
        !          2559: }
        !          2560: 
1.1       root     2561: /* Emit the code to divide OP0 by OP1, putting the result in TARGET
                   2562:    if that is convenient, and returning where the result is.
                   2563:    You may request either the quotient or the remainder as the result;
                   2564:    specify REM_FLAG nonzero to get the remainder.
                   2565: 
                   2566:    CODE is the expression code for which kind of division this is;
                   2567:    it controls how rounding is done.  MODE is the machine mode to use.
                   2568:    UNSIGNEDP nonzero means do unsigned division.  */
                   2569: 
                   2570: /* ??? For CEIL_MOD_EXPR, can compute incorrect remainder with ANDI
                   2571:    and then correct it by or'ing in missing high bits
                   2572:    if result of ANDI is nonzero.
                   2573:    For ROUND_MOD_EXPR, can use ANDI and then sign-extend the result.
                   2574:    This could optimize to a bfexts instruction.
                   2575:    But C doesn't use these operations, so their optimizations are
                   2576:    left for later.  */
                   2577: 
1.1.1.7 ! root     2578: #define EXACT_POWER_OF_2_OR_ZERO_P(x) (((x) & ((x) - 1)) == 0)
        !          2579: 
1.1       root     2580: rtx
                   2581: expand_divmod (rem_flag, code, mode, op0, op1, target, unsignedp)
                   2582:      int rem_flag;
                   2583:      enum tree_code code;
                   2584:      enum machine_mode mode;
                   2585:      register rtx op0, op1, target;
                   2586:      int unsignedp;
                   2587: {
                   2588:   enum machine_mode compute_mode;
1.1.1.7 ! root     2589:   register rtx tquotient;
        !          2590:   rtx quotient = 0, remainder = 0;
        !          2591:   rtx last;
1.1.1.4   root     2592:   int size;
1.1.1.7 ! root     2593:   rtx insn, set;
1.1       root     2594:   optab optab1, optab2;
1.1.1.7 ! root     2595:   int op1_is_constant, op1_is_pow2;
1.1       root     2596: 
1.1.1.7 ! root     2597:   op1_is_constant = GET_CODE (op1) == CONST_INT;
        !          2598:   op1_is_pow2 = (op1_is_constant
        !          2599:                 && ((EXACT_POWER_OF_2_OR_ZERO_P (INTVAL (op1))
        !          2600:                      || EXACT_POWER_OF_2_OR_ZERO_P (-INTVAL (op1)))));
        !          2601: 
        !          2602:   /*
        !          2603:      This is the structure of expand_divmod:
        !          2604: 
        !          2605:      First comes code to fix up the operands so we can perform the operations
        !          2606:      correctly and efficiently.
        !          2607: 
        !          2608:      Second comes a switch statement with code specific for each rounding mode.
        !          2609:      For some special operands this code emits all RTL for the desired
        !          2610:      operation, for other cases, it generates only a quotient and stores it in
        !          2611:      QUOTIENT.  The case for trunc division/remainder might leave quotient = 0,
        !          2612:      to indicate that it has not done anything.
        !          2613: 
        !          2614:      Last comes code that finishes the operation.  If QUOTIENT is set and
        !          2615:      REM_FLAG is set, the remainder is computed as OP0 - QUOTIENT * OP1.  If
        !          2616:      QUOTIENT is not set, it is computed using trunc rounding.
        !          2617: 
        !          2618:      We try to generate special code for division and remainder when OP1 is a
        !          2619:      constant.  If |OP1| = 2**n we can use shifts and some other fast
        !          2620:      operations.  For other values of OP1, we compute a carefully selected
        !          2621:      fixed-point approximation m = 1/OP1, and generate code that multiplies OP0
        !          2622:      by m.
        !          2623: 
        !          2624:      In all cases but EXACT_DIV_EXPR, this multiplication requires the upper
        !          2625:      half of the product.  Different strategies for generating the product are
        !          2626:      implemented in expand_mult_highpart.
        !          2627: 
        !          2628:      If what we actually want is the remainder, we generate that by another
        !          2629:      by-constant multiplication and a subtraction.  */
        !          2630: 
        !          2631:   /* We shouldn't be called with OP1 == const1_rtx, but some of the
1.1.1.4   root     2632:      code below will malfunction if we are, so check here and handle
                   2633:      the special case if so.  */
                   2634:   if (op1 == const1_rtx)
                   2635:     return rem_flag ? const0_rtx : op0;
                   2636: 
1.1.1.6   root     2637:   if (target
                   2638:       /* Don't use the function value register as a target
                   2639:         since we have to read it as well as write it,
                   2640:         and function-inlining gets confused by this.  */
                   2641:       && ((REG_P (target) && REG_FUNCTION_VALUE_P (target))
                   2642:          /* Don't clobber an operand while doing a multi-step calculation.  */
1.1.1.7 ! root     2643:          || ((rem_flag || op1_is_constant)
1.1.1.6   root     2644:              && (reg_mentioned_p (target, op0)
                   2645:                  || (GET_CODE (op0) == MEM && GET_CODE (target) == MEM)))
                   2646:          || reg_mentioned_p (target, op1)
                   2647:          || (GET_CODE (op1) == MEM && GET_CODE (target) == MEM)))
1.1       root     2648:     target = 0;
                   2649: 
                   2650:   /* Get the mode in which to perform this computation.  Normally it will
                   2651:      be MODE, but sometimes we can't do the desired operation in MODE.
                   2652:      If so, pick a wider mode in which we can do the operation.  Convert
                   2653:      to that mode at the start to avoid repeated conversions.
                   2654: 
                   2655:      First see what operations we need.  These depend on the expression
                   2656:      we are evaluating.  (We assume that divxx3 insns exist under the
                   2657:      same conditions that modxx3 insns and that these insns don't normally
                   2658:      fail.  If these assumptions are not correct, we may generate less
                   2659:      efficient code in some cases.)
                   2660: 
                   2661:      Then see if we find a mode in which we can open-code that operation
                   2662:      (either a division, modulus, or shift).  Finally, check for the smallest
                   2663:      mode for which we can do the operation with a library call.  */
                   2664: 
1.1.1.7 ! root     2665:   /* We might want to refine this now that we have division-by-constant
        !          2666:      optimization.  Since expand_mult_highpart tries so many variants, it is
        !          2667:      not straightforward to generalize this.  Maybe we should make an array
        !          2668:      of possible modes in init_expmed?  Save this for GCC 2.7.  */
        !          2669: 
        !          2670:   optab1 = (op1_is_pow2 ? (unsignedp ? lshr_optab : ashr_optab)
1.1       root     2671:            : (unsignedp ? udiv_optab : sdiv_optab));
1.1.1.7 ! root     2672:   optab2 = (op1_is_pow2 ? optab1 : (unsignedp ? udivmod_optab : sdivmod_optab));
1.1       root     2673: 
                   2674:   for (compute_mode = mode; compute_mode != VOIDmode;
                   2675:        compute_mode = GET_MODE_WIDER_MODE (compute_mode))
                   2676:     if (optab1->handlers[(int) compute_mode].insn_code != CODE_FOR_nothing
                   2677:        || optab2->handlers[(int) compute_mode].insn_code != CODE_FOR_nothing)
                   2678:       break;
                   2679: 
                   2680:   if (compute_mode == VOIDmode)
                   2681:     for (compute_mode = mode; compute_mode != VOIDmode;
                   2682:         compute_mode = GET_MODE_WIDER_MODE (compute_mode))
                   2683:       if (optab1->handlers[(int) compute_mode].libfunc
                   2684:          || optab2->handlers[(int) compute_mode].libfunc)
                   2685:        break;
                   2686: 
1.1.1.6   root     2687:   /* If we still couldn't find a mode, use MODE, but we'll probably abort
                   2688:      in expand_binop.  */
1.1       root     2689:   if (compute_mode == VOIDmode)
                   2690:     compute_mode = mode;
                   2691: 
1.1.1.7 ! root     2692:   if (target && GET_MODE (target) == compute_mode)
        !          2693:     tquotient = target;
        !          2694:   else
        !          2695:     tquotient = gen_reg_rtx (compute_mode);
        !          2696: 
1.1.1.4   root     2697:   size = GET_MODE_BITSIZE (compute_mode);
1.1.1.7 ! root     2698: #if 0
        !          2699:   /* It should be possible to restrict the precision to GET_MODE_BITSIZE
        !          2700:      (mode), and thereby get better code when OP1 is a constant.  Do that for
        !          2701:      GCC 2.7.  It will require going over all usages of SIZE below.  */
        !          2702:   size = GET_MODE_BITSIZE (mode);
        !          2703: #endif
1.1.1.4   root     2704: 
1.1.1.7 ! root     2705:   /* Now convert to the best mode to use.  */
1.1       root     2706:   if (compute_mode != mode)
                   2707:     {
1.1.1.7 ! root     2708:       op0 = convert_modes (compute_mode, mode, op0, unsignedp);
1.1.1.6   root     2709:       op1 = convert_modes (compute_mode, mode, op1, unsignedp);
1.1       root     2710:     }
                   2711: 
1.1.1.7 ! root     2712:   /* If one of the operands is a volatile MEM, copy it into a register.  */
1.1.1.3   root     2713: 
1.1.1.7 ! root     2714:   if (GET_CODE (op0) == MEM && MEM_VOLATILE_P (op0))
        !          2715:     op0 = force_reg (compute_mode, op0);
        !          2716:   if (GET_CODE (op1) == MEM && MEM_VOLATILE_P (op1))
1.1.1.3   root     2717:     op1 = force_reg (compute_mode, op1);
                   2718: 
1.1.1.7 ! root     2719:   /* If we need the remainder or if OP1 is constant, we need to
        !          2720:      put OP0 in a register in case it has any queued subexpressions.  */
        !          2721:   if (rem_flag || op1_is_constant)
        !          2722:     op0 = force_reg (compute_mode, op0);
1.1.1.6   root     2723: 
1.1.1.7 ! root     2724:   last = get_last_insn ();
1.1.1.6   root     2725: 
1.1.1.7 ! root     2726:   /* Promote floor rouding to trunc rounding for unsigned operations.  */
        !          2727:   if (unsignedp)
        !          2728:     {
        !          2729:       if (code == FLOOR_DIV_EXPR)
        !          2730:        code = TRUNC_DIV_EXPR;
        !          2731:       if (code == FLOOR_MOD_EXPR)
        !          2732:        code = TRUNC_MOD_EXPR;
1.1.1.6   root     2733:     }
                   2734: 
1.1.1.7 ! root     2735:   if (op1 != const0_rtx)
        !          2736:     switch (code)
        !          2737:       {
        !          2738:       case TRUNC_MOD_EXPR:
        !          2739:       case TRUNC_DIV_EXPR:
        !          2740:        if (op1_is_constant && HOST_BITS_PER_WIDE_INT >= size)
        !          2741:          {
        !          2742:            if (unsignedp
        !          2743:                || (INTVAL (op1)
        !          2744:                    == (HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE (compute_mode) - 1)))
        !          2745:              {
        !          2746:                unsigned HOST_WIDE_INT mh, ml;
        !          2747:                int pre_shift, post_shift;
        !          2748:                int dummy;
        !          2749:                unsigned HOST_WIDE_INT d = INTVAL (op1);
        !          2750: 
        !          2751:                if (EXACT_POWER_OF_2_OR_ZERO_P (d))
        !          2752:                  {
        !          2753:                    pre_shift = floor_log2 (d);
        !          2754:                    if (rem_flag)
        !          2755:                      {
        !          2756:                        remainder = expand_binop (compute_mode, and_optab, op0,
        !          2757:                                                  GEN_INT (((HOST_WIDE_INT) 1 << pre_shift) - 1),
        !          2758:                                                  remainder, 1,
        !          2759:                                                  OPTAB_LIB_WIDEN);
        !          2760:                        if (remainder)
        !          2761:                          return gen_lowpart (mode, remainder);
        !          2762:                      }
        !          2763:                    quotient = expand_shift (RSHIFT_EXPR, compute_mode, op0,
        !          2764:                                             build_int_2 (pre_shift, 0),
        !          2765:                                             tquotient, 1);
        !          2766:                  }
        !          2767:                else if (d >= ((unsigned HOST_WIDE_INT) 1 << (size - 1)))
        !          2768:                  {
        !          2769:                    /* Most significant bit of divisor is set, emit a scc insn.
        !          2770:                       emit_store_flag needs to be passed a place for the
        !          2771:                       result.  */
        !          2772:                    quotient = emit_store_flag (tquotient, GEU, op0, op1,
        !          2773:                                                compute_mode, 1, 1);
        !          2774:                    /* Can emit_store_flag have failed? */
        !          2775:                    if (quotient == 0)
        !          2776:                      goto fail1;
        !          2777:                  }
        !          2778:                else
        !          2779:                  {
        !          2780:                    /* Find a suitable multiplier and right shift count instead
        !          2781:                       of multiplying with D.  */
        !          2782: 
        !          2783:                    mh = choose_multiplier (d, size, size,
        !          2784:                                            &ml, &post_shift, &dummy);
        !          2785: 
        !          2786:                    /* If the suggested multiplier is more than SIZE bits, we
        !          2787:                       can do better for even divisors, using an initial right
        !          2788:                       shift.  */
        !          2789:                    if (mh != 0 && (d & 1) == 0)
        !          2790:                      {
        !          2791:                        pre_shift = floor_log2 (d & -d);
        !          2792:                        mh = choose_multiplier (d >> pre_shift, size,
        !          2793:                                                size - pre_shift,
        !          2794:                                                &ml, &post_shift, &dummy);
        !          2795:                        if (mh)
        !          2796:                          abort ();
        !          2797:                      }
        !          2798:                    else
        !          2799:                      pre_shift = 0;
        !          2800: 
        !          2801:                    if (mh != 0)
        !          2802:                      {
        !          2803:                        rtx t1, t2, t3, t4;
        !          2804: 
        !          2805:                        t1 = expand_mult_highpart (compute_mode, op0, ml,
        !          2806:                                                   NULL_RTX, 1);
        !          2807:                        if (t1 == 0)
        !          2808:                          goto fail1;
        !          2809:                        t2 = force_operand (gen_rtx (MINUS, compute_mode,
        !          2810:                                                     op0, t1),
        !          2811:                                            NULL_RTX);
        !          2812:                        t3 = expand_shift (RSHIFT_EXPR, compute_mode, t2,
        !          2813:                                           build_int_2 (1, 0), NULL_RTX, 1);
        !          2814:                        t4 = force_operand (gen_rtx (PLUS, compute_mode,
        !          2815:                                                     t1, t3),
        !          2816:                                            NULL_RTX);
        !          2817:                        quotient = expand_shift (RSHIFT_EXPR, compute_mode, t4,
        !          2818:                                                 build_int_2 (post_shift - 1,
        !          2819:                                                              0),
        !          2820:                                                 tquotient, 1);
        !          2821:                      }
        !          2822:                    else
        !          2823:                      {
        !          2824:                        rtx t1, t2;
        !          2825: 
        !          2826:                        t1 = expand_shift (RSHIFT_EXPR, compute_mode, op0,
        !          2827:                                           build_int_2 (pre_shift, 0),
        !          2828:                                           NULL_RTX, 1);
        !          2829:                        t2 = expand_mult_highpart (compute_mode, t1, ml,
        !          2830:                                                   NULL_RTX, 1);
        !          2831:                        if (t2 == 0)
        !          2832:                          goto fail1;
        !          2833:                        quotient = expand_shift (RSHIFT_EXPR, compute_mode, t2,
        !          2834:                                                 build_int_2 (post_shift, 0),
        !          2835:                                                 tquotient, 1);
        !          2836:                      }
        !          2837:                  }
        !          2838: 
        !          2839:                insn = get_last_insn ();
        !          2840:                if (insn != last
        !          2841:                    && (set = single_set (insn)) != 0
        !          2842:                    && SET_DEST (set) == quotient)
        !          2843:                  REG_NOTES (insn)
        !          2844:                    = gen_rtx (EXPR_LIST, REG_EQUAL,
        !          2845:                               gen_rtx (UDIV, compute_mode, op0, op1),
        !          2846:                               REG_NOTES (insn));
        !          2847:              }
        !          2848:            else                /* TRUNC_DIV, signed */
        !          2849:              {
        !          2850:                unsigned HOST_WIDE_INT ml;
        !          2851:                int lgup, post_shift;
        !          2852:                HOST_WIDE_INT d = INTVAL (op1);
        !          2853:                unsigned HOST_WIDE_INT abs_d = d >= 0 ? d : -d;
        !          2854: 
        !          2855:                /* n rem d = n rem -d */
        !          2856:                if (rem_flag && d < 0)
        !          2857:                  {
        !          2858:                    d = abs_d;
        !          2859:                    op1 = GEN_INT (abs_d);
        !          2860:                  }
        !          2861: 
        !          2862:                if (d == 1)
        !          2863:                  quotient = op0;
        !          2864:                else if (d == -1)
        !          2865:                  quotient = expand_unop (compute_mode, neg_optab, op0,
        !          2866:                                          tquotient, 0);
        !          2867:                else if (EXACT_POWER_OF_2_OR_ZERO_P (d)
        !          2868:                         && (rem_flag ? smod_pow2_cheap : sdiv_pow2_cheap))
        !          2869:                  ;
        !          2870:                else if (EXACT_POWER_OF_2_OR_ZERO_P (abs_d))
        !          2871:                  {
        !          2872:                    lgup = floor_log2 (abs_d);
        !          2873:                    if (abs_d != 2 && BRANCH_COST < 3)
        !          2874:                      {
        !          2875:                        rtx label = gen_label_rtx ();
        !          2876:                        rtx t1;
        !          2877: 
        !          2878:                        t1 = copy_to_mode_reg (compute_mode, op0);
        !          2879:                        emit_cmp_insn (t1, const0_rtx, GE, 
        !          2880:                                       NULL_RTX, compute_mode, 0, 0);
        !          2881:                        emit_jump_insn (gen_bge (label));
        !          2882:                        expand_inc (t1, GEN_INT (abs_d - 1));
        !          2883:                        emit_label (label);
        !          2884:                        quotient = expand_shift (RSHIFT_EXPR, compute_mode, t1,
        !          2885:                                                 build_int_2 (lgup, 0),
        !          2886:                                                 tquotient, 0);
        !          2887:                      }
        !          2888:                    else
        !          2889:                      {
        !          2890:                        rtx t1, t2, t3;
        !          2891:                        t1 = expand_shift (RSHIFT_EXPR, compute_mode, op0,
        !          2892:                                           build_int_2 (size - 1, 0),
        !          2893:                                           NULL_RTX, 0);
        !          2894:                        t2 = expand_shift (RSHIFT_EXPR, compute_mode, t1,
        !          2895:                                           build_int_2 (size - lgup, 0),
        !          2896:                                           NULL_RTX, 1);
        !          2897:                        t3 = force_operand (gen_rtx (PLUS, compute_mode,
        !          2898:                                                     op0, t2),
        !          2899:                                            NULL_RTX);
        !          2900:                        quotient = expand_shift (RSHIFT_EXPR, compute_mode, t3,
        !          2901:                                                 build_int_2 (lgup, 0),
        !          2902:                                                 tquotient, 0);
        !          2903:                      }
        !          2904: 
        !          2905:                    /* We have computed OP0 / abs(OP1).  If OP1 is negative, negate
        !          2906:                       the quotient.  */
        !          2907:                    if (d < 0)
        !          2908:                      {
        !          2909:                        insn = get_last_insn ();
        !          2910:                        if (insn != last
        !          2911:                            && (set = single_set (insn)) != 0
        !          2912:                            && SET_DEST (set) == quotient)
        !          2913:                          REG_NOTES (insn)
        !          2914:                            = gen_rtx (EXPR_LIST, REG_EQUAL,
        !          2915:                                       gen_rtx (DIV, compute_mode, op0,
        !          2916:                                                GEN_INT (abs_d)),
        !          2917:                                       REG_NOTES (insn));
        !          2918: 
        !          2919:                        quotient = expand_unop (compute_mode, neg_optab,
        !          2920:                                                quotient, quotient, 0);
        !          2921:                      }
        !          2922:                  }
        !          2923:                else
        !          2924:                  {
        !          2925:                    choose_multiplier (abs_d, size, size - 1,
        !          2926:                                       &ml, &post_shift, &lgup);
        !          2927:                    if (ml < (unsigned HOST_WIDE_INT) 1 << (size - 1))
        !          2928:                      {
        !          2929:                        rtx t1, t2, t3;
        !          2930: 
        !          2931:                        t1 = expand_mult_highpart (compute_mode, op0, ml,
        !          2932:                                                   NULL_RTX, 0);
        !          2933:                        if (t1 == 0)
        !          2934:                          goto fail1;
        !          2935:                        t2 = expand_shift (RSHIFT_EXPR, compute_mode, t1,
        !          2936:                                           build_int_2 (post_shift, 0), NULL_RTX, 0);
        !          2937:                        t3 = expand_shift (RSHIFT_EXPR, compute_mode, op0,
        !          2938:                                           build_int_2 (size - 1, 0), NULL_RTX, 0);
        !          2939:                        if (d < 0)
        !          2940:                          quotient = force_operand (gen_rtx (MINUS, compute_mode, t3, t2),
        !          2941:                                                    tquotient);
        !          2942:                        else
        !          2943:                          quotient = force_operand (gen_rtx (MINUS, compute_mode, t2, t3),
        !          2944:                                                    tquotient);
        !          2945:                      }
        !          2946:                    else
        !          2947:                      {
        !          2948:                        rtx t1, t2, t3, t4;
        !          2949: 
        !          2950:                        ml |= (~(unsigned HOST_WIDE_INT) 0) << (size - 1);
        !          2951:                        t1 = expand_mult_highpart (compute_mode, op0, ml,
        !          2952:                                                   NULL_RTX, 0);
        !          2953:                        if (t1 == 0)
        !          2954:                          goto fail1;
        !          2955:                        t2 = force_operand (gen_rtx (PLUS, compute_mode, t1, op0),
        !          2956:                                            NULL_RTX);
        !          2957:                        t3 = expand_shift (RSHIFT_EXPR, compute_mode, t2,
        !          2958:                                           build_int_2 (post_shift, 0), NULL_RTX, 0);
        !          2959:                        t4 = expand_shift (RSHIFT_EXPR, compute_mode, op0,
        !          2960:                                           build_int_2 (size - 1, 0), NULL_RTX, 0);
        !          2961:                        if (d < 0)
        !          2962:                          quotient = force_operand (gen_rtx (MINUS, compute_mode, t4, t3),
        !          2963:                                                    tquotient);
        !          2964:                        else
        !          2965:                          quotient = force_operand (gen_rtx (MINUS, compute_mode, t3, t4),
        !          2966:                                                    tquotient);
        !          2967:                      }
        !          2968:                  }
        !          2969: 
        !          2970:                insn = get_last_insn ();
        !          2971:                if (insn != last
        !          2972:                    && (set = single_set (insn)) != 0
        !          2973:                    && SET_DEST (set) == quotient)
        !          2974:                  REG_NOTES (insn)
        !          2975:                    = gen_rtx (EXPR_LIST, REG_EQUAL,
        !          2976:                               gen_rtx (DIV, compute_mode, op0, op1),
        !          2977:                               REG_NOTES (insn));
        !          2978:              }
        !          2979:            break;
        !          2980:          }
        !          2981:       fail1:
        !          2982:        delete_insns_since (last);
        !          2983:        break;
1.1       root     2984: 
1.1.1.7 ! root     2985:       case FLOOR_DIV_EXPR:
        !          2986:       case FLOOR_MOD_EXPR:
        !          2987:       /* We will come here only for signed operations.  */
        !          2988:        if (op1_is_constant && HOST_BITS_PER_WIDE_INT >= size)
        !          2989:          {
        !          2990:            unsigned HOST_WIDE_INT mh, ml;
        !          2991:            int pre_shift, lgup, post_shift;
        !          2992:            HOST_WIDE_INT d = INTVAL (op1);
        !          2993: 
        !          2994:            if (d > 0)
        !          2995:              {
        !          2996:                /* We could just as easily deal with negative constants here,
        !          2997:                   but it does not seem worth the trouble for GCC 2.6.  */
        !          2998:                if (EXACT_POWER_OF_2_OR_ZERO_P (d))
        !          2999:                  {
        !          3000:                    pre_shift = floor_log2 (d);
        !          3001:                    if (rem_flag)
        !          3002:                      {
        !          3003:                        remainder = expand_binop (compute_mode, and_optab, op0,
        !          3004:                                                  GEN_INT (((HOST_WIDE_INT) 1 << pre_shift) - 1),
        !          3005:                                                  remainder, 0, OPTAB_LIB_WIDEN);
        !          3006:                        if (remainder)
        !          3007:                          return gen_lowpart (mode, remainder);
        !          3008:                      }
        !          3009:                    quotient = expand_shift (RSHIFT_EXPR, compute_mode, op0,
        !          3010:                                             build_int_2 (pre_shift, 0),
        !          3011:                                             tquotient, 0);
        !          3012:                  }
        !          3013:                else
        !          3014:                  {
        !          3015:                    rtx t1, t2, t3, t4;
        !          3016: 
        !          3017:                    mh = choose_multiplier (d, size, size - 1,
        !          3018:                                            &ml, &post_shift, &lgup);
        !          3019:                    if (mh)
        !          3020:                      abort ();
        !          3021: 
        !          3022:                    t1 = expand_shift (RSHIFT_EXPR, compute_mode, op0,
        !          3023:                                       build_int_2 (size - 1, 0), NULL_RTX, 0);
        !          3024:                    t2 = expand_binop (compute_mode, xor_optab, op0, t1,
        !          3025:                                       NULL_RTX, 0, OPTAB_WIDEN);
        !          3026:                    t3 = expand_mult_highpart (compute_mode, t2, ml,
        !          3027:                                               NULL_RTX, 1);
        !          3028:                    if (t3 != 0)
        !          3029:                      {
        !          3030:                        t4 = expand_shift (RSHIFT_EXPR, compute_mode, t3,
        !          3031:                                           build_int_2 (post_shift, 0),
        !          3032:                                           NULL_RTX, 1);
        !          3033:                        quotient = expand_binop (compute_mode, xor_optab,
        !          3034:                                                 t4, t1, tquotient, 0,
        !          3035:                                                 OPTAB_WIDEN);
        !          3036:                      }
        !          3037:                  }
        !          3038:              }
        !          3039:            else
        !          3040:              {
        !          3041:                rtx nsign, t1, t2, t3, t4;
        !          3042:                t1 = force_operand (gen_rtx (PLUS, compute_mode,
        !          3043:                                             op0, constm1_rtx), NULL_RTX);
        !          3044:                t2 = expand_binop (compute_mode, ior_optab, op0, t1, NULL_RTX,
        !          3045:                                   0, OPTAB_WIDEN);
        !          3046:                nsign = expand_shift (RSHIFT_EXPR, compute_mode, t2,
        !          3047:                                      build_int_2 (size - 1, 0), NULL_RTX, 0);
        !          3048:                t3 = force_operand (gen_rtx (MINUS, compute_mode, t1, nsign),
        !          3049:                                    NULL_RTX);
        !          3050:                t4 = expand_divmod (0, TRUNC_DIV_EXPR, compute_mode, t3, op1,
        !          3051:                                    NULL_RTX, 0);
        !          3052:                if (t4)
        !          3053:                  {
        !          3054:                    rtx t5;
        !          3055:                    t5 = expand_unop (compute_mode, one_cmpl_optab, nsign,
        !          3056:                                      NULL_RTX, 0);
        !          3057:                    quotient = force_operand (gen_rtx (PLUS, compute_mode,
        !          3058:                                                       t4, t5),
        !          3059:                                              tquotient);
        !          3060:                  }
        !          3061:              }
        !          3062:          }
1.1.1.6   root     3063: 
1.1.1.7 ! root     3064:        if (quotient != 0)
        !          3065:          break;
        !          3066:        delete_insns_since (last);
1.1       root     3067: 
1.1.1.7 ! root     3068:        /* Try using an instruction that produces both the quotient and
        !          3069:           remainder, using truncation.  We can easily compensate the quotient
        !          3070:           or remainder to get floor rounding, once we have the remainder.
        !          3071:           Notice that we compute also the final remainder value here,
        !          3072:           and return the result right away.  */
        !          3073:        if (target == 0)
        !          3074:          target = gen_reg_rtx (compute_mode);
        !          3075:        if (rem_flag)
        !          3076:          {
        !          3077:            remainder = target;
        !          3078:            quotient = gen_reg_rtx (compute_mode);
        !          3079:          }
        !          3080:        else
        !          3081:          {
        !          3082:            quotient = target;
        !          3083:            remainder = gen_reg_rtx (compute_mode);
        !          3084:          }
        !          3085: 
        !          3086:        if (expand_twoval_binop (sdivmod_optab, op0, op1,
        !          3087:                                 quotient, remainder, 0))
        !          3088:          {
        !          3089:            /* This could be computed with a branch-less sequence.
        !          3090:               Save that for later.  */
        !          3091:            rtx tem;
        !          3092:            rtx label = gen_label_rtx ();
        !          3093:            emit_cmp_insn (remainder, const0_rtx, EQ, NULL_RTX,
        !          3094:                           compute_mode, 0, 0);
        !          3095:            emit_jump_insn (gen_beq (label));
        !          3096:            tem = expand_binop (compute_mode, xor_optab, op0, op1,
        !          3097:                                NULL_RTX, 0, OPTAB_WIDEN);
        !          3098:            emit_cmp_insn (tem, const0_rtx, GE, NULL_RTX, compute_mode, 0, 0);
        !          3099:            emit_jump_insn (gen_bge (label));
        !          3100:            expand_dec (quotient, const1_rtx);
        !          3101:            expand_inc (remainder, op1);
        !          3102:            emit_label (label);
        !          3103:            return gen_lowpart (mode, rem_flag ? remainder : quotient);
        !          3104:          }
1.1       root     3105: 
1.1.1.7 ! root     3106:        /* No luck with division elimination or divmod.  Have to do it
        !          3107:           by conditionally adjusting op0 *and* the result.  */
        !          3108:        {
        !          3109:          rtx label1, label2, label3, label4, label5;
        !          3110:          rtx adjusted_op0;
        !          3111:          rtx tem;
        !          3112: 
        !          3113:          quotient = gen_reg_rtx (compute_mode);
        !          3114:          adjusted_op0 = copy_to_mode_reg (compute_mode, op0);
        !          3115:          label1 = gen_label_rtx ();
        !          3116:          label2 = gen_label_rtx ();
        !          3117:          label3 = gen_label_rtx ();
        !          3118:          label4 = gen_label_rtx ();
        !          3119:          label5 = gen_label_rtx ();
        !          3120:          emit_cmp_insn (op1, const0_rtx, LT, NULL_RTX, compute_mode, 0, 0);
        !          3121:          emit_jump_insn (gen_blt (label2));
        !          3122:          emit_cmp_insn (adjusted_op0, const0_rtx, LT, NULL_RTX,
        !          3123:                         compute_mode, 0, 0);
        !          3124:          emit_jump_insn (gen_blt (label1));
        !          3125:          tem = expand_binop (compute_mode, sdiv_optab, adjusted_op0, op1,
        !          3126:                              quotient, 0, OPTAB_LIB_WIDEN);
        !          3127:          if (tem != quotient)
        !          3128:            emit_move_insn (quotient, tem);
        !          3129:          emit_jump_insn (gen_jump (label5));
        !          3130:          emit_barrier ();
        !          3131:          emit_label (label1);
        !          3132:          expand_inc (adjusted_op0, const1_rtx);
        !          3133:          emit_jump_insn (gen_jump (label4));
        !          3134:          emit_barrier ();
        !          3135:          emit_label (label2);
        !          3136:          emit_cmp_insn (adjusted_op0, const0_rtx, GT, NULL_RTX,
        !          3137:                         compute_mode, 0, 0);
        !          3138:          emit_jump_insn (gen_bgt (label3));
        !          3139:          tem = expand_binop (compute_mode, sdiv_optab, adjusted_op0, op1,
        !          3140:                              quotient, 0, OPTAB_LIB_WIDEN);
        !          3141:          if (tem != quotient)
        !          3142:            emit_move_insn (quotient, tem);
        !          3143:          emit_jump_insn (gen_jump (label5));
        !          3144:          emit_barrier ();
        !          3145:          emit_label (label3);
1.1       root     3146:          expand_dec (adjusted_op0, const1_rtx);
1.1.1.7 ! root     3147:          emit_label (label4);
        !          3148:          tem = expand_binop (compute_mode, sdiv_optab, adjusted_op0, op1,
        !          3149:                              quotient, 0, OPTAB_LIB_WIDEN);
        !          3150:          if (tem != quotient)
        !          3151:            emit_move_insn (quotient, tem);
        !          3152:          expand_dec (quotient, const1_rtx);
        !          3153:          emit_label (label5);
1.1       root     3154:        }
1.1.1.7 ! root     3155:        break;
1.1       root     3156: 
1.1.1.7 ! root     3157:       case CEIL_DIV_EXPR:
        !          3158:       case CEIL_MOD_EXPR:
        !          3159:        if (unsignedp)
        !          3160:          {
        !          3161:            if (op1_is_constant && EXACT_POWER_OF_2_OR_ZERO_P (INTVAL (op1)))
        !          3162:              {
        !          3163:                rtx t1, t2, t3;
        !          3164:                unsigned HOST_WIDE_INT d = INTVAL (op1);
        !          3165:                t1 = expand_shift (RSHIFT_EXPR, compute_mode, op0,
        !          3166:                                   build_int_2 (floor_log2 (d), 0),
        !          3167:                                   tquotient, 1);
        !          3168:                t2 = expand_binop (compute_mode, and_optab, op0,
        !          3169:                                   GEN_INT (d - 1),
        !          3170:                                   NULL_RTX, 1, OPTAB_LIB_WIDEN);
        !          3171:                t3 = gen_reg_rtx (compute_mode);
        !          3172:                t3 = emit_store_flag (t3, NE, t2, const0_rtx,
        !          3173:                                      compute_mode, 1, 1);
        !          3174:                if (t3 == 0)
        !          3175:                  {
        !          3176:                    rtx lab;
        !          3177:                    lab = gen_label_rtx ();
        !          3178:                    emit_cmp_insn (t2, const0_rtx, EQ, NULL_RTX,
        !          3179:                                   compute_mode, 0, 0);
        !          3180:                    emit_jump_insn (gen_beq (lab));
        !          3181:                    expand_inc (t1, const1_rtx);
        !          3182:                    emit_label (lab);
        !          3183:                    quotient = t1;
        !          3184:                  }
        !          3185:                else
        !          3186:                  quotient = force_operand (gen_rtx (PLUS, compute_mode,
        !          3187:                                                     t1, t3),
        !          3188:                                            tquotient);
        !          3189:                break;
        !          3190:              }
        !          3191: 
        !          3192:            /* Try using an instruction that produces both the quotient and
        !          3193:               remainder, using truncation.  We can easily compensate the
        !          3194:               quotient or remainder to get ceiling rounding, once we have the
        !          3195:               remainder.  Notice that we compute also the final remainder
        !          3196:               value here, and return the result right away.  */
        !          3197:            if (target == 0)
        !          3198:              target = gen_reg_rtx (compute_mode);
        !          3199:            if (rem_flag)
        !          3200:              {
        !          3201:                remainder = target;
        !          3202:                quotient = gen_reg_rtx (compute_mode);
        !          3203:              }
        !          3204:            else
        !          3205:              {
        !          3206:                quotient = target;
        !          3207:                remainder = gen_reg_rtx (compute_mode);
        !          3208:              }
        !          3209: 
        !          3210:            if (expand_twoval_binop (udivmod_optab, op0, op1, quotient,
        !          3211:                                     remainder, 1))
        !          3212:              {
        !          3213:                /* This could be computed with a branch-less sequence.
        !          3214:                   Save that for later.  */
        !          3215:                rtx label = gen_label_rtx ();
        !          3216:                emit_cmp_insn (remainder, const0_rtx, EQ, NULL_RTX,
        !          3217:                               compute_mode, 0, 0);
        !          3218:                emit_jump_insn (gen_beq (label));
        !          3219:                expand_inc (quotient, const1_rtx);
        !          3220:                expand_dec (remainder, op1);
        !          3221:                emit_label (label);
        !          3222:                return gen_lowpart (mode, rem_flag ? remainder : quotient);
        !          3223:              }
        !          3224: 
        !          3225:            /* No luck with division elimination or divmod.  Have to do it
        !          3226:               by conditionally adjusting op0 *and* the result.  */
        !          3227:            {
        !          3228:              rtx label1, label2;
        !          3229:              rtx adjusted_op0, tem;
        !          3230: 
        !          3231:              quotient = gen_reg_rtx (compute_mode);
        !          3232:              adjusted_op0 = copy_to_mode_reg (compute_mode, op0);
        !          3233:              label1 = gen_label_rtx ();
        !          3234:              label2 = gen_label_rtx ();
        !          3235:              emit_cmp_insn (adjusted_op0, const0_rtx, NE, NULL_RTX,
        !          3236:                             compute_mode, 0, 0);
        !          3237:              emit_jump_insn (gen_bne (label1));
        !          3238:              emit_move_insn  (quotient, const0_rtx);
        !          3239:              emit_jump_insn (gen_jump (label2));
        !          3240:              emit_barrier ();
        !          3241:              emit_label (label1);
        !          3242:              expand_dec (adjusted_op0, const1_rtx);
        !          3243:              tem = expand_binop (compute_mode, udiv_optab, adjusted_op0, op1,
        !          3244:                                  quotient, 1, OPTAB_LIB_WIDEN);
        !          3245:              if (tem != quotient)
        !          3246:                emit_move_insn (quotient, tem);
        !          3247:              expand_inc (quotient, const1_rtx);
        !          3248:              emit_label (label2);
        !          3249:            }
        !          3250:          }
        !          3251:        else /* signed */
        !          3252:          {
        !          3253:            if (op1_is_constant && EXACT_POWER_OF_2_OR_ZERO_P (INTVAL (op1))
        !          3254:                && INTVAL (op1) >= 0)
        !          3255:              {
        !          3256:                /* This is extremely similar to the code for the unsigned case
        !          3257:                   above.  For 2.7 we should merge these variants, but for
        !          3258:                   2.6.1 I don't want to touch the code for unsigned since that
        !          3259:                   get used in C.  The signed case will only be used by other
        !          3260:                   languages (Ada).  */
        !          3261: 
        !          3262:                rtx t1, t2, t3;
        !          3263:                unsigned HOST_WIDE_INT d = INTVAL (op1);
        !          3264:                t1 = expand_shift (RSHIFT_EXPR, compute_mode, op0,
        !          3265:                                   build_int_2 (floor_log2 (d), 0),
        !          3266:                                   tquotient, 0);
        !          3267:                t2 = expand_binop (compute_mode, and_optab, op0,
        !          3268:                                   GEN_INT (d - 1),
        !          3269:                                   NULL_RTX, 1, OPTAB_LIB_WIDEN);
        !          3270:                t3 = gen_reg_rtx (compute_mode);
        !          3271:                t3 = emit_store_flag (t3, NE, t2, const0_rtx,
        !          3272:                                      compute_mode, 1, 1);
        !          3273:                if (t3 == 0)
        !          3274:                  {
        !          3275:                    rtx lab;
        !          3276:                    lab = gen_label_rtx ();
        !          3277:                    emit_cmp_insn (t2, const0_rtx, EQ, NULL_RTX,
        !          3278:                                   compute_mode, 0, 0);
        !          3279:                    emit_jump_insn (gen_beq (lab));
        !          3280:                    expand_inc (t1, const1_rtx);
        !          3281:                    emit_label (lab);
        !          3282:                    quotient = t1;
        !          3283:                  }
        !          3284:                else
        !          3285:                  quotient = force_operand (gen_rtx (PLUS, compute_mode,
        !          3286:                                                     t1, t3),
        !          3287:                                            tquotient);
        !          3288:                break;
        !          3289:              }
        !          3290: 
        !          3291:            /* Try using an instruction that produces both the quotient and
        !          3292:               remainder, using truncation.  We can easily compensate the
        !          3293:               quotient or remainder to get ceiling rounding, once we have the
        !          3294:               remainder.  Notice that we compute also the final remainder
        !          3295:               value here, and return the result right away.  */
        !          3296:            if (target == 0)
        !          3297:              target = gen_reg_rtx (compute_mode);
        !          3298:            if (rem_flag)
        !          3299:              {
        !          3300:                remainder = target;
        !          3301:                quotient = gen_reg_rtx (compute_mode);
        !          3302:              }
        !          3303:            else
        !          3304:              {
        !          3305:                quotient = target;
        !          3306:                remainder = gen_reg_rtx (compute_mode);
        !          3307:              }
        !          3308: 
        !          3309:            if (expand_twoval_binop (sdivmod_optab, op0, op1, quotient,
        !          3310:                                     remainder, 0))
        !          3311:              {
        !          3312:                /* This could be computed with a branch-less sequence.
        !          3313:                   Save that for later.  */
        !          3314:                rtx tem;
        !          3315:                rtx label = gen_label_rtx ();
        !          3316:                emit_cmp_insn (remainder, const0_rtx, EQ, NULL_RTX,
        !          3317:                               compute_mode, 0, 0);
        !          3318:                emit_jump_insn (gen_beq (label));
        !          3319:                tem = expand_binop (compute_mode, xor_optab, op0, op1,
        !          3320:                                    NULL_RTX, 0, OPTAB_WIDEN);
        !          3321:                emit_cmp_insn (tem, const0_rtx, LT, NULL_RTX,
        !          3322:                               compute_mode, 0, 0);
        !          3323:                emit_jump_insn (gen_blt (label));
        !          3324:                expand_inc (quotient, const1_rtx);
        !          3325:                expand_dec (remainder, op1);
        !          3326:                emit_label (label);
        !          3327:                return gen_lowpart (mode, rem_flag ? remainder : quotient);
        !          3328:              }
        !          3329: 
        !          3330:            /* No luck with division elimination or divmod.  Have to do it
        !          3331:               by conditionally adjusting op0 *and* the result.  */
        !          3332:            {
        !          3333:              rtx label1, label2, label3, label4, label5;
        !          3334:              rtx adjusted_op0;
        !          3335:              rtx tem;
        !          3336: 
        !          3337:              quotient = gen_reg_rtx (compute_mode);
        !          3338:              adjusted_op0 = copy_to_mode_reg (compute_mode, op0);
        !          3339:              label1 = gen_label_rtx ();
        !          3340:              label2 = gen_label_rtx ();
        !          3341:              label3 = gen_label_rtx ();
        !          3342:              label4 = gen_label_rtx ();
        !          3343:              label5 = gen_label_rtx ();
        !          3344:              emit_cmp_insn (op1, const0_rtx, LT, NULL_RTX,
        !          3345:                             compute_mode, 0, 0);
        !          3346:              emit_jump_insn (gen_blt (label2));
        !          3347:              emit_cmp_insn (adjusted_op0, const0_rtx, GT, NULL_RTX,
        !          3348:                             compute_mode, 0, 0);
        !          3349:              emit_jump_insn (gen_bgt (label1));
        !          3350:              tem = expand_binop (compute_mode, sdiv_optab, adjusted_op0, op1,
        !          3351:                                  quotient, 0, OPTAB_LIB_WIDEN);
        !          3352:              if (tem != quotient)
        !          3353:                emit_move_insn (quotient, tem);
        !          3354:              emit_jump_insn (gen_jump (label5));
        !          3355:              emit_barrier ();
        !          3356:              emit_label (label1);
        !          3357:              expand_dec (adjusted_op0, const1_rtx);
        !          3358:              emit_jump_insn (gen_jump (label4));
        !          3359:              emit_barrier ();
        !          3360:              emit_label (label2);
        !          3361:              emit_cmp_insn (adjusted_op0, const0_rtx, LT, NULL_RTX,
        !          3362:                             compute_mode, 0, 0);
        !          3363:              emit_jump_insn (gen_blt (label3));
        !          3364:              tem = expand_binop (compute_mode, sdiv_optab, adjusted_op0, op1,
        !          3365:                                  quotient, 0, OPTAB_LIB_WIDEN);
        !          3366:              if (tem != quotient)
        !          3367:                emit_move_insn (quotient, tem);
        !          3368:              emit_jump_insn (gen_jump (label5));
        !          3369:              emit_barrier ();
        !          3370:              emit_label (label3);
        !          3371:              expand_inc (adjusted_op0, const1_rtx);
        !          3372:              emit_label (label4);
        !          3373:              tem = expand_binop (compute_mode, sdiv_optab, adjusted_op0, op1,
        !          3374:                                  quotient, 0, OPTAB_LIB_WIDEN);
        !          3375:              if (tem != quotient)
        !          3376:                emit_move_insn (quotient, tem);
        !          3377:              expand_inc (quotient, const1_rtx);
        !          3378:              emit_label (label5);
1.1       root     3379:            }
1.1.1.7 ! root     3380:          }
        !          3381:        break;
1.1.1.6   root     3382: 
1.1.1.7 ! root     3383:       case EXACT_DIV_EXPR:
        !          3384:        if (op1_is_constant && HOST_BITS_PER_WIDE_INT >= size)
        !          3385:          {
        !          3386:            HOST_WIDE_INT d = INTVAL (op1);
        !          3387:            unsigned HOST_WIDE_INT ml;
        !          3388:            int post_shift;
        !          3389:            rtx t1;
        !          3390: 
        !          3391:            post_shift = floor_log2 (d & -d);
        !          3392:            ml = invert_mod2n (d >> post_shift, size);
        !          3393:            t1 = expand_mult (compute_mode, op0, GEN_INT (ml), NULL_RTX,
        !          3394:                              unsignedp);
        !          3395:            quotient = expand_shift (RSHIFT_EXPR, compute_mode, t1,
        !          3396:                                     build_int_2 (post_shift, 0),
        !          3397:                                     NULL_RTX, unsignedp);
        !          3398: 
        !          3399:            insn = get_last_insn ();
        !          3400:            REG_NOTES (insn)
        !          3401:              = gen_rtx (EXPR_LIST, REG_EQUAL,
        !          3402:                         gen_rtx (unsignedp ? UDIV : DIV, compute_mode,
        !          3403:                                  op0, op1),
        !          3404:                         REG_NOTES (insn));
        !          3405:          }
        !          3406:        break;
1.1       root     3407: 
1.1.1.7 ! root     3408:       case ROUND_DIV_EXPR:
        !          3409:       case ROUND_MOD_EXPR:
        !          3410:        if (unsignedp)
        !          3411:          {
        !          3412:            rtx tem;
        !          3413:            rtx label;
        !          3414:            label = gen_label_rtx ();
        !          3415:            quotient = gen_reg_rtx (compute_mode);
        !          3416:            remainder = gen_reg_rtx (compute_mode);
        !          3417:            if (expand_twoval_binop (udivmod_optab, op0, op1, quotient, remainder, 1) == 0)
        !          3418:              {
        !          3419:                rtx tem;
        !          3420:                quotient = expand_binop (compute_mode, udiv_optab, op0, op1,
        !          3421:                                         quotient, 1, OPTAB_LIB_WIDEN);
        !          3422:                tem = expand_mult (compute_mode, quotient, op1, NULL_RTX, 1);
        !          3423:                remainder = expand_binop (compute_mode, sub_optab, op0, tem,
        !          3424:                                          remainder, 1, OPTAB_LIB_WIDEN);
        !          3425:              }
        !          3426:            tem = plus_constant (op1, -1);
        !          3427:            tem = expand_shift (RSHIFT_EXPR, compute_mode, tem,
        !          3428:                                build_int_2 (1, 0), NULL_RTX, 1);
        !          3429:            emit_cmp_insn (remainder, tem, LEU, NULL_RTX, compute_mode, 0, 0);
        !          3430:            emit_jump_insn (gen_bleu (label));
        !          3431:            expand_inc (quotient, const1_rtx);
        !          3432:            expand_dec (remainder, op1);
        !          3433:            emit_label (label);
        !          3434:          }
        !          3435:        else
        !          3436:          {
        !          3437:            rtx abs_rem, abs_op1, tem, mask;
        !          3438:            rtx label;
        !          3439:            label = gen_label_rtx ();
        !          3440:            quotient = gen_reg_rtx (compute_mode);
        !          3441:            remainder = gen_reg_rtx (compute_mode);
        !          3442:            if (expand_twoval_binop (sdivmod_optab, op0, op1, quotient, remainder, 0) == 0)
        !          3443:              {
        !          3444:                rtx tem;
        !          3445:                quotient = expand_binop (compute_mode, sdiv_optab, op0, op1,
        !          3446:                                         quotient, 0, OPTAB_LIB_WIDEN);
        !          3447:                tem = expand_mult (compute_mode, quotient, op1, NULL_RTX, 0);
        !          3448:                remainder = expand_binop (compute_mode, sub_optab, op0, tem,
        !          3449:                                          remainder, 0, OPTAB_LIB_WIDEN);
        !          3450:              }
        !          3451:            abs_rem = expand_abs (compute_mode, remainder, NULL_RTX, 0, 0);
        !          3452:            abs_op1 = expand_abs (compute_mode, op1, NULL_RTX, 0, 0);
        !          3453:            tem = expand_shift (LSHIFT_EXPR, compute_mode, abs_rem,
        !          3454:                                build_int_2 (1, 0), NULL_RTX, 1);
        !          3455:            emit_cmp_insn (tem, abs_op1, LTU, NULL_RTX, compute_mode, 0, 0);
        !          3456:            emit_jump_insn (gen_bltu (label));
        !          3457:            tem = expand_binop (compute_mode, xor_optab, op0, op1,
        !          3458:                                NULL_RTX, 0, OPTAB_WIDEN);
        !          3459:            mask = expand_shift (RSHIFT_EXPR, compute_mode, tem,
        !          3460:                                build_int_2 (size - 1, 0), NULL_RTX, 0);
        !          3461:            tem = expand_binop (compute_mode, xor_optab, mask, const1_rtx,
        !          3462:                                NULL_RTX, 0, OPTAB_WIDEN);
        !          3463:            tem = expand_binop (compute_mode, sub_optab, tem, mask,
        !          3464:                                NULL_RTX, 0, OPTAB_WIDEN);
        !          3465:            expand_inc (quotient, tem);
        !          3466:            tem = expand_binop (compute_mode, xor_optab, mask, op1,
        !          3467:                                NULL_RTX, 0, OPTAB_WIDEN);
        !          3468:            tem = expand_binop (compute_mode, sub_optab, tem, mask,
        !          3469:                                NULL_RTX, 0, OPTAB_WIDEN);
        !          3470:            expand_dec (remainder, tem);
        !          3471:            emit_label (label);
        !          3472:          }
        !          3473:        return gen_lowpart (mode, rem_flag ? remainder : quotient);
        !          3474:       }
        !          3475: 
        !          3476:   if (quotient == 0)
1.1       root     3477:     {
1.1.1.7 ! root     3478:       if (rem_flag)
1.1       root     3479:        {
1.1.1.7 ! root     3480:          /* Try to produce the remainder directly without a library call.  */
        !          3481:          remainder = sign_expand_binop (compute_mode, umod_optab, smod_optab,
        !          3482:                                         op0, op1, target,
        !          3483:                                         unsignedp, OPTAB_WIDEN);
        !          3484:          if (remainder == 0)
1.1       root     3485:            {
                   3486:              /* No luck there.  Can we do remainder and divide at once
                   3487:                 without a library call?  */
1.1.1.7 ! root     3488:              remainder = gen_reg_rtx (compute_mode);
        !          3489:              if (! expand_twoval_binop ((unsignedp
        !          3490:                                          ? udivmod_optab
        !          3491:                                          : sdivmod_optab),
        !          3492:                                         op0, op1,
        !          3493:                                         NULL_RTX, remainder, unsignedp))
        !          3494:                remainder = 0;
1.1       root     3495:            }
1.1.1.7 ! root     3496: 
        !          3497:          if (remainder)
        !          3498:            return gen_lowpart (mode, remainder);
1.1       root     3499:        }
                   3500: 
1.1.1.7 ! root     3501:       /* Produce the quotient.  */
1.1       root     3502:       /* Try a quotient insn, but not a library call.  */
1.1.1.7 ! root     3503:       quotient = sign_expand_binop (compute_mode, udiv_optab, sdiv_optab,
        !          3504:                                    op0, op1, rem_flag ? NULL_RTX : target,
        !          3505:                                    unsignedp, OPTAB_WIDEN);
        !          3506:       if (quotient == 0)
1.1       root     3507:        {
                   3508:          /* No luck there.  Try a quotient-and-remainder insn,
                   3509:             keeping the quotient alone.  */
1.1.1.7 ! root     3510:          quotient = gen_reg_rtx (compute_mode);
1.1       root     3511:          if (! expand_twoval_binop (unsignedp ? udivmod_optab : sdivmod_optab,
1.1.1.7 ! root     3512:                                     op0, op1,
        !          3513:                                     quotient, NULL_RTX, unsignedp))
        !          3514:            {
        !          3515:              quotient = 0;
        !          3516:              if (! rem_flag)
        !          3517:                /* Still no luck.  If we are not computing the remainder,
        !          3518:                   use a library call for the quotient.  */
        !          3519:                quotient = sign_expand_binop (compute_mode,
        !          3520:                                              udiv_optab, sdiv_optab,
        !          3521:                                              op0, op1, target,
        !          3522:                                              unsignedp, OPTAB_LIB_WIDEN);
        !          3523:            }
1.1       root     3524:        }
                   3525:     }
                   3526: 
                   3527:   if (rem_flag)
                   3528:     {
1.1.1.7 ! root     3529:       if (quotient == 0)
1.1       root     3530:        /* No divide instruction either.  Use library for remainder.  */
1.1.1.7 ! root     3531:        remainder = sign_expand_binop (compute_mode, umod_optab, smod_optab,
        !          3532:                                       op0, op1, target,
        !          3533:                                       unsignedp, OPTAB_LIB_WIDEN);
1.1       root     3534:       else
                   3535:        {
                   3536:          /* We divided.  Now finish doing X - Y * (X / Y).  */
1.1.1.7 ! root     3537:          remainder = expand_mult (compute_mode, quotient, op1,
        !          3538:                                   NULL_RTX, unsignedp);
        !          3539:          remainder = expand_binop (compute_mode, sub_optab, op0,
        !          3540:                                    remainder, target, unsignedp,
        !          3541:                                    OPTAB_LIB_WIDEN);
1.1       root     3542:        }
                   3543:     }
                   3544: 
1.1.1.7 ! root     3545:   return gen_lowpart (mode, rem_flag ? remainder : quotient);
1.1       root     3546: }
                   3547: 
                   3548: /* Return a tree node with data type TYPE, describing the value of X.
                   3549:    Usually this is an RTL_EXPR, if there is no obvious better choice.
                   3550:    X may be an expression, however we only support those expressions
                   3551:    generated by loop.c.   */
                   3552: 
                   3553: tree
                   3554: make_tree (type, x)
                   3555:      tree type;
                   3556:      rtx x;
                   3557: {
                   3558:   tree t;
                   3559: 
                   3560:   switch (GET_CODE (x))
                   3561:     {
                   3562:     case CONST_INT:
                   3563:       t = build_int_2 (INTVAL (x),
1.1.1.6   root     3564:                       TREE_UNSIGNED (type) || INTVAL (x) >= 0 ? 0 : -1);
1.1       root     3565:       TREE_TYPE (t) = type;
                   3566:       return t;
                   3567: 
                   3568:     case CONST_DOUBLE:
                   3569:       if (GET_MODE (x) == VOIDmode)
                   3570:        {
                   3571:          t = build_int_2 (CONST_DOUBLE_LOW (x), CONST_DOUBLE_HIGH (x));
                   3572:          TREE_TYPE (t) = type;
                   3573:        }
                   3574:       else
                   3575:        {
                   3576:          REAL_VALUE_TYPE d;
                   3577: 
                   3578:          REAL_VALUE_FROM_CONST_DOUBLE (d, x);
                   3579:          t = build_real (type, d);
                   3580:        }
                   3581: 
                   3582:       return t;
                   3583:          
                   3584:     case PLUS:
                   3585:       return fold (build (PLUS_EXPR, type, make_tree (type, XEXP (x, 0)),
                   3586:                          make_tree (type, XEXP (x, 1))));
                   3587:                                                       
                   3588:     case MINUS:
                   3589:       return fold (build (MINUS_EXPR, type, make_tree (type, XEXP (x, 0)),
                   3590:                          make_tree (type, XEXP (x, 1))));
                   3591:                                                       
                   3592:     case NEG:
                   3593:       return fold (build1 (NEGATE_EXPR, type, make_tree (type, XEXP (x, 0))));
                   3594: 
                   3595:     case MULT:
                   3596:       return fold (build (MULT_EXPR, type, make_tree (type, XEXP (x, 0)),
                   3597:                          make_tree (type, XEXP (x, 1))));
                   3598:                                                      
                   3599:     case ASHIFT:
                   3600:       return fold (build (LSHIFT_EXPR, type, make_tree (type, XEXP (x, 0)),
                   3601:                          make_tree (type, XEXP (x, 1))));
                   3602:                                                      
                   3603:     case LSHIFTRT:
                   3604:       return fold (convert (type,
                   3605:                            build (RSHIFT_EXPR, unsigned_type (type),
                   3606:                                   make_tree (unsigned_type (type),
                   3607:                                              XEXP (x, 0)),
                   3608:                                   make_tree (type, XEXP (x, 1)))));
                   3609:                                                      
                   3610:     case ASHIFTRT:
                   3611:       return fold (convert (type,
                   3612:                            build (RSHIFT_EXPR, signed_type (type),
                   3613:                                   make_tree (signed_type (type), XEXP (x, 0)),
                   3614:                                   make_tree (type, XEXP (x, 1)))));
                   3615:                                                      
                   3616:     case DIV:
                   3617:       if (TREE_CODE (type) != REAL_TYPE)
                   3618:        t = signed_type (type);
                   3619:       else
                   3620:        t = type;
                   3621: 
                   3622:       return fold (convert (type,
                   3623:                            build (TRUNC_DIV_EXPR, t,
                   3624:                                   make_tree (t, XEXP (x, 0)),
                   3625:                                   make_tree (t, XEXP (x, 1)))));
                   3626:     case UDIV:
                   3627:       t = unsigned_type (type);
                   3628:       return fold (convert (type,
                   3629:                            build (TRUNC_DIV_EXPR, t,
                   3630:                                   make_tree (t, XEXP (x, 0)),
                   3631:                                   make_tree (t, XEXP (x, 1)))));
                   3632:    default:
                   3633:       t = make_node (RTL_EXPR);
                   3634:       TREE_TYPE (t) = type;
                   3635:       RTL_EXPR_RTL (t) = x;
                   3636:       /* There are no insns to be output
                   3637:         when this rtl_expr is used.  */
                   3638:       RTL_EXPR_SEQUENCE (t) = 0;
                   3639:       return t;
                   3640:     }
                   3641: }
                   3642: 
                   3643: /* Return an rtx representing the value of X * MULT + ADD.
                   3644:    TARGET is a suggestion for where to store the result (an rtx).
                   3645:    MODE is the machine mode for the computation.
                   3646:    X and MULT must have mode MODE.  ADD may have a different mode.
                   3647:    So can X (defaults to same as MODE).
                   3648:    UNSIGNEDP is non-zero to do unsigned multiplication.
                   3649:    This may emit insns.  */
                   3650: 
                   3651: rtx
                   3652: expand_mult_add (x, target, mult, add, mode, unsignedp)
                   3653:      rtx x, target, mult, add;
                   3654:      enum machine_mode mode;
                   3655:      int unsignedp;
                   3656: {
                   3657:   tree type = type_for_mode (mode, unsignedp);
                   3658:   tree add_type = (GET_MODE (add) == VOIDmode
1.1.1.2   root     3659:                   ? type : type_for_mode (GET_MODE (add), unsignedp));
1.1       root     3660:   tree result =  fold (build (PLUS_EXPR, type,
                   3661:                              fold (build (MULT_EXPR, type,
                   3662:                                           make_tree (type, x),
                   3663:                                           make_tree (type, mult))),
                   3664:                              make_tree (add_type, add)));
                   3665: 
                   3666:   return expand_expr (result, target, VOIDmode, 0);
                   3667: }
                   3668: 
                   3669: /* Compute the logical-and of OP0 and OP1, storing it in TARGET
                   3670:    and returning TARGET.
                   3671: 
                   3672:    If TARGET is 0, a pseudo-register or constant is returned.  */
                   3673: 
                   3674: rtx
                   3675: expand_and (op0, op1, target)
                   3676:      rtx op0, op1, target;
                   3677: {
                   3678:   enum machine_mode mode = VOIDmode;
                   3679:   rtx tem;
                   3680: 
                   3681:   if (GET_MODE (op0) != VOIDmode)
                   3682:     mode = GET_MODE (op0);
                   3683:   else if (GET_MODE (op1) != VOIDmode)
                   3684:     mode = GET_MODE (op1);
                   3685: 
                   3686:   if (mode != VOIDmode)
                   3687:     tem = expand_binop (mode, and_optab, op0, op1, target, 0, OPTAB_LIB_WIDEN);
                   3688:   else if (GET_CODE (op0) == CONST_INT && GET_CODE (op1) == CONST_INT)
1.1.1.4   root     3689:     tem = GEN_INT (INTVAL (op0) & INTVAL (op1));
1.1       root     3690:   else
                   3691:     abort ();
                   3692: 
                   3693:   if (target == 0)
                   3694:     target = tem;
                   3695:   else if (tem != target)
                   3696:     emit_move_insn (target, tem);
                   3697:   return target;
                   3698: }
                   3699: 
                   3700: /* Emit a store-flags instruction for comparison CODE on OP0 and OP1
                   3701:    and storing in TARGET.  Normally return TARGET.
                   3702:    Return 0 if that cannot be done.
                   3703: 
                   3704:    MODE is the mode to use for OP0 and OP1 should they be CONST_INTs.  If
                   3705:    it is VOIDmode, they cannot both be CONST_INT.  
                   3706: 
                   3707:    UNSIGNEDP is for the case where we have to widen the operands
                   3708:    to perform the operation.  It says to use zero-extension.
                   3709: 
                   3710:    NORMALIZEP is 1 if we should convert the result to be either zero
                   3711:    or one one.  Normalize is -1 if we should convert the result to be
                   3712:    either zero or -1.  If NORMALIZEP is zero, the result will be left
                   3713:    "raw" out of the scc insn.  */
                   3714: 
                   3715: rtx
                   3716: emit_store_flag (target, code, op0, op1, mode, unsignedp, normalizep)
                   3717:      rtx target;
                   3718:      enum rtx_code code;
                   3719:      rtx op0, op1;
                   3720:      enum machine_mode mode;
                   3721:      int unsignedp;
                   3722:      int normalizep;
                   3723: {
                   3724:   rtx subtarget;
                   3725:   enum insn_code icode;
                   3726:   enum machine_mode compare_mode;
                   3727:   enum machine_mode target_mode = GET_MODE (target);
                   3728:   rtx tem;
                   3729:   rtx last = 0;
                   3730:   rtx pattern, comparison;
                   3731: 
                   3732:   if (mode == VOIDmode)
                   3733:     mode = GET_MODE (op0);
                   3734: 
1.1.1.5   root     3735:   /* If one operand is constant, make it the second one.  Only do this
                   3736:      if the other operand is not constant as well.  */
                   3737: 
                   3738:   if ((CONSTANT_P (op0) && ! CONSTANT_P (op1))
                   3739:       || (GET_CODE (op0) == CONST_INT && GET_CODE (op1) != CONST_INT))
                   3740:     {
                   3741:       tem = op0;
                   3742:       op0 = op1;
                   3743:       op1 = tem;
                   3744:       code = swap_condition (code);
                   3745:     }
                   3746: 
1.1       root     3747:   /* For some comparisons with 1 and -1, we can convert this to 
                   3748:      comparisons with zero.  This will often produce more opportunities for
                   3749:      store-flag insns. */
                   3750: 
                   3751:   switch (code)
                   3752:     {
                   3753:     case LT:
                   3754:       if (op1 == const1_rtx)
                   3755:        op1 = const0_rtx, code = LE;
                   3756:       break;
                   3757:     case LE:
                   3758:       if (op1 == constm1_rtx)
                   3759:        op1 = const0_rtx, code = LT;
                   3760:       break;
                   3761:     case GE:
                   3762:       if (op1 == const1_rtx)
                   3763:        op1 = const0_rtx, code = GT;
                   3764:       break;
                   3765:     case GT:
                   3766:       if (op1 == constm1_rtx)
                   3767:        op1 = const0_rtx, code = GE;
                   3768:       break;
                   3769:     case GEU:
                   3770:       if (op1 == const1_rtx)
                   3771:        op1 = const0_rtx, code = NE;
                   3772:       break;
                   3773:     case LTU:
                   3774:       if (op1 == const1_rtx)
                   3775:        op1 = const0_rtx, code = EQ;
                   3776:       break;
                   3777:     }
                   3778: 
                   3779:   /* From now on, we won't change CODE, so set ICODE now.  */
                   3780:   icode = setcc_gen_code[(int) code];
                   3781: 
                   3782:   /* If this is A < 0 or A >= 0, we can do this by taking the ones
                   3783:      complement of A (for GE) and shifting the sign bit to the low bit.  */
                   3784:   if (op1 == const0_rtx && (code == LT || code == GE)
                   3785:       && GET_MODE_CLASS (mode) == MODE_INT
                   3786:       && (normalizep || STORE_FLAG_VALUE == 1
1.1.1.4   root     3787:          || (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
                   3788:              && (STORE_FLAG_VALUE 
                   3789:                  == (HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE (mode) - 1)))))
1.1       root     3790:     {
1.1.1.5   root     3791:       subtarget = target;
1.1       root     3792: 
                   3793:       /* If the result is to be wider than OP0, it is best to convert it
                   3794:         first.  If it is to be narrower, it is *incorrect* to convert it
                   3795:         first.  */
                   3796:       if (GET_MODE_SIZE (target_mode) > GET_MODE_SIZE (mode))
                   3797:        {
1.1.1.4   root     3798:          op0 = protect_from_queue (op0, 0);
1.1.1.6   root     3799:          op0 = convert_modes (target_mode, mode, op0, 0);
1.1       root     3800:          mode = target_mode;
                   3801:        }
                   3802: 
                   3803:       if (target_mode != mode)
                   3804:        subtarget = 0;
                   3805: 
                   3806:       if (code == GE)
                   3807:        op0 = expand_unop (mode, one_cmpl_optab, op0, subtarget, 0);
                   3808: 
                   3809:       if (normalizep || STORE_FLAG_VALUE == 1)
                   3810:        /* If we are supposed to produce a 0/1 value, we want to do
                   3811:           a logical shift from the sign bit to the low-order bit; for
                   3812:           a -1/0 value, we do an arithmetic shift.  */
                   3813:        op0 = expand_shift (RSHIFT_EXPR, mode, op0,
                   3814:                            size_int (GET_MODE_BITSIZE (mode) - 1),
                   3815:                            subtarget, normalizep != -1);
                   3816: 
                   3817:       if (mode != target_mode)
1.1.1.6   root     3818:        op0 = convert_modes (target_mode, mode, op0, 0);
1.1       root     3819: 
                   3820:       return op0;
                   3821:     }
                   3822: 
                   3823:   if (icode != CODE_FOR_nothing)
                   3824:     {
                   3825:       /* We think we may be able to do this with a scc insn.  Emit the
                   3826:         comparison and then the scc insn.
                   3827: 
                   3828:         compare_from_rtx may call emit_queue, which would be deleted below
                   3829:         if the scc insn fails.  So call it ourselves before setting LAST.  */
                   3830: 
                   3831:       emit_queue ();
                   3832:       last = get_last_insn ();
                   3833: 
1.1.1.4   root     3834:       comparison
                   3835:        = compare_from_rtx (op0, op1, code, unsignedp, mode, NULL_RTX, 0);
1.1       root     3836:       if (GET_CODE (comparison) == CONST_INT)
                   3837:        return (comparison == const0_rtx ? const0_rtx
                   3838:                : normalizep == 1 ? const1_rtx
                   3839:                : normalizep == -1 ? constm1_rtx
                   3840:                : const_true_rtx);
                   3841: 
1.1.1.5   root     3842:       /* If the code of COMPARISON doesn't match CODE, something is
                   3843:         wrong; we can no longer be sure that we have the operation.  
                   3844:         We could handle this case, but it should not happen.  */
                   3845: 
                   3846:       if (GET_CODE (comparison) != code)
                   3847:        abort ();
                   3848: 
1.1       root     3849:       /* Get a reference to the target in the proper mode for this insn.  */
                   3850:       compare_mode = insn_operand_mode[(int) icode][0];
                   3851:       subtarget = target;
                   3852:       if (preserve_subexpressions_p ()
                   3853:          || ! (*insn_operand_predicate[(int) icode][0]) (subtarget, compare_mode))
                   3854:        subtarget = gen_reg_rtx (compare_mode);
                   3855: 
                   3856:       pattern = GEN_FCN (icode) (subtarget);
                   3857:       if (pattern)
                   3858:        {
                   3859:          emit_insn (pattern);
                   3860: 
                   3861:          /* If we are converting to a wider mode, first convert to
                   3862:             TARGET_MODE, then normalize.  This produces better combining
                   3863:             opportunities on machines that have a SIGN_EXTRACT when we are
                   3864:             testing a single bit.  This mostly benefits the 68k.
                   3865: 
                   3866:             If STORE_FLAG_VALUE does not have the sign bit set when
                   3867:             interpreted in COMPARE_MODE, we can do this conversion as
                   3868:             unsigned, which is usually more efficient.  */
                   3869:          if (GET_MODE_SIZE (target_mode) > GET_MODE_SIZE (compare_mode))
                   3870:            {
                   3871:              convert_move (target, subtarget,
                   3872:                            (GET_MODE_BITSIZE (compare_mode)
1.1.1.4   root     3873:                             <= HOST_BITS_PER_WIDE_INT)
1.1       root     3874:                            && 0 == (STORE_FLAG_VALUE
1.1.1.4   root     3875:                                     & ((HOST_WIDE_INT) 1
                   3876:                                        << (GET_MODE_BITSIZE (compare_mode) -1))));
1.1       root     3877:              op0 = target;
                   3878:              compare_mode = target_mode;
                   3879:            }
                   3880:          else
                   3881:            op0 = subtarget;
                   3882: 
1.1.1.4   root     3883:          /* If we want to keep subexpressions around, don't reuse our
                   3884:             last target.  */
                   3885: 
                   3886:          if (preserve_subexpressions_p ())
                   3887:            subtarget = 0;
                   3888: 
1.1       root     3889:          /* Now normalize to the proper value in COMPARE_MODE.  Sometimes
                   3890:             we don't have to do anything.  */
                   3891:          if (normalizep == 0 || normalizep == STORE_FLAG_VALUE)
                   3892:            ;
                   3893:          else if (normalizep == - STORE_FLAG_VALUE)
                   3894:            op0 = expand_unop (compare_mode, neg_optab, op0, subtarget, 0);
                   3895: 
                   3896:          /* We don't want to use STORE_FLAG_VALUE < 0 below since this
                   3897:             makes it hard to use a value of just the sign bit due to
                   3898:             ANSI integer constant typing rules.  */
1.1.1.4   root     3899:          else if (GET_MODE_BITSIZE (compare_mode) <= HOST_BITS_PER_WIDE_INT
1.1       root     3900:                   && (STORE_FLAG_VALUE
1.1.1.4   root     3901:                       & ((HOST_WIDE_INT) 1
                   3902:                          << (GET_MODE_BITSIZE (compare_mode) - 1))))
1.1       root     3903:            op0 = expand_shift (RSHIFT_EXPR, compare_mode, op0,
                   3904:                                size_int (GET_MODE_BITSIZE (compare_mode) - 1),
                   3905:                                subtarget, normalizep == 1);
                   3906:          else if (STORE_FLAG_VALUE & 1)
                   3907:            {
                   3908:              op0 = expand_and (op0, const1_rtx, subtarget);
                   3909:              if (normalizep == -1)
                   3910:                op0 = expand_unop (compare_mode, neg_optab, op0, op0, 0);
                   3911:            }
                   3912:          else
                   3913:            abort ();
                   3914: 
                   3915:          /* If we were converting to a smaller mode, do the 
                   3916:             conversion now.  */
                   3917:          if (target_mode != compare_mode)
                   3918:            {
1.1.1.5   root     3919:              convert_move (target, op0, 0);
1.1       root     3920:              return target;
                   3921:            }
                   3922:          else
                   3923:            return op0;
                   3924:        }
                   3925:     }
                   3926: 
                   3927:   if (last)
                   3928:     delete_insns_since (last);
                   3929: 
                   3930:   subtarget = target_mode == mode ? target : 0;
                   3931: 
                   3932:   /* If we reached here, we can't do this with a scc insn.  However, there
                   3933:      are some comparisons that can be done directly.  For example, if
                   3934:      this is an equality comparison of integers, we can try to exclusive-or
                   3935:      (or subtract) the two operands and use a recursive call to try the
                   3936:      comparison with zero.  Don't do any of these cases if branches are
                   3937:      very cheap.  */
                   3938: 
1.1.1.5   root     3939:   if (BRANCH_COST > 0
1.1       root     3940:       && GET_MODE_CLASS (mode) == MODE_INT && (code == EQ || code == NE)
                   3941:       && op1 != const0_rtx)
                   3942:     {
                   3943:       tem = expand_binop (mode, xor_optab, op0, op1, subtarget, 1,
                   3944:                          OPTAB_WIDEN);
                   3945: 
                   3946:       if (tem == 0)
                   3947:        tem = expand_binop (mode, sub_optab, op0, op1, subtarget, 1,
                   3948:                            OPTAB_WIDEN);
                   3949:       if (tem != 0)
                   3950:        tem = emit_store_flag (target, code, tem, const0_rtx,
                   3951:                               mode, unsignedp, normalizep);
                   3952:       if (tem == 0)
                   3953:        delete_insns_since (last);
                   3954:       return tem;
                   3955:     }
                   3956: 
                   3957:   /* Some other cases we can do are EQ, NE, LE, and GT comparisons with 
                   3958:      the constant zero.  Reject all other comparisons at this point.  Only
                   3959:      do LE and GT if branches are expensive since they are expensive on
                   3960:      2-operand machines.  */
                   3961: 
                   3962:   if (BRANCH_COST == 0
                   3963:       || GET_MODE_CLASS (mode) != MODE_INT || op1 != const0_rtx
                   3964:       || (code != EQ && code != NE
                   3965:          && (BRANCH_COST <= 1 || (code != LE && code != GT))))
                   3966:     return 0;
                   3967: 
                   3968:   /* See what we need to return.  We can only return a 1, -1, or the
                   3969:      sign bit.  */
                   3970: 
                   3971:   if (normalizep == 0)
                   3972:     {
                   3973:       if (STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1)
                   3974:        normalizep = STORE_FLAG_VALUE;
                   3975: 
1.1.1.4   root     3976:       else if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
                   3977:               && (STORE_FLAG_VALUE
                   3978:                   == (HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE (mode) - 1)))
1.1       root     3979:        ;
                   3980:       else
                   3981:        return 0;
                   3982:     }
                   3983: 
                   3984:   /* Try to put the result of the comparison in the sign bit.  Assume we can't
                   3985:      do the necessary operation below.  */
                   3986: 
                   3987:   tem = 0;
                   3988: 
                   3989:   /* To see if A <= 0, compute (A | (A - 1)).  A <= 0 iff that result has
                   3990:      the sign bit set.  */
                   3991: 
                   3992:   if (code == LE)
                   3993:     {
                   3994:       /* This is destructive, so SUBTARGET can't be OP0.  */
                   3995:       if (rtx_equal_p (subtarget, op0))
                   3996:        subtarget = 0;
                   3997: 
                   3998:       tem = expand_binop (mode, sub_optab, op0, const1_rtx, subtarget, 0,
                   3999:                          OPTAB_WIDEN);
                   4000:       if (tem)
                   4001:        tem = expand_binop (mode, ior_optab, op0, tem, subtarget, 0,
                   4002:                            OPTAB_WIDEN);
                   4003:     }
                   4004: 
                   4005:   /* To see if A > 0, compute (((signed) A) << BITS) - A, where BITS is the
                   4006:      number of bits in the mode of OP0, minus one.  */
                   4007: 
                   4008:   if (code == GT)
                   4009:     {
                   4010:       if (rtx_equal_p (subtarget, op0))
                   4011:        subtarget = 0;
                   4012: 
                   4013:       tem = expand_shift (RSHIFT_EXPR, mode, op0,
                   4014:                          size_int (GET_MODE_BITSIZE (mode) - 1),
                   4015:                          subtarget, 0);
                   4016:       tem = expand_binop (mode, sub_optab, tem, op0, subtarget, 0,
                   4017:                          OPTAB_WIDEN);
                   4018:     }
                   4019:                                    
                   4020:   if (code == EQ || code == NE)
                   4021:     {
                   4022:       /* For EQ or NE, one way to do the comparison is to apply an operation
                   4023:         that converts the operand into a positive number if it is non-zero
                   4024:         or zero if it was originally zero.  Then, for EQ, we subtract 1 and
                   4025:         for NE we negate.  This puts the result in the sign bit.  Then we
                   4026:         normalize with a shift, if needed. 
                   4027: 
                   4028:         Two operations that can do the above actions are ABS and FFS, so try
                   4029:         them.  If that doesn't work, and MODE is smaller than a full word,
1.1.1.2   root     4030:         we can use zero-extension to the wider mode (an unsigned conversion)
1.1       root     4031:         as the operation.  */
                   4032: 
                   4033:       if (abs_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
                   4034:        tem = expand_unop (mode, abs_optab, op0, subtarget, 1);
                   4035:       else if (ffs_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
                   4036:        tem = expand_unop (mode, ffs_optab, op0, subtarget, 1);
                   4037:       else if (GET_MODE_SIZE (mode) < UNITS_PER_WORD)
                   4038:        {
1.1.1.4   root     4039:          op0 = protect_from_queue (op0, 0);
1.1.1.6   root     4040:          tem = convert_modes (word_mode, mode, op0, 1);
                   4041:          mode = word_mode;
1.1       root     4042:        }
                   4043: 
                   4044:       if (tem != 0)
                   4045:        {
                   4046:          if (code == EQ)
                   4047:            tem = expand_binop (mode, sub_optab, tem, const1_rtx, subtarget,
                   4048:                                0, OPTAB_WIDEN);
                   4049:          else
                   4050:            tem = expand_unop (mode, neg_optab, tem, subtarget, 0);
                   4051:        }
                   4052: 
                   4053:       /* If we couldn't do it that way, for NE we can "or" the two's complement
                   4054:         of the value with itself.  For EQ, we take the one's complement of
                   4055:         that "or", which is an extra insn, so we only handle EQ if branches
                   4056:         are expensive.  */
                   4057: 
                   4058:       if (tem == 0 && (code == NE || BRANCH_COST > 1))
                   4059:        {
1.1.1.2   root     4060:          if (rtx_equal_p (subtarget, op0))
                   4061:            subtarget = 0;
                   4062: 
1.1       root     4063:          tem = expand_unop (mode, neg_optab, op0, subtarget, 0);
                   4064:          tem = expand_binop (mode, ior_optab, tem, op0, subtarget, 0,
                   4065:                              OPTAB_WIDEN);
                   4066: 
                   4067:          if (tem && code == EQ)
                   4068:            tem = expand_unop (mode, one_cmpl_optab, tem, subtarget, 0);
                   4069:        }
                   4070:     }
                   4071: 
                   4072:   if (tem && normalizep)
                   4073:     tem = expand_shift (RSHIFT_EXPR, mode, tem,
                   4074:                        size_int (GET_MODE_BITSIZE (mode) - 1),
                   4075:                        tem, normalizep == 1);
                   4076: 
                   4077:   if (tem && GET_MODE (tem) != target_mode)
                   4078:     {
                   4079:       convert_move (target, tem, 0);
                   4080:       tem = target;
                   4081:     }
                   4082: 
                   4083:   if (tem == 0)
                   4084:     delete_insns_since (last);
                   4085: 
                   4086:   return tem;
                   4087: }

unix.superglobalmegacorp.com

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