OSDN Git Service

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