OSDN Git Service

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