OSDN Git Service

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