OSDN Git Service

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