]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/gcc/expmed.c
This commit was generated by cvs2svn to compensate for changes in r94880,
[FreeBSD/FreeBSD.git] / contrib / 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, 2002 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         return expand_binop (GET_MODE (op0), and_optab, op0,
1626                              mask_rtx (GET_MODE (op0), 0, bitsize, 0),
1627                              target, 1, OPTAB_LIB_WIDEN);
1628       return op0;
1629     }
1630
1631   /* To extract a signed bit-field, first shift its msb to the msb of the word,
1632      then arithmetic-shift its lsb to the lsb of the word.  */
1633   op0 = force_reg (mode, op0);
1634   if (mode != tmode)
1635     target = 0;
1636
1637   /* Find the narrowest integer mode that contains the field.  */
1638
1639   for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT); mode != VOIDmode;
1640        mode = GET_MODE_WIDER_MODE (mode))
1641     if (GET_MODE_BITSIZE (mode) >= bitsize + bitpos)
1642       {
1643         op0 = convert_to_mode (mode, op0, 0);
1644         break;
1645       }
1646
1647   if (GET_MODE_BITSIZE (mode) != (bitsize + bitpos))
1648     {
1649       tree amount
1650         = build_int_2 (GET_MODE_BITSIZE (mode) - (bitsize + bitpos), 0);
1651       /* Maybe propagate the target for the shift.  */
1652       /* But not if we will return the result--could confuse integrate.c.  */
1653       rtx subtarget = (target != 0 && GET_CODE (target) == REG
1654                        && ! REG_FUNCTION_VALUE_P (target)
1655                        ? target : 0);
1656       op0 = expand_shift (LSHIFT_EXPR, mode, op0, amount, subtarget, 1);
1657     }
1658
1659   return expand_shift (RSHIFT_EXPR, mode, op0,
1660                        build_int_2 (GET_MODE_BITSIZE (mode) - bitsize, 0), 
1661                        target, 0);
1662 }
1663 \f
1664 /* Return a constant integer (CONST_INT or CONST_DOUBLE) mask value
1665    of mode MODE with BITSIZE ones followed by BITPOS zeros, or the
1666    complement of that if COMPLEMENT.  The mask is truncated if
1667    necessary to the width of mode MODE.  The mask is zero-extended if
1668    BITSIZE+BITPOS is too small for MODE.  */
1669
1670 static rtx
1671 mask_rtx (mode, bitpos, bitsize, complement)
1672      enum machine_mode mode;
1673      int bitpos, bitsize, complement;
1674 {
1675   HOST_WIDE_INT masklow, maskhigh;
1676
1677   if (bitpos < HOST_BITS_PER_WIDE_INT)
1678     masklow = (HOST_WIDE_INT) -1 << bitpos;
1679   else
1680     masklow = 0;
1681
1682   if (bitpos + bitsize < HOST_BITS_PER_WIDE_INT)
1683     masklow &= ((unsigned HOST_WIDE_INT) -1
1684                 >> (HOST_BITS_PER_WIDE_INT - bitpos - bitsize));
1685   
1686   if (bitpos <= HOST_BITS_PER_WIDE_INT)
1687     maskhigh = -1;
1688   else
1689     maskhigh = (HOST_WIDE_INT) -1 << (bitpos - HOST_BITS_PER_WIDE_INT);
1690
1691   if (bitpos + bitsize > HOST_BITS_PER_WIDE_INT)
1692     maskhigh &= ((unsigned HOST_WIDE_INT) -1
1693                  >> (2 * HOST_BITS_PER_WIDE_INT - bitpos - bitsize));
1694   else
1695     maskhigh = 0;
1696
1697   if (complement)
1698     {
1699       maskhigh = ~maskhigh;
1700       masklow = ~masklow;
1701     }
1702
1703   return immed_double_const (masklow, maskhigh, mode);
1704 }
1705
1706 /* Return a constant integer (CONST_INT or CONST_DOUBLE) rtx with the value
1707    VALUE truncated to BITSIZE bits and then shifted left BITPOS bits.  */
1708
1709 static rtx
1710 lshift_value (mode, value, bitpos, bitsize)
1711      enum machine_mode mode;
1712      rtx value;
1713      int bitpos, bitsize;
1714 {
1715   unsigned HOST_WIDE_INT v = INTVAL (value);
1716   HOST_WIDE_INT low, high;
1717
1718   if (bitsize < HOST_BITS_PER_WIDE_INT)
1719     v &= ~((HOST_WIDE_INT) -1 << bitsize);
1720
1721   if (bitpos < HOST_BITS_PER_WIDE_INT)
1722     {
1723       low = v << bitpos;
1724       high = (bitpos > 0 ? (v >> (HOST_BITS_PER_WIDE_INT - bitpos)) : 0);
1725     }
1726   else
1727     {
1728       low = 0;
1729       high = v << (bitpos - HOST_BITS_PER_WIDE_INT);
1730     }
1731
1732   return immed_double_const (low, high, mode);
1733 }
1734 \f
1735 /* Extract a bit field that is split across two words
1736    and return an RTX for the result.
1737
1738    OP0 is the REG, SUBREG or MEM rtx for the first of the two words.
1739    BITSIZE is the field width; BITPOS, position of its first bit, in the word.
1740    UNSIGNEDP is 1 if should zero-extend the contents; else sign-extend.  */
1741
1742 static rtx
1743 extract_split_bit_field (op0, bitsize, bitpos, unsignedp)
1744      rtx op0;
1745      unsigned HOST_WIDE_INT bitsize, bitpos;
1746      int unsignedp;
1747 {
1748   unsigned int unit;
1749   unsigned int bitsdone = 0;
1750   rtx result = NULL_RTX;
1751   int first = 1;
1752
1753   /* Make sure UNIT isn't larger than BITS_PER_WORD, we can only handle that
1754      much at a time.  */
1755   if (GET_CODE (op0) == REG || GET_CODE (op0) == SUBREG)
1756     unit = BITS_PER_WORD;
1757   else
1758     unit = MIN (MEM_ALIGN (op0), BITS_PER_WORD);
1759
1760   while (bitsdone < bitsize)
1761     {
1762       unsigned HOST_WIDE_INT thissize;
1763       rtx part, word;
1764       unsigned HOST_WIDE_INT thispos;
1765       unsigned HOST_WIDE_INT offset;
1766
1767       offset = (bitpos + bitsdone) / unit;
1768       thispos = (bitpos + bitsdone) % unit;
1769
1770       /* THISSIZE must not overrun a word boundary.  Otherwise,
1771          extract_fixed_bit_field will call us again, and we will mutually
1772          recurse forever.  */
1773       thissize = MIN (bitsize - bitsdone, BITS_PER_WORD);
1774       thissize = MIN (thissize, unit - thispos);
1775
1776       /* If OP0 is a register, then handle OFFSET here.
1777
1778          When handling multiword bitfields, extract_bit_field may pass
1779          down a word_mode SUBREG of a larger REG for a bitfield that actually
1780          crosses a word boundary.  Thus, for a SUBREG, we must find
1781          the current word starting from the base register.  */
1782       if (GET_CODE (op0) == SUBREG)
1783         {
1784           int word_offset = (SUBREG_BYTE (op0) / UNITS_PER_WORD) + offset;
1785           word = operand_subword_force (SUBREG_REG (op0), word_offset,
1786                                         GET_MODE (SUBREG_REG (op0)));
1787           offset = 0;
1788         }
1789       else if (GET_CODE (op0) == REG)
1790         {
1791           word = operand_subword_force (op0, offset, GET_MODE (op0));
1792           offset = 0;
1793         }
1794       else
1795         word = op0;
1796
1797       /* Extract the parts in bit-counting order,
1798          whose meaning is determined by BYTES_PER_UNIT.
1799          OFFSET is in UNITs, and UNIT is in bits.
1800          extract_fixed_bit_field wants offset in bytes.  */
1801       part = extract_fixed_bit_field (word_mode, word,
1802                                       offset * unit / BITS_PER_UNIT,
1803                                       thissize, thispos, 0, 1);
1804       bitsdone += thissize;
1805
1806       /* Shift this part into place for the result.  */
1807       if (BYTES_BIG_ENDIAN)
1808         {
1809           if (bitsize != bitsdone)
1810             part = expand_shift (LSHIFT_EXPR, word_mode, part,
1811                                  build_int_2 (bitsize - bitsdone, 0), 0, 1);
1812         }
1813       else
1814         {
1815           if (bitsdone != thissize)
1816             part = expand_shift (LSHIFT_EXPR, word_mode, part,
1817                                  build_int_2 (bitsdone - thissize, 0), 0, 1);
1818         }
1819
1820       if (first)
1821         result = part;
1822       else
1823         /* Combine the parts with bitwise or.  This works
1824            because we extracted each part as an unsigned bit field.  */
1825         result = expand_binop (word_mode, ior_optab, part, result, NULL_RTX, 1,
1826                                OPTAB_LIB_WIDEN);
1827
1828       first = 0;
1829     }
1830
1831   /* Unsigned bit field: we are done.  */
1832   if (unsignedp)
1833     return result;
1834   /* Signed bit field: sign-extend with two arithmetic shifts.  */
1835   result = expand_shift (LSHIFT_EXPR, word_mode, result,
1836                          build_int_2 (BITS_PER_WORD - bitsize, 0),
1837                          NULL_RTX, 0);
1838   return expand_shift (RSHIFT_EXPR, word_mode, result,
1839                        build_int_2 (BITS_PER_WORD - bitsize, 0), NULL_RTX, 0);
1840 }
1841 \f
1842 /* Add INC into TARGET.  */
1843
1844 void
1845 expand_inc (target, inc)
1846      rtx target, inc;
1847 {
1848   rtx value = expand_binop (GET_MODE (target), add_optab,
1849                             target, inc,
1850                             target, 0, OPTAB_LIB_WIDEN);
1851   if (value != target)
1852     emit_move_insn (target, value);
1853 }
1854
1855 /* Subtract DEC from TARGET.  */
1856
1857 void
1858 expand_dec (target, dec)
1859      rtx target, dec;
1860 {
1861   rtx value = expand_binop (GET_MODE (target), sub_optab,
1862                             target, dec,
1863                             target, 0, OPTAB_LIB_WIDEN);
1864   if (value != target)
1865     emit_move_insn (target, value);
1866 }
1867 \f
1868 /* Output a shift instruction for expression code CODE,
1869    with SHIFTED being the rtx for the value to shift,
1870    and AMOUNT the tree for the amount to shift by.
1871    Store the result in the rtx TARGET, if that is convenient.
1872    If UNSIGNEDP is nonzero, do a logical shift; otherwise, arithmetic.
1873    Return the rtx for where the value is.  */
1874
1875 rtx
1876 expand_shift (code, mode, shifted, amount, target, unsignedp)
1877      enum tree_code code;
1878      enum machine_mode mode;
1879      rtx shifted;
1880      tree amount;
1881      rtx target;
1882      int unsignedp;
1883 {
1884   rtx op1, temp = 0;
1885   int left = (code == LSHIFT_EXPR || code == LROTATE_EXPR);
1886   int rotate = (code == LROTATE_EXPR || code == RROTATE_EXPR);
1887   int try;
1888
1889   /* Previously detected shift-counts computed by NEGATE_EXPR
1890      and shifted in the other direction; but that does not work
1891      on all machines.  */
1892
1893   op1 = expand_expr (amount, NULL_RTX, VOIDmode, 0);
1894
1895 #ifdef SHIFT_COUNT_TRUNCATED
1896   if (SHIFT_COUNT_TRUNCATED)
1897     {
1898       if (GET_CODE (op1) == CONST_INT
1899           && ((unsigned HOST_WIDE_INT) INTVAL (op1) >=
1900               (unsigned HOST_WIDE_INT) GET_MODE_BITSIZE (mode)))
1901         op1 = GEN_INT ((unsigned HOST_WIDE_INT) INTVAL (op1)
1902                        % GET_MODE_BITSIZE (mode));
1903       else if (GET_CODE (op1) == SUBREG
1904                && SUBREG_BYTE (op1) == 0)
1905         op1 = SUBREG_REG (op1);
1906     }
1907 #endif
1908
1909   if (op1 == const0_rtx)
1910     return shifted;
1911
1912   for (try = 0; temp == 0 && try < 3; try++)
1913     {
1914       enum optab_methods methods;
1915
1916       if (try == 0)
1917         methods = OPTAB_DIRECT;
1918       else if (try == 1)
1919         methods = OPTAB_WIDEN;
1920       else
1921         methods = OPTAB_LIB_WIDEN;
1922
1923       if (rotate)
1924         {
1925           /* Widening does not work for rotation.  */
1926           if (methods == OPTAB_WIDEN)
1927             continue;
1928           else if (methods == OPTAB_LIB_WIDEN)
1929             {
1930               /* If we have been unable to open-code this by a rotation,
1931                  do it as the IOR of two shifts.  I.e., to rotate A
1932                  by N bits, compute (A << N) | ((unsigned) A >> (C - N))
1933                  where C is the bitsize of A.
1934
1935                  It is theoretically possible that the target machine might
1936                  not be able to perform either shift and hence we would
1937                  be making two libcalls rather than just the one for the
1938                  shift (similarly if IOR could not be done).  We will allow
1939                  this extremely unlikely lossage to avoid complicating the
1940                  code below.  */
1941
1942               rtx subtarget = target == shifted ? 0 : target;
1943               rtx temp1;
1944               tree type = TREE_TYPE (amount);
1945               tree new_amount = make_tree (type, op1);
1946               tree other_amount
1947                 = fold (build (MINUS_EXPR, type,
1948                                convert (type,
1949                                         build_int_2 (GET_MODE_BITSIZE (mode),
1950                                                      0)),
1951                                amount));
1952
1953               shifted = force_reg (mode, shifted);
1954
1955               temp = expand_shift (left ? LSHIFT_EXPR : RSHIFT_EXPR,
1956                                    mode, shifted, new_amount, subtarget, 1);
1957               temp1 = expand_shift (left ? RSHIFT_EXPR : LSHIFT_EXPR,
1958                                     mode, shifted, other_amount, 0, 1);
1959               return expand_binop (mode, ior_optab, temp, temp1, target,
1960                                    unsignedp, methods);
1961             }
1962
1963           temp = expand_binop (mode,
1964                                left ? rotl_optab : rotr_optab,
1965                                shifted, op1, target, unsignedp, methods);
1966
1967           /* If we don't have the rotate, but we are rotating by a constant
1968              that is in range, try a rotate in the opposite direction.  */
1969
1970           if (temp == 0 && GET_CODE (op1) == CONST_INT
1971               && INTVAL (op1) > 0
1972               && (unsigned int) INTVAL (op1) < GET_MODE_BITSIZE (mode))
1973             temp = expand_binop (mode,
1974                                  left ? rotr_optab : rotl_optab,
1975                                  shifted, 
1976                                  GEN_INT (GET_MODE_BITSIZE (mode)
1977                                           - INTVAL (op1)),
1978                                  target, unsignedp, methods);
1979         }
1980       else if (unsignedp)
1981         temp = expand_binop (mode,
1982                              left ? ashl_optab : lshr_optab,
1983                              shifted, op1, target, unsignedp, methods);
1984
1985       /* Do arithmetic shifts.
1986          Also, if we are going to widen the operand, we can just as well
1987          use an arithmetic right-shift instead of a logical one.  */
1988       if (temp == 0 && ! rotate
1989           && (! unsignedp || (! left && methods == OPTAB_WIDEN)))
1990         {
1991           enum optab_methods methods1 = methods;
1992
1993           /* If trying to widen a log shift to an arithmetic shift,
1994              don't accept an arithmetic shift of the same size.  */
1995           if (unsignedp)
1996             methods1 = OPTAB_MUST_WIDEN;
1997
1998           /* Arithmetic shift */
1999
2000           temp = expand_binop (mode,
2001                                left ? ashl_optab : ashr_optab,
2002                                shifted, op1, target, unsignedp, methods1);
2003         }
2004
2005       /* We used to try extzv here for logical right shifts, but that was
2006          only useful for one machine, the VAX, and caused poor code 
2007          generation there for lshrdi3, so the code was deleted and a
2008          define_expand for lshrsi3 was added to vax.md.  */
2009     }
2010
2011   if (temp == 0)
2012     abort ();
2013   return temp;
2014 }
2015 \f
2016 enum alg_code { alg_zero, alg_m, alg_shift,
2017                   alg_add_t_m2, alg_sub_t_m2,
2018                   alg_add_factor, alg_sub_factor,
2019                   alg_add_t2_m, alg_sub_t2_m,
2020                   alg_add, alg_subtract, alg_factor, alg_shiftop };
2021
2022 /* This structure records a sequence of operations.
2023    `ops' is the number of operations recorded.
2024    `cost' is their total cost.
2025    The operations are stored in `op' and the corresponding
2026    logarithms of the integer coefficients in `log'.
2027
2028    These are the operations:
2029    alg_zero             total := 0;
2030    alg_m                total := multiplicand;
2031    alg_shift            total := total * coeff
2032    alg_add_t_m2         total := total + multiplicand * coeff;
2033    alg_sub_t_m2         total := total - multiplicand * coeff;
2034    alg_add_factor       total := total * coeff + total;
2035    alg_sub_factor       total := total * coeff - total;
2036    alg_add_t2_m         total := total * coeff + multiplicand;
2037    alg_sub_t2_m         total := total * coeff - multiplicand;
2038
2039    The first operand must be either alg_zero or alg_m.  */
2040
2041 struct algorithm
2042 {
2043   short cost;
2044   short ops;
2045   /* The size of the OP and LOG fields are not directly related to the
2046      word size, but the worst-case algorithms will be if we have few
2047      consecutive ones or zeros, i.e., a multiplicand like 10101010101...
2048      In that case we will generate shift-by-2, add, shift-by-2, add,...,
2049      in total wordsize operations.  */
2050   enum alg_code op[MAX_BITS_PER_WORD];
2051   char log[MAX_BITS_PER_WORD];
2052 };
2053
2054 static void synth_mult                  PARAMS ((struct algorithm *,
2055                                                  unsigned HOST_WIDE_INT,
2056                                                  int));
2057 static unsigned HOST_WIDE_INT choose_multiplier PARAMS ((unsigned HOST_WIDE_INT,
2058                                                          int, int,
2059                                                          unsigned HOST_WIDE_INT *,
2060                                                          int *, int *));
2061 static unsigned HOST_WIDE_INT invert_mod2n      PARAMS ((unsigned HOST_WIDE_INT,
2062                                                          int));
2063 /* Compute and return the best algorithm for multiplying by T.
2064    The algorithm must cost less than cost_limit
2065    If retval.cost >= COST_LIMIT, no algorithm was found and all
2066    other field of the returned struct are undefined.  */
2067
2068 static void
2069 synth_mult (alg_out, t, cost_limit)
2070      struct algorithm *alg_out;
2071      unsigned HOST_WIDE_INT t;
2072      int cost_limit;
2073 {
2074   int m;
2075   struct algorithm *alg_in, *best_alg;
2076   int cost;
2077   unsigned HOST_WIDE_INT q;
2078
2079   /* Indicate that no algorithm is yet found.  If no algorithm
2080      is found, this value will be returned and indicate failure.  */
2081   alg_out->cost = cost_limit;
2082
2083   if (cost_limit <= 0)
2084     return;
2085
2086   /* t == 1 can be done in zero cost.  */
2087   if (t == 1)
2088     {
2089       alg_out->ops = 1;
2090       alg_out->cost = 0;
2091       alg_out->op[0] = alg_m;
2092       return;
2093     }
2094
2095   /* t == 0 sometimes has a cost.  If it does and it exceeds our limit,
2096      fail now.  */
2097   if (t == 0)
2098     {
2099       if (zero_cost >= cost_limit)
2100         return;
2101       else
2102         {
2103           alg_out->ops = 1;
2104           alg_out->cost = zero_cost;
2105           alg_out->op[0] = alg_zero;
2106           return;
2107         }
2108     }
2109
2110   /* We'll be needing a couple extra algorithm structures now.  */
2111
2112   alg_in = (struct algorithm *)alloca (sizeof (struct algorithm));
2113   best_alg = (struct algorithm *)alloca (sizeof (struct algorithm));
2114
2115   /* If we have a group of zero bits at the low-order part of T, try
2116      multiplying by the remaining bits and then doing a shift.  */
2117
2118   if ((t & 1) == 0)
2119     {
2120       m = floor_log2 (t & -t);  /* m = number of low zero bits */
2121       if (m < BITS_PER_WORD)
2122         {
2123           q = t >> m;
2124           cost = shift_cost[m];
2125           synth_mult (alg_in, q, cost_limit - cost);
2126
2127           cost += alg_in->cost;
2128           if (cost < cost_limit)
2129             {
2130               struct algorithm *x;
2131               x = alg_in, alg_in = best_alg, best_alg = x;
2132               best_alg->log[best_alg->ops] = m;
2133               best_alg->op[best_alg->ops] = alg_shift;
2134               cost_limit = cost;
2135             }
2136         }
2137     }
2138
2139   /* If we have an odd number, add or subtract one.  */
2140   if ((t & 1) != 0)
2141     {
2142       unsigned HOST_WIDE_INT w;
2143
2144       for (w = 1; (w & t) != 0; w <<= 1)
2145         ;
2146       /* If T was -1, then W will be zero after the loop.  This is another
2147          case where T ends with ...111.  Handling this with (T + 1) and 
2148          subtract 1 produces slightly better code and results in algorithm
2149          selection much faster than treating it like the ...0111 case
2150          below.  */
2151       if (w == 0
2152           || (w > 2
2153               /* Reject the case where t is 3.
2154                  Thus we prefer addition in that case.  */
2155               && t != 3))
2156         {
2157           /* T ends with ...111.  Multiply by (T + 1) and subtract 1.  */
2158
2159           cost = add_cost;
2160           synth_mult (alg_in, t + 1, cost_limit - cost);
2161
2162           cost += alg_in->cost;
2163           if (cost < cost_limit)
2164             {
2165               struct algorithm *x;
2166               x = alg_in, alg_in = best_alg, best_alg = x;
2167               best_alg->log[best_alg->ops] = 0;
2168               best_alg->op[best_alg->ops] = alg_sub_t_m2;
2169               cost_limit = cost;
2170             }
2171         }
2172       else
2173         {
2174           /* T ends with ...01 or ...011.  Multiply by (T - 1) and add 1.  */
2175
2176           cost = add_cost;
2177           synth_mult (alg_in, t - 1, cost_limit - cost);
2178
2179           cost += alg_in->cost;
2180           if (cost < cost_limit)
2181             {
2182               struct algorithm *x;
2183               x = alg_in, alg_in = best_alg, best_alg = x;
2184               best_alg->log[best_alg->ops] = 0;
2185               best_alg->op[best_alg->ops] = alg_add_t_m2;
2186               cost_limit = cost;
2187             }
2188         }
2189     }
2190
2191   /* Look for factors of t of the form
2192      t = q(2**m +- 1), 2 <= m <= floor(log2(t - 1)).
2193      If we find such a factor, we can multiply by t using an algorithm that
2194      multiplies by q, shift the result by m and add/subtract it to itself.
2195
2196      We search for large factors first and loop down, even if large factors
2197      are less probable than small; if we find a large factor we will find a
2198      good sequence quickly, and therefore be able to prune (by decreasing
2199      COST_LIMIT) the search.  */
2200
2201   for (m = floor_log2 (t - 1); m >= 2; m--)
2202     {
2203       unsigned HOST_WIDE_INT d;
2204
2205       d = ((unsigned HOST_WIDE_INT) 1 << m) + 1;
2206       if (t % d == 0 && t > d && m < BITS_PER_WORD)
2207         {
2208           cost = MIN (shiftadd_cost[m], add_cost + shift_cost[m]);
2209           synth_mult (alg_in, t / d, cost_limit - cost);
2210
2211           cost += alg_in->cost;
2212           if (cost < cost_limit)
2213             {
2214               struct algorithm *x;
2215               x = alg_in, alg_in = best_alg, best_alg = x;
2216               best_alg->log[best_alg->ops] = m;
2217               best_alg->op[best_alg->ops] = alg_add_factor;
2218               cost_limit = cost;
2219             }
2220           /* Other factors will have been taken care of in the recursion.  */
2221           break;
2222         }
2223
2224       d = ((unsigned HOST_WIDE_INT) 1 << m) - 1;
2225       if (t % d == 0 && t > d && m < BITS_PER_WORD)
2226         {
2227           cost = MIN (shiftsub_cost[m], add_cost + shift_cost[m]);
2228           synth_mult (alg_in, t / d, cost_limit - cost);
2229
2230           cost += alg_in->cost;
2231           if (cost < cost_limit)
2232             {
2233               struct algorithm *x;
2234               x = alg_in, alg_in = best_alg, best_alg = x;
2235               best_alg->log[best_alg->ops] = m;
2236               best_alg->op[best_alg->ops] = alg_sub_factor;
2237               cost_limit = cost;
2238             }
2239           break;
2240         }
2241     }
2242
2243   /* Try shift-and-add (load effective address) instructions,
2244      i.e. do a*3, a*5, a*9.  */
2245   if ((t & 1) != 0)
2246     {
2247       q = t - 1;
2248       q = q & -q;
2249       m = exact_log2 (q);
2250       if (m >= 0 && m < BITS_PER_WORD)
2251         {
2252           cost = shiftadd_cost[m];
2253           synth_mult (alg_in, (t - 1) >> m, cost_limit - cost);
2254
2255           cost += alg_in->cost;
2256           if (cost < cost_limit)
2257             {
2258               struct algorithm *x;
2259               x = alg_in, alg_in = best_alg, best_alg = x;
2260               best_alg->log[best_alg->ops] = m;
2261               best_alg->op[best_alg->ops] = alg_add_t2_m;
2262               cost_limit = cost;
2263             }
2264         }
2265
2266       q = t + 1;
2267       q = q & -q;
2268       m = exact_log2 (q);
2269       if (m >= 0 && m < BITS_PER_WORD)
2270         {
2271           cost = shiftsub_cost[m];
2272           synth_mult (alg_in, (t + 1) >> m, cost_limit - cost);
2273
2274           cost += alg_in->cost;
2275           if (cost < cost_limit)
2276             {
2277               struct algorithm *x;
2278               x = alg_in, alg_in = best_alg, best_alg = x;
2279               best_alg->log[best_alg->ops] = m;
2280               best_alg->op[best_alg->ops] = alg_sub_t2_m;
2281               cost_limit = cost;
2282             }
2283         }
2284     }
2285
2286   /* If cost_limit has not decreased since we stored it in alg_out->cost,
2287      we have not found any algorithm.  */
2288   if (cost_limit == alg_out->cost)
2289     return;
2290
2291   /* If we are getting a too long sequence for `struct algorithm'
2292      to record, make this search fail.  */
2293   if (best_alg->ops == MAX_BITS_PER_WORD)
2294     return;
2295
2296   /* Copy the algorithm from temporary space to the space at alg_out.
2297      We avoid using structure assignment because the majority of
2298      best_alg is normally undefined, and this is a critical function.  */
2299   alg_out->ops = best_alg->ops + 1;
2300   alg_out->cost = cost_limit;
2301   memcpy (alg_out->op, best_alg->op,
2302           alg_out->ops * sizeof *alg_out->op);
2303   memcpy (alg_out->log, best_alg->log,
2304           alg_out->ops * sizeof *alg_out->log);
2305 }
2306 \f
2307 /* Perform a multiplication and return an rtx for the result.
2308    MODE is mode of value; OP0 and OP1 are what to multiply (rtx's);
2309    TARGET is a suggestion for where to store the result (an rtx).
2310
2311    We check specially for a constant integer as OP1.
2312    If you want this check for OP0 as well, then before calling
2313    you should swap the two operands if OP0 would be constant.  */
2314
2315 rtx
2316 expand_mult (mode, op0, op1, target, unsignedp)
2317      enum machine_mode mode;
2318      rtx op0, op1, target;
2319      int unsignedp;
2320 {
2321   rtx const_op1 = op1;
2322
2323   /* synth_mult does an `unsigned int' multiply.  As long as the mode is
2324      less than or equal in size to `unsigned int' this doesn't matter.
2325      If the mode is larger than `unsigned int', then synth_mult works only
2326      if the constant value exactly fits in an `unsigned int' without any
2327      truncation.  This means that multiplying by negative values does
2328      not work; results are off by 2^32 on a 32 bit machine.  */
2329
2330   /* If we are multiplying in DImode, it may still be a win
2331      to try to work with shifts and adds.  */
2332   if (GET_CODE (op1) == CONST_DOUBLE
2333       && GET_MODE_CLASS (GET_MODE (op1)) == MODE_INT
2334       && HOST_BITS_PER_INT >= BITS_PER_WORD
2335       && CONST_DOUBLE_HIGH (op1) == 0)
2336     const_op1 = GEN_INT (CONST_DOUBLE_LOW (op1));
2337   else if (HOST_BITS_PER_INT < GET_MODE_BITSIZE (mode)
2338            && GET_CODE (op1) == CONST_INT
2339            && INTVAL (op1) < 0)
2340     const_op1 = 0;
2341
2342   /* We used to test optimize here, on the grounds that it's better to
2343      produce a smaller program when -O is not used.
2344      But this causes such a terrible slowdown sometimes
2345      that it seems better to use synth_mult always.  */
2346
2347   if (const_op1 && GET_CODE (const_op1) == CONST_INT
2348       && (unsignedp || ! flag_trapv))
2349     {
2350       struct algorithm alg;
2351       struct algorithm alg2;
2352       HOST_WIDE_INT val = INTVAL (op1);
2353       HOST_WIDE_INT val_so_far;
2354       rtx insn;
2355       int mult_cost;
2356       enum {basic_variant, negate_variant, add_variant} variant = basic_variant;
2357
2358       /* op0 must be register to make mult_cost match the precomputed
2359          shiftadd_cost array.  */
2360       op0 = force_reg (mode, op0);
2361
2362       /* Try to do the computation three ways: multiply by the negative of OP1
2363          and then negate, do the multiplication directly, or do multiplication
2364          by OP1 - 1.  */
2365
2366       mult_cost = rtx_cost (gen_rtx_MULT (mode, op0, op1), SET);
2367       mult_cost = MIN (12 * add_cost, mult_cost);
2368
2369       synth_mult (&alg, val, mult_cost);
2370
2371       /* This works only if the inverted value actually fits in an
2372          `unsigned int' */
2373       if (HOST_BITS_PER_INT >= GET_MODE_BITSIZE (mode))
2374         {
2375           synth_mult (&alg2, - val,
2376                       (alg.cost < mult_cost ? alg.cost : mult_cost) - negate_cost);
2377           if (alg2.cost + negate_cost < alg.cost)
2378             alg = alg2, variant = negate_variant;
2379         }
2380
2381       /* This proves very useful for division-by-constant.  */
2382       synth_mult (&alg2, val - 1,
2383                   (alg.cost < mult_cost ? alg.cost : mult_cost) - add_cost);
2384       if (alg2.cost + add_cost < alg.cost)
2385         alg = alg2, variant = add_variant;
2386
2387       if (alg.cost < mult_cost)
2388         {
2389           /* We found something cheaper than a multiply insn.  */
2390           int opno;
2391           rtx accum, tem;
2392           enum machine_mode nmode;
2393
2394           op0 = protect_from_queue (op0, 0);
2395
2396           /* Avoid referencing memory over and over.
2397              For speed, but also for correctness when mem is volatile.  */
2398           if (GET_CODE (op0) == MEM)
2399             op0 = force_reg (mode, op0);
2400
2401           /* ACCUM starts out either as OP0 or as a zero, depending on
2402              the first operation.  */
2403
2404           if (alg.op[0] == alg_zero)
2405             {
2406               accum = copy_to_mode_reg (mode, const0_rtx);
2407               val_so_far = 0;
2408             }
2409           else if (alg.op[0] == alg_m)
2410             {
2411               accum = copy_to_mode_reg (mode, op0);
2412               val_so_far = 1;
2413             }
2414           else
2415             abort ();
2416
2417           for (opno = 1; opno < alg.ops; opno++)
2418             {
2419               int log = alg.log[opno];
2420               int preserve = preserve_subexpressions_p ();
2421               rtx shift_subtarget = preserve ? 0 : accum;
2422               rtx add_target
2423                 = (opno == alg.ops - 1 && target != 0 && variant != add_variant
2424                    && ! preserve)
2425                   ? target : 0;
2426               rtx accum_target = preserve ? 0 : accum;
2427               
2428               switch (alg.op[opno])
2429                 {
2430                 case alg_shift:
2431                   accum = expand_shift (LSHIFT_EXPR, mode, accum,
2432                                         build_int_2 (log, 0), NULL_RTX, 0);
2433                   val_so_far <<= log;
2434                   break;
2435
2436                 case alg_add_t_m2:
2437                   tem = expand_shift (LSHIFT_EXPR, mode, op0,
2438                                       build_int_2 (log, 0), NULL_RTX, 0);
2439                   accum = force_operand (gen_rtx_PLUS (mode, accum, tem),
2440                                          add_target
2441                                          ? add_target : accum_target);
2442                   val_so_far += (HOST_WIDE_INT) 1 << log;
2443                   break;
2444
2445                 case alg_sub_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_MINUS (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_add_t2_m:
2455                   accum = expand_shift (LSHIFT_EXPR, mode, accum,
2456                                         build_int_2 (log, 0), shift_subtarget,
2457                                         0);
2458                   accum = force_operand (gen_rtx_PLUS (mode, accum, op0),
2459                                          add_target
2460                                          ? add_target : accum_target);
2461                   val_so_far = (val_so_far << log) + 1;
2462                   break;
2463
2464                 case alg_sub_t2_m:
2465                   accum = expand_shift (LSHIFT_EXPR, mode, accum,
2466                                         build_int_2 (log, 0), shift_subtarget,
2467                                         0);
2468                   accum = force_operand (gen_rtx_MINUS (mode, accum, op0),
2469                                          add_target
2470                                          ? add_target : accum_target);
2471                   val_so_far = (val_so_far << log) - 1;
2472                   break;
2473
2474                 case alg_add_factor:
2475                   tem = expand_shift (LSHIFT_EXPR, mode, accum,
2476                                       build_int_2 (log, 0), NULL_RTX, 0);
2477                   accum = force_operand (gen_rtx_PLUS (mode, accum, tem),
2478                                          add_target
2479                                          ? add_target : accum_target);
2480                   val_so_far += val_so_far << log;
2481                   break;
2482
2483                 case alg_sub_factor:
2484                   tem = expand_shift (LSHIFT_EXPR, mode, accum,
2485                                       build_int_2 (log, 0), NULL_RTX, 0);
2486                   accum = force_operand (gen_rtx_MINUS (mode, tem, accum),
2487                                          (add_target ? add_target
2488                                           : preserve ? 0 : tem));
2489                   val_so_far = (val_so_far << log) - val_so_far;
2490                   break;
2491
2492                 default:
2493                   abort ();
2494                 }
2495
2496               /* Write a REG_EQUAL note on the last insn so that we can cse
2497                  multiplication sequences.  Note that if ACCUM is a SUBREG,
2498                  we've set the inner register and must properly indicate
2499                  that.  */
2500
2501               tem = op0, nmode = mode;
2502               if (GET_CODE (accum) == SUBREG)
2503                 {
2504                   nmode = GET_MODE (SUBREG_REG (accum));
2505                   tem = gen_lowpart (nmode, op0);
2506                 }
2507
2508               insn = get_last_insn ();
2509               set_unique_reg_note (insn, 
2510                                    REG_EQUAL,
2511                                    gen_rtx_MULT (nmode, tem,
2512                                                  GEN_INT (val_so_far)));
2513             }
2514
2515           if (variant == negate_variant)
2516             {
2517               val_so_far = - val_so_far;
2518               accum = expand_unop (mode, neg_optab, accum, target, 0);
2519             }
2520           else if (variant == add_variant)
2521             {
2522               val_so_far = val_so_far + 1;
2523               accum = force_operand (gen_rtx_PLUS (mode, accum, op0), target);
2524             }
2525
2526           if (val != val_so_far)
2527             abort ();
2528
2529           return accum;
2530         }
2531     }
2532
2533   /* This used to use umul_optab if unsigned, but for non-widening multiply
2534      there is no difference between signed and unsigned.  */
2535   op0 = expand_binop (mode, 
2536                       ! unsignedp
2537                        && flag_trapv && (GET_MODE_CLASS(mode) == MODE_INT)
2538                        ? smulv_optab : smul_optab,
2539                       op0, op1, target, unsignedp, OPTAB_LIB_WIDEN);
2540   if (op0 == 0)
2541     abort ();
2542   return op0;
2543 }
2544 \f
2545 /* Return the smallest n such that 2**n >= X.  */
2546
2547 int
2548 ceil_log2 (x)
2549      unsigned HOST_WIDE_INT x;
2550 {
2551   return floor_log2 (x - 1) + 1;
2552 }
2553
2554 /* Choose a minimal N + 1 bit approximation to 1/D that can be used to
2555    replace division by D, and put the least significant N bits of the result
2556    in *MULTIPLIER_PTR and return the most significant bit.
2557
2558    The width of operations is N (should be <= HOST_BITS_PER_WIDE_INT), the
2559    needed precision is in PRECISION (should be <= N).
2560
2561    PRECISION should be as small as possible so this function can choose
2562    multiplier more freely.
2563
2564    The rounded-up logarithm of D is placed in *lgup_ptr.  A shift count that
2565    is to be used for a final right shift is placed in *POST_SHIFT_PTR.
2566
2567    Using this function, x/D will be equal to (x * m) >> (*POST_SHIFT_PTR),
2568    where m is the full HOST_BITS_PER_WIDE_INT + 1 bit multiplier.  */
2569
2570 static
2571 unsigned HOST_WIDE_INT
2572 choose_multiplier (d, n, precision, multiplier_ptr, post_shift_ptr, lgup_ptr)
2573      unsigned HOST_WIDE_INT d;
2574      int n;
2575      int precision;
2576      unsigned HOST_WIDE_INT *multiplier_ptr;
2577      int *post_shift_ptr;
2578      int *lgup_ptr;
2579 {
2580   HOST_WIDE_INT mhigh_hi, mlow_hi;
2581   unsigned HOST_WIDE_INT mhigh_lo, mlow_lo;
2582   int lgup, post_shift;
2583   int pow, pow2;
2584   unsigned HOST_WIDE_INT nl, dummy1;
2585   HOST_WIDE_INT nh, dummy2;
2586
2587   /* lgup = ceil(log2(divisor)); */
2588   lgup = ceil_log2 (d);
2589
2590   if (lgup > n)
2591     abort ();
2592
2593   pow = n + lgup;
2594   pow2 = n + lgup - precision;
2595
2596   if (pow == 2 * HOST_BITS_PER_WIDE_INT)
2597     {
2598       /* We could handle this with some effort, but this case is much better
2599          handled directly with a scc insn, so rely on caller using that.  */
2600       abort ();
2601     }
2602
2603   /* mlow = 2^(N + lgup)/d */
2604  if (pow >= HOST_BITS_PER_WIDE_INT)
2605     {
2606       nh = (HOST_WIDE_INT) 1 << (pow - HOST_BITS_PER_WIDE_INT);
2607       nl = 0;
2608     }
2609   else
2610     {
2611       nh = 0;
2612       nl = (unsigned HOST_WIDE_INT) 1 << pow;
2613     }
2614   div_and_round_double (TRUNC_DIV_EXPR, 1, nl, nh, d, (HOST_WIDE_INT) 0,
2615                         &mlow_lo, &mlow_hi, &dummy1, &dummy2);
2616
2617   /* mhigh = (2^(N + lgup) + 2^N + lgup - precision)/d */
2618   if (pow2 >= HOST_BITS_PER_WIDE_INT)
2619     nh |= (HOST_WIDE_INT) 1 << (pow2 - HOST_BITS_PER_WIDE_INT);
2620   else
2621     nl |= (unsigned HOST_WIDE_INT) 1 << pow2;
2622   div_and_round_double (TRUNC_DIV_EXPR, 1, nl, nh, d, (HOST_WIDE_INT) 0,
2623                         &mhigh_lo, &mhigh_hi, &dummy1, &dummy2);
2624
2625   if (mhigh_hi && nh - d >= d)
2626     abort ();
2627   if (mhigh_hi > 1 || mlow_hi > 1)
2628     abort ();
2629   /* assert that mlow < mhigh.  */
2630   if (! (mlow_hi < mhigh_hi || (mlow_hi == mhigh_hi && mlow_lo < mhigh_lo)))
2631     abort ();
2632
2633   /* If precision == N, then mlow, mhigh exceed 2^N
2634      (but they do not exceed 2^(N+1)).  */
2635
2636   /* Reduce to lowest terms */
2637   for (post_shift = lgup; post_shift > 0; post_shift--)
2638     {
2639       unsigned HOST_WIDE_INT ml_lo = (mlow_hi << (HOST_BITS_PER_WIDE_INT - 1)) | (mlow_lo >> 1);
2640       unsigned HOST_WIDE_INT mh_lo = (mhigh_hi << (HOST_BITS_PER_WIDE_INT - 1)) | (mhigh_lo >> 1);
2641       if (ml_lo >= mh_lo)
2642         break;
2643
2644       mlow_hi = 0;
2645       mlow_lo = ml_lo;
2646       mhigh_hi = 0;
2647       mhigh_lo = mh_lo;
2648     }
2649
2650   *post_shift_ptr = post_shift;
2651   *lgup_ptr = lgup;
2652   if (n < HOST_BITS_PER_WIDE_INT)
2653     {
2654       unsigned HOST_WIDE_INT mask = ((unsigned HOST_WIDE_INT) 1 << n) - 1;
2655       *multiplier_ptr = mhigh_lo & mask;
2656       return mhigh_lo >= mask;
2657     }
2658   else
2659     {
2660       *multiplier_ptr = mhigh_lo;
2661       return mhigh_hi;
2662     }
2663 }
2664
2665 /* Compute the inverse of X mod 2**n, i.e., find Y such that X * Y is
2666    congruent to 1 (mod 2**N).  */
2667
2668 static unsigned HOST_WIDE_INT
2669 invert_mod2n (x, n)
2670      unsigned HOST_WIDE_INT x;
2671      int n;
2672 {
2673   /* Solve x*y == 1 (mod 2^n), where x is odd.  Return y.  */
2674
2675   /* The algorithm notes that the choice y = x satisfies
2676      x*y == 1 mod 2^3, since x is assumed odd.
2677      Each iteration doubles the number of bits of significance in y.  */
2678
2679   unsigned HOST_WIDE_INT mask;
2680   unsigned HOST_WIDE_INT y = x;
2681   int nbit = 3;
2682
2683   mask = (n == HOST_BITS_PER_WIDE_INT
2684           ? ~(unsigned HOST_WIDE_INT) 0
2685           : ((unsigned HOST_WIDE_INT) 1 << n) - 1);
2686
2687   while (nbit < n)
2688     {
2689       y = y * (2 - x*y) & mask;         /* Modulo 2^N */
2690       nbit *= 2;
2691     }
2692   return y;
2693 }
2694
2695 /* Emit code to adjust ADJ_OPERAND after multiplication of wrong signedness
2696    flavor of OP0 and OP1.  ADJ_OPERAND is already the high half of the
2697    product OP0 x OP1.  If UNSIGNEDP is nonzero, adjust the signed product
2698    to become unsigned, if UNSIGNEDP is zero, adjust the unsigned product to
2699    become signed.
2700
2701    The result is put in TARGET if that is convenient.
2702
2703    MODE is the mode of operation.  */
2704
2705 rtx
2706 expand_mult_highpart_adjust (mode, adj_operand, op0, op1, target, unsignedp)
2707      enum machine_mode mode;
2708      rtx adj_operand, op0, op1, target;
2709      int unsignedp;
2710 {
2711   rtx tem;
2712   enum rtx_code adj_code = unsignedp ? PLUS : MINUS;
2713
2714   tem = expand_shift (RSHIFT_EXPR, mode, op0,
2715                       build_int_2 (GET_MODE_BITSIZE (mode) - 1, 0),
2716                       NULL_RTX, 0);
2717   tem = expand_and (tem, op1, NULL_RTX);
2718   adj_operand
2719     = force_operand (gen_rtx_fmt_ee (adj_code, mode, adj_operand, tem),
2720                      adj_operand);
2721
2722   tem = expand_shift (RSHIFT_EXPR, mode, op1,
2723                       build_int_2 (GET_MODE_BITSIZE (mode) - 1, 0),
2724                       NULL_RTX, 0);
2725   tem = expand_and (tem, op0, NULL_RTX);
2726   target = force_operand (gen_rtx_fmt_ee (adj_code, mode, adj_operand, tem),
2727                           target);
2728
2729   return target;
2730 }
2731
2732 /* Emit code to multiply OP0 and CNST1, putting the high half of the result
2733    in TARGET if that is convenient, and return where the result is.  If the
2734    operation can not be performed, 0 is returned.
2735
2736    MODE is the mode of operation and result.
2737
2738    UNSIGNEDP nonzero means unsigned multiply.
2739
2740    MAX_COST is the total allowed cost for the expanded RTL.  */
2741
2742 rtx
2743 expand_mult_highpart (mode, op0, cnst1, target, unsignedp, max_cost)
2744      enum machine_mode mode;
2745      rtx op0, target;
2746      unsigned HOST_WIDE_INT cnst1;
2747      int unsignedp;
2748      int max_cost;
2749 {
2750   enum machine_mode wider_mode = GET_MODE_WIDER_MODE (mode);
2751   optab mul_highpart_optab;
2752   optab moptab;
2753   rtx tem;
2754   int size = GET_MODE_BITSIZE (mode);
2755   rtx op1, wide_op1;
2756
2757   /* We can't support modes wider than HOST_BITS_PER_INT.  */
2758   if (size > HOST_BITS_PER_WIDE_INT)
2759     abort ();
2760
2761   op1 = GEN_INT (trunc_int_for_mode (cnst1, mode));
2762
2763   if (GET_MODE_BITSIZE (wider_mode) <= HOST_BITS_PER_INT)
2764     wide_op1 = op1;
2765   else
2766     wide_op1
2767       = immed_double_const (cnst1,
2768                             (unsignedp
2769                              ? (HOST_WIDE_INT) 0
2770                              : -(cnst1 >> (HOST_BITS_PER_WIDE_INT - 1))),
2771                             wider_mode);
2772
2773   /* expand_mult handles constant multiplication of word_mode
2774      or narrower.  It does a poor job for large modes.  */
2775   if (size < BITS_PER_WORD
2776       && mul_cost[(int) wider_mode] + shift_cost[size-1] < max_cost)
2777     {
2778       /* We have to do this, since expand_binop doesn't do conversion for
2779          multiply.  Maybe change expand_binop to handle widening multiply?  */
2780       op0 = convert_to_mode (wider_mode, op0, unsignedp);
2781
2782       /* We know that this can't have signed overflow, so pretend this is
2783          an unsigned multiply.  */
2784       tem = expand_mult (wider_mode, op0, wide_op1, NULL_RTX, 0);
2785       tem = expand_shift (RSHIFT_EXPR, wider_mode, tem,
2786                           build_int_2 (size, 0), NULL_RTX, 1);
2787       return convert_modes (mode, wider_mode, tem, unsignedp);
2788     }
2789
2790   if (target == 0)
2791     target = gen_reg_rtx (mode);
2792
2793   /* Firstly, try using a multiplication insn that only generates the needed
2794      high part of the product, and in the sign flavor of unsignedp.  */
2795   if (mul_highpart_cost[(int) mode] < max_cost)
2796     {
2797       mul_highpart_optab = unsignedp ? umul_highpart_optab : smul_highpart_optab;
2798       target = expand_binop (mode, mul_highpart_optab,
2799                              op0, op1, target, unsignedp, OPTAB_DIRECT);
2800       if (target)
2801         return target;
2802     }
2803
2804   /* Secondly, same as above, but use sign flavor opposite of unsignedp.
2805      Need to adjust the result after the multiplication.  */
2806   if (size - 1 < BITS_PER_WORD
2807       && (mul_highpart_cost[(int) mode] + 2 * shift_cost[size-1] + 4 * add_cost
2808           < max_cost))
2809     {
2810       mul_highpart_optab = unsignedp ? smul_highpart_optab : umul_highpart_optab;
2811       target = expand_binop (mode, mul_highpart_optab,
2812                              op0, op1, target, unsignedp, OPTAB_DIRECT);
2813       if (target)
2814         /* We used the wrong signedness.  Adjust the result.  */
2815         return expand_mult_highpart_adjust (mode, target, op0,
2816                                             op1, target, unsignedp);
2817     }
2818
2819   /* Try widening multiplication.  */
2820   moptab = unsignedp ? umul_widen_optab : smul_widen_optab;
2821   if (moptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing
2822       && mul_widen_cost[(int) wider_mode] < max_cost)
2823     {
2824       op1 = force_reg (mode, op1);
2825       goto try;
2826     } 
2827
2828   /* Try widening the mode and perform a non-widening multiplication.  */
2829   moptab = smul_optab;
2830   if (smul_optab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing
2831       && size - 1 < BITS_PER_WORD
2832       && mul_cost[(int) wider_mode] + shift_cost[size-1] < max_cost)
2833     {
2834       op1 = wide_op1;
2835       goto try;
2836     }
2837
2838   /* Try widening multiplication of opposite signedness, and adjust.  */
2839   moptab = unsignedp ? smul_widen_optab : umul_widen_optab;
2840   if (moptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing
2841       && size - 1 < BITS_PER_WORD
2842       && (mul_widen_cost[(int) wider_mode]
2843           + 2 * shift_cost[size-1] + 4 * add_cost < max_cost))
2844     {
2845       rtx regop1 = force_reg (mode, op1);
2846       tem = expand_binop (wider_mode, moptab, op0, regop1,
2847                           NULL_RTX, ! unsignedp, OPTAB_WIDEN);
2848       if (tem != 0)
2849         {
2850           /* Extract the high half of the just generated product.  */
2851           tem = expand_shift (RSHIFT_EXPR, wider_mode, tem,
2852                               build_int_2 (size, 0), NULL_RTX, 1);
2853           tem = convert_modes (mode, wider_mode, tem, unsignedp);
2854           /* We used the wrong signedness.  Adjust the result.  */
2855           return expand_mult_highpart_adjust (mode, tem, op0, op1,
2856                                               target, unsignedp);
2857         }
2858     }
2859
2860   return 0;
2861
2862  try:
2863   /* Pass NULL_RTX as target since TARGET has wrong mode.  */
2864   tem = expand_binop (wider_mode, moptab, op0, op1,
2865                       NULL_RTX, unsignedp, OPTAB_WIDEN);
2866   if (tem == 0)
2867     return 0;
2868
2869   /* Extract the high half of the just generated product.  */
2870   if (mode == word_mode)
2871     {
2872       return gen_highpart (mode, tem);
2873     }
2874   else
2875     {
2876       tem = expand_shift (RSHIFT_EXPR, wider_mode, tem,
2877                           build_int_2 (size, 0), NULL_RTX, 1);
2878       return convert_modes (mode, wider_mode, tem, unsignedp);
2879     }
2880 }
2881 \f
2882 /* Emit the code to divide OP0 by OP1, putting the result in TARGET
2883    if that is convenient, and returning where the result is.
2884    You may request either the quotient or the remainder as the result;
2885    specify REM_FLAG nonzero to get the remainder.
2886
2887    CODE is the expression code for which kind of division this is;
2888    it controls how rounding is done.  MODE is the machine mode to use.
2889    UNSIGNEDP nonzero means do unsigned division.  */
2890
2891 /* ??? For CEIL_MOD_EXPR, can compute incorrect remainder with ANDI
2892    and then correct it by or'ing in missing high bits
2893    if result of ANDI is nonzero.
2894    For ROUND_MOD_EXPR, can use ANDI and then sign-extend the result.
2895    This could optimize to a bfexts instruction.
2896    But C doesn't use these operations, so their optimizations are
2897    left for later.  */
2898 /* ??? For modulo, we don't actually need the highpart of the first product,
2899    the low part will do nicely.  And for small divisors, the second multiply
2900    can also be a low-part only multiply or even be completely left out.
2901    E.g. to calculate the remainder of a division by 3 with a 32 bit
2902    multiply, multiply with 0x55555556 and extract the upper two bits;
2903    the result is exact for inputs up to 0x1fffffff.
2904    The input range can be reduced by using cross-sum rules.
2905    For odd divisors >= 3, the following table gives right shift counts
2906    so that if an number is shifted by an integer multiple of the given
2907    amount, the remainder stays the same:
2908    2, 4, 3, 6, 10, 12, 4, 8, 18, 6, 11, 20, 18, 0, 5, 10, 12, 0, 12, 20,
2909    14, 12, 23, 21, 8, 0, 20, 18, 0, 0, 6, 12, 0, 22, 0, 18, 20, 30, 0, 0,
2910    0, 8, 0, 11, 12, 10, 36, 0, 30, 0, 0, 12, 0, 0, 0, 0, 44, 12, 24, 0,
2911    20, 0, 7, 14, 0, 18, 36, 0, 0, 46, 60, 0, 42, 0, 15, 24, 20, 0, 0, 33,
2912    0, 20, 0, 0, 18, 0, 60, 0, 0, 0, 0, 0, 40, 18, 0, 0, 12
2913
2914    Cross-sum rules for even numbers can be derived by leaving as many bits
2915    to the right alone as the divisor has zeros to the right.
2916    E.g. if x is an unsigned 32 bit number:
2917    (x mod 12) == (((x & 1023) + ((x >> 8) & ~3)) * 0x15555558 >> 2 * 3) >> 28
2918    */
2919
2920 #define EXACT_POWER_OF_2_OR_ZERO_P(x) (((x) & ((x) - 1)) == 0)
2921
2922 rtx
2923 expand_divmod (rem_flag, code, mode, op0, op1, target, unsignedp)
2924      int rem_flag;
2925      enum tree_code code;
2926      enum machine_mode mode;
2927      rtx op0, op1, target;
2928      int unsignedp;
2929 {
2930   enum machine_mode compute_mode;
2931   rtx tquotient;
2932   rtx quotient = 0, remainder = 0;
2933   rtx last;
2934   int size;
2935   rtx insn, set;
2936   optab optab1, optab2;
2937   int op1_is_constant, op1_is_pow2;
2938   int max_cost, extra_cost;
2939   static HOST_WIDE_INT last_div_const = 0;
2940
2941   op1_is_constant = GET_CODE (op1) == CONST_INT;
2942   op1_is_pow2 = (op1_is_constant
2943                  && ((EXACT_POWER_OF_2_OR_ZERO_P (INTVAL (op1))
2944                       || (! unsignedp && EXACT_POWER_OF_2_OR_ZERO_P (-INTVAL (op1))))));
2945
2946   /*
2947      This is the structure of expand_divmod:
2948
2949      First comes code to fix up the operands so we can perform the operations
2950      correctly and efficiently.
2951
2952      Second comes a switch statement with code specific for each rounding mode.
2953      For some special operands this code emits all RTL for the desired
2954      operation, for other cases, it generates only a quotient and stores it in
2955      QUOTIENT.  The case for trunc division/remainder might leave quotient = 0,
2956      to indicate that it has not done anything.
2957
2958      Last comes code that finishes the operation.  If QUOTIENT is set and
2959      REM_FLAG is set, the remainder is computed as OP0 - QUOTIENT * OP1.  If
2960      QUOTIENT is not set, it is computed using trunc rounding.
2961
2962      We try to generate special code for division and remainder when OP1 is a
2963      constant.  If |OP1| = 2**n we can use shifts and some other fast
2964      operations.  For other values of OP1, we compute a carefully selected
2965      fixed-point approximation m = 1/OP1, and generate code that multiplies OP0
2966      by m.
2967
2968      In all cases but EXACT_DIV_EXPR, this multiplication requires the upper
2969      half of the product.  Different strategies for generating the product are
2970      implemented in expand_mult_highpart.
2971
2972      If what we actually want is the remainder, we generate that by another
2973      by-constant multiplication and a subtraction.  */
2974
2975   /* We shouldn't be called with OP1 == const1_rtx, but some of the
2976      code below will malfunction if we are, so check here and handle
2977      the special case if so.  */
2978   if (op1 == const1_rtx)
2979     return rem_flag ? const0_rtx : op0;
2980
2981     /* When dividing by -1, we could get an overflow.
2982      negv_optab can handle overflows.  */
2983   if (! unsignedp && op1 == constm1_rtx)
2984     {
2985       if (rem_flag)
2986         return const0_rtx;
2987       return expand_unop (mode, flag_trapv && GET_MODE_CLASS(mode) == MODE_INT
2988                         ? negv_optab : neg_optab, op0, target, 0);
2989     }
2990
2991   if (target
2992       /* Don't use the function value register as a target
2993          since we have to read it as well as write it,
2994          and function-inlining gets confused by this.  */
2995       && ((REG_P (target) && REG_FUNCTION_VALUE_P (target))
2996           /* Don't clobber an operand while doing a multi-step calculation.  */
2997           || ((rem_flag || op1_is_constant)
2998               && (reg_mentioned_p (target, op0)
2999                   || (GET_CODE (op0) == MEM && GET_CODE (target) == MEM)))
3000           || reg_mentioned_p (target, op1)
3001           || (GET_CODE (op1) == MEM && GET_CODE (target) == MEM)))
3002     target = 0;
3003
3004   /* Get the mode in which to perform this computation.  Normally it will
3005      be MODE, but sometimes we can't do the desired operation in MODE.
3006      If so, pick a wider mode in which we can do the operation.  Convert
3007      to that mode at the start to avoid repeated conversions.
3008
3009      First see what operations we need.  These depend on the expression
3010      we are evaluating.  (We assume that divxx3 insns exist under the
3011      same conditions that modxx3 insns and that these insns don't normally
3012      fail.  If these assumptions are not correct, we may generate less
3013      efficient code in some cases.)
3014
3015      Then see if we find a mode in which we can open-code that operation
3016      (either a division, modulus, or shift).  Finally, check for the smallest
3017      mode for which we can do the operation with a library call.  */
3018
3019   /* We might want to refine this now that we have division-by-constant
3020      optimization.  Since expand_mult_highpart tries so many variants, it is
3021      not straightforward to generalize this.  Maybe we should make an array
3022      of possible modes in init_expmed?  Save this for GCC 2.7.  */
3023
3024   optab1 = (op1_is_pow2 ? (unsignedp ? lshr_optab : ashr_optab)
3025             : (unsignedp ? udiv_optab : sdiv_optab));
3026   optab2 = (op1_is_pow2 ? optab1 : (unsignedp ? udivmod_optab : sdivmod_optab));
3027
3028   for (compute_mode = mode; compute_mode != VOIDmode;
3029        compute_mode = GET_MODE_WIDER_MODE (compute_mode))
3030     if (optab1->handlers[(int) compute_mode].insn_code != CODE_FOR_nothing
3031         || optab2->handlers[(int) compute_mode].insn_code != CODE_FOR_nothing)
3032       break;
3033
3034   if (compute_mode == VOIDmode)
3035     for (compute_mode = mode; compute_mode != VOIDmode;
3036          compute_mode = GET_MODE_WIDER_MODE (compute_mode))
3037       if (optab1->handlers[(int) compute_mode].libfunc
3038           || optab2->handlers[(int) compute_mode].libfunc)
3039         break;
3040
3041   /* If we still couldn't find a mode, use MODE, but we'll probably abort
3042      in expand_binop.  */
3043   if (compute_mode == VOIDmode)
3044     compute_mode = mode;
3045
3046   if (target && GET_MODE (target) == compute_mode)
3047     tquotient = target;
3048   else
3049     tquotient = gen_reg_rtx (compute_mode);
3050
3051   size = GET_MODE_BITSIZE (compute_mode);
3052 #if 0
3053   /* It should be possible to restrict the precision to GET_MODE_BITSIZE
3054      (mode), and thereby get better code when OP1 is a constant.  Do that
3055      later.  It will require going over all usages of SIZE below.  */
3056   size = GET_MODE_BITSIZE (mode);
3057 #endif
3058
3059   /* Only deduct something for a REM if the last divide done was
3060      for a different constant.   Then set the constant of the last
3061      divide.  */
3062   max_cost = div_cost[(int) compute_mode]
3063     - (rem_flag && ! (last_div_const != 0 && op1_is_constant
3064                       && INTVAL (op1) == last_div_const)
3065        ? mul_cost[(int) compute_mode] + add_cost : 0);
3066
3067   last_div_const = ! rem_flag && op1_is_constant ? INTVAL (op1) : 0;
3068
3069   /* Now convert to the best mode to use.  */
3070   if (compute_mode != mode)
3071     {
3072       op0 = convert_modes (compute_mode, mode, op0, unsignedp);
3073       op1 = convert_modes (compute_mode, mode, op1, unsignedp);
3074
3075       /* convert_modes may have placed op1 into a register, so we
3076          must recompute the following.  */
3077       op1_is_constant = GET_CODE (op1) == CONST_INT;
3078       op1_is_pow2 = (op1_is_constant
3079                      && ((EXACT_POWER_OF_2_OR_ZERO_P (INTVAL (op1))
3080                           || (! unsignedp
3081                               && EXACT_POWER_OF_2_OR_ZERO_P (-INTVAL (op1)))))) ;
3082     }
3083
3084   /* If one of the operands is a volatile MEM, copy it into a register.  */
3085
3086   if (GET_CODE (op0) == MEM && MEM_VOLATILE_P (op0))
3087     op0 = force_reg (compute_mode, op0);
3088   if (GET_CODE (op1) == MEM && MEM_VOLATILE_P (op1))
3089     op1 = force_reg (compute_mode, op1);
3090
3091   /* If we need the remainder or if OP1 is constant, we need to
3092      put OP0 in a register in case it has any queued subexpressions.  */
3093   if (rem_flag || op1_is_constant)
3094     op0 = force_reg (compute_mode, op0);
3095
3096   last = get_last_insn ();
3097
3098   /* Promote floor rounding to trunc rounding for unsigned operations.  */
3099   if (unsignedp)
3100     {
3101       if (code == FLOOR_DIV_EXPR)
3102         code = TRUNC_DIV_EXPR;
3103       if (code == FLOOR_MOD_EXPR)
3104         code = TRUNC_MOD_EXPR;
3105       if (code == EXACT_DIV_EXPR && op1_is_pow2)
3106         code = TRUNC_DIV_EXPR;
3107     }
3108
3109   if (op1 != const0_rtx)
3110     switch (code)
3111       {
3112       case TRUNC_MOD_EXPR:
3113       case TRUNC_DIV_EXPR:
3114         if (op1_is_constant)
3115           {
3116             if (unsignedp)
3117               {
3118                 unsigned HOST_WIDE_INT mh, ml;
3119                 int pre_shift, post_shift;
3120                 int dummy;
3121                 unsigned HOST_WIDE_INT d = INTVAL (op1);
3122
3123                 if (EXACT_POWER_OF_2_OR_ZERO_P (d))
3124                   {
3125                     pre_shift = floor_log2 (d);
3126                     if (rem_flag)
3127                       {
3128                         remainder
3129                           = expand_binop (compute_mode, and_optab, op0,
3130                                           GEN_INT (((HOST_WIDE_INT) 1 << pre_shift) - 1),
3131                                           remainder, 1,
3132                                           OPTAB_LIB_WIDEN);
3133                         if (remainder)
3134                           return gen_lowpart (mode, remainder);
3135                       }
3136                     quotient = expand_shift (RSHIFT_EXPR, compute_mode, op0,
3137                                              build_int_2 (pre_shift, 0),
3138                                              tquotient, 1);
3139                   }
3140                 else if (size <= HOST_BITS_PER_WIDE_INT)
3141                   {
3142                     if (d >= ((unsigned HOST_WIDE_INT) 1 << (size - 1)))
3143                       {
3144                         /* Most significant bit of divisor is set; emit an scc
3145                            insn.  */
3146                         quotient = emit_store_flag (tquotient, GEU, op0, op1,
3147                                                     compute_mode, 1, 1);
3148                         if (quotient == 0)
3149                           goto fail1;
3150                       }
3151                     else
3152                       {
3153                         /* Find a suitable multiplier and right shift count
3154                            instead of multiplying with D.  */
3155
3156                         mh = choose_multiplier (d, size, size,
3157                                                 &ml, &post_shift, &dummy);
3158
3159                         /* If the suggested multiplier is more than SIZE bits,
3160                            we can do better for even divisors, using an
3161                            initial right shift.  */
3162                         if (mh != 0 && (d & 1) == 0)
3163                           {
3164                             pre_shift = floor_log2 (d & -d);
3165                             mh = choose_multiplier (d >> pre_shift, size,
3166                                                     size - pre_shift,
3167                                                     &ml, &post_shift, &dummy);
3168                             if (mh)
3169                               abort ();
3170                           }
3171                         else
3172                           pre_shift = 0;
3173
3174                         if (mh != 0)
3175                           {
3176                             rtx t1, t2, t3, t4;
3177
3178                             if (post_shift - 1 >= BITS_PER_WORD)
3179                               goto fail1;
3180
3181                             extra_cost = (shift_cost[post_shift - 1]
3182                                           + shift_cost[1] + 2 * add_cost);
3183                             t1 = expand_mult_highpart (compute_mode, op0, ml,
3184                                                        NULL_RTX, 1,
3185                                                        max_cost - extra_cost);
3186                             if (t1 == 0)
3187                               goto fail1;
3188                             t2 = force_operand (gen_rtx_MINUS (compute_mode,
3189                                                                op0, t1),
3190                                                 NULL_RTX);
3191                             t3 = expand_shift (RSHIFT_EXPR, compute_mode, t2,
3192                                                build_int_2 (1, 0), NULL_RTX,1);
3193                             t4 = force_operand (gen_rtx_PLUS (compute_mode,
3194                                                               t1, t3),
3195                                                 NULL_RTX);
3196                             quotient
3197                               = expand_shift (RSHIFT_EXPR, compute_mode, t4,
3198                                               build_int_2 (post_shift - 1, 0),
3199                                               tquotient, 1);
3200                           }
3201                         else
3202                           {
3203                             rtx t1, t2;
3204
3205                             if (pre_shift >= BITS_PER_WORD
3206                                 || post_shift >= BITS_PER_WORD)
3207                               goto fail1;
3208
3209                             t1 = expand_shift (RSHIFT_EXPR, compute_mode, op0,
3210                                                build_int_2 (pre_shift, 0),
3211                                                NULL_RTX, 1);
3212                             extra_cost = (shift_cost[pre_shift]
3213                                           + shift_cost[post_shift]);
3214                             t2 = expand_mult_highpart (compute_mode, t1, ml,
3215                                                        NULL_RTX, 1,
3216                                                        max_cost - extra_cost);
3217                             if (t2 == 0)
3218                               goto fail1;
3219                             quotient
3220                               = expand_shift (RSHIFT_EXPR, compute_mode, t2,
3221                                               build_int_2 (post_shift, 0),
3222                                               tquotient, 1);
3223                           }
3224                       }
3225                   }
3226                 else            /* Too wide mode to use tricky code */
3227                   break;
3228
3229                 insn = get_last_insn ();
3230                 if (insn != last
3231                     && (set = single_set (insn)) != 0
3232                     && SET_DEST (set) == quotient)
3233                   set_unique_reg_note (insn, 
3234                                        REG_EQUAL,
3235                                        gen_rtx_UDIV (compute_mode, op0, op1));
3236               }
3237             else                /* TRUNC_DIV, signed */
3238               {
3239                 unsigned HOST_WIDE_INT ml;
3240                 int lgup, post_shift;
3241                 HOST_WIDE_INT d = INTVAL (op1);
3242                 unsigned HOST_WIDE_INT abs_d = d >= 0 ? d : -d;
3243
3244                 /* n rem d = n rem -d */
3245                 if (rem_flag && d < 0)
3246                   {
3247                     d = abs_d;
3248                     op1 = GEN_INT (trunc_int_for_mode (abs_d, compute_mode));
3249                   }
3250
3251                 if (d == 1)
3252                   quotient = op0;
3253                 else if (d == -1)
3254                   quotient = expand_unop (compute_mode, neg_optab, op0,
3255                                           tquotient, 0);
3256                 else if (abs_d == (unsigned HOST_WIDE_INT) 1 << (size - 1))
3257                   {
3258                     /* This case is not handled correctly below.  */
3259                     quotient = emit_store_flag (tquotient, EQ, op0, op1,
3260                                                 compute_mode, 1, 1);
3261                     if (quotient == 0)
3262                       goto fail1;
3263                   }
3264                 else if (EXACT_POWER_OF_2_OR_ZERO_P (d)
3265                          && (rem_flag ? smod_pow2_cheap : sdiv_pow2_cheap)
3266                          /* ??? The cheap metric is computed only for
3267                             word_mode.  If this operation is wider, this may
3268                             not be so.  Assume true if the optab has an
3269                             expander for this mode.  */
3270                          && (((rem_flag ? smod_optab : sdiv_optab)
3271                               ->handlers[(int) compute_mode].insn_code
3272                               != CODE_FOR_nothing)
3273                              || (sdivmod_optab->handlers[(int) compute_mode]
3274                                  .insn_code != CODE_FOR_nothing)))
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   /* ??? Ok to do this and then fail? */
4202   op0 = protect_from_queue (op0, 0);
4203   op1 = protect_from_queue (op1, 0);
4204
4205   if (unsignedp)
4206     code = unsigned_condition (code);
4207
4208   /* If one operand is constant, make it the second one.  Only do this
4209      if the other operand is not constant as well.  */
4210
4211   if (swap_commutative_operands_p (op0, op1))
4212     {
4213       tem = op0;
4214       op0 = op1;
4215       op1 = tem;
4216       code = swap_condition (code);
4217     }
4218
4219   if (mode == VOIDmode)
4220     mode = GET_MODE (op0);
4221
4222   /* For some comparisons with 1 and -1, we can convert this to 
4223      comparisons with zero.  This will often produce more opportunities for
4224      store-flag insns.  */
4225
4226   switch (code)
4227     {
4228     case LT:
4229       if (op1 == const1_rtx)
4230         op1 = const0_rtx, code = LE;
4231       break;
4232     case LE:
4233       if (op1 == constm1_rtx)
4234         op1 = const0_rtx, code = LT;
4235       break;
4236     case GE:
4237       if (op1 == const1_rtx)
4238         op1 = const0_rtx, code = GT;
4239       break;
4240     case GT:
4241       if (op1 == constm1_rtx)
4242         op1 = const0_rtx, code = GE;
4243       break;
4244     case GEU:
4245       if (op1 == const1_rtx)
4246         op1 = const0_rtx, code = NE;
4247       break;
4248     case LTU:
4249       if (op1 == const1_rtx)
4250         op1 = const0_rtx, code = EQ;
4251       break;
4252     default:
4253       break;
4254     }
4255
4256   /* If we are comparing a double-word integer with zero, we can convert
4257      the comparison into one involving a single word.  */
4258   if (GET_MODE_BITSIZE (mode) == BITS_PER_WORD * 2
4259       && GET_MODE_CLASS (mode) == MODE_INT
4260       && op1 == const0_rtx)
4261     {
4262       if (code == EQ || code == NE)
4263         {
4264           /* Do a logical OR of the two words and compare the result.  */
4265           rtx op0h = gen_highpart (word_mode, op0);
4266           rtx op0l = gen_lowpart (word_mode, op0);
4267           rtx op0both = expand_binop (word_mode, ior_optab, op0h, op0l,
4268                                       NULL_RTX, unsignedp, OPTAB_DIRECT);
4269           if (op0both != 0)
4270             return emit_store_flag (target, code, op0both, op1, word_mode,
4271                                     unsignedp, normalizep);
4272         }
4273       else if (code == LT || code == GE)
4274         /* If testing the sign bit, can just test on high word.  */
4275         return emit_store_flag (target, code, gen_highpart (word_mode, op0),
4276                                 op1, word_mode, unsignedp, normalizep);
4277     }
4278
4279   /* From now on, we won't change CODE, so set ICODE now.  */
4280   icode = setcc_gen_code[(int) code];
4281
4282   /* If this is A < 0 or A >= 0, we can do this by taking the ones
4283      complement of A (for GE) and shifting the sign bit to the low bit.  */
4284   if (op1 == const0_rtx && (code == LT || code == GE)
4285       && GET_MODE_CLASS (mode) == MODE_INT
4286       && (normalizep || STORE_FLAG_VALUE == 1
4287           || (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
4288               && ((STORE_FLAG_VALUE & GET_MODE_MASK (mode))
4289                   == (HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE (mode) - 1)))))
4290     {
4291       subtarget = target;
4292
4293       /* If the result is to be wider than OP0, it is best to convert it
4294          first.  If it is to be narrower, it is *incorrect* to convert it
4295          first.  */
4296       if (GET_MODE_SIZE (target_mode) > GET_MODE_SIZE (mode))
4297         {
4298           op0 = protect_from_queue (op0, 0);
4299           op0 = convert_modes (target_mode, mode, op0, 0);
4300           mode = target_mode;
4301         }
4302
4303       if (target_mode != mode)
4304         subtarget = 0;
4305
4306       if (code == GE)
4307         op0 = expand_unop (mode, one_cmpl_optab, op0,
4308                            ((STORE_FLAG_VALUE == 1 || normalizep)
4309                             ? 0 : subtarget), 0);
4310
4311       if (STORE_FLAG_VALUE == 1 || normalizep)
4312         /* If we are supposed to produce a 0/1 value, we want to do
4313            a logical shift from the sign bit to the low-order bit; for
4314            a -1/0 value, we do an arithmetic shift.  */
4315         op0 = expand_shift (RSHIFT_EXPR, mode, op0,
4316                             size_int (GET_MODE_BITSIZE (mode) - 1),
4317                             subtarget, normalizep != -1);
4318
4319       if (mode != target_mode)
4320         op0 = convert_modes (target_mode, mode, op0, 0);
4321
4322       return op0;
4323     }
4324
4325   if (icode != CODE_FOR_nothing)
4326     {
4327       insn_operand_predicate_fn pred;
4328
4329       /* We think we may be able to do this with a scc insn.  Emit the
4330          comparison and then the scc insn.
4331
4332          compare_from_rtx may call emit_queue, which would be deleted below
4333          if the scc insn fails.  So call it ourselves before setting LAST.
4334          Likewise for do_pending_stack_adjust.  */
4335
4336       emit_queue ();
4337       do_pending_stack_adjust ();
4338       last = get_last_insn ();
4339
4340       comparison
4341         = compare_from_rtx (op0, op1, code, unsignedp, mode, NULL_RTX);
4342       if (GET_CODE (comparison) == CONST_INT)
4343         return (comparison == const0_rtx ? const0_rtx
4344                 : normalizep == 1 ? const1_rtx
4345                 : normalizep == -1 ? constm1_rtx
4346                 : const_true_rtx);
4347
4348       /* The code of COMPARISON may not match CODE if compare_from_rtx
4349          decided to swap its operands and reverse the original code.
4350
4351          We know that compare_from_rtx returns either a CONST_INT or
4352          a new comparison code, so it is safe to just extract the
4353          code from COMPARISON.  */
4354       code = GET_CODE (comparison);
4355
4356       /* Get a reference to the target in the proper mode for this insn.  */
4357       compare_mode = insn_data[(int) icode].operand[0].mode;
4358       subtarget = target;
4359       pred = insn_data[(int) icode].operand[0].predicate;
4360       if (preserve_subexpressions_p ()
4361           || ! (*pred) (subtarget, compare_mode))
4362         subtarget = gen_reg_rtx (compare_mode);
4363
4364       pattern = GEN_FCN (icode) (subtarget);
4365       if (pattern)
4366         {
4367           emit_insn (pattern);
4368
4369           /* If we are converting to a wider mode, first convert to
4370              TARGET_MODE, then normalize.  This produces better combining
4371              opportunities on machines that have a SIGN_EXTRACT when we are
4372              testing a single bit.  This mostly benefits the 68k.
4373
4374              If STORE_FLAG_VALUE does not have the sign bit set when
4375              interpreted in COMPARE_MODE, we can do this conversion as
4376              unsigned, which is usually more efficient.  */
4377           if (GET_MODE_SIZE (target_mode) > GET_MODE_SIZE (compare_mode))
4378             {
4379               convert_move (target, subtarget,
4380                             (GET_MODE_BITSIZE (compare_mode)
4381                              <= HOST_BITS_PER_WIDE_INT)
4382                             && 0 == (STORE_FLAG_VALUE
4383                                      & ((HOST_WIDE_INT) 1
4384                                         << (GET_MODE_BITSIZE (compare_mode) -1))));
4385               op0 = target;
4386               compare_mode = target_mode;
4387             }
4388           else
4389             op0 = subtarget;
4390
4391           /* If we want to keep subexpressions around, don't reuse our
4392              last target.  */
4393
4394           if (preserve_subexpressions_p ())
4395             subtarget = 0;
4396
4397           /* Now normalize to the proper value in COMPARE_MODE.  Sometimes
4398              we don't have to do anything.  */
4399           if (normalizep == 0 || normalizep == STORE_FLAG_VALUE)
4400             ;
4401           /* STORE_FLAG_VALUE might be the most negative number, so write
4402              the comparison this way to avoid a compiler-time warning.  */
4403           else if (- normalizep == STORE_FLAG_VALUE)
4404             op0 = expand_unop (compare_mode, neg_optab, op0, subtarget, 0);
4405
4406           /* We don't want to use STORE_FLAG_VALUE < 0 below since this
4407              makes it hard to use a value of just the sign bit due to
4408              ANSI integer constant typing rules.  */
4409           else if (GET_MODE_BITSIZE (compare_mode) <= HOST_BITS_PER_WIDE_INT
4410                    && (STORE_FLAG_VALUE
4411                        & ((HOST_WIDE_INT) 1
4412                           << (GET_MODE_BITSIZE (compare_mode) - 1))))
4413             op0 = expand_shift (RSHIFT_EXPR, compare_mode, op0,
4414                                 size_int (GET_MODE_BITSIZE (compare_mode) - 1),
4415                                 subtarget, normalizep == 1);
4416           else if (STORE_FLAG_VALUE & 1)
4417             {
4418               op0 = expand_and (op0, const1_rtx, subtarget);
4419               if (normalizep == -1)
4420                 op0 = expand_unop (compare_mode, neg_optab, op0, op0, 0);
4421             }
4422           else
4423             abort ();
4424
4425           /* If we were converting to a smaller mode, do the 
4426              conversion now.  */
4427           if (target_mode != compare_mode)
4428             {
4429               convert_move (target, op0, 0);
4430               return target;
4431             }
4432           else
4433             return op0;
4434         }
4435     }
4436
4437   delete_insns_since (last);
4438
4439   /* If expensive optimizations, use different pseudo registers for each
4440      insn, instead of reusing the same pseudo.  This leads to better CSE,
4441      but slows down the compiler, since there are more pseudos */
4442   subtarget = (!flag_expensive_optimizations
4443                && (target_mode == mode)) ? target : NULL_RTX;
4444
4445   /* If we reached here, we can't do this with a scc insn.  However, there
4446      are some comparisons that can be done directly.  For example, if
4447      this is an equality comparison of integers, we can try to exclusive-or
4448      (or subtract) the two operands and use a recursive call to try the
4449      comparison with zero.  Don't do any of these cases if branches are
4450      very cheap.  */
4451
4452   if (BRANCH_COST > 0
4453       && GET_MODE_CLASS (mode) == MODE_INT && (code == EQ || code == NE)
4454       && op1 != const0_rtx)
4455     {
4456       tem = expand_binop (mode, xor_optab, op0, op1, subtarget, 1,
4457                           OPTAB_WIDEN);
4458
4459       if (tem == 0)
4460         tem = expand_binop (mode, sub_optab, op0, op1, subtarget, 1,
4461                             OPTAB_WIDEN);
4462       if (tem != 0)
4463         tem = emit_store_flag (target, code, tem, const0_rtx,
4464                                mode, unsignedp, normalizep);
4465       if (tem == 0)
4466         delete_insns_since (last);
4467       return tem;
4468     }
4469
4470   /* Some other cases we can do are EQ, NE, LE, and GT comparisons with 
4471      the constant zero.  Reject all other comparisons at this point.  Only
4472      do LE and GT if branches are expensive since they are expensive on
4473      2-operand machines.  */
4474
4475   if (BRANCH_COST == 0
4476       || GET_MODE_CLASS (mode) != MODE_INT || op1 != const0_rtx
4477       || (code != EQ && code != NE
4478           && (BRANCH_COST <= 1 || (code != LE && code != GT))))
4479     return 0;
4480
4481   /* See what we need to return.  We can only return a 1, -1, or the
4482      sign bit.  */
4483
4484   if (normalizep == 0)
4485     {
4486       if (STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1)
4487         normalizep = STORE_FLAG_VALUE;
4488
4489       else if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
4490                && ((STORE_FLAG_VALUE & GET_MODE_MASK (mode))
4491                    == (unsigned HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE (mode) - 1)))
4492         ;
4493       else
4494         return 0;
4495     }
4496
4497   /* Try to put the result of the comparison in the sign bit.  Assume we can't
4498      do the necessary operation below.  */
4499
4500   tem = 0;
4501
4502   /* To see if A <= 0, compute (A | (A - 1)).  A <= 0 iff that result has
4503      the sign bit set.  */
4504
4505   if (code == LE)
4506     {
4507       /* This is destructive, so SUBTARGET can't be OP0.  */
4508       if (rtx_equal_p (subtarget, op0))
4509         subtarget = 0;
4510
4511       tem = expand_binop (mode, sub_optab, op0, const1_rtx, subtarget, 0,
4512                           OPTAB_WIDEN);
4513       if (tem)
4514         tem = expand_binop (mode, ior_optab, op0, tem, subtarget, 0,
4515                             OPTAB_WIDEN);
4516     }
4517
4518   /* To see if A > 0, compute (((signed) A) << BITS) - A, where BITS is the
4519      number of bits in the mode of OP0, minus one.  */
4520
4521   if (code == GT)
4522     {
4523       if (rtx_equal_p (subtarget, op0))
4524         subtarget = 0;
4525
4526       tem = expand_shift (RSHIFT_EXPR, mode, op0,
4527                           size_int (GET_MODE_BITSIZE (mode) - 1),
4528                           subtarget, 0);
4529       tem = expand_binop (mode, sub_optab, tem, op0, subtarget, 0,
4530                           OPTAB_WIDEN);
4531     }
4532                                     
4533   if (code == EQ || code == NE)
4534     {
4535       /* For EQ or NE, one way to do the comparison is to apply an operation
4536          that converts the operand into a positive number if it is non-zero
4537          or zero if it was originally zero.  Then, for EQ, we subtract 1 and
4538          for NE we negate.  This puts the result in the sign bit.  Then we
4539          normalize with a shift, if needed. 
4540
4541          Two operations that can do the above actions are ABS and FFS, so try
4542          them.  If that doesn't work, and MODE is smaller than a full word,
4543          we can use zero-extension to the wider mode (an unsigned conversion)
4544          as the operation.  */
4545
4546       /* Note that ABS doesn't yield a positive number for INT_MIN, but 
4547          that is compensated by the subsequent overflow when subtracting 
4548          one / negating.  */
4549
4550       if (abs_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
4551         tem = expand_unop (mode, abs_optab, op0, subtarget, 1);
4552       else if (ffs_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
4553         tem = expand_unop (mode, ffs_optab, op0, subtarget, 1);
4554       else if (GET_MODE_SIZE (mode) < UNITS_PER_WORD)
4555         {
4556           op0 = protect_from_queue (op0, 0);
4557           tem = convert_modes (word_mode, mode, op0, 1);
4558           mode = word_mode;
4559         }
4560
4561       if (tem != 0)
4562         {
4563           if (code == EQ)
4564             tem = expand_binop (mode, sub_optab, tem, const1_rtx, subtarget,
4565                                 0, OPTAB_WIDEN);
4566           else
4567             tem = expand_unop (mode, neg_optab, tem, subtarget, 0);
4568         }
4569
4570       /* If we couldn't do it that way, for NE we can "or" the two's complement
4571          of the value with itself.  For EQ, we take the one's complement of
4572          that "or", which is an extra insn, so we only handle EQ if branches
4573          are expensive.  */
4574
4575       if (tem == 0 && (code == NE || BRANCH_COST > 1))
4576         {
4577           if (rtx_equal_p (subtarget, op0))
4578             subtarget = 0;
4579
4580           tem = expand_unop (mode, neg_optab, op0, subtarget, 0);
4581           tem = expand_binop (mode, ior_optab, tem, op0, subtarget, 0,
4582                               OPTAB_WIDEN);
4583
4584           if (tem && code == EQ)
4585             tem = expand_unop (mode, one_cmpl_optab, tem, subtarget, 0);
4586         }
4587     }
4588
4589   if (tem && normalizep)
4590     tem = expand_shift (RSHIFT_EXPR, mode, tem,
4591                         size_int (GET_MODE_BITSIZE (mode) - 1),
4592                         subtarget, normalizep == 1);
4593
4594   if (tem)
4595     {
4596       if (GET_MODE (tem) != target_mode)
4597         {
4598           convert_move (target, tem, 0);
4599           tem = target;
4600         }
4601       else if (!subtarget)
4602         {
4603           emit_move_insn (target, tem);
4604           tem = target;
4605         }
4606     }
4607   else
4608     delete_insns_since (last);
4609
4610   return tem;
4611 }
4612
4613 /* Like emit_store_flag, but always succeeds.  */
4614
4615 rtx
4616 emit_store_flag_force (target, code, op0, op1, mode, unsignedp, normalizep)
4617      rtx target;
4618      enum rtx_code code;
4619      rtx op0, op1;
4620      enum machine_mode mode;
4621      int unsignedp;
4622      int normalizep;
4623 {
4624   rtx tem, label;
4625
4626   /* First see if emit_store_flag can do the job.  */
4627   tem = emit_store_flag (target, code, op0, op1, mode, unsignedp, normalizep);
4628   if (tem != 0)
4629     return tem;
4630
4631   if (normalizep == 0)
4632     normalizep = 1;
4633
4634   /* If this failed, we have to do this with set/compare/jump/set code.  */
4635
4636   if (GET_CODE (target) != REG
4637       || reg_mentioned_p (target, op0) || reg_mentioned_p (target, op1))
4638     target = gen_reg_rtx (GET_MODE (target));
4639
4640   emit_move_insn (target, const1_rtx);
4641   label = gen_label_rtx ();
4642   do_compare_rtx_and_jump (op0, op1, code, unsignedp, mode, NULL_RTX,
4643                            NULL_RTX, label);
4644
4645   emit_move_insn (target, const0_rtx);
4646   emit_label (label);
4647
4648   return target;
4649 }
4650 \f
4651 /* Perform possibly multi-word comparison and conditional jump to LABEL
4652    if ARG1 OP ARG2 true where ARG1 and ARG2 are of mode MODE
4653
4654    The algorithm is based on the code in expr.c:do_jump.
4655
4656    Note that this does not perform a general comparison.  Only variants
4657    generated within expmed.c are correctly handled, others abort (but could
4658    be handled if needed).  */
4659
4660 static void
4661 do_cmp_and_jump (arg1, arg2, op, mode, label)
4662      rtx arg1, arg2, label;
4663      enum rtx_code op;
4664      enum machine_mode mode;
4665 {
4666   /* If this mode is an integer too wide to compare properly,
4667      compare word by word.  Rely on cse to optimize constant cases.  */
4668
4669   if (GET_MODE_CLASS (mode) == MODE_INT
4670       && ! can_compare_p (op, mode, ccp_jump))
4671     {
4672       rtx label2 = gen_label_rtx ();
4673
4674       switch (op)
4675         {
4676         case LTU:
4677           do_jump_by_parts_greater_rtx (mode, 1, arg2, arg1, label2, label);
4678           break;
4679
4680         case LEU:
4681           do_jump_by_parts_greater_rtx (mode, 1, arg1, arg2, label, label2);
4682           break;
4683
4684         case LT:
4685           do_jump_by_parts_greater_rtx (mode, 0, arg2, arg1, label2, label);
4686           break;
4687
4688         case GT:
4689           do_jump_by_parts_greater_rtx (mode, 0, arg1, arg2, label2, label);
4690           break;
4691
4692         case GE:
4693           do_jump_by_parts_greater_rtx (mode, 0, arg2, arg1, label, label2);
4694           break;
4695
4696           /* do_jump_by_parts_equality_rtx compares with zero.  Luckily
4697              that's the only equality operations we do */
4698         case EQ:
4699           if (arg2 != const0_rtx || mode != GET_MODE(arg1))
4700             abort ();
4701           do_jump_by_parts_equality_rtx (arg1, label2, label);
4702           break;
4703
4704         case NE:
4705           if (arg2 != const0_rtx || mode != GET_MODE(arg1))
4706             abort ();
4707           do_jump_by_parts_equality_rtx (arg1, label, label2);
4708           break;
4709
4710         default:
4711           abort ();
4712         }
4713
4714       emit_label (label2);
4715     }
4716   else
4717     emit_cmp_and_jump_insns (arg1, arg2, op, NULL_RTX, mode, 0, label);
4718 }