OSDN Git Service

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