OSDN Git Service

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