OSDN Git Service

(init_expmed): Supply missing arg to rtx_cost.
[pf3gnuchains/gcc-fork.git] / gcc / expmed.c
1 /* Medium-level subroutines: convert bit-field store and extract
2    and shifts, multiplies and divides to rtl instructions.
3    Copyright (C) 1987, 1988, 1989, 1992, 1993 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, 675 Mass Ave, Cambridge, MA 02139, USA.  */
20
21
22 #include "config.h"
23 #include "rtl.h"
24 #include "tree.h"
25 #include "flags.h"
26 #include "insn-flags.h"
27 #include "insn-codes.h"
28 #include "insn-config.h"
29 #include "expr.h"
30 #include "real.h"
31 #include "recog.h"
32
33 static rtx extract_split_bit_field ();
34 static rtx extract_fixed_bit_field ();
35 static void store_split_bit_field ();
36 static void store_fixed_bit_field ();
37 static rtx mask_rtx ();
38 static rtx lshift_value ();
39
40 #define CEIL(x,y) (((x) + (y) - 1) / (y))
41
42 /* Non-zero means multiply instructions are cheaper than shifts.  */
43 int mult_is_very_cheap;
44
45 /* Non-zero means divides or modulus operations are relatively cheap for
46    powers of two, so don't use branches; emit the operation instead. 
47    Usually, this will mean that the MD file will emit non-branch
48    sequences.  */
49
50 static int sdiv_pow2_cheap, smod_pow2_cheap;
51
52 /* Cost of various pieces of RTL.  */
53 static int add_cost, mult_cost, negate_cost, zero_cost;
54 static int shift_cost[BITS_PER_WORD];
55 static int shiftadd_cost[BITS_PER_WORD];
56 static int shiftsub_cost[BITS_PER_WORD];
57
58 void
59 init_expmed ()
60 {
61   char *free_point;
62   /* This is "some random pseudo register" for purposes of calling recog
63      to see what insns exist.  */
64   rtx reg = gen_rtx (REG, word_mode, FIRST_PSEUDO_REGISTER);
65   rtx shift_insn, shiftadd_insn, shiftsub_insn;
66   int dummy;
67   int m;
68
69   start_sequence ();
70
71   /* Since we are on the permanent obstack, we must be sure we save this
72      spot AFTER we call start_sequence, since it will reuse the rtl it
73      makes.  */
74
75   free_point = (char *) oballoc (0);
76
77   zero_cost = rtx_cost (const0_rtx, 0);
78   add_cost = rtx_cost (gen_rtx (PLUS, word_mode, reg, reg), SET);
79
80   shift_insn = emit_insn (gen_rtx (SET, VOIDmode, reg,
81                                    gen_rtx (ASHIFT, word_mode, reg,
82                                             const0_rtx)));
83
84   shiftadd_insn = emit_insn (gen_rtx (SET, VOIDmode, reg,
85                                       gen_rtx (PLUS, word_mode,
86                                                gen_rtx (MULT, word_mode,
87                                                         reg, const0_rtx),
88                                                reg)));
89
90   shiftsub_insn = emit_insn (gen_rtx (SET, VOIDmode, reg,
91                                       gen_rtx (MINUS, word_mode,
92                                                gen_rtx (MULT, word_mode,
93                                                          reg, const0_rtx),
94                                                 reg)));
95
96   init_recog ();
97
98   shift_cost[0] = 0;
99   shiftadd_cost[0] = shiftsub_cost[0] = add_cost;
100
101   for (m = 1; m < BITS_PER_WORD; m++)
102     {
103       shift_cost[m] = shiftadd_cost[m] = shiftsub_cost[m] = 32000;
104
105       XEXP (SET_SRC (PATTERN (shift_insn)), 1) = GEN_INT (m);
106       if (recog (PATTERN (shift_insn), shift_insn, &dummy) >= 0)
107         shift_cost[m] = rtx_cost (SET_SRC (PATTERN (shift_insn)), SET);
108
109       XEXP (XEXP (SET_SRC (PATTERN (shiftadd_insn)), 0), 1)
110         = GEN_INT ((HOST_WIDE_INT) 1 << m);
111       if (recog (PATTERN (shiftadd_insn), shiftadd_insn, &dummy) >= 0)
112         shiftadd_cost[m] = rtx_cost (SET_SRC (PATTERN (shiftadd_insn)), SET);
113
114       XEXP (XEXP (SET_SRC (PATTERN (shiftsub_insn)), 0), 1)
115         = GEN_INT ((HOST_WIDE_INT) 1 << m);
116       if (recog (PATTERN (shiftsub_insn), shiftsub_insn, &dummy) >= 0)
117         shiftsub_cost[m] = rtx_cost (SET_SRC (PATTERN (shiftsub_insn)), SET);
118     }
119
120   mult_cost = rtx_cost (gen_rtx (MULT, word_mode, reg, reg), SET);
121   negate_cost = rtx_cost (gen_rtx (NEG, word_mode, reg), SET);
122
123   /* 999999 is chosen to avoid any plausible faster special case.  */
124   mult_is_very_cheap
125     = (rtx_cost (gen_rtx (MULT, word_mode, reg, GEN_INT (999999)), SET)
126        < rtx_cost (gen_rtx (ASHIFT, word_mode, reg, GEN_INT (7)), SET));
127
128   sdiv_pow2_cheap
129     = (rtx_cost (gen_rtx (DIV, word_mode, reg, GEN_INT (32)), SET)
130        <= 2 * add_cost);
131   smod_pow2_cheap
132     = (rtx_cost (gen_rtx (MOD, word_mode, reg, GEN_INT (32)), SET)
133        <= 2 * add_cost);
134
135   /* Free the objects we just allocated.  */
136   end_sequence ();
137   obfree (free_point);
138 }
139
140 /* Return an rtx representing minus the value of X.
141    MODE is the intended mode of the result,
142    useful if X is a CONST_INT.  */
143
144 rtx
145 negate_rtx (mode, x)
146      enum machine_mode mode;
147      rtx x;
148 {
149   if (GET_CODE (x) == CONST_INT)
150     {
151       HOST_WIDE_INT val = - INTVAL (x);
152       if (GET_MODE_BITSIZE (mode) < HOST_BITS_PER_WIDE_INT)
153         {
154           /* Sign extend the value from the bits that are significant.  */
155           if (val & ((HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE (mode) - 1)))
156             val |= (HOST_WIDE_INT) (-1) << GET_MODE_BITSIZE (mode);
157           else
158             val &= ((HOST_WIDE_INT) 1 << GET_MODE_BITSIZE (mode)) - 1;
159         }
160       return GEN_INT (val);
161     }
162   else
163     return expand_unop (GET_MODE (x), neg_optab, x, NULL_RTX, 0);
164 }
165 \f
166 /* Generate code to store value from rtx VALUE
167    into a bit-field within structure STR_RTX
168    containing BITSIZE bits starting at bit BITNUM.
169    FIELDMODE is the machine-mode of the FIELD_DECL node for this field.
170    ALIGN is the alignment that STR_RTX is known to have, measured in bytes.
171    TOTAL_SIZE is the size of the structure in bytes, or -1 if varying.  */
172
173 /* ??? Note that there are two different ideas here for how
174    to determine the size to count bits within, for a register.
175    One is BITS_PER_WORD, and the other is the size of operand 3
176    of the insv pattern.  (The latter assumes that an n-bit machine
177    will be able to insert bit fields up to n bits wide.)
178    It isn't certain that either of these is right.
179    extract_bit_field has the same quandary.  */
180
181 rtx
182 store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, align, total_size)
183      rtx str_rtx;
184      register int bitsize;
185      int bitnum;
186      enum machine_mode fieldmode;
187      rtx value;
188      int align;
189      int total_size;
190 {
191   int unit = (GET_CODE (str_rtx) == MEM) ? BITS_PER_UNIT : BITS_PER_WORD;
192   register int offset = bitnum / unit;
193   register int bitpos = bitnum % unit;
194   register rtx op0 = str_rtx;
195
196   if (GET_CODE (str_rtx) == MEM && ! MEM_IN_STRUCT_P (str_rtx))
197     abort ();
198
199   /* Discount the part of the structure before the desired byte.
200      We need to know how many bytes are safe to reference after it.  */
201   if (total_size >= 0)
202     total_size -= (bitpos / BIGGEST_ALIGNMENT
203                    * (BIGGEST_ALIGNMENT / BITS_PER_UNIT));
204
205   while (GET_CODE (op0) == SUBREG)
206     {
207       /* The following line once was done only if WORDS_BIG_ENDIAN,
208          but I think that is a mistake.  WORDS_BIG_ENDIAN is
209          meaningful at a much higher level; when structures are copied
210          between memory and regs, the higher-numbered regs
211          always get higher addresses.  */
212       offset += SUBREG_WORD (op0);
213       /* We used to adjust BITPOS here, but now we do the whole adjustment
214          right after the loop.  */
215       op0 = SUBREG_REG (op0);
216     }
217
218 #if BYTES_BIG_ENDIAN
219   /* If OP0 is a register, BITPOS must count within a word.
220      But as we have it, it counts within whatever size OP0 now has.
221      On a bigendian machine, these are not the same, so convert.  */
222   if (GET_CODE (op0) != MEM && unit > GET_MODE_BITSIZE (GET_MODE (op0)))
223     bitpos += unit - GET_MODE_BITSIZE (GET_MODE (op0));
224 #endif
225
226   value = protect_from_queue (value, 0);
227
228   if (flag_force_mem)
229     value = force_not_mem (value);
230
231   /* Note that the adjustment of BITPOS above has no effect on whether
232      BITPOS is 0 in a REG bigger than a word.  */
233   if (GET_MODE_SIZE (fieldmode) >= UNITS_PER_WORD
234       && (! STRICT_ALIGNMENT || GET_CODE (op0) != MEM)
235       && bitpos == 0 && bitsize == GET_MODE_BITSIZE (fieldmode))
236     {
237       /* Storing in a full-word or multi-word field in a register
238          can be done with just SUBREG.  */
239       if (GET_MODE (op0) != fieldmode)
240         if (GET_CODE (op0) == REG)
241           op0 = gen_rtx (SUBREG, fieldmode, op0, offset);
242         else
243           op0 = change_address (op0, fieldmode,
244                                 plus_constant (XEXP (op0, 0), offset));
245       emit_move_insn (op0, value);
246       return value;
247     }
248
249   /* Storing an lsb-aligned field in a register
250      can be done with a movestrict instruction.  */
251
252   if (GET_CODE (op0) != MEM
253 #if BYTES_BIG_ENDIAN
254       && bitpos + bitsize == unit
255 #else
256       && bitpos == 0
257 #endif
258       && bitsize == GET_MODE_BITSIZE (fieldmode)
259       && (GET_MODE (op0) == fieldmode
260           || (movstrict_optab->handlers[(int) fieldmode].insn_code
261               != CODE_FOR_nothing)))
262     {
263       /* Get appropriate low part of the value being stored.  */
264       if (GET_CODE (value) == CONST_INT || GET_CODE (value) == REG)
265         value = gen_lowpart (fieldmode, value);
266       else if (!(GET_CODE (value) == SYMBOL_REF
267                  || GET_CODE (value) == LABEL_REF
268                  || GET_CODE (value) == CONST))
269         value = convert_to_mode (fieldmode, value, 0);
270
271       if (GET_MODE (op0) == fieldmode)
272         emit_move_insn (op0, value);
273       else
274         {
275           int icode = movstrict_optab->handlers[(int) fieldmode].insn_code;
276           if(! (*insn_operand_predicate[icode][1]) (value, fieldmode))
277             value = copy_to_mode_reg (fieldmode, value);
278           emit_insn (GEN_FCN (icode)
279                    (gen_rtx (SUBREG, fieldmode, op0, offset), value));
280         }
281       return value;
282     }
283
284   /* Handle fields bigger than a word.  */
285
286   if (bitsize > BITS_PER_WORD)
287     {
288       /* Here we transfer the words of the field
289          in the order least significant first.
290          This is because the most significant word is the one which may
291          be less than full.  */
292
293       int nwords = (bitsize + (BITS_PER_WORD - 1)) / BITS_PER_WORD;
294       int i;
295
296       /* This is the mode we must force value to, so that there will be enough
297          subwords to extract.  Note that fieldmode will often (always?) be
298          VOIDmode, because that is what store_field uses to indicate that this
299          is a bit field, but passing VOIDmode to operand_subword_force will
300          result in an abort.  */
301       fieldmode = mode_for_size (nwords * BITS_PER_WORD, MODE_INT, 0);
302
303       for (i = 0; i < nwords; i++)
304         {
305           /* If I is 0, use the low-order word in both field and target;
306              if I is 1, use the next to lowest word; and so on.  */
307           int wordnum = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i);
308           int bit_offset = (WORDS_BIG_ENDIAN
309                             ? MAX (bitsize - (i + 1) * BITS_PER_WORD, 0)
310                             : i * BITS_PER_WORD);
311           store_bit_field (op0, MIN (BITS_PER_WORD,
312                                      bitsize - i * BITS_PER_WORD),
313                            bitnum + bit_offset, word_mode,
314                            operand_subword_force (value, wordnum, fieldmode),
315                            align, total_size);
316         }
317       return value;
318     }
319
320   /* From here on we can assume that the field to be stored in is
321      a full-word (whatever type that is), since it is shorter than a word.  */
322
323   /* OFFSET is the number of words or bytes (UNIT says which)
324      from STR_RTX to the first word or byte containing part of the field.  */
325
326   if (GET_CODE (op0) == REG)
327     {
328       if (offset != 0
329           || GET_MODE_SIZE (GET_MODE (op0)) > UNITS_PER_WORD)
330         op0 = gen_rtx (SUBREG, TYPE_MODE (type_for_size (BITS_PER_WORD, 0)),
331                        op0, offset);
332       offset = 0;
333     }
334   else
335     {
336       op0 = protect_from_queue (op0, 1);
337     }
338
339   /* Now OFFSET is nonzero only if OP0 is memory
340      and is therefore always measured in bytes.  */
341
342 #ifdef HAVE_insv
343   if (HAVE_insv
344       && !(bitsize == 1 && GET_CODE (value) == CONST_INT)
345       /* Ensure insv's size is wide enough for this field.  */
346       && (GET_MODE_BITSIZE (insn_operand_mode[(int) CODE_FOR_insv][3])
347           >= bitsize))
348     {
349       int xbitpos = bitpos;
350       rtx value1;
351       rtx xop0 = op0;
352       rtx last = get_last_insn ();
353       rtx pat;
354       enum machine_mode maxmode
355         = insn_operand_mode[(int) CODE_FOR_insv][3];
356
357       int save_volatile_ok = volatile_ok;
358       volatile_ok = 1;
359
360       /* If this machine's insv can only insert into a register, or if we
361          are to force MEMs into a register, copy OP0 into a register and
362          save it back later.  */
363       if (GET_CODE (op0) == MEM
364           && (flag_force_mem
365               || ! ((*insn_operand_predicate[(int) CODE_FOR_insv][0])
366                     (op0, VOIDmode))))
367         {
368           rtx tempreg;
369           enum machine_mode bestmode;
370
371           /* Get the mode to use for inserting into this field.  If OP0 is
372              BLKmode, get the smallest mode consistent with the alignment. If
373              OP0 is a non-BLKmode object that is no wider than MAXMODE, use its
374              mode. Otherwise, use the smallest mode containing the field.  */
375
376           if (GET_MODE (op0) == BLKmode
377               || GET_MODE_SIZE (GET_MODE (op0)) > GET_MODE_SIZE (maxmode))
378             bestmode
379               = get_best_mode (bitsize, bitnum, align * BITS_PER_UNIT, maxmode,
380                                MEM_VOLATILE_P (op0));
381           else
382             bestmode = GET_MODE (op0);
383
384           if (bestmode == VOIDmode)
385             goto insv_loses;
386
387           /* Adjust address to point to the containing unit of that mode.  */
388           unit = GET_MODE_BITSIZE (bestmode);
389           /* Compute offset as multiple of this unit, counting in bytes.  */
390           offset = (bitnum / unit) * GET_MODE_SIZE (bestmode);
391           bitpos = bitnum % unit;
392           op0 = change_address (op0, bestmode, 
393                                 plus_constant (XEXP (op0, 0), offset));
394
395           /* Fetch that unit, store the bitfield in it, then store the unit.  */
396           tempreg = copy_to_reg (op0);
397           store_bit_field (tempreg, bitsize, bitpos, fieldmode, value,
398                            align, total_size);
399           emit_move_insn (op0, tempreg);
400           return value;
401         }
402       volatile_ok = save_volatile_ok;
403
404       /* Add OFFSET into OP0's address.  */
405       if (GET_CODE (xop0) == MEM)
406         xop0 = change_address (xop0, byte_mode,
407                                plus_constant (XEXP (xop0, 0), offset));
408
409       /* If xop0 is a register, we need it in MAXMODE
410          to make it acceptable to the format of insv.  */
411       if (GET_CODE (xop0) == SUBREG)
412         PUT_MODE (xop0, maxmode);
413       if (GET_CODE (xop0) == REG && GET_MODE (xop0) != maxmode)
414         xop0 = gen_rtx (SUBREG, maxmode, xop0, 0);
415
416       /* On big-endian machines, we count bits from the most significant.
417          If the bit field insn does not, we must invert.  */
418
419 #if BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN
420       xbitpos = unit - bitsize - xbitpos;
421 #endif
422       /* We have been counting XBITPOS within UNIT.
423          Count instead within the size of the register.  */
424 #if BITS_BIG_ENDIAN
425       if (GET_CODE (xop0) != MEM)
426         xbitpos += GET_MODE_BITSIZE (maxmode) - unit;
427 #endif
428       unit = GET_MODE_BITSIZE (maxmode);
429
430       /* Convert VALUE to maxmode (which insv insn wants) in VALUE1.  */
431       value1 = value;
432       if (GET_MODE (value) != maxmode)
433         {
434           if (GET_MODE_BITSIZE (GET_MODE (value)) >= bitsize)
435             {
436               /* Optimization: Don't bother really extending VALUE
437                  if it has all the bits we will actually use.  However,
438                  if we must narrow it, be sure we do it correctly.  */
439
440               if (GET_MODE_SIZE (GET_MODE (value)) < GET_MODE_SIZE (maxmode))
441                 {
442                   /* Avoid making subreg of a subreg, or of a mem.  */
443                   if (GET_CODE (value1) != REG)
444                 value1 = copy_to_reg (value1);
445                   value1 = gen_rtx (SUBREG, maxmode, value1, 0);
446                 }
447               else
448                 value1 = gen_lowpart (maxmode, value1);
449             }
450           else if (!CONSTANT_P (value))
451             /* Parse phase is supposed to make VALUE's data type
452                match that of the component reference, which is a type
453                at least as wide as the field; so VALUE should have
454                a mode that corresponds to that type.  */
455             abort ();
456         }
457
458       /* If this machine's insv insists on a register,
459          get VALUE1 into a register.  */
460       if (! ((*insn_operand_predicate[(int) CODE_FOR_insv][3])
461              (value1, maxmode)))
462         value1 = force_reg (maxmode, value1);
463
464       pat = gen_insv (xop0, GEN_INT (bitsize), GEN_INT (xbitpos), value1);
465       if (pat)
466         emit_insn (pat);
467       else
468         {
469           delete_insns_since (last);
470           store_fixed_bit_field (op0, offset, bitsize, bitpos, value, align);
471         }
472     }
473   else
474     insv_loses:
475 #endif
476     /* Insv is not available; store using shifts and boolean ops.  */
477     store_fixed_bit_field (op0, offset, bitsize, bitpos, value, align);
478   return value;
479 }
480 \f
481 /* Use shifts and boolean operations to store VALUE
482    into a bit field of width BITSIZE
483    in a memory location specified by OP0 except offset by OFFSET bytes.
484      (OFFSET must be 0 if OP0 is a register.)
485    The field starts at position BITPOS within the byte.
486     (If OP0 is a register, it may be a full word or a narrower mode,
487      but BITPOS still counts within a full word,
488      which is significant on bigendian machines.)
489    STRUCT_ALIGN is the alignment the structure is known to have (in bytes).
490
491    Note that protect_from_queue has already been done on OP0 and VALUE.  */
492
493 static void
494 store_fixed_bit_field (op0, offset, bitsize, bitpos, value, struct_align)
495      register rtx op0;
496      register int offset, bitsize, bitpos;
497      register rtx value;
498      int struct_align;
499 {
500   register enum machine_mode mode;
501   int total_bits = BITS_PER_WORD;
502   rtx subtarget, temp;
503   int all_zero = 0;
504   int all_one = 0;
505
506   /* Add OFFSET to OP0's address (if it is in memory)
507      and if a single byte contains the whole bit field
508      change OP0 to a byte.  */
509
510   /* There is a case not handled here:
511      a structure with a known alignment of just a halfword
512      and a field split across two aligned halfwords within the structure.
513      Or likewise a structure with a known alignment of just a byte
514      and a field split across two bytes.
515      Such cases are not supposed to be able to occur.  */
516
517   if (GET_CODE (op0) == REG || GET_CODE (op0) == SUBREG)
518     {
519       if (offset != 0)
520         abort ();
521       /* Special treatment for a bit field split across two registers.  */
522       if (bitsize + bitpos > BITS_PER_WORD)
523         {
524           store_split_bit_field (op0, bitsize, bitpos, value, BITS_PER_WORD);
525           return;
526         }
527     }
528   else
529     {
530       /* Get the proper mode to use for this field.  We want a mode that
531          includes the entire field.  If such a mode would be larger than
532          a word, we won't be doing the extraction the normal way.  */
533
534       mode = get_best_mode (bitsize, bitpos + offset * BITS_PER_UNIT,
535                             struct_align * BITS_PER_UNIT, word_mode,
536                             GET_CODE (op0) == MEM && MEM_VOLATILE_P (op0));
537
538       if (mode == VOIDmode)
539         {
540           /* The only way this should occur is if the field spans word
541              boundaries.  */
542           store_split_bit_field (op0, bitsize, bitpos + offset * BITS_PER_UNIT,
543                                  value, struct_align);
544           return;
545         }
546
547       total_bits = GET_MODE_BITSIZE (mode);
548
549       /* Get ref to an aligned byte, halfword, or word containing the field.
550          Adjust BITPOS to be position within a word,
551          and OFFSET to be the offset of that word.
552          Then alter OP0 to refer to that word.  */
553       bitpos += (offset % (total_bits / BITS_PER_UNIT)) * BITS_PER_UNIT;
554       offset -= (offset % (total_bits / BITS_PER_UNIT));
555       op0 = change_address (op0, mode,
556                             plus_constant (XEXP (op0, 0), offset));
557     }
558
559   mode = GET_MODE (op0);
560
561   /* Now MODE is either some integral mode for a MEM as OP0,
562      or is a full-word for a REG as OP0.  TOTAL_BITS corresponds.
563      The bit field is contained entirely within OP0.
564      BITPOS is the starting bit number within OP0.
565      (OP0's mode may actually be narrower than MODE.)  */
566
567 #if BYTES_BIG_ENDIAN
568   /* BITPOS is the distance between our msb
569      and that of the containing datum.
570      Convert it to the distance from the lsb.  */
571
572   bitpos = total_bits - bitsize - bitpos;
573 #endif
574   /* Now BITPOS is always the distance between our lsb
575      and that of OP0.  */
576
577   /* Shift VALUE left by BITPOS bits.  If VALUE is not constant,
578      we must first convert its mode to MODE.  */
579
580   if (GET_CODE (value) == CONST_INT)
581     {
582       register HOST_WIDE_INT v = INTVAL (value);
583
584       if (bitsize < HOST_BITS_PER_WIDE_INT)
585         v &= ((HOST_WIDE_INT) 1 << bitsize) - 1;
586
587       if (v == 0)
588         all_zero = 1;
589       else if ((bitsize < HOST_BITS_PER_WIDE_INT
590                 && v == ((HOST_WIDE_INT) 1 << bitsize) - 1)
591                || (bitsize == HOST_BITS_PER_WIDE_INT && v == -1))
592         all_one = 1;
593
594       value = lshift_value (mode, value, bitpos, bitsize);
595     }
596   else
597     {
598       int must_and = (GET_MODE_BITSIZE (GET_MODE (value)) != bitsize
599                       && bitpos + bitsize != GET_MODE_BITSIZE (mode));
600
601       if (GET_MODE (value) != mode)
602         {
603           /* If VALUE is a floating-point mode, access it as an integer
604              of the corresponding size, then convert it.  This can occur on
605              a machine with 64 bit registers that uses SFmode for float.  */
606           if (GET_MODE_CLASS (GET_MODE (value)) == MODE_FLOAT)
607             {
608               if (GET_CODE (value) != REG)
609                 value = copy_to_reg (value);
610               value
611                 = gen_rtx (SUBREG, word_mode, value, 0);
612             }
613
614           if ((GET_CODE (value) == REG || GET_CODE (value) == SUBREG)
615               && GET_MODE_SIZE (mode) < GET_MODE_SIZE (GET_MODE (value)))
616             value = gen_lowpart (mode, value);
617           else
618             value = convert_to_mode (mode, value, 1);
619         }
620
621       if (must_and)
622         value = expand_binop (mode, and_optab, value,
623                               mask_rtx (mode, 0, bitsize, 0),
624                               NULL_RTX, 1, OPTAB_LIB_WIDEN);
625       if (bitpos > 0)
626         value = expand_shift (LSHIFT_EXPR, mode, value,
627                               build_int_2 (bitpos, 0), NULL_RTX, 1);
628     }
629
630   /* Now clear the chosen bits in OP0,
631      except that if VALUE is -1 we need not bother.  */
632
633   subtarget = (GET_CODE (op0) == REG || ! flag_force_mem) ? op0 : 0;
634
635   if (! all_one)
636     {
637       temp = expand_binop (mode, and_optab, op0,
638                            mask_rtx (mode, bitpos, bitsize, 1),
639                            subtarget, 1, OPTAB_LIB_WIDEN);
640       subtarget = temp;
641     }
642   else
643     temp = op0;
644
645   /* Now logical-or VALUE into OP0, unless it is zero.  */
646
647   if (! all_zero)
648     temp = expand_binop (mode, ior_optab, temp, value,
649                          subtarget, 1, OPTAB_LIB_WIDEN);
650   if (op0 != temp)
651     emit_move_insn (op0, temp);
652 }
653 \f
654 /* Store a bit field that is split across two words.
655
656    OP0 is the REG, SUBREG or MEM rtx for the first of the two words.
657    BITSIZE is the field width; BITPOS the position of its first bit
658    (within the word).
659    VALUE is the value to store.  */
660
661 static void
662 store_split_bit_field (op0, bitsize, bitpos, value, align)
663      rtx op0;
664      int bitsize, bitpos;
665      rtx value;
666      int align;
667 {
668   /* BITSIZE_1 is size of the part in the first word.  */
669   int bitsize_1 = BITS_PER_WORD - bitpos % BITS_PER_WORD;
670   /* BITSIZE_2 is size of the rest (in the following word).  */
671   int bitsize_2 = bitsize - bitsize_1;
672   rtx part1, part2;
673   int unit = GET_CODE (op0) == MEM ? BITS_PER_UNIT : BITS_PER_WORD;
674   int offset = bitpos / unit;
675   rtx word;
676
677   /* The field must span exactly one word boundary.  */
678   if (bitpos / BITS_PER_WORD != (bitpos + bitsize - 1) / BITS_PER_WORD - 1)
679     abort ();
680
681   if (GET_MODE (value) != VOIDmode)
682     value = convert_to_mode (word_mode, value, 1);
683
684   if (GET_CODE (value) == CONST_DOUBLE
685       && (part1 = gen_lowpart_common (word_mode, value)) != 0)
686     value = part1;
687
688   if (CONSTANT_P (value) && GET_CODE (value) != CONST_INT)
689     value = copy_to_mode_reg (word_mode, value);
690
691   /* Split the value into two parts:
692      PART1 gets that which goes in the first word; PART2 the other.  */
693 #if BYTES_BIG_ENDIAN
694   /* PART1 gets the more significant part.  */
695   if (GET_CODE (value) == CONST_INT)
696     {
697       part1 = GEN_INT ((unsigned HOST_WIDE_INT) (INTVAL (value)) >> bitsize_2);
698       part2 = GEN_INT ((unsigned HOST_WIDE_INT) (INTVAL (value))
699                        & (((HOST_WIDE_INT) 1 << bitsize_2) - 1));
700     }
701   else
702     {
703       part1 = extract_fixed_bit_field (word_mode, value, 0, bitsize_1,
704                                        BITS_PER_WORD - bitsize, NULL_RTX, 1,
705                                        BITS_PER_WORD);
706       part2 = extract_fixed_bit_field (word_mode, value, 0, bitsize_2,
707                                        BITS_PER_WORD - bitsize_2, NULL_RTX, 1,
708                                        BITS_PER_WORD);
709     }
710 #else
711   /* PART1 gets the less significant part.  */
712   if (GET_CODE (value) == CONST_INT)
713     {
714       part1 = GEN_INT ((unsigned HOST_WIDE_INT) (INTVAL (value))
715                        & (((HOST_WIDE_INT) 1 << bitsize_1) - 1));
716       part2 = GEN_INT ((unsigned HOST_WIDE_INT) (INTVAL (value)) >> bitsize_1);
717     }
718   else
719     {
720       part1 = extract_fixed_bit_field (word_mode, value, 0, bitsize_1, 0,
721                                        NULL_RTX, 1, BITS_PER_WORD);
722       part2 = extract_fixed_bit_field (word_mode, value, 0, bitsize_2,
723                                        bitsize_1, NULL_RTX, 1, BITS_PER_WORD);
724     }
725 #endif
726
727   /* Store PART1 into the first word.  If OP0 is a MEM, pass OP0 and the
728      offset computed above.  Otherwise, get the proper word and pass an
729      offset of zero.  */
730   word = (GET_CODE (op0) == MEM ? op0
731           : operand_subword (op0, offset, 1, GET_MODE (op0)));
732   if (word == 0)
733     abort ();
734
735   store_fixed_bit_field (word, GET_CODE (op0) == MEM ? offset : 0,
736                          bitsize_1, bitpos % unit, part1, align);
737
738   /* Offset op0 by 1 word to get to the following one.  */
739   if (GET_CODE (op0) == SUBREG)
740     word = operand_subword (SUBREG_REG (op0), SUBREG_WORD (op0) + offset + 1,
741                             1, VOIDmode);
742   else if (GET_CODE (op0) == MEM)
743     word = op0;
744   else
745     word = operand_subword (op0, offset + 1, 1, GET_MODE (op0));
746
747   if (word == 0)
748     abort ();
749
750   /* Store PART2 into the second word.  */
751   store_fixed_bit_field (word,
752                          (GET_CODE (op0) == MEM
753                           ? CEIL (offset + 1, UNITS_PER_WORD) * UNITS_PER_WORD
754                           : 0),
755                          bitsize_2, 0, part2, align);
756 }
757 \f
758 /* Generate code to extract a byte-field from STR_RTX
759    containing BITSIZE bits, starting at BITNUM,
760    and put it in TARGET if possible (if TARGET is nonzero).
761    Regardless of TARGET, we return the rtx for where the value is placed.
762    It may be a QUEUED.
763
764    STR_RTX is the structure containing the byte (a REG or MEM).
765    UNSIGNEDP is nonzero if this is an unsigned bit field.
766    MODE is the natural mode of the field value once extracted.
767    TMODE is the mode the caller would like the value to have;
768    but the value may be returned with type MODE instead.
769
770    ALIGN is the alignment that STR_RTX is known to have, measured in bytes.
771    TOTAL_SIZE is the size in bytes of the containing structure,
772    or -1 if varying.
773
774    If a TARGET is specified and we can store in it at no extra cost,
775    we do so, and return TARGET.
776    Otherwise, we return a REG of mode TMODE or MODE, with TMODE preferred
777    if they are equally easy.  */
778
779 rtx
780 extract_bit_field (str_rtx, bitsize, bitnum, unsignedp,
781                    target, mode, tmode, align, total_size)
782      rtx str_rtx;
783      register int bitsize;
784      int bitnum;
785      int unsignedp;
786      rtx target;
787      enum machine_mode mode, tmode;
788      int align;
789      int total_size;
790 {
791   int unit = (GET_CODE (str_rtx) == MEM) ? BITS_PER_UNIT : BITS_PER_WORD;
792   register int offset = bitnum / unit;
793   register int bitpos = bitnum % unit;
794   register rtx op0 = str_rtx;
795   rtx spec_target = target;
796   rtx spec_target_subreg = 0;
797
798   if (GET_CODE (str_rtx) == MEM && ! MEM_IN_STRUCT_P (str_rtx))
799     abort ();
800
801   /* Discount the part of the structure before the desired byte.
802      We need to know how many bytes are safe to reference after it.  */
803   if (total_size >= 0)
804     total_size -= (bitpos / BIGGEST_ALIGNMENT
805                    * (BIGGEST_ALIGNMENT / BITS_PER_UNIT));
806
807   if (tmode == VOIDmode)
808     tmode = mode;
809   while (GET_CODE (op0) == SUBREG)
810     {
811       offset += SUBREG_WORD (op0);
812       op0 = SUBREG_REG (op0);
813     }
814   
815 #if BYTES_BIG_ENDIAN
816   /* If OP0 is a register, BITPOS must count within a word.
817      But as we have it, it counts within whatever size OP0 now has.
818      On a bigendian machine, these are not the same, so convert.  */
819   if (GET_CODE (op0) != MEM && unit > GET_MODE_BITSIZE (GET_MODE (op0)))
820     bitpos += unit - GET_MODE_BITSIZE (GET_MODE (op0));
821 #endif
822
823   /* Extracting a full-word or multi-word value
824      from a structure in a register.
825      This can be done with just SUBREG.
826      So too extracting a subword value in
827      the least significant part of the register.  */
828
829   if (GET_CODE (op0) == REG
830       && ((bitsize >= BITS_PER_WORD && bitsize == GET_MODE_BITSIZE (mode)
831            && bitpos % BITS_PER_WORD == 0)
832           || (mode_for_size (bitsize, GET_MODE_CLASS (tmode), 0) != BLKmode
833 #if BYTES_BIG_ENDIAN
834               && bitpos + bitsize == BITS_PER_WORD
835 #else
836               && bitpos == 0
837 #endif
838               )))
839     {
840       enum machine_mode mode1
841         = mode_for_size (bitsize, GET_MODE_CLASS (tmode), 0);
842
843       if (mode1 != GET_MODE (op0))
844         op0 = gen_rtx (SUBREG, mode1, op0, offset);
845
846       if (mode1 != mode)
847         return convert_to_mode (tmode, op0, unsignedp);
848       return op0;
849     }
850
851   /* Handle fields bigger than a word.  */
852   
853   if (bitsize > BITS_PER_WORD)
854     {
855       /* Here we transfer the words of the field
856          in the order least significant first.
857          This is because the most significant word is the one which may
858          be less than full.  */
859
860       int nwords = (bitsize + (BITS_PER_WORD - 1)) / BITS_PER_WORD;
861       int i;
862
863       if (target == 0 || GET_CODE (target) != REG)
864         target = gen_reg_rtx (mode);
865
866       for (i = 0; i < nwords; i++)
867         {
868           /* If I is 0, use the low-order word in both field and target;
869              if I is 1, use the next to lowest word; and so on.  */
870           int wordnum = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i);
871           int bit_offset = (WORDS_BIG_ENDIAN
872                             ? MAX (0, bitsize - (i + 1) * BITS_PER_WORD)
873                             : i * BITS_PER_WORD);
874           rtx target_part = operand_subword (target, wordnum, 1, VOIDmode);
875           rtx result_part
876             = extract_bit_field (op0, MIN (BITS_PER_WORD,
877                                            bitsize - i * BITS_PER_WORD),
878                                  bitnum + bit_offset,
879                                  1, target_part, mode, word_mode,
880                                  align, total_size);
881
882           if (target_part == 0)
883             abort ();
884
885           if (result_part != target_part)
886             emit_move_insn (target_part, result_part);
887         }
888
889       return target;
890     }
891   
892   /* From here on we know the desired field is smaller than a word
893      so we can assume it is an integer.  So we can safely extract it as one
894      size of integer, if necessary, and then truncate or extend
895      to the size that is wanted.  */
896
897   /* OFFSET is the number of words or bytes (UNIT says which)
898      from STR_RTX to the first word or byte containing part of the field.  */
899
900   if (GET_CODE (op0) == REG)
901     {
902       if (offset != 0
903           || GET_MODE_SIZE (GET_MODE (op0)) > UNITS_PER_WORD)
904         op0 = gen_rtx (SUBREG, TYPE_MODE (type_for_size (BITS_PER_WORD, 0)),
905                        op0, offset);
906       offset = 0;
907     }
908   else
909     {
910       op0 = protect_from_queue (str_rtx, 1);
911     }
912
913   /* Now OFFSET is nonzero only for memory operands.  */
914
915   if (unsignedp)
916     {
917 #ifdef HAVE_extzv
918       if (HAVE_extzv
919           && (GET_MODE_BITSIZE (insn_operand_mode[(int) CODE_FOR_extzv][0])
920               >= bitsize))
921         {
922           int xbitpos = bitpos, xoffset = offset;
923           rtx bitsize_rtx, bitpos_rtx;
924           rtx last = get_last_insn();
925           rtx xop0 = op0;
926           rtx xtarget = target;
927           rtx xspec_target = spec_target;
928           rtx xspec_target_subreg = spec_target_subreg;
929           rtx pat;
930           enum machine_mode maxmode
931             = insn_operand_mode[(int) CODE_FOR_extzv][0];
932
933           if (GET_CODE (xop0) == MEM)
934             {
935               int save_volatile_ok = volatile_ok;
936               volatile_ok = 1;
937
938               /* Is the memory operand acceptable?  */
939               if (flag_force_mem
940                   || ! ((*insn_operand_predicate[(int) CODE_FOR_extzv][1])
941                         (xop0, GET_MODE (xop0))))
942                 {
943                   /* No, load into a reg and extract from there.  */
944                   enum machine_mode bestmode;
945
946                   /* Get the mode to use for inserting into this field.  If
947                      OP0 is BLKmode, get the smallest mode consistent with the
948                      alignment. If OP0 is a non-BLKmode object that is no
949                      wider than MAXMODE, use its mode. Otherwise, use the
950                      smallest mode containing the field.  */
951
952                   if (GET_MODE (xop0) == BLKmode
953                       || (GET_MODE_SIZE (GET_MODE (op0))
954                           > GET_MODE_SIZE (maxmode)))
955                     bestmode = get_best_mode (bitsize, bitnum,
956                                               align * BITS_PER_UNIT, maxmode,
957                                               MEM_VOLATILE_P (xop0));
958                   else
959                     bestmode = GET_MODE (xop0);
960
961                   if (bestmode == VOIDmode)
962                     goto extzv_loses;
963
964                   /* Compute offset as multiple of this unit,
965                      counting in bytes.  */
966                   unit = GET_MODE_BITSIZE (bestmode);
967                   xoffset = (bitnum / unit) * GET_MODE_SIZE (bestmode);
968                   xbitpos = bitnum % unit;
969                   xop0 = change_address (xop0, bestmode,
970                                          plus_constant (XEXP (xop0, 0),
971                                                         xoffset));
972                   /* Fetch it to a register in that size.  */
973                   xop0 = force_reg (bestmode, xop0);
974
975                   /* XBITPOS counts within UNIT, which is what is expected.  */
976                 }
977               else
978                 /* Get ref to first byte containing part of the field.  */
979                 xop0 = change_address (xop0, byte_mode,
980                                        plus_constant (XEXP (xop0, 0), xoffset));
981
982               volatile_ok = save_volatile_ok;
983             }
984
985           /* If op0 is a register, we need it in MAXMODE (which is usually
986              SImode). to make it acceptable to the format of extzv.  */
987           if (GET_CODE (xop0) == SUBREG && GET_MODE (xop0) != maxmode)
988             abort ();
989           if (GET_CODE (xop0) == REG && GET_MODE (xop0) != maxmode)
990             xop0 = gen_rtx (SUBREG, maxmode, xop0, 0);
991
992           /* On big-endian machines, we count bits from the most significant.
993              If the bit field insn does not, we must invert.  */
994 #if BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN
995           xbitpos = unit - bitsize - xbitpos;
996 #endif
997           /* Now convert from counting within UNIT to counting in MAXMODE.  */
998 #if BITS_BIG_ENDIAN
999           if (GET_CODE (xop0) != MEM)
1000             xbitpos += GET_MODE_BITSIZE (maxmode) - unit;
1001 #endif
1002           unit = GET_MODE_BITSIZE (maxmode);
1003
1004           if (xtarget == 0
1005               || (flag_force_mem && GET_CODE (xtarget) == MEM))
1006             xtarget = xspec_target = gen_reg_rtx (tmode);
1007
1008           if (GET_MODE (xtarget) != maxmode)
1009             {
1010               if (GET_CODE (xtarget) == REG)
1011                 {
1012                   int wider = (GET_MODE_SIZE (maxmode)
1013                                > GET_MODE_SIZE (GET_MODE (xtarget)));
1014                   xtarget = gen_lowpart (maxmode, xtarget);
1015                   if (wider)
1016                     xspec_target_subreg = xtarget;
1017                 }
1018               else
1019                 xtarget = gen_reg_rtx (maxmode);
1020             }
1021
1022           /* If this machine's extzv insists on a register target,
1023              make sure we have one.  */
1024           if (! ((*insn_operand_predicate[(int) CODE_FOR_extzv][0])
1025                  (xtarget, maxmode)))
1026             xtarget = gen_reg_rtx (maxmode);
1027
1028           bitsize_rtx = GEN_INT (bitsize);
1029           bitpos_rtx = GEN_INT (xbitpos);
1030
1031           pat = gen_extzv (protect_from_queue (xtarget, 1),
1032                            xop0, bitsize_rtx, bitpos_rtx);
1033           if (pat)
1034             {
1035               emit_insn (pat);
1036               target = xtarget;
1037               spec_target = xspec_target;
1038               spec_target_subreg = xspec_target_subreg;
1039             }
1040           else
1041             {
1042               delete_insns_since (last);
1043               target = extract_fixed_bit_field (tmode, op0, offset, bitsize,
1044                                                 bitpos, target, 1, align);
1045             }
1046         }
1047       else
1048         extzv_loses:
1049 #endif
1050         target = extract_fixed_bit_field (tmode, op0, offset, bitsize, bitpos,
1051                                           target, 1, align);
1052     }
1053   else
1054     {
1055 #ifdef HAVE_extv
1056       if (HAVE_extv
1057           && (GET_MODE_BITSIZE (insn_operand_mode[(int) CODE_FOR_extv][0])
1058               >= bitsize))
1059         {
1060           int xbitpos = bitpos, xoffset = offset;
1061           rtx bitsize_rtx, bitpos_rtx;
1062           rtx last = get_last_insn();
1063           rtx xop0 = op0, xtarget = target;
1064           rtx xspec_target = spec_target;
1065           rtx xspec_target_subreg = spec_target_subreg;
1066           rtx pat;
1067           enum machine_mode maxmode
1068             = insn_operand_mode[(int) CODE_FOR_extv][0];
1069
1070           if (GET_CODE (xop0) == MEM)
1071             {
1072               /* Is the memory operand acceptable?  */
1073               if (! ((*insn_operand_predicate[(int) CODE_FOR_extv][1])
1074                      (xop0, GET_MODE (xop0))))
1075                 {
1076                   /* No, load into a reg and extract from there.  */
1077                   enum machine_mode bestmode;
1078
1079                   /* Get the mode to use for inserting into this field.  If
1080                      OP0 is BLKmode, get the smallest mode consistent with the
1081                      alignment. If OP0 is a non-BLKmode object that is no
1082                      wider than MAXMODE, use its mode. Otherwise, use the
1083                      smallest mode containing the field.  */
1084
1085                   if (GET_MODE (xop0) == BLKmode
1086                       || (GET_MODE_SIZE (GET_MODE (op0))
1087                           > GET_MODE_SIZE (maxmode)))
1088                     bestmode = get_best_mode (bitsize, bitnum,
1089                                               align * BITS_PER_UNIT, maxmode,
1090                                               MEM_VOLATILE_P (xop0));
1091                   else
1092                     bestmode = GET_MODE (xop0);
1093
1094                   if (bestmode == VOIDmode)
1095                     goto extv_loses;
1096
1097                   /* Compute offset as multiple of this unit,
1098                      counting in bytes.  */
1099                   unit = GET_MODE_BITSIZE (bestmode);
1100                   xoffset = (bitnum / unit) * GET_MODE_SIZE (bestmode);
1101                   xbitpos = bitnum % unit;
1102                   xop0 = change_address (xop0, bestmode,
1103                                          plus_constant (XEXP (xop0, 0),
1104                                                         xoffset));
1105                   /* Fetch it to a register in that size.  */
1106                   xop0 = force_reg (bestmode, xop0);
1107
1108                   /* XBITPOS counts within UNIT, which is what is expected.  */
1109                 }
1110               else
1111                 /* Get ref to first byte containing part of the field.  */
1112                 xop0 = change_address (xop0, byte_mode,
1113                                        plus_constant (XEXP (xop0, 0), xoffset));
1114             }
1115
1116           /* If op0 is a register, we need it in MAXMODE (which is usually
1117              SImode) to make it acceptable to the format of extv.  */
1118           if (GET_CODE (xop0) == SUBREG && GET_MODE (xop0) != maxmode)
1119             abort ();
1120           if (GET_CODE (xop0) == REG && GET_MODE (xop0) != maxmode)
1121             xop0 = gen_rtx (SUBREG, maxmode, xop0, 0);
1122
1123           /* On big-endian machines, we count bits from the most significant.
1124              If the bit field insn does not, we must invert.  */
1125 #if BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN
1126           xbitpos = unit - bitsize - xbitpos;
1127 #endif
1128           /* XBITPOS counts within a size of UNIT.
1129              Adjust to count within a size of MAXMODE.  */
1130 #if BITS_BIG_ENDIAN
1131           if (GET_CODE (xop0) != MEM)
1132             xbitpos += (GET_MODE_BITSIZE (maxmode) - unit);
1133 #endif
1134           unit = GET_MODE_BITSIZE (maxmode);
1135
1136           if (xtarget == 0
1137               || (flag_force_mem && GET_CODE (xtarget) == MEM))
1138             xtarget = xspec_target = gen_reg_rtx (tmode);
1139
1140           if (GET_MODE (xtarget) != maxmode)
1141             {
1142               if (GET_CODE (xtarget) == REG)
1143                 {
1144                   int wider = (GET_MODE_SIZE (maxmode)
1145                                > GET_MODE_SIZE (GET_MODE (xtarget)));
1146                   xtarget = gen_lowpart (maxmode, xtarget);
1147                   if (wider)
1148                     xspec_target_subreg = xtarget;
1149                 }
1150               else
1151                 xtarget = gen_reg_rtx (maxmode);
1152             }
1153
1154           /* If this machine's extv insists on a register target,
1155              make sure we have one.  */
1156           if (! ((*insn_operand_predicate[(int) CODE_FOR_extv][0])
1157                  (xtarget, maxmode)))
1158             xtarget = gen_reg_rtx (maxmode);
1159
1160           bitsize_rtx = GEN_INT (bitsize);
1161           bitpos_rtx = GEN_INT (xbitpos);
1162
1163           pat = gen_extv (protect_from_queue (xtarget, 1),
1164                           xop0, bitsize_rtx, bitpos_rtx);
1165           if (pat)
1166             {
1167               emit_insn (pat);
1168               target = xtarget;
1169               spec_target = xspec_target;
1170               spec_target_subreg = xspec_target_subreg;
1171             }
1172           else
1173             {
1174               delete_insns_since (last);
1175               target = extract_fixed_bit_field (tmode, op0, offset, bitsize,
1176                                                 bitpos, target, 0, align);
1177             }
1178         } 
1179       else
1180         extv_loses:
1181 #endif
1182         target = extract_fixed_bit_field (tmode, op0, offset, bitsize, bitpos,
1183                                           target, 0, align);
1184     }
1185   if (target == spec_target)
1186     return target;
1187   if (target == spec_target_subreg)
1188     return spec_target;
1189   if (GET_MODE (target) != tmode && GET_MODE (target) != mode)
1190     {
1191       /* If the target mode is floating-point, first convert to the
1192          integer mode of that size and then access it as a floating-point
1193          value via a SUBREG.  */
1194       if (GET_MODE_CLASS (tmode) == MODE_FLOAT)
1195         {
1196           target = convert_to_mode (mode_for_size (GET_MODE_BITSIZE (tmode),
1197                                                    MODE_INT, 0),
1198                                     target, unsignedp);
1199           if (GET_CODE (target) != REG)
1200             target = copy_to_reg (target);
1201           return gen_rtx (SUBREG, tmode, target, 0);
1202         }
1203       else
1204         return convert_to_mode (tmode, target, unsignedp);
1205     }
1206   return target;
1207 }
1208 \f
1209 /* Extract a bit field using shifts and boolean operations
1210    Returns an rtx to represent the value.
1211    OP0 addresses a register (word) or memory (byte).
1212    BITPOS says which bit within the word or byte the bit field starts in.
1213    OFFSET says how many bytes farther the bit field starts;
1214     it is 0 if OP0 is a register.
1215    BITSIZE says how many bits long the bit field is.
1216     (If OP0 is a register, it may be narrower than a full word,
1217      but BITPOS still counts within a full word,
1218      which is significant on bigendian machines.)
1219
1220    UNSIGNEDP is nonzero for an unsigned bit field (don't sign-extend value).
1221    If TARGET is nonzero, attempts to store the value there
1222    and return TARGET, but this is not guaranteed.
1223    If TARGET is not used, create a pseudo-reg of mode TMODE for the value.
1224
1225    ALIGN is the alignment that STR_RTX is known to have, measured in bytes.  */
1226
1227 static rtx
1228 extract_fixed_bit_field (tmode, op0, offset, bitsize, bitpos,
1229                          target, unsignedp, align)
1230      enum machine_mode tmode;
1231      register rtx op0, target;
1232      register int offset, bitsize, bitpos;
1233      int unsignedp;
1234      int align;
1235 {
1236   int total_bits = BITS_PER_WORD;
1237   enum machine_mode mode;
1238
1239   if (GET_CODE (op0) == SUBREG || GET_CODE (op0) == REG)
1240     {
1241       /* Special treatment for a bit field split across two registers.  */
1242       if (bitsize + bitpos > BITS_PER_WORD)
1243         return extract_split_bit_field (op0, bitsize, bitpos,
1244                                         unsignedp, align);
1245     }
1246   else
1247     {
1248       /* Get the proper mode to use for this field.  We want a mode that
1249          includes the entire field.  If such a mode would be larger than
1250          a word, we won't be doing the extraction the normal way.  */
1251
1252       mode = get_best_mode (bitsize, bitpos + offset * BITS_PER_UNIT,
1253                             align * BITS_PER_UNIT, word_mode,
1254                             GET_CODE (op0) == MEM && MEM_VOLATILE_P (op0));
1255
1256       if (mode == VOIDmode)
1257         /* The only way this should occur is if the field spans word
1258            boundaries.  */
1259         return extract_split_bit_field (op0, bitsize,
1260                                         bitpos + offset * BITS_PER_UNIT,
1261                                         unsignedp, align);
1262
1263       total_bits = GET_MODE_BITSIZE (mode);
1264
1265       /* Make sure bitpos is valid for the chosen mode.  Adjust BITPOS to
1266          be be in the range 0 to total_bits-1, and put any excess bytes in
1267          OFFSET.  */
1268       if (bitpos >= total_bits)
1269         {
1270           offset += (bitpos / total_bits) * (total_bits / BITS_PER_UNIT);
1271           bitpos -= ((bitpos / total_bits) * (total_bits / BITS_PER_UNIT)
1272                      * BITS_PER_UNIT);
1273         }
1274
1275       /* Get ref to an aligned byte, halfword, or word containing the field.
1276          Adjust BITPOS to be position within a word,
1277          and OFFSET to be the offset of that word.
1278          Then alter OP0 to refer to that word.  */
1279       bitpos += (offset % (total_bits / BITS_PER_UNIT)) * BITS_PER_UNIT;
1280       offset -= (offset % (total_bits / BITS_PER_UNIT));
1281       op0 = change_address (op0, mode,
1282                             plus_constant (XEXP (op0, 0), offset));
1283     }
1284
1285   mode = GET_MODE (op0);
1286
1287 #if BYTES_BIG_ENDIAN
1288   /* BITPOS is the distance between our msb and that of OP0.
1289      Convert it to the distance from the lsb.  */
1290
1291   bitpos = total_bits - bitsize - bitpos;
1292 #endif
1293   /* Now BITPOS is always the distance between the field's lsb and that of OP0.
1294      We have reduced the big-endian case to the little-endian case.  */
1295
1296   if (unsignedp)
1297     {
1298       if (bitpos)
1299         {
1300           /* If the field does not already start at the lsb,
1301              shift it so it does.  */
1302           tree amount = build_int_2 (bitpos, 0);
1303           /* Maybe propagate the target for the shift.  */
1304           /* But not if we will return it--could confuse integrate.c.  */
1305           rtx subtarget = (target != 0 && GET_CODE (target) == REG
1306                            && !REG_FUNCTION_VALUE_P (target)
1307                            ? target : 0);
1308           if (tmode != mode) subtarget = 0;
1309           op0 = expand_shift (RSHIFT_EXPR, mode, op0, amount, subtarget, 1);
1310         }
1311       /* Convert the value to the desired mode.  */
1312       if (mode != tmode)
1313         op0 = convert_to_mode (tmode, op0, 1);
1314
1315       /* Unless the msb of the field used to be the msb when we shifted,
1316          mask out the upper bits.  */
1317
1318       if (GET_MODE_BITSIZE (mode) != bitpos + bitsize
1319 #if 0
1320 #ifdef SLOW_ZERO_EXTEND
1321           /* Always generate an `and' if
1322              we just zero-extended op0 and SLOW_ZERO_EXTEND, since it
1323              will combine fruitfully with the zero-extend. */
1324           || tmode != mode
1325 #endif
1326 #endif
1327           )
1328         return expand_binop (GET_MODE (op0), and_optab, op0,
1329                              mask_rtx (GET_MODE (op0), 0, bitsize, 0),
1330                              target, 1, OPTAB_LIB_WIDEN);
1331       return op0;
1332     }
1333
1334   /* To extract a signed bit-field, first shift its msb to the msb of the word,
1335      then arithmetic-shift its lsb to the lsb of the word.  */
1336   op0 = force_reg (mode, op0);
1337   if (mode != tmode)
1338     target = 0;
1339
1340   /* Find the narrowest integer mode that contains the field.  */
1341
1342   for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT); mode != VOIDmode;
1343        mode = GET_MODE_WIDER_MODE (mode))
1344     if (GET_MODE_BITSIZE (mode) >= bitsize + bitpos)
1345       {
1346         op0 = convert_to_mode (mode, op0, 0);
1347         break;
1348       }
1349
1350   if (GET_MODE_BITSIZE (mode) != (bitsize + bitpos))
1351     {
1352       tree amount = build_int_2 (GET_MODE_BITSIZE (mode) - (bitsize + bitpos), 0);
1353       /* Maybe propagate the target for the shift.  */
1354       /* But not if we will return the result--could confuse integrate.c.  */
1355       rtx subtarget = (target != 0 && GET_CODE (target) == REG
1356                        && ! REG_FUNCTION_VALUE_P (target)
1357                        ? target : 0);
1358       op0 = expand_shift (LSHIFT_EXPR, mode, op0, amount, subtarget, 1);
1359     }
1360
1361   return expand_shift (RSHIFT_EXPR, mode, op0,
1362                        build_int_2 (GET_MODE_BITSIZE (mode) - bitsize, 0), 
1363                        target, 0);
1364 }
1365 \f
1366 /* Return a constant integer (CONST_INT or CONST_DOUBLE) mask value
1367    of mode MODE with BITSIZE ones followed by BITPOS zeros, or the
1368    complement of that if COMPLEMENT.  The mask is truncated if
1369    necessary to the width of mode MODE.  */
1370
1371 static rtx
1372 mask_rtx (mode, bitpos, bitsize, complement)
1373      enum machine_mode mode;
1374      int bitpos, bitsize, complement;
1375 {
1376   HOST_WIDE_INT masklow, maskhigh;
1377
1378   if (bitpos < HOST_BITS_PER_WIDE_INT)
1379     masklow = (HOST_WIDE_INT) -1 << bitpos;
1380   else
1381     masklow = 0;
1382
1383   if (bitpos + bitsize < HOST_BITS_PER_WIDE_INT)
1384     masklow &= ((unsigned HOST_WIDE_INT) -1
1385                 >> (HOST_BITS_PER_WIDE_INT - bitpos - bitsize));
1386   
1387   if (bitpos <= HOST_BITS_PER_WIDE_INT)
1388     maskhigh = -1;
1389   else
1390     maskhigh = (HOST_WIDE_INT) -1 << (bitpos - HOST_BITS_PER_WIDE_INT);
1391
1392   if (bitpos + bitsize > HOST_BITS_PER_WIDE_INT)
1393     maskhigh &= ((unsigned HOST_WIDE_INT) -1
1394                  >> (2 * HOST_BITS_PER_WIDE_INT - bitpos - bitsize));
1395   else
1396     maskhigh = 0;
1397
1398   if (complement)
1399     {
1400       maskhigh = ~maskhigh;
1401       masklow = ~masklow;
1402     }
1403
1404   return immed_double_const (masklow, maskhigh, mode);
1405 }
1406
1407 /* Return a constant integer (CONST_INT or CONST_DOUBLE) rtx with the value
1408    VALUE truncated to BITSIZE bits and then shifted left BITPOS bits.  */
1409
1410 static rtx
1411 lshift_value (mode, value, bitpos, bitsize)
1412      enum machine_mode mode;
1413      rtx value;
1414      int bitpos, bitsize;
1415 {
1416   unsigned HOST_WIDE_INT v = INTVAL (value);
1417   HOST_WIDE_INT low, high;
1418
1419   if (bitsize < HOST_BITS_PER_WIDE_INT)
1420     v &= ~((HOST_WIDE_INT) -1 << bitsize);
1421
1422   if (bitpos < HOST_BITS_PER_WIDE_INT)
1423     {
1424       low = v << bitpos;
1425       high = (bitpos > 0 ? (v >> (HOST_BITS_PER_WIDE_INT - bitpos)) : 0);
1426     }
1427   else
1428     {
1429       low = 0;
1430       high = v << (bitpos - HOST_BITS_PER_WIDE_INT);
1431     }
1432
1433   return immed_double_const (low, high, mode);
1434 }
1435 \f
1436 /* Extract a bit field that is split across two words
1437    and return an RTX for the result.
1438
1439    OP0 is the REG, SUBREG or MEM rtx for the first of the two words.
1440    BITSIZE is the field width; BITPOS, position of its first bit, in the word.
1441    UNSIGNEDP is 1 if should zero-extend the contents; else sign-extend.  */
1442
1443 static rtx
1444 extract_split_bit_field (op0, bitsize, bitpos, unsignedp, align)
1445      rtx op0;
1446      int bitsize, bitpos, unsignedp, align;
1447 {
1448   /* BITSIZE_1 is size of the part in the first word.  */
1449   int bitsize_1 = BITS_PER_WORD - bitpos % BITS_PER_WORD;
1450   /* BITSIZE_2 is size of the rest (in the following word).  */
1451   int bitsize_2 = bitsize - bitsize_1;
1452   rtx part1, part2, result;
1453   int unit = GET_CODE (op0) == MEM ? BITS_PER_UNIT : BITS_PER_WORD;
1454   int offset = bitpos / unit;
1455   rtx word;
1456  
1457   /* The field must span exactly one word boundary.  */
1458   if (bitpos / BITS_PER_WORD != (bitpos + bitsize - 1) / BITS_PER_WORD - 1)
1459     abort ();
1460
1461   /* Get the part of the bit field from the first word.  If OP0 is a MEM,
1462      pass OP0 and the offset computed above.  Otherwise, get the proper
1463      word and pass an offset of zero.  */
1464   word = (GET_CODE (op0) == MEM ? op0
1465           : operand_subword_force (op0, offset, GET_MODE (op0)));
1466   part1 = extract_fixed_bit_field (word_mode, word,
1467                                    GET_CODE (op0) == MEM ? offset : 0,
1468                                    bitsize_1, bitpos % unit, NULL_RTX,
1469                                    1, align);
1470
1471   /* Offset op0 by 1 word to get to the following one.  */
1472   if (GET_CODE (op0) == SUBREG)
1473     word = operand_subword_force (SUBREG_REG (op0),
1474                                   SUBREG_WORD (op0) + offset + 1, VOIDmode);
1475   else if (GET_CODE (op0) == MEM)
1476     word = op0;
1477   else
1478     word = operand_subword_force (op0, offset + 1, GET_MODE (op0));
1479
1480   /* Get the part of the bit field from the second word.  */
1481   part2 = extract_fixed_bit_field (word_mode, word,
1482                                    (GET_CODE (op0) == MEM
1483                                     ? CEIL (offset + 1, UNITS_PER_WORD) * UNITS_PER_WORD
1484                                     : 0),
1485                                    bitsize_2, 0, NULL_RTX, 1, align);
1486
1487   /* Shift the more significant part up to fit above the other part.  */
1488 #if BYTES_BIG_ENDIAN
1489   part1 = expand_shift (LSHIFT_EXPR, word_mode, part1,
1490                         build_int_2 (bitsize_2, 0), 0, 1);
1491 #else
1492   part2 = expand_shift (LSHIFT_EXPR, word_mode, part2,
1493                         build_int_2 (bitsize_1, 0), 0, 1);
1494 #endif
1495
1496   /* Combine the two parts with bitwise or.  This works
1497      because we extracted both parts as unsigned bit fields.  */
1498   result = expand_binop (word_mode, ior_optab, part1, part2, NULL_RTX, 1,
1499                          OPTAB_LIB_WIDEN);
1500
1501   /* Unsigned bit field: we are done.  */
1502   if (unsignedp)
1503     return result;
1504   /* Signed bit field: sign-extend with two arithmetic shifts.  */
1505   result = expand_shift (LSHIFT_EXPR, word_mode, result,
1506                          build_int_2 (BITS_PER_WORD - bitsize, 0),
1507                          NULL_RTX, 0);
1508   return expand_shift (RSHIFT_EXPR, word_mode, result,
1509                        build_int_2 (BITS_PER_WORD - bitsize, 0), NULL_RTX, 0);
1510 }
1511 \f
1512 /* Add INC into TARGET.  */
1513
1514 void
1515 expand_inc (target, inc)
1516      rtx target, inc;
1517 {
1518   rtx value = expand_binop (GET_MODE (target), add_optab,
1519                             target, inc,
1520                             target, 0, OPTAB_LIB_WIDEN);
1521   if (value != target)
1522     emit_move_insn (target, value);
1523 }
1524
1525 /* Subtract DEC from TARGET.  */
1526
1527 void
1528 expand_dec (target, dec)
1529      rtx target, dec;
1530 {
1531   rtx value = expand_binop (GET_MODE (target), sub_optab,
1532                             target, dec,
1533                             target, 0, OPTAB_LIB_WIDEN);
1534   if (value != target)
1535     emit_move_insn (target, value);
1536 }
1537 \f
1538 /* Output a shift instruction for expression code CODE,
1539    with SHIFTED being the rtx for the value to shift,
1540    and AMOUNT the tree for the amount to shift by.
1541    Store the result in the rtx TARGET, if that is convenient.
1542    If UNSIGNEDP is nonzero, do a logical shift; otherwise, arithmetic.
1543    Return the rtx for where the value is.  */
1544
1545 rtx
1546 expand_shift (code, mode, shifted, amount, target, unsignedp)
1547      enum tree_code code;
1548      register enum machine_mode mode;
1549      rtx shifted;
1550      tree amount;
1551      register rtx target;
1552      int unsignedp;
1553 {
1554   register rtx op1, temp = 0;
1555   register int left = (code == LSHIFT_EXPR || code == LROTATE_EXPR);
1556   register int rotate = (code == LROTATE_EXPR || code == RROTATE_EXPR);
1557   int try;
1558
1559   /* Previously detected shift-counts computed by NEGATE_EXPR
1560      and shifted in the other direction; but that does not work
1561      on all machines.  */
1562
1563   op1 = expand_expr (amount, NULL_RTX, VOIDmode, 0);
1564
1565   if (op1 == const0_rtx)
1566     return shifted;
1567
1568   for (try = 0; temp == 0 && try < 3; try++)
1569     {
1570       enum optab_methods methods;
1571
1572       if (try == 0)
1573         methods = OPTAB_DIRECT;
1574       else if (try == 1)
1575         methods = OPTAB_WIDEN;
1576       else
1577         methods = OPTAB_LIB_WIDEN;
1578
1579       if (rotate)
1580         {
1581           /* Widening does not work for rotation.  */
1582           if (methods == OPTAB_WIDEN)
1583             continue;
1584           else if (methods == OPTAB_LIB_WIDEN)
1585             {
1586               /* If we are rotating by a constant that is valid and
1587                  we have been unable to open-code this by a rotation,
1588                  do it as the IOR of two shifts.  I.e., to rotate A
1589                  by N bits, compute (A << N) | ((unsigned) A >> (C - N))
1590                  where C is the bitsize of A.
1591
1592                  It is theoretically possible that the target machine might
1593                  not be able to perform either shift and hence we would
1594                  be making two libcalls rather than just the one for the
1595                  shift (similarly if IOR could not be done).  We will allow
1596                  this extremely unlikely lossage to avoid complicating the
1597                  code below.  */
1598
1599               if (GET_CODE (op1) == CONST_INT && INTVAL (op1) > 0
1600                   && INTVAL (op1) < GET_MODE_BITSIZE (mode))
1601                 {
1602                   rtx subtarget = target == shifted ? 0 : target;
1603                   rtx temp1;
1604                   tree other_amount
1605                     = build_int_2 (GET_MODE_BITSIZE (mode) - INTVAL (op1), 0);
1606
1607                   shifted = force_reg (mode, shifted);
1608
1609                   temp = expand_shift (left ? LSHIFT_EXPR : RSHIFT_EXPR,
1610                                        mode, shifted, amount, subtarget, 1);
1611                   temp1 = expand_shift (left ? RSHIFT_EXPR : LSHIFT_EXPR,
1612                                         mode, shifted, other_amount, 0, 1);
1613                   return expand_binop (mode, ior_optab, temp, temp1, target,
1614                                        unsignedp, methods);
1615                 }
1616               else
1617                 methods = OPTAB_LIB;
1618             }
1619
1620           temp = expand_binop (mode,
1621                                left ? rotl_optab : rotr_optab,
1622                                shifted, op1, target, unsignedp, methods);
1623
1624           /* If we don't have the rotate, but we are rotating by a constant
1625              that is in range, try a rotate in the opposite direction.  */
1626
1627           if (temp == 0 && GET_CODE (op1) == CONST_INT
1628               && INTVAL (op1) > 0 && INTVAL (op1) < GET_MODE_BITSIZE (mode))
1629             temp = expand_binop (mode,
1630                                  left ? rotr_optab : rotl_optab,
1631                                  shifted, 
1632                                  GEN_INT (GET_MODE_BITSIZE (mode)
1633                                           - INTVAL (op1)),
1634                                  target, unsignedp, methods);
1635         }
1636       else if (unsignedp)
1637         {
1638           temp = expand_binop (mode,
1639                                left ? lshl_optab : lshr_optab,
1640                                shifted, op1, target, unsignedp, methods);
1641           if (temp == 0 && left)
1642             temp = expand_binop (mode, ashl_optab,
1643                                  shifted, op1, target, unsignedp, methods);
1644         }
1645
1646       /* Do arithmetic shifts.
1647          Also, if we are going to widen the operand, we can just as well
1648          use an arithmetic right-shift instead of a logical one.  */
1649       if (temp == 0 && ! rotate
1650           && (! unsignedp || (! left && methods == OPTAB_WIDEN)))
1651         {
1652           enum optab_methods methods1 = methods;
1653
1654           /* If trying to widen a log shift to an arithmetic shift,
1655              don't accept an arithmetic shift of the same size.  */
1656           if (unsignedp)
1657             methods1 = OPTAB_MUST_WIDEN;
1658
1659           /* Arithmetic shift */
1660
1661           temp = expand_binop (mode,
1662                                left ? ashl_optab : ashr_optab,
1663                                shifted, op1, target, unsignedp, methods1);
1664         }
1665
1666 #ifdef HAVE_extzv
1667       /* We can do a logical (unsigned) right shift with a bit-field
1668          extract insn.  But first check if one of the above methods worked.  */
1669       if (temp != 0)
1670         return temp;
1671
1672       if (unsignedp && code == RSHIFT_EXPR && ! BITS_BIG_ENDIAN && HAVE_extzv)
1673         {
1674           enum machine_mode output_mode
1675             = insn_operand_mode[(int) CODE_FOR_extzv][0];
1676
1677           if ((methods == OPTAB_DIRECT && mode == output_mode)
1678               || (methods == OPTAB_WIDEN
1679                   && GET_MODE_SIZE (mode) < GET_MODE_SIZE (output_mode)))
1680             {
1681               rtx shifted1 = convert_to_mode (output_mode,
1682                                               protect_from_queue (shifted, 0),
1683                                               1);
1684               enum machine_mode length_mode
1685                 = insn_operand_mode[(int) CODE_FOR_extzv][2];
1686               enum machine_mode pos_mode
1687                 = insn_operand_mode[(int) CODE_FOR_extzv][3];
1688               rtx target1 = 0;
1689               rtx last = get_last_insn ();
1690               rtx width;
1691               rtx xop1 = op1;
1692               rtx pat;
1693
1694               if (target != 0)
1695                 target1 = protect_from_queue (target, 1);
1696
1697               /* We define extract insns as having OUTPUT_MODE in a register
1698                  and the mode of operand 1 in memory.  Since we want
1699                  OUTPUT_MODE, we will always force the operand into a
1700                  register.  At some point we might want to support MEM
1701                  directly. */
1702               shifted1 = force_reg (output_mode, shifted1);
1703
1704               /* If we don't have or cannot use a suggested target,
1705                  make a place for the result, in the proper mode.  */
1706               if (methods == OPTAB_WIDEN || target1 == 0
1707                   || ! ((*insn_operand_predicate[(int) CODE_FOR_extzv][0])
1708                         (target1, output_mode)))
1709                 target1 = gen_reg_rtx (output_mode);
1710
1711               xop1 = protect_from_queue (xop1, 0);
1712               xop1 = convert_to_mode (pos_mode, xop1,
1713                                       TREE_UNSIGNED (TREE_TYPE (amount)));
1714
1715               /* If this machine's extzv insists on a register for
1716                  operand 3 (position), arrange for that.  */
1717               if (! ((*insn_operand_predicate[(int) CODE_FOR_extzv][3])
1718                      (xop1, pos_mode)))
1719                 xop1 = force_reg (pos_mode, xop1);
1720
1721               /* WIDTH gets the width of the bit field to extract:
1722                  wordsize minus # bits to shift by.  */
1723               if (GET_CODE (xop1) == CONST_INT)
1724                 width = GEN_INT (GET_MODE_BITSIZE (mode) - INTVAL (op1));
1725               else
1726                 {
1727                   /* Now get the width in the proper mode.  */
1728                   op1 = protect_from_queue (op1, 0);
1729                   width = convert_to_mode (length_mode, op1,
1730                                            TREE_UNSIGNED (TREE_TYPE (amount)));
1731
1732                   width = expand_binop (length_mode, sub_optab,
1733                                         GEN_INT (GET_MODE_BITSIZE (mode)),
1734                                         width, NULL_RTX, 0, OPTAB_LIB_WIDEN);
1735                 }
1736
1737               /* If this machine's extzv insists on a register for
1738                  operand 2 (length), arrange for that.  */
1739               if (! ((*insn_operand_predicate[(int) CODE_FOR_extzv][2])
1740                      (width, length_mode)))
1741                 width = force_reg (length_mode, width);
1742
1743               /* Now extract with WIDTH, omitting OP1 least sig bits.  */
1744               pat = gen_extzv (target1, shifted1, width, xop1);
1745               if (pat)
1746                 {
1747                   emit_insn (pat);
1748                   temp = convert_to_mode (mode, target1, 1);
1749                 }
1750               else
1751                 delete_insns_since (last);
1752             }
1753
1754           /* Can also do logical shift with signed bit-field extract
1755              followed by inserting the bit-field at a different position.
1756              That strategy is not yet implemented.  */
1757         }
1758 #endif /* HAVE_extzv */
1759     }
1760
1761   if (temp == 0)
1762     abort ();
1763   return temp;
1764 }
1765 \f
1766 enum alg_code { alg_zero, alg_m, alg_shift,
1767                   alg_add_t_m2, alg_sub_t_m2,
1768                   alg_add_factor, alg_sub_factor,
1769                   alg_add_t2_m, alg_sub_t2_m,
1770                   alg_add, alg_subtract, alg_factor, alg_shiftop };
1771
1772 /* This structure records a sequence of operations.
1773    `ops' is the number of operations recorded.
1774    `cost' is their total cost.
1775    The operations are stored in `op' and the corresponding
1776    logarithms of the integer coefficients in `log'.
1777
1778    These are the operations:
1779    alg_zero             total := 0;
1780    alg_m                total := multiplicand;
1781    alg_shift            total := total * coeff
1782    alg_add_t_m2         total := total + multiplicand * coeff;
1783    alg_sub_t_m2         total := total - multiplicand * coeff;
1784    alg_add_factor       total := total * coeff + total;
1785    alg_sub_factor       total := total * coeff - total;
1786    alg_add_t2_m         total := total * coeff + multiplicand;
1787    alg_sub_t2_m         total := total * coeff - multiplicand;
1788
1789    The first operand must be either alg_zero or alg_m.  */
1790
1791 #ifndef MAX_BITS_PER_WORD
1792 #define MAX_BITS_PER_WORD BITS_PER_WORD
1793 #endif
1794
1795 struct algorithm
1796 {
1797   short cost;
1798   short ops;
1799   /* The size of the OP and LOG fields are not directly related to the
1800      word size, but the worst-case algorithms will be if we have few
1801      consecutive ones or zeros, i.e., a multiplicand like 10101010101...
1802      In that case we will generate shift-by-2, add, shift-by-2, add,...,
1803      in total wordsize operations.  */
1804   enum alg_code op[MAX_BITS_PER_WORD];
1805   char log[MAX_BITS_PER_WORD];
1806 };
1807
1808 /* Compute and return the best algorithm for multiplying by T.
1809    The algorithm must cost less than cost_limit
1810    If retval.cost >= COST_LIMIT, no algorithm was found and all
1811    other field of the returned struct are undefined.  */
1812
1813 static struct algorithm
1814 synth_mult (t, cost_limit)
1815      unsigned HOST_WIDE_INT t;
1816      int cost_limit;
1817 {
1818   int m;
1819   struct algorithm *best_alg
1820     = (struct algorithm *)alloca (sizeof (struct algorithm));
1821   struct algorithm *alg_in
1822     = (struct algorithm *)alloca (sizeof (struct algorithm));
1823   unsigned int cost;
1824   unsigned HOST_WIDE_INT q;
1825
1826   /* Indicate that no algorithm is yet found.  If no algorithm
1827      is found, this value will be returned and indicate failure.  */
1828   best_alg->cost = cost_limit;
1829
1830   if (cost_limit <= 0)
1831     return *best_alg;
1832
1833   /* t == 1 can be done in zero cost.  */
1834   if (t == 1)
1835     {
1836       best_alg->ops = 1;
1837       best_alg->cost = 0;
1838       best_alg->op[0] = alg_m;
1839       return *best_alg;
1840     }
1841
1842   /* t == 0 sometimes has a cost.  If it does and it exceeds our limit,
1843      fail now.  */
1844
1845   else if (t == 0)
1846     {
1847       if (zero_cost >= cost_limit)
1848         return *best_alg;
1849       else
1850         {
1851           best_alg->ops = 1;
1852           best_alg->cost = zero_cost;
1853           best_alg->op[0] = alg_zero;
1854           return *best_alg;
1855         }
1856     }
1857
1858   /* If we have a group of zero bits at the low-order part of T, try
1859      multiplying by the remaining bits and then doing a shift.  */
1860
1861   if ((t & 1) == 0)
1862     {
1863       m = floor_log2 (t & -t);  /* m = number of low zero bits */
1864       q = t >> m;
1865       cost = shift_cost[m];
1866       if (cost < cost_limit)
1867         {
1868           *alg_in = synth_mult (q, cost_limit - cost);
1869
1870           cost += alg_in->cost;
1871           if (cost < best_alg->cost)
1872             {
1873               struct algorithm *x;
1874               x = alg_in, alg_in = best_alg, best_alg = x;
1875               best_alg->log[best_alg->ops] = m;
1876               best_alg->op[best_alg->ops++] = alg_shift;
1877               best_alg->cost = cost_limit = cost;
1878             }
1879         }
1880     }
1881
1882   /* Look for factors of t of the form
1883      t = q(2**m +- 1), 2 <= m <= floor(log2(t - 1)).
1884      If we find such a factor, we can multiply by t using an algorithm that
1885      multiplies by q, shift the result by m and add/subtract it to itself.
1886
1887      We search for large factors first and loop down, even if large factors
1888      are less probable than small; if we find a large factor we will find a
1889      good sequence quickly, and therefore be able to prune (by decreasing
1890      COST_LIMIT) the search.  */
1891
1892   for (m = floor_log2 (t - 1); m >= 2; m--)
1893     {
1894       unsigned HOST_WIDE_INT d;
1895
1896       d = ((unsigned HOST_WIDE_INT) 1 << m) + 1;
1897       if (t % d == 0 && t > d)
1898         {
1899           cost = MIN (shiftadd_cost[m], add_cost + shift_cost[m]);
1900           *alg_in = synth_mult (t / d, cost_limit - cost);
1901
1902           cost += alg_in->cost;
1903           if (cost < best_alg->cost)
1904             {
1905               struct algorithm *x;
1906               x = alg_in, alg_in = best_alg, best_alg = x;
1907               best_alg->log[best_alg->ops] = m;
1908               best_alg->op[best_alg->ops++] = alg_add_factor;
1909               best_alg->cost = cost_limit = cost;
1910             }
1911         }
1912
1913       d = ((unsigned HOST_WIDE_INT) 1 << m) - 1;
1914       if (t % d == 0 && t > d)
1915         {
1916           cost = MIN (shiftsub_cost[m], add_cost + shift_cost[m]);
1917           *alg_in = synth_mult (t / d, cost_limit - cost);
1918
1919           cost += alg_in->cost;
1920           if (cost < best_alg->cost)
1921             {
1922               struct algorithm *x;
1923               x = alg_in, alg_in = best_alg, best_alg = x;
1924               best_alg->log[best_alg->ops] = m;
1925               best_alg->op[best_alg->ops++] = alg_sub_factor;
1926               best_alg->cost = cost_limit = cost;
1927             }
1928         }
1929     }
1930
1931   /* Try shift-and-add (load effective address) instructions,
1932      i.e. do a*3, a*5, a*9.  */
1933   if ((t & 1) != 0)
1934     {
1935       q = t - 1;
1936       q = q & -q;
1937       m = exact_log2 (q);
1938       if (m >= 0)
1939         {
1940           cost = shiftadd_cost[m];
1941           *alg_in = synth_mult ((t - 1) >> m, cost_limit - cost);
1942
1943           cost += alg_in->cost;
1944           if (cost < best_alg->cost)
1945             {
1946               struct algorithm *x;
1947               x = alg_in, alg_in = best_alg, best_alg = x;
1948               best_alg->log[best_alg->ops] = m;
1949               best_alg->op[best_alg->ops++] = alg_add_t2_m;
1950               best_alg->cost = cost_limit = cost;
1951             }
1952         }
1953
1954       q = t + 1;
1955       q = q & -q;
1956       m = exact_log2 (q);
1957       if (m >= 0)
1958         {
1959           cost = shiftsub_cost[m];
1960           *alg_in = synth_mult ((t + 1) >> m, cost_limit - cost);
1961
1962           cost += alg_in->cost;
1963           if (cost < best_alg->cost)
1964             {
1965               struct algorithm *x;
1966               x = alg_in, alg_in = best_alg, best_alg = x;
1967               best_alg->log[best_alg->ops] = m;
1968               best_alg->op[best_alg->ops++] = alg_sub_t2_m;
1969               best_alg->cost = cost_limit = cost;
1970             }
1971         }
1972     }
1973
1974   /* Now, use the simple method of adding or subtracting at the leftmost
1975      1-bit.  */
1976   {
1977     unsigned HOST_WIDE_INT w;
1978
1979     q = t & -t;                 /* get out lsb */
1980     for (w = q; (w & t) != 0; w <<= 1)
1981       ;
1982     if ((w > q << 1)
1983         /* Reject the case where t has only two bits.
1984            Thus we prefer addition in that case.  */
1985         && !(t < w && w == q << 2))
1986       {
1987         /* There are many bits in a row.  Make 'em by subtraction.  */
1988
1989         m = exact_log2 (q);
1990
1991         /* Don't use shiftsub_cost here, this operation
1992            scales wrong operand.  */
1993         cost = add_cost + shift_cost[m];
1994         *alg_in = synth_mult (t + q, cost_limit - cost);
1995
1996         cost += alg_in->cost;
1997         if (cost < best_alg->cost)
1998           {
1999             struct algorithm *x;
2000             x = alg_in, alg_in = best_alg, best_alg = x;
2001             best_alg->log[best_alg->ops] = m;
2002             best_alg->op[best_alg->ops++] = alg_sub_t_m2;
2003             best_alg->cost = cost_limit = cost;
2004           }
2005       }
2006     else
2007       {
2008         /* There's only one or two bit at the left.  Make it by addition.  */
2009
2010         m = exact_log2 (q);
2011         cost = MIN (shiftadd_cost[m], add_cost + shift_cost[m]);
2012         *alg_in = synth_mult (t - q, cost_limit - cost);
2013
2014         cost += alg_in->cost;
2015         if (cost < best_alg->cost)
2016           {
2017             struct algorithm *x;
2018             x = alg_in, alg_in = best_alg, best_alg = x;
2019             best_alg->log[best_alg->ops] = m;
2020             best_alg->op[best_alg->ops++] = alg_add_t_m2;
2021             best_alg->cost = cost_limit = cost;
2022           }
2023       }
2024   }
2025
2026   /* If we are getting a too long sequence for `struct algorithm'
2027      to record, store a fake cost to make this search fail.  */
2028   if (best_alg->ops == MAX_BITS_PER_WORD)
2029     best_alg->cost = cost_limit;
2030
2031   return *best_alg;
2032 }
2033 \f
2034 /* Perform a multiplication and return an rtx for the result.
2035    MODE is mode of value; OP0 and OP1 are what to multiply (rtx's);
2036    TARGET is a suggestion for where to store the result (an rtx).
2037
2038    We check specially for a constant integer as OP1.
2039    If you want this check for OP0 as well, then before calling
2040    you should swap the two operands if OP0 would be constant.  */
2041
2042 rtx
2043 expand_mult (mode, op0, op1, target, unsignedp)
2044      enum machine_mode mode;
2045      register rtx op0, op1, target;
2046      int unsignedp;
2047 {
2048   rtx const_op1 = op1;
2049
2050   /* If we are multiplying in DImode, it may still be a win
2051      to try to work with shifts and adds.  */
2052   if (GET_CODE (op1) == CONST_DOUBLE
2053       && GET_MODE_CLASS (GET_MODE (op1)) == MODE_INT
2054       && HOST_BITS_PER_INT <= BITS_PER_WORD)
2055     {
2056       if ((CONST_DOUBLE_HIGH (op1) == 0 && CONST_DOUBLE_LOW (op1) >= 0)
2057           || (CONST_DOUBLE_HIGH (op1) == -1 && CONST_DOUBLE_LOW (op1) < 0))
2058         const_op1 = GEN_INT (CONST_DOUBLE_LOW (op1));
2059     }
2060
2061   /* We used to test optimize here, on the grounds that it's better to
2062      produce a smaller program when -O is not used.
2063      But this causes such a terrible slowdown sometimes
2064      that it seems better to use synth_mult always.  */
2065
2066   if (GET_CODE (const_op1) == CONST_INT && ! mult_is_very_cheap)
2067     {
2068       struct algorithm alg;
2069       struct algorithm neg_alg;
2070       int negate = 0;
2071       HOST_WIDE_INT val = INTVAL (op1);
2072       HOST_WIDE_INT val_so_far;
2073       rtx insn;
2074
2075       /* Try to do the computation two ways: multiply by the negative of OP1
2076          and then negate, or do the multiplication directly.  The latter is
2077          usually faster for positive numbers and the former for negative
2078          numbers, but the opposite can be faster if the original value
2079          has a factor of 2**m +/- 1, while the negated value does not or
2080          vice versa.  */
2081
2082       alg = synth_mult (val, mult_cost);
2083       neg_alg = synth_mult (- val,
2084                             (alg.cost < mult_cost ? alg.cost : mult_cost)
2085                             - negate_cost);
2086
2087       if (neg_alg.cost + negate_cost < alg.cost)
2088         alg = neg_alg, negate = 1;
2089
2090       if (alg.cost < mult_cost)
2091         {
2092           /* We found something cheaper than a multiply insn.  */
2093           int opno;
2094           rtx accum, tem;
2095
2096           op0 = protect_from_queue (op0, 0);
2097
2098           /* Avoid referencing memory over and over.
2099              For speed, but also for correctness when mem is volatile.  */
2100           if (GET_CODE (op0) == MEM)
2101             op0 = force_reg (mode, op0);
2102
2103           /* ACCUM starts out either as OP0 or as a zero, depending on
2104              the first operation.  */
2105
2106           if (alg.op[0] == alg_zero)
2107             {
2108               accum = copy_to_mode_reg (mode, const0_rtx);
2109               val_so_far = 0;
2110             }
2111           else if (alg.op[0] == alg_m)
2112             {
2113               accum  = copy_to_mode_reg (mode, op0);
2114               val_so_far = 1;
2115             }
2116           else
2117             abort ();
2118
2119           for (opno = 1; opno < alg.ops; opno++)
2120             {
2121               int log = alg.log[opno];
2122               rtx shift_subtarget = preserve_subexpressions_p () ? 0 : accum;
2123               rtx add_target = opno == alg.ops - 1 && target != 0 ? target : 0;
2124
2125               switch (alg.op[opno])
2126                 {
2127                 case alg_shift:
2128                   accum = expand_shift (LSHIFT_EXPR, mode, accum,
2129                                         build_int_2 (log, 0), NULL_RTX, 0);
2130                   val_so_far <<= log;
2131                   break;
2132
2133                 case alg_add_t_m2:
2134                   tem = expand_shift (LSHIFT_EXPR, mode, op0,
2135                                       build_int_2 (log, 0), NULL_RTX, 0);
2136                   accum = force_operand (gen_rtx (PLUS, mode, accum, tem),
2137                                          add_target ? add_target : accum);
2138                   val_so_far += (HOST_WIDE_INT) 1 << log;
2139                   break;
2140
2141                 case alg_sub_t_m2:
2142                   tem = expand_shift (LSHIFT_EXPR, mode, op0,
2143                                       build_int_2 (log, 0), NULL_RTX, 0);
2144                   accum = force_operand (gen_rtx (MINUS, mode, accum, tem),
2145                                          add_target ? add_target : accum);
2146                   val_so_far -= (HOST_WIDE_INT) 1 << log;
2147                   break;
2148
2149                 case alg_add_t2_m:
2150                   accum = expand_shift (LSHIFT_EXPR, mode, accum,
2151                                         build_int_2 (log, 0), accum, 0);
2152                   accum = force_operand (gen_rtx (PLUS, mode, accum, op0),
2153                                          add_target ? add_target : accum);
2154                   val_so_far = (val_so_far << log) + 1;
2155                   break;
2156
2157                 case alg_sub_t2_m:
2158                   accum = expand_shift (LSHIFT_EXPR, mode, accum,
2159                                         build_int_2 (log, 0), accum, 0);
2160                   accum = force_operand (gen_rtx (MINUS, mode, accum, op0),
2161                                          add_target ? add_target : accum);
2162                   val_so_far = (val_so_far << log) - 1;
2163                   break;
2164
2165                 case alg_add_factor:
2166                   tem = expand_shift (LSHIFT_EXPR, mode, accum,
2167                                       build_int_2 (log, 0), NULL_RTX, 0);
2168                   accum = force_operand (gen_rtx (PLUS, mode, accum, tem),
2169                                          add_target ? add_target : accum);
2170                   val_so_far += val_so_far << log;
2171                   break;
2172
2173                 case alg_sub_factor:
2174                   tem = expand_shift (LSHIFT_EXPR, mode, accum,
2175                                       build_int_2 (log, 0), NULL_RTX, 0);
2176                   accum = force_operand (gen_rtx (MINUS, mode, tem, accum),
2177                                          add_target ? add_target : tem);
2178                   val_so_far = (val_so_far << log) - val_so_far;
2179                   break;
2180
2181                 default:
2182                   abort ();;
2183                 }
2184
2185               /* Write a REG_EQUAL note on the last insn so that we can cse
2186                  multiplication sequences.  */
2187
2188               insn = get_last_insn ();
2189               REG_NOTES (insn)
2190                 = gen_rtx (EXPR_LIST, REG_EQUAL,
2191                            gen_rtx (MULT, mode, op0, GEN_INT (val_so_far)),
2192                            REG_NOTES (insn));
2193             }
2194
2195           if (negate)
2196             {
2197               val_so_far = - val_so_far;
2198               accum = expand_unop (mode, neg_optab, accum, target, 0);
2199             }
2200
2201           if (val != val_so_far)
2202             abort ();
2203
2204           return accum;
2205         }
2206     }
2207
2208   /* This used to use umul_optab if unsigned,
2209      but for non-widening multiply there is no difference
2210      between signed and unsigned.  */
2211   op0 = expand_binop (mode, smul_optab,
2212                       op0, op1, target, unsignedp, OPTAB_LIB_WIDEN);
2213   if (op0 == 0)
2214     abort ();
2215   return op0;
2216 }
2217 \f
2218 /* Emit the code to divide OP0 by OP1, putting the result in TARGET
2219    if that is convenient, and returning where the result is.
2220    You may request either the quotient or the remainder as the result;
2221    specify REM_FLAG nonzero to get the remainder.
2222
2223    CODE is the expression code for which kind of division this is;
2224    it controls how rounding is done.  MODE is the machine mode to use.
2225    UNSIGNEDP nonzero means do unsigned division.  */
2226
2227 /* ??? For CEIL_MOD_EXPR, can compute incorrect remainder with ANDI
2228    and then correct it by or'ing in missing high bits
2229    if result of ANDI is nonzero.
2230    For ROUND_MOD_EXPR, can use ANDI and then sign-extend the result.
2231    This could optimize to a bfexts instruction.
2232    But C doesn't use these operations, so their optimizations are
2233    left for later.  */
2234
2235 rtx
2236 expand_divmod (rem_flag, code, mode, op0, op1, target, unsignedp)
2237      int rem_flag;
2238      enum tree_code code;
2239      enum machine_mode mode;
2240      register rtx op0, op1, target;
2241      int unsignedp;
2242 {
2243   register rtx result = 0;
2244   enum machine_mode compute_mode;
2245   int log = -1;
2246   int size;
2247   int can_clobber_op0;
2248   int mod_insn_no_good = 0;
2249   rtx adjusted_op0 = op0;
2250   optab optab1, optab2;
2251
2252   /* We shouldn't be called with op1 == const1_rtx, but some of the
2253      code below will malfunction if we are, so check here and handle
2254      the special case if so.  */
2255   if (op1 == const1_rtx)
2256     return rem_flag ? const0_rtx : op0;
2257
2258   /* Don't use the function value register as a target
2259      since we have to read it as well as write it,
2260      and function-inlining gets confused by this.  */
2261   if (target && REG_P (target) && REG_FUNCTION_VALUE_P (target))
2262     target = 0;
2263
2264   /* Don't clobber an operand while doing a multi-step calculation.  */
2265   if (target)
2266     if ((rem_flag && (reg_mentioned_p (target, op0)
2267                       || (GET_CODE (op0) == MEM && GET_CODE (target) == MEM)))
2268         || reg_mentioned_p (target, op1)
2269         || (GET_CODE (op1) == MEM && GET_CODE (target) == MEM))
2270       target = 0;
2271
2272   can_clobber_op0 = (GET_CODE (op0) == REG && op0 == target);
2273
2274   if (GET_CODE (op1) == CONST_INT)
2275     log = exact_log2 (INTVAL (op1));
2276
2277   /* If log is >= 0, we are dividing by 2**log, and will do it by shifting,
2278      which is really floor-division.  Otherwise we will really do a divide,
2279      and we assume that is trunc-division.
2280
2281      We must correct the dividend by adding or subtracting something
2282      based on the divisor, in order to do the kind of rounding specified
2283      by CODE.  The correction depends on what kind of rounding is actually
2284      available, and that depends on whether we will shift or divide.
2285
2286      In many of these cases it is possible to perform the operation by a
2287      clever series of logical operations (shifts and/or exclusive-ors).
2288      Although avoiding the jump has the advantage that it extends the basic
2289      block and allows further optimization, the branch-free code is normally
2290      at least one instruction longer in the (most common) case where the
2291      dividend is non-negative.  Performance measurements of the two
2292      alternatives show that the branch-free code is slightly faster on the
2293      IBM ROMP but slower on CISC processors (significantly slower on the
2294      VAX).  Accordingly, the jump code has been retained.
2295
2296      On machines where the jump code is slower, the cost of a DIV or MOD
2297      operation can be set small (less than twice that of an addition); in 
2298      that case, we pretend that we don't have a power of two and perform
2299      a normal division or modulus operation.  */
2300
2301   if ((code == TRUNC_MOD_EXPR || code == TRUNC_DIV_EXPR)
2302       && ! unsignedp
2303       && (rem_flag ? smod_pow2_cheap : sdiv_pow2_cheap))
2304     log = -1;
2305
2306   /* Get the mode in which to perform this computation.  Normally it will
2307      be MODE, but sometimes we can't do the desired operation in MODE.
2308      If so, pick a wider mode in which we can do the operation.  Convert
2309      to that mode at the start to avoid repeated conversions.
2310
2311      First see what operations we need.  These depend on the expression
2312      we are evaluating.  (We assume that divxx3 insns exist under the
2313      same conditions that modxx3 insns and that these insns don't normally
2314      fail.  If these assumptions are not correct, we may generate less
2315      efficient code in some cases.)
2316
2317      Then see if we find a mode in which we can open-code that operation
2318      (either a division, modulus, or shift).  Finally, check for the smallest
2319      mode for which we can do the operation with a library call.  */
2320
2321   optab1 = (log >= 0 ? (unsignedp ? lshr_optab : ashr_optab)
2322             : (unsignedp ? udiv_optab : sdiv_optab));
2323   optab2 = (log >= 0 ? optab1 : (unsignedp ? udivmod_optab : sdivmod_optab));
2324
2325   for (compute_mode = mode; compute_mode != VOIDmode;
2326        compute_mode = GET_MODE_WIDER_MODE (compute_mode))
2327     if (optab1->handlers[(int) compute_mode].insn_code != CODE_FOR_nothing
2328         || optab2->handlers[(int) compute_mode].insn_code != CODE_FOR_nothing)
2329       break;
2330
2331   if (compute_mode == VOIDmode)
2332     for (compute_mode = mode; compute_mode != VOIDmode;
2333          compute_mode = GET_MODE_WIDER_MODE (compute_mode))
2334       if (optab1->handlers[(int) compute_mode].libfunc
2335           || optab2->handlers[(int) compute_mode].libfunc)
2336         break;
2337
2338   /* If we still couldn't find a mode, use MODE; we'll probably abort in
2339      expand_binop.  */
2340   if (compute_mode == VOIDmode)
2341     compute_mode = mode;
2342
2343   size = GET_MODE_BITSIZE (compute_mode);
2344
2345   /* Now convert to the best mode to use.  Show we made a copy of OP0
2346      and hence we can clobber it (we cannot use a SUBREG to widen
2347      something.  */
2348   if (compute_mode != mode)
2349     {
2350       adjusted_op0 = op0 = convert_to_mode (compute_mode, op0, unsignedp);
2351       can_clobber_op0 = 1;
2352       op1 = convert_to_mode (compute_mode, op1, unsignedp);
2353     }
2354
2355   /* If we are computing the remainder and one of the operands is a volatile
2356      MEM, copy it into a register.  */
2357
2358   if (rem_flag && GET_CODE (op0) == MEM && MEM_VOLATILE_P (op0))
2359     adjusted_op0 = op0 = force_reg (compute_mode, op0), can_clobber_op0 = 1;
2360   if (rem_flag && GET_CODE (op1) == MEM && MEM_VOLATILE_P (op1))
2361     op1 = force_reg (compute_mode, op1);
2362
2363   /* If we are computing the remainder, op0 will be needed later to calculate
2364      X - Y * (X / Y), therefore cannot be clobbered. */
2365   if (rem_flag)
2366     can_clobber_op0 = 0;
2367
2368   if (target == 0 || GET_MODE (target) != compute_mode)
2369     target = gen_reg_rtx (compute_mode);
2370
2371   switch (code)
2372     {
2373     case TRUNC_MOD_EXPR:
2374     case TRUNC_DIV_EXPR:
2375       if (log >= 0 && ! unsignedp)
2376         {
2377           /* Here we need to add OP1-1 if OP0 is negative, 0 otherwise.
2378              This can be computed without jumps by arithmetically shifting
2379              OP0 right LOG-1 places and then shifting right logically
2380              SIZE-LOG bits.  The resulting value is unconditionally added
2381              to OP0.  */
2382           if (log == 1 || BRANCH_COST >= 3)
2383             {
2384               rtx temp = gen_reg_rtx (compute_mode);
2385               if (! can_clobber_op0)
2386                 /* Copy op0 to a reg, to play safe,
2387                    since this is done in the other path.  */
2388                 op0 = force_reg (compute_mode, op0);
2389               temp = copy_to_suggested_reg (adjusted_op0, temp, compute_mode);
2390               temp = expand_shift (RSHIFT_EXPR, compute_mode, temp,
2391                                    build_int_2 (log - 1, 0), NULL_RTX, 0);
2392               temp = expand_shift (RSHIFT_EXPR, compute_mode, temp,
2393                                    build_int_2 (size - log, 0),
2394                                    temp, 1);
2395               /* We supply 0 as the target to make a new pseudo
2396                  for the value; that helps loop.c optimize the result.  */
2397               adjusted_op0 = expand_binop (compute_mode, add_optab,
2398                                            adjusted_op0, temp,
2399                                            0, 0, OPTAB_LIB_WIDEN);
2400             }
2401           else
2402             {
2403               rtx label = gen_label_rtx ();
2404               if (! can_clobber_op0)
2405                 {
2406                   adjusted_op0 = copy_to_suggested_reg (adjusted_op0, target,
2407                                                         compute_mode);
2408                   /* Copy op0 to a reg, since emit_cmp_insn will call emit_queue
2409                      which will screw up mem refs for autoincrements.  */
2410                   op0 = force_reg (compute_mode, op0);
2411                 }
2412               emit_cmp_insn (adjusted_op0, const0_rtx, GE, 
2413                              NULL_RTX, compute_mode, 0, 0);
2414               emit_jump_insn (gen_bge (label));
2415               expand_inc (adjusted_op0, plus_constant (op1, -1));
2416               emit_label (label);
2417             }
2418           mod_insn_no_good = 1;
2419         }
2420       break;
2421
2422     case FLOOR_DIV_EXPR:
2423     case FLOOR_MOD_EXPR:
2424       if (log < 0 && ! unsignedp)
2425         {
2426           rtx label = gen_label_rtx ();
2427           if (! can_clobber_op0)
2428             {
2429               adjusted_op0 = copy_to_suggested_reg (adjusted_op0, target,
2430                                                     compute_mode);
2431               /* Copy op0 to a reg, since emit_cmp_insn will call emit_queue
2432                  which will screw up mem refs for autoincrements.  */
2433               op0 = force_reg (compute_mode, op0);
2434             }
2435           emit_cmp_insn (adjusted_op0, const0_rtx, GE, 
2436                          NULL_RTX, compute_mode, 0, 0);
2437           emit_jump_insn (gen_bge (label));
2438           expand_dec (adjusted_op0, op1);
2439           expand_inc (adjusted_op0, const1_rtx);
2440           emit_label (label);
2441           mod_insn_no_good = 1;
2442         }
2443       break;
2444
2445     case CEIL_DIV_EXPR:
2446     case CEIL_MOD_EXPR:
2447       if (! can_clobber_op0)
2448         {
2449           adjusted_op0 = copy_to_suggested_reg (adjusted_op0, target,
2450                                                 compute_mode);
2451           /* Copy op0 to a reg, since emit_cmp_insn will call emit_queue
2452              which will screw up mem refs for autoincrements.  */
2453           op0 = force_reg (compute_mode, op0);
2454         }
2455       if (log < 0)
2456         {
2457           rtx label = 0;
2458           if (! unsignedp)
2459             {
2460               label = gen_label_rtx ();
2461               emit_cmp_insn (adjusted_op0, const0_rtx, LE, 
2462                              NULL_RTX, compute_mode, 0, 0);
2463               emit_jump_insn (gen_ble (label));
2464             }
2465           expand_inc (adjusted_op0, op1);
2466           expand_dec (adjusted_op0, const1_rtx);
2467           if (! unsignedp)
2468             emit_label (label);
2469         }
2470       else
2471         {
2472           adjusted_op0 = expand_binop (compute_mode, add_optab,
2473                                        adjusted_op0, plus_constant (op1, -1),
2474                                        NULL_RTX, 0, OPTAB_LIB_WIDEN);
2475         }
2476       mod_insn_no_good = 1;
2477       break;
2478
2479     case ROUND_DIV_EXPR:
2480     case ROUND_MOD_EXPR:
2481       if (! can_clobber_op0)
2482         {
2483           adjusted_op0 = copy_to_suggested_reg (adjusted_op0, target,
2484                                                 compute_mode);
2485           /* Copy op0 to a reg, since emit_cmp_insn will call emit_queue
2486              which will screw up mem refs for autoincrements.  */
2487           op0 = force_reg (compute_mode, op0);
2488         }
2489       if (log < 0)
2490         {
2491           op1 = expand_shift (RSHIFT_EXPR, compute_mode, op1,
2492                               integer_one_node, NULL_RTX, 0);
2493           if (! unsignedp)
2494             {
2495               if (BRANCH_COST >= 2)
2496                 {
2497                   /* Negate OP1 if OP0 < 0.  Do this by computing a temporary
2498                      that has all bits equal to the sign bit and exclusive
2499                      or-ing it with OP1.  */
2500                   rtx temp = gen_reg_rtx (compute_mode);
2501                   temp = copy_to_suggested_reg (adjusted_op0, temp, compute_mode);
2502                   temp = expand_shift (RSHIFT_EXPR, compute_mode, temp,
2503                                        build_int_2 (size - 1, 0),
2504                                        NULL_RTX, 0);
2505                   op1 = expand_binop (compute_mode, xor_optab, op1, temp, op1,
2506                                       unsignedp, OPTAB_LIB_WIDEN);
2507                 }
2508               else
2509                 {
2510                   rtx label = gen_label_rtx ();
2511                   emit_cmp_insn (adjusted_op0, const0_rtx, GE, NULL_RTX,
2512                                  compute_mode, 0, 0);
2513                   emit_jump_insn (gen_bge (label));
2514                   expand_unop (compute_mode, neg_optab, op1, op1, 0);
2515                   emit_label (label);
2516                 }
2517             }
2518           expand_inc (adjusted_op0, op1);
2519         }
2520       else
2521         {
2522           op1 = GEN_INT (((HOST_WIDE_INT) 1 << log) / 2);
2523           expand_inc (adjusted_op0, op1);
2524         }
2525       mod_insn_no_good = 1;
2526       break;
2527     }
2528
2529   if (rem_flag && !mod_insn_no_good)
2530     {
2531       /* Try to produce the remainder directly */
2532       if (log >= 0)
2533         result = expand_binop (compute_mode, and_optab, adjusted_op0,
2534                                GEN_INT (((HOST_WIDE_INT) 1 << log) - 1),
2535                                target, 1, OPTAB_LIB_WIDEN);
2536       else
2537         {
2538           /* See if we can do remainder without a library call.  */
2539           result = sign_expand_binop (mode, umod_optab, smod_optab,
2540                                       adjusted_op0, op1, target,
2541                                       unsignedp, OPTAB_WIDEN);
2542           if (result == 0)
2543             {
2544               /* No luck there.  Can we do remainder and divide at once
2545                  without a library call?  */
2546               result = gen_reg_rtx (compute_mode);
2547               if (! expand_twoval_binop (unsignedp
2548                                          ? udivmod_optab : sdivmod_optab,
2549                                          adjusted_op0, op1,
2550                                          NULL_RTX, result, unsignedp))
2551                 result = 0;
2552             }
2553         }
2554     }
2555
2556   if (result)
2557     return gen_lowpart (mode, result);
2558
2559   /* Produce the quotient.  */
2560   if (log >= 0)
2561     result = expand_shift (RSHIFT_EXPR, compute_mode, adjusted_op0,
2562                            build_int_2 (log, 0), target, unsignedp);
2563   else if (rem_flag && !mod_insn_no_good)
2564     /* If producing quotient in order to subtract for remainder,
2565        and a remainder subroutine would be ok,
2566        don't use a divide subroutine.  */
2567     result = sign_expand_binop (compute_mode, udiv_optab, sdiv_optab,
2568                                 adjusted_op0, op1, NULL_RTX, unsignedp,
2569                                 OPTAB_WIDEN);
2570   else
2571     {
2572       /* Try a quotient insn, but not a library call.  */
2573       result = sign_expand_binop (compute_mode, udiv_optab, sdiv_optab,
2574                                   adjusted_op0, op1,
2575                                   rem_flag ? NULL_RTX : target,
2576                                   unsignedp, OPTAB_WIDEN);
2577       if (result == 0)
2578         {
2579           /* No luck there.  Try a quotient-and-remainder insn,
2580              keeping the quotient alone.  */
2581           result = gen_reg_rtx (mode);
2582           if (! expand_twoval_binop (unsignedp ? udivmod_optab : sdivmod_optab,
2583                                      adjusted_op0, op1,
2584                                      result, NULL_RTX, unsignedp))
2585             result = 0;
2586         }
2587
2588       /* If still no luck, use a library call.  */
2589       if (result == 0)
2590         result = sign_expand_binop (compute_mode, udiv_optab, sdiv_optab,
2591                                     adjusted_op0, op1,
2592                                     rem_flag ? NULL_RTX : target,
2593                                     unsignedp, OPTAB_LIB_WIDEN);
2594     }
2595
2596   /* If we really want the remainder, get it by subtraction.  */
2597   if (rem_flag)
2598     {
2599       if (result == 0)
2600         /* No divide instruction either.  Use library for remainder.  */
2601         result = sign_expand_binop (compute_mode, umod_optab, smod_optab,
2602                                     op0, op1, target,
2603                                     unsignedp, OPTAB_LIB_WIDEN);
2604       else
2605         {
2606           /* We divided.  Now finish doing X - Y * (X / Y).  */
2607           result = expand_mult (compute_mode, result, op1, target, unsignedp);
2608           if (! result) abort ();
2609           result = expand_binop (compute_mode, sub_optab, op0,
2610                                  result, target, unsignedp, OPTAB_LIB_WIDEN);
2611         }
2612     }
2613
2614   if (result == 0)
2615     abort ();
2616
2617   return gen_lowpart (mode, result);
2618 }
2619 \f
2620 /* Return a tree node with data type TYPE, describing the value of X.
2621    Usually this is an RTL_EXPR, if there is no obvious better choice.
2622    X may be an expression, however we only support those expressions
2623    generated by loop.c.   */
2624
2625 tree
2626 make_tree (type, x)
2627      tree type;
2628      rtx x;
2629 {
2630   tree t;
2631
2632   switch (GET_CODE (x))
2633     {
2634     case CONST_INT:
2635       t = build_int_2 (INTVAL (x),
2636                        ! TREE_UNSIGNED (type) && INTVAL (x) >= 0 ? 0 : -1);
2637       TREE_TYPE (t) = type;
2638       return t;
2639
2640     case CONST_DOUBLE:
2641       if (GET_MODE (x) == VOIDmode)
2642         {
2643           t = build_int_2 (CONST_DOUBLE_LOW (x), CONST_DOUBLE_HIGH (x));
2644           TREE_TYPE (t) = type;
2645         }
2646       else
2647         {
2648           REAL_VALUE_TYPE d;
2649
2650           REAL_VALUE_FROM_CONST_DOUBLE (d, x);
2651           t = build_real (type, d);
2652         }
2653
2654       return t;
2655           
2656     case PLUS:
2657       return fold (build (PLUS_EXPR, type, make_tree (type, XEXP (x, 0)),
2658                           make_tree (type, XEXP (x, 1))));
2659                                                        
2660     case MINUS:
2661       return fold (build (MINUS_EXPR, type, make_tree (type, XEXP (x, 0)),
2662                           make_tree (type, XEXP (x, 1))));
2663                                                        
2664     case NEG:
2665       return fold (build1 (NEGATE_EXPR, type, make_tree (type, XEXP (x, 0))));
2666
2667     case MULT:
2668       return fold (build (MULT_EXPR, type, make_tree (type, XEXP (x, 0)),
2669                           make_tree (type, XEXP (x, 1))));
2670                                                       
2671     case ASHIFT:
2672       return fold (build (LSHIFT_EXPR, type, make_tree (type, XEXP (x, 0)),
2673                           make_tree (type, XEXP (x, 1))));
2674                                                       
2675     case LSHIFTRT:
2676       return fold (convert (type,
2677                             build (RSHIFT_EXPR, unsigned_type (type),
2678                                    make_tree (unsigned_type (type),
2679                                               XEXP (x, 0)),
2680                                    make_tree (type, XEXP (x, 1)))));
2681                                                       
2682     case ASHIFTRT:
2683       return fold (convert (type,
2684                             build (RSHIFT_EXPR, signed_type (type),
2685                                    make_tree (signed_type (type), XEXP (x, 0)),
2686                                    make_tree (type, XEXP (x, 1)))));
2687                                                       
2688     case DIV:
2689       if (TREE_CODE (type) != REAL_TYPE)
2690         t = signed_type (type);
2691       else
2692         t = type;
2693
2694       return fold (convert (type,
2695                             build (TRUNC_DIV_EXPR, t,
2696                                    make_tree (t, XEXP (x, 0)),
2697                                    make_tree (t, XEXP (x, 1)))));
2698     case UDIV:
2699       t = unsigned_type (type);
2700       return fold (convert (type,
2701                             build (TRUNC_DIV_EXPR, t,
2702                                    make_tree (t, XEXP (x, 0)),
2703                                    make_tree (t, XEXP (x, 1)))));
2704    default:
2705       t = make_node (RTL_EXPR);
2706       TREE_TYPE (t) = type;
2707       RTL_EXPR_RTL (t) = x;
2708       /* There are no insns to be output
2709          when this rtl_expr is used.  */
2710       RTL_EXPR_SEQUENCE (t) = 0;
2711       return t;
2712     }
2713 }
2714
2715 /* Return an rtx representing the value of X * MULT + ADD.
2716    TARGET is a suggestion for where to store the result (an rtx).
2717    MODE is the machine mode for the computation.
2718    X and MULT must have mode MODE.  ADD may have a different mode.
2719    So can X (defaults to same as MODE).
2720    UNSIGNEDP is non-zero to do unsigned multiplication.
2721    This may emit insns.  */
2722
2723 rtx
2724 expand_mult_add (x, target, mult, add, mode, unsignedp)
2725      rtx x, target, mult, add;
2726      enum machine_mode mode;
2727      int unsignedp;
2728 {
2729   tree type = type_for_mode (mode, unsignedp);
2730   tree add_type = (GET_MODE (add) == VOIDmode
2731                    ? type : type_for_mode (GET_MODE (add), unsignedp));
2732   tree result =  fold (build (PLUS_EXPR, type,
2733                               fold (build (MULT_EXPR, type,
2734                                            make_tree (type, x),
2735                                            make_tree (type, mult))),
2736                               make_tree (add_type, add)));
2737
2738   return expand_expr (result, target, VOIDmode, 0);
2739 }
2740 \f
2741 /* Compute the logical-and of OP0 and OP1, storing it in TARGET
2742    and returning TARGET.
2743
2744    If TARGET is 0, a pseudo-register or constant is returned.  */
2745
2746 rtx
2747 expand_and (op0, op1, target)
2748      rtx op0, op1, target;
2749 {
2750   enum machine_mode mode = VOIDmode;
2751   rtx tem;
2752
2753   if (GET_MODE (op0) != VOIDmode)
2754     mode = GET_MODE (op0);
2755   else if (GET_MODE (op1) != VOIDmode)
2756     mode = GET_MODE (op1);
2757
2758   if (mode != VOIDmode)
2759     tem = expand_binop (mode, and_optab, op0, op1, target, 0, OPTAB_LIB_WIDEN);
2760   else if (GET_CODE (op0) == CONST_INT && GET_CODE (op1) == CONST_INT)
2761     tem = GEN_INT (INTVAL (op0) & INTVAL (op1));
2762   else
2763     abort ();
2764
2765   if (target == 0)
2766     target = tem;
2767   else if (tem != target)
2768     emit_move_insn (target, tem);
2769   return target;
2770 }
2771 \f
2772 /* Emit a store-flags instruction for comparison CODE on OP0 and OP1
2773    and storing in TARGET.  Normally return TARGET.
2774    Return 0 if that cannot be done.
2775
2776    MODE is the mode to use for OP0 and OP1 should they be CONST_INTs.  If
2777    it is VOIDmode, they cannot both be CONST_INT.  
2778
2779    UNSIGNEDP is for the case where we have to widen the operands
2780    to perform the operation.  It says to use zero-extension.
2781
2782    NORMALIZEP is 1 if we should convert the result to be either zero
2783    or one one.  Normalize is -1 if we should convert the result to be
2784    either zero or -1.  If NORMALIZEP is zero, the result will be left
2785    "raw" out of the scc insn.  */
2786
2787 rtx
2788 emit_store_flag (target, code, op0, op1, mode, unsignedp, normalizep)
2789      rtx target;
2790      enum rtx_code code;
2791      rtx op0, op1;
2792      enum machine_mode mode;
2793      int unsignedp;
2794      int normalizep;
2795 {
2796   rtx subtarget;
2797   enum insn_code icode;
2798   enum machine_mode compare_mode;
2799   enum machine_mode target_mode = GET_MODE (target);
2800   rtx tem;
2801   rtx last = 0;
2802   rtx pattern, comparison;
2803
2804   if (mode == VOIDmode)
2805     mode = GET_MODE (op0);
2806
2807   /* If one operand is constant, make it the second one.  Only do this
2808      if the other operand is not constant as well.  */
2809
2810   if ((CONSTANT_P (op0) && ! CONSTANT_P (op1))
2811       || (GET_CODE (op0) == CONST_INT && GET_CODE (op1) != CONST_INT))
2812     {
2813       tem = op0;
2814       op0 = op1;
2815       op1 = tem;
2816       code = swap_condition (code);
2817     }
2818
2819   /* For some comparisons with 1 and -1, we can convert this to 
2820      comparisons with zero.  This will often produce more opportunities for
2821      store-flag insns. */
2822
2823   switch (code)
2824     {
2825     case LT:
2826       if (op1 == const1_rtx)
2827         op1 = const0_rtx, code = LE;
2828       break;
2829     case LE:
2830       if (op1 == constm1_rtx)
2831         op1 = const0_rtx, code = LT;
2832       break;
2833     case GE:
2834       if (op1 == const1_rtx)
2835         op1 = const0_rtx, code = GT;
2836       break;
2837     case GT:
2838       if (op1 == constm1_rtx)
2839         op1 = const0_rtx, code = GE;
2840       break;
2841     case GEU:
2842       if (op1 == const1_rtx)
2843         op1 = const0_rtx, code = NE;
2844       break;
2845     case LTU:
2846       if (op1 == const1_rtx)
2847         op1 = const0_rtx, code = EQ;
2848       break;
2849     }
2850
2851   /* From now on, we won't change CODE, so set ICODE now.  */
2852   icode = setcc_gen_code[(int) code];
2853
2854   /* If this is A < 0 or A >= 0, we can do this by taking the ones
2855      complement of A (for GE) and shifting the sign bit to the low bit.  */
2856   if (op1 == const0_rtx && (code == LT || code == GE)
2857       && GET_MODE_CLASS (mode) == MODE_INT
2858       && (normalizep || STORE_FLAG_VALUE == 1
2859           || (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
2860               && (STORE_FLAG_VALUE 
2861                   == (HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE (mode) - 1)))))
2862     {
2863       subtarget = target;
2864
2865       /* If the result is to be wider than OP0, it is best to convert it
2866          first.  If it is to be narrower, it is *incorrect* to convert it
2867          first.  */
2868       if (GET_MODE_SIZE (target_mode) > GET_MODE_SIZE (mode))
2869         {
2870           op0 = protect_from_queue (op0, 0);
2871           op0 = convert_to_mode (target_mode, op0, 0);
2872           mode = target_mode;
2873         }
2874
2875       if (target_mode != mode)
2876         subtarget = 0;
2877
2878       if (code == GE)
2879         op0 = expand_unop (mode, one_cmpl_optab, op0, subtarget, 0);
2880
2881       if (normalizep || STORE_FLAG_VALUE == 1)
2882         /* If we are supposed to produce a 0/1 value, we want to do
2883            a logical shift from the sign bit to the low-order bit; for
2884            a -1/0 value, we do an arithmetic shift.  */
2885         op0 = expand_shift (RSHIFT_EXPR, mode, op0,
2886                             size_int (GET_MODE_BITSIZE (mode) - 1),
2887                             subtarget, normalizep != -1);
2888
2889       if (mode != target_mode)
2890         op0 = convert_to_mode (target_mode, op0, 0);
2891
2892       return op0;
2893     }
2894
2895   if (icode != CODE_FOR_nothing)
2896     {
2897       /* We think we may be able to do this with a scc insn.  Emit the
2898          comparison and then the scc insn.
2899
2900          compare_from_rtx may call emit_queue, which would be deleted below
2901          if the scc insn fails.  So call it ourselves before setting LAST.  */
2902
2903       emit_queue ();
2904       last = get_last_insn ();
2905
2906       comparison
2907         = compare_from_rtx (op0, op1, code, unsignedp, mode, NULL_RTX, 0);
2908       if (GET_CODE (comparison) == CONST_INT)
2909         return (comparison == const0_rtx ? const0_rtx
2910                 : normalizep == 1 ? const1_rtx
2911                 : normalizep == -1 ? constm1_rtx
2912                 : const_true_rtx);
2913
2914       /* If the code of COMPARISON doesn't match CODE, something is
2915          wrong; we can no longer be sure that we have the operation.  
2916          We could handle this case, but it should not happen.  */
2917
2918       if (GET_CODE (comparison) != code)
2919         abort ();
2920
2921       /* Get a reference to the target in the proper mode for this insn.  */
2922       compare_mode = insn_operand_mode[(int) icode][0];
2923       subtarget = target;
2924       if (preserve_subexpressions_p ()
2925           || ! (*insn_operand_predicate[(int) icode][0]) (subtarget, compare_mode))
2926         subtarget = gen_reg_rtx (compare_mode);
2927
2928       pattern = GEN_FCN (icode) (subtarget);
2929       if (pattern)
2930         {
2931           emit_insn (pattern);
2932
2933           /* If we are converting to a wider mode, first convert to
2934              TARGET_MODE, then normalize.  This produces better combining
2935              opportunities on machines that have a SIGN_EXTRACT when we are
2936              testing a single bit.  This mostly benefits the 68k.
2937
2938              If STORE_FLAG_VALUE does not have the sign bit set when
2939              interpreted in COMPARE_MODE, we can do this conversion as
2940              unsigned, which is usually more efficient.  */
2941           if (GET_MODE_SIZE (target_mode) > GET_MODE_SIZE (compare_mode))
2942             {
2943               convert_move (target, subtarget,
2944                             (GET_MODE_BITSIZE (compare_mode)
2945                              <= HOST_BITS_PER_WIDE_INT)
2946                             && 0 == (STORE_FLAG_VALUE
2947                                      & ((HOST_WIDE_INT) 1
2948                                         << (GET_MODE_BITSIZE (compare_mode) -1))));
2949               op0 = target;
2950               compare_mode = target_mode;
2951             }
2952           else
2953             op0 = subtarget;
2954
2955           /* If we want to keep subexpressions around, don't reuse our
2956              last target.  */
2957
2958           if (preserve_subexpressions_p ())
2959             subtarget = 0;
2960
2961           /* Now normalize to the proper value in COMPARE_MODE.  Sometimes
2962              we don't have to do anything.  */
2963           if (normalizep == 0 || normalizep == STORE_FLAG_VALUE)
2964             ;
2965           else if (normalizep == - STORE_FLAG_VALUE)
2966             op0 = expand_unop (compare_mode, neg_optab, op0, subtarget, 0);
2967
2968           /* We don't want to use STORE_FLAG_VALUE < 0 below since this
2969              makes it hard to use a value of just the sign bit due to
2970              ANSI integer constant typing rules.  */
2971           else if (GET_MODE_BITSIZE (compare_mode) <= HOST_BITS_PER_WIDE_INT
2972                    && (STORE_FLAG_VALUE
2973                        & ((HOST_WIDE_INT) 1
2974                           << (GET_MODE_BITSIZE (compare_mode) - 1))))
2975             op0 = expand_shift (RSHIFT_EXPR, compare_mode, op0,
2976                                 size_int (GET_MODE_BITSIZE (compare_mode) - 1),
2977                                 subtarget, normalizep == 1);
2978           else if (STORE_FLAG_VALUE & 1)
2979             {
2980               op0 = expand_and (op0, const1_rtx, subtarget);
2981               if (normalizep == -1)
2982                 op0 = expand_unop (compare_mode, neg_optab, op0, op0, 0);
2983             }
2984           else
2985             abort ();
2986
2987           /* If we were converting to a smaller mode, do the 
2988              conversion now.  */
2989           if (target_mode != compare_mode)
2990             {
2991               convert_move (target, op0, 0);
2992               return target;
2993             }
2994           else
2995             return op0;
2996         }
2997     }
2998
2999   if (last)
3000     delete_insns_since (last);
3001
3002   subtarget = target_mode == mode ? target : 0;
3003
3004   /* If we reached here, we can't do this with a scc insn.  However, there
3005      are some comparisons that can be done directly.  For example, if
3006      this is an equality comparison of integers, we can try to exclusive-or
3007      (or subtract) the two operands and use a recursive call to try the
3008      comparison with zero.  Don't do any of these cases if branches are
3009      very cheap.  */
3010
3011   if (BRANCH_COST > 0
3012       && GET_MODE_CLASS (mode) == MODE_INT && (code == EQ || code == NE)
3013       && op1 != const0_rtx)
3014     {
3015       tem = expand_binop (mode, xor_optab, op0, op1, subtarget, 1,
3016                           OPTAB_WIDEN);
3017
3018       if (tem == 0)
3019         tem = expand_binop (mode, sub_optab, op0, op1, subtarget, 1,
3020                             OPTAB_WIDEN);
3021       if (tem != 0)
3022         tem = emit_store_flag (target, code, tem, const0_rtx,
3023                                mode, unsignedp, normalizep);
3024       if (tem == 0)
3025         delete_insns_since (last);
3026       return tem;
3027     }
3028
3029   /* Some other cases we can do are EQ, NE, LE, and GT comparisons with 
3030      the constant zero.  Reject all other comparisons at this point.  Only
3031      do LE and GT if branches are expensive since they are expensive on
3032      2-operand machines.  */
3033
3034   if (BRANCH_COST == 0
3035       || GET_MODE_CLASS (mode) != MODE_INT || op1 != const0_rtx
3036       || (code != EQ && code != NE
3037           && (BRANCH_COST <= 1 || (code != LE && code != GT))))
3038     return 0;
3039
3040   /* See what we need to return.  We can only return a 1, -1, or the
3041      sign bit.  */
3042
3043   if (normalizep == 0)
3044     {
3045       if (STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1)
3046         normalizep = STORE_FLAG_VALUE;
3047
3048       else if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
3049                && (STORE_FLAG_VALUE
3050                    == (HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE (mode) - 1)))
3051         ;
3052       else
3053         return 0;
3054     }
3055
3056   /* Try to put the result of the comparison in the sign bit.  Assume we can't
3057      do the necessary operation below.  */
3058
3059   tem = 0;
3060
3061   /* To see if A <= 0, compute (A | (A - 1)).  A <= 0 iff that result has
3062      the sign bit set.  */
3063
3064   if (code == LE)
3065     {
3066       /* This is destructive, so SUBTARGET can't be OP0.  */
3067       if (rtx_equal_p (subtarget, op0))
3068         subtarget = 0;
3069
3070       tem = expand_binop (mode, sub_optab, op0, const1_rtx, subtarget, 0,
3071                           OPTAB_WIDEN);
3072       if (tem)
3073         tem = expand_binop (mode, ior_optab, op0, tem, subtarget, 0,
3074                             OPTAB_WIDEN);
3075     }
3076
3077   /* To see if A > 0, compute (((signed) A) << BITS) - A, where BITS is the
3078      number of bits in the mode of OP0, minus one.  */
3079
3080   if (code == GT)
3081     {
3082       if (rtx_equal_p (subtarget, op0))
3083         subtarget = 0;
3084
3085       tem = expand_shift (RSHIFT_EXPR, mode, op0,
3086                           size_int (GET_MODE_BITSIZE (mode) - 1),
3087                           subtarget, 0);
3088       tem = expand_binop (mode, sub_optab, tem, op0, subtarget, 0,
3089                           OPTAB_WIDEN);
3090     }
3091                                     
3092   if (code == EQ || code == NE)
3093     {
3094       /* For EQ or NE, one way to do the comparison is to apply an operation
3095          that converts the operand into a positive number if it is non-zero
3096          or zero if it was originally zero.  Then, for EQ, we subtract 1 and
3097          for NE we negate.  This puts the result in the sign bit.  Then we
3098          normalize with a shift, if needed. 
3099
3100          Two operations that can do the above actions are ABS and FFS, so try
3101          them.  If that doesn't work, and MODE is smaller than a full word,
3102          we can use zero-extension to the wider mode (an unsigned conversion)
3103          as the operation.  */
3104
3105       if (abs_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
3106         tem = expand_unop (mode, abs_optab, op0, subtarget, 1);
3107       else if (ffs_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
3108         tem = expand_unop (mode, ffs_optab, op0, subtarget, 1);
3109       else if (GET_MODE_SIZE (mode) < UNITS_PER_WORD)
3110         {
3111           mode = word_mode;
3112           op0 = protect_from_queue (op0, 0);
3113           tem = convert_to_mode (mode, op0, 1);
3114         }
3115
3116       if (tem != 0)
3117         {
3118           if (code == EQ)
3119             tem = expand_binop (mode, sub_optab, tem, const1_rtx, subtarget,
3120                                 0, OPTAB_WIDEN);
3121           else
3122             tem = expand_unop (mode, neg_optab, tem, subtarget, 0);
3123         }
3124
3125       /* If we couldn't do it that way, for NE we can "or" the two's complement
3126          of the value with itself.  For EQ, we take the one's complement of
3127          that "or", which is an extra insn, so we only handle EQ if branches
3128          are expensive.  */
3129
3130       if (tem == 0 && (code == NE || BRANCH_COST > 1))
3131         {
3132           if (rtx_equal_p (subtarget, op0))
3133             subtarget = 0;
3134
3135           tem = expand_unop (mode, neg_optab, op0, subtarget, 0);
3136           tem = expand_binop (mode, ior_optab, tem, op0, subtarget, 0,
3137                               OPTAB_WIDEN);
3138
3139           if (tem && code == EQ)
3140             tem = expand_unop (mode, one_cmpl_optab, tem, subtarget, 0);
3141         }
3142     }
3143
3144   if (tem && normalizep)
3145     tem = expand_shift (RSHIFT_EXPR, mode, tem,
3146                         size_int (GET_MODE_BITSIZE (mode) - 1),
3147                         tem, normalizep == 1);
3148
3149   if (tem && GET_MODE (tem) != target_mode)
3150     {
3151       convert_move (target, tem, 0);
3152       tem = target;
3153     }
3154
3155   if (tem == 0)
3156     delete_insns_since (last);
3157
3158   return tem;
3159 }
3160   emit_jump_insn ((*bcc_gen_fctn[(int) code]) (label));
3161   emit_move_insn (target, const1_rtx);
3162   emit_label (label);
3163
3164   return target;
3165 }