OSDN Git Service

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