OSDN Git Service

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