OSDN Git Service

(expand_{binop,unop}): Don't make invalid paradoxical SUBREGs.
[pf3gnuchains/gcc-fork.git] / gcc / optabs.c
1 /* Expand the basic unary and binary arithmetic operations, for GNU compiler.
2    Copyright (C) 1987, 1988, 1992 Free Software Foundation, Inc.
3
4 This file is part of GNU CC.
5
6 GNU CC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GNU CC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU CC; see the file COPYING.  If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
19
20
21 #include "config.h"
22 #include "rtl.h"
23 #include "tree.h"
24 #include "flags.h"
25 #include "insn-flags.h"
26 #include "insn-codes.h"
27 #include "expr.h"
28 #include "insn-config.h"
29 #include "recog.h"
30 #include <ctype.h>
31
32 /* Each optab contains info on how this target machine
33    can perform a particular operation
34    for all sizes and kinds of operands.
35
36    The operation to be performed is often specified
37    by passing one of these optabs as an argument.
38
39    See expr.h for documentation of these optabs.  */
40
41 optab add_optab;
42 optab sub_optab;
43 optab smul_optab;
44 optab smul_widen_optab;
45 optab umul_widen_optab;
46 optab sdiv_optab;
47 optab sdivmod_optab;
48 optab udiv_optab;
49 optab udivmod_optab;
50 optab smod_optab;
51 optab umod_optab;
52 optab flodiv_optab;
53 optab ftrunc_optab;
54 optab and_optab;
55 optab ior_optab;
56 optab xor_optab;
57 optab ashl_optab;
58 optab lshr_optab;
59 optab lshl_optab;
60 optab ashr_optab;
61 optab rotl_optab;
62 optab rotr_optab;
63 optab smin_optab;
64 optab smax_optab;
65 optab umin_optab;
66 optab umax_optab;
67
68 optab mov_optab;
69 optab movstrict_optab;
70
71 optab neg_optab;
72 optab abs_optab;
73 optab one_cmpl_optab;
74 optab ffs_optab;
75 optab sqrt_optab;
76 optab sin_optab;
77 optab cos_optab;
78
79 optab cmp_optab;
80 optab ucmp_optab;  /* Used only for libcalls for unsigned comparisons.  */
81 optab tst_optab;
82
83 optab strlen_optab;
84
85 /* SYMBOL_REF rtx's for the library functions that are called
86    implicitly and not via optabs.  */
87
88 rtx extendsfdf2_libfunc;
89 rtx extendsfxf2_libfunc;
90 rtx extendsftf2_libfunc;
91 rtx extenddfxf2_libfunc;
92 rtx extenddftf2_libfunc;
93
94 rtx truncdfsf2_libfunc;
95 rtx truncxfsf2_libfunc;
96 rtx trunctfsf2_libfunc;
97 rtx truncxfdf2_libfunc;
98 rtx trunctfdf2_libfunc;
99
100 rtx memcpy_libfunc;
101 rtx bcopy_libfunc;
102 rtx memcmp_libfunc;
103 rtx bcmp_libfunc;
104 rtx memset_libfunc;
105 rtx bzero_libfunc;
106
107 rtx eqsf2_libfunc;
108 rtx nesf2_libfunc;
109 rtx gtsf2_libfunc;
110 rtx gesf2_libfunc;
111 rtx ltsf2_libfunc;
112 rtx lesf2_libfunc;
113
114 rtx eqdf2_libfunc;
115 rtx nedf2_libfunc;
116 rtx gtdf2_libfunc;
117 rtx gedf2_libfunc;
118 rtx ltdf2_libfunc;
119 rtx ledf2_libfunc;
120
121 rtx eqxf2_libfunc;
122 rtx nexf2_libfunc;
123 rtx gtxf2_libfunc;
124 rtx gexf2_libfunc;
125 rtx ltxf2_libfunc;
126 rtx lexf2_libfunc;
127
128 rtx eqtf2_libfunc;
129 rtx netf2_libfunc;
130 rtx gttf2_libfunc;
131 rtx getf2_libfunc;
132 rtx lttf2_libfunc;
133 rtx letf2_libfunc;
134
135 rtx floatsisf_libfunc;
136 rtx floatdisf_libfunc;
137 rtx floattisf_libfunc;
138
139 rtx floatsidf_libfunc;
140 rtx floatdidf_libfunc;
141 rtx floattidf_libfunc;
142
143 rtx floatsixf_libfunc;
144 rtx floatdixf_libfunc;
145 rtx floattixf_libfunc;
146
147 rtx floatsitf_libfunc;
148 rtx floatditf_libfunc;
149 rtx floattitf_libfunc;
150
151 rtx fixsfsi_libfunc;
152 rtx fixsfdi_libfunc;
153 rtx fixsfti_libfunc;
154
155 rtx fixdfsi_libfunc;
156 rtx fixdfdi_libfunc;
157 rtx fixdfti_libfunc;
158
159 rtx fixxfsi_libfunc;
160 rtx fixxfdi_libfunc;
161 rtx fixxfti_libfunc;
162
163 rtx fixtfsi_libfunc;
164 rtx fixtfdi_libfunc;
165 rtx fixtfti_libfunc;
166
167 rtx fixunssfsi_libfunc;
168 rtx fixunssfdi_libfunc;
169 rtx fixunssfti_libfunc;
170
171 rtx fixunsdfsi_libfunc;
172 rtx fixunsdfdi_libfunc;
173 rtx fixunsdfti_libfunc;
174
175 rtx fixunsxfsi_libfunc;
176 rtx fixunsxfdi_libfunc;
177 rtx fixunsxfti_libfunc;
178
179 rtx fixunstfsi_libfunc;
180 rtx fixunstfdi_libfunc;
181 rtx fixunstfti_libfunc;
182
183 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
184    gives the gen_function to make a branch to test that condition.  */
185
186 rtxfun bcc_gen_fctn[NUM_RTX_CODE];
187
188 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
189    gives the insn code to make a store-condition insn
190    to test that condition.  */
191
192 enum insn_code setcc_gen_code[NUM_RTX_CODE];
193
194 static void emit_float_lib_cmp ();
195 \f
196 /* Add a REG_EQUAL note to the last insn in SEQ.  TARGET is being set to
197    the result of operation CODE applied to OP0 (and OP1 if it is a binary
198    operation).
199
200    If the last insn does not set TARGET, don't do anything, but return 1.
201
202    If a previous insn sets TARGET and TARGET is one of OP0 or OP1,
203    don't add the REG_EQUAL note but return 0.  Our caller can then try
204    again, ensuring that TARGET is not one of the operands.  */
205
206 static int
207 add_equal_note (seq, target, code, op0, op1)
208      rtx seq;
209      rtx target;
210      enum rtx_code code;
211      rtx op0, op1;
212 {
213   rtx set;
214   int i;
215   rtx note;
216
217   if ((GET_RTX_CLASS (code) != '1' && GET_RTX_CLASS (code) != '2'
218        && GET_RTX_CLASS (code) != 'c' && GET_RTX_CLASS (code) != '<')
219       || GET_CODE (seq) != SEQUENCE
220       || (set = single_set (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1))) == 0
221       || GET_CODE (target) == ZERO_EXTRACT
222       || (! rtx_equal_p (SET_DEST (set), target)
223           /* For a STRICT_LOW_PART, the REG_NOTE applies to what is inside the
224              SUBREG.  */
225           && (GET_CODE (SET_DEST (set)) != STRICT_LOW_PART
226               || ! rtx_equal_p (SUBREG_REG (XEXP (SET_DEST (set), 0)),
227                                 target))))
228     return 1;
229
230   /* If TARGET is in OP0 or OP1, check if anything in SEQ sets TARGET
231      besides the last insn.  */
232   if (reg_overlap_mentioned_p (target, op0)
233       || (op1 && reg_overlap_mentioned_p (target, op1)))
234     for (i = XVECLEN (seq, 0) - 2; i >= 0; i--)
235       if (reg_set_p (target, XVECEXP (seq, 0, i)))
236         return 0;
237
238   if (GET_RTX_CLASS (code) == '1')
239     note = gen_rtx (code, GET_MODE (target), op0);
240   else
241     note = gen_rtx (code, GET_MODE (target), op0, op1);
242
243   REG_NOTES (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1))
244     = gen_rtx (EXPR_LIST, REG_EQUAL, note,
245                REG_NOTES (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1)));
246
247   return 1;
248 }
249 \f
250 /* Generate code to perform an operation specified by BINOPTAB
251    on operands OP0 and OP1, with result having machine-mode MODE.
252
253    UNSIGNEDP is for the case where we have to widen the operands
254    to perform the operation.  It says to use zero-extension.
255
256    If TARGET is nonzero, the value
257    is generated there, if it is convenient to do so.
258    In all cases an rtx is returned for the locus of the value;
259    this may or may not be TARGET.  */
260
261 rtx
262 expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods)
263      enum machine_mode mode;
264      optab binoptab;
265      rtx op0, op1;
266      rtx target;
267      int unsignedp;
268      enum optab_methods methods;
269 {
270   enum mode_class class;
271   enum machine_mode wider_mode;
272   register rtx temp;
273   int commutative_op = 0;
274   int shift_op = (binoptab->code ==  ASHIFT
275                   || binoptab->code == ASHIFTRT
276                   || binoptab->code == LSHIFT
277                   || binoptab->code == LSHIFTRT
278                   || binoptab->code == ROTATE
279                   || binoptab->code == ROTATERT);
280   rtx last;
281
282   class = GET_MODE_CLASS (mode);
283
284   op0 = protect_from_queue (op0, 0);
285   op1 = protect_from_queue (op1, 0);
286   if (target)
287     target = protect_from_queue (target, 1);
288
289   if (flag_force_mem)
290     {
291       op0 = force_not_mem (op0);
292       op1 = force_not_mem (op1);
293     }
294
295   /* If we are inside an appropriately-short loop and one operand is an
296      expensive constant, force it into a register.  */
297   if (CONSTANT_P (op0) && preserve_subexpressions_p ()
298       && rtx_cost (op0, binoptab->code) > 2)
299     op0 = force_reg (mode, op0);
300
301   if (CONSTANT_P (op1) && preserve_subexpressions_p ()
302       && rtx_cost (op1, binoptab->code) > 2)
303     op1 = force_reg (shift_op ? word_mode : mode, op1);
304
305 #if 0  /* Turned off because it seems to be a kludgy method.  */
306   /* If subtracting integer from pointer, and the pointer has a special mode,
307      then change it to an add.  We use the add insn of Pmode for combining
308      integers with pointers, and the sub insn to subtract two pointers.  */
309
310   if (binoptab == sub_optab
311       && GET_MODE (op0) == Pmode && GET_MODE (op1) != Pmode)
312     {
313       op1 = negate_rtx (GET_MODE(op1), op1);
314       binoptab = add_optab;
315     }
316 #endif /* 0 */
317
318   /* Record where to delete back to if we backtrack.  */
319   last = get_last_insn ();
320
321   /* If operation is commutative,
322      try to make the first operand a register.
323      Even better, try to make it the same as the target.
324      Also try to make the last operand a constant.  */
325   if (GET_RTX_CLASS (binoptab->code) == 'c'
326       || binoptab == smul_widen_optab
327       || binoptab == umul_widen_optab)
328     {
329       commutative_op = 1;
330
331       if (((target == 0 || GET_CODE (target) == REG)
332            ? ((GET_CODE (op1) == REG
333                && GET_CODE (op0) != REG)
334               || target == op1)
335            : rtx_equal_p (op1, target))
336           || GET_CODE (op0) == CONST_INT)
337         {
338           temp = op1;
339           op1 = op0;
340           op0 = temp;
341         }
342     }
343
344   /* If we can do it with a three-operand insn, do so.  */
345
346   if (methods != OPTAB_MUST_WIDEN
347       && binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
348     {
349       int icode = (int) binoptab->handlers[(int) mode].insn_code;
350       enum machine_mode mode0 = insn_operand_mode[icode][1];
351       enum machine_mode mode1 = insn_operand_mode[icode][2];
352       rtx pat;
353       rtx xop0 = op0, xop1 = op1;
354
355       if (target)
356         temp = target;
357       else
358         temp = gen_reg_rtx (mode);
359
360       /* If it is a commutative operator and the modes would match
361          if we would swap the operands, we can save the conversions. */
362       if (commutative_op)
363         {
364           if (GET_MODE (op0) != mode0 && GET_MODE (op1) != mode1
365               && GET_MODE (op0) == mode1 && GET_MODE (op1) == mode0)
366             {
367               register rtx tmp;
368
369               tmp = op0; op0 = op1; op1 = tmp;
370               tmp = xop0; xop0 = xop1; xop1 = tmp;
371             }
372         }
373
374       /* In case the insn wants input operands in modes different from
375          the result, convert the operands.  */
376
377       if (GET_MODE (op0) != VOIDmode
378           && GET_MODE (op0) != mode0)
379         xop0 = convert_to_mode (mode0, xop0, unsignedp);
380
381       if (GET_MODE (xop1) != VOIDmode
382           && GET_MODE (xop1) != mode1)
383         xop1 = convert_to_mode (mode1, xop1, unsignedp);
384
385       /* Now, if insn's predicates don't allow our operands, put them into
386          pseudo regs.  */
387
388       if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
389         xop0 = copy_to_mode_reg (mode0, xop0);
390
391       if (! (*insn_operand_predicate[icode][2]) (xop1, mode1))
392         xop1 = copy_to_mode_reg (mode1, xop1);
393
394       if (! (*insn_operand_predicate[icode][0]) (temp, mode))
395         temp = gen_reg_rtx (mode);
396
397       pat = GEN_FCN (icode) (temp, xop0, xop1);
398       if (pat)
399         {
400           /* If PAT is a multi-insn sequence, try to add an appropriate
401              REG_EQUAL note to it.  If we can't because TEMP conflicts with an
402              operand, call ourselves again, this time without a target.  */
403           if (GET_CODE (pat) == SEQUENCE
404               && ! add_equal_note (pat, temp, binoptab->code, xop0, xop1))
405             {
406               delete_insns_since (last);
407               return expand_binop (mode, binoptab, op0, op1, NULL_RTX,
408                                    unsignedp, methods);
409             }
410
411           emit_insn (pat);
412           return temp;
413         }
414       else
415         delete_insns_since (last);
416     }
417
418   /* If this is a multiply, see if we can do a widening operation that
419      takes operands of this mode and makes a wider mode.  */
420
421   if (binoptab == smul_optab && GET_MODE_WIDER_MODE (mode) != VOIDmode
422       && (((unsignedp ? umul_widen_optab : smul_widen_optab)
423            ->handlers[(int) GET_MODE_WIDER_MODE (mode)].insn_code)
424           != CODE_FOR_nothing))
425     {
426       temp = expand_binop (GET_MODE_WIDER_MODE (mode),
427                            unsignedp ? umul_widen_optab : smul_widen_optab,
428                            op0, op1, 0, unsignedp, OPTAB_DIRECT);
429
430       if (GET_MODE_CLASS (mode) == MODE_INT)
431         return gen_lowpart (mode, temp);
432       else
433         return convert_to_mode (mode, temp, unsignedp);
434     }
435
436   /* Look for a wider mode of the same class for which we think we
437      can open-code the operation.  Check for a widening multiply at the
438      wider mode as well.  */
439
440   if ((class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
441       && mode != OPTAB_DIRECT && mode != OPTAB_LIB)
442     for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
443          wider_mode = GET_MODE_WIDER_MODE (wider_mode))
444       {
445         if (binoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing
446             || (binoptab == smul_optab
447                 && GET_MODE_WIDER_MODE (wider_mode) != VOIDmode
448                 && (((unsignedp ? umul_widen_optab : smul_widen_optab)
449                      ->handlers[(int) GET_MODE_WIDER_MODE (wider_mode)].insn_code)
450                     != CODE_FOR_nothing)))
451           {
452             rtx xop0 = op0, xop1 = op1;
453             int no_extend = 0;
454
455             /* For certain integer operations, we need not actually extend
456                the narrow operands, as long as we will truncate
457                the results to the same narrowness.  Don't do this when
458                WIDER_MODE is wider than a word since a paradoxical SUBREG
459                isn't valid for such modes.  */
460
461             if ((binoptab == ior_optab || binoptab == and_optab
462                  || binoptab == xor_optab
463                  || binoptab == add_optab || binoptab == sub_optab
464                  || binoptab == smul_optab
465                  || binoptab == ashl_optab || binoptab == lshl_optab)
466                 && class == MODE_INT
467                 && GET_MODE_SIZE (wider_mode) <= UNITS_PER_WORD)
468               no_extend = 1;
469
470             /* If an operand is a constant integer, we might as well
471                convert it since that is more efficient than using a SUBREG,
472                unlike the case for other operands.  */
473
474             if (no_extend && GET_MODE (xop0) != VOIDmode)
475               xop0 = gen_rtx (SUBREG, wider_mode,
476                               force_reg (GET_MODE (xop0), xop0), 0);
477             else
478               xop0 = convert_to_mode (wider_mode, xop0, unsignedp);
479
480             if (no_extend && GET_MODE (xop1) != VOIDmode)
481               xop1 = gen_rtx (SUBREG, wider_mode,
482                                 force_reg (GET_MODE (xop1), xop1), 0);
483             else
484               xop1 = convert_to_mode (wider_mode, xop1, unsignedp);
485
486             temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
487                                  unsignedp, OPTAB_DIRECT);
488             if (temp)
489               {
490                 if (class != MODE_INT)
491                   {
492                     if (target == 0)
493                       target = gen_reg_rtx (mode);
494                     convert_move (target, temp, 0);
495                     return target;
496                   }
497                 else
498                   return gen_lowpart (mode, temp);
499               }
500             else
501               delete_insns_since (last);
502           }
503       }
504
505   /* These can be done a word at a time.  */
506   if ((binoptab == and_optab || binoptab == ior_optab || binoptab == xor_optab)
507       && class == MODE_INT
508       && GET_MODE_SIZE (mode) > UNITS_PER_WORD
509       && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
510     {
511       int i;
512       rtx insns;
513       rtx equiv_value;
514
515       /* If TARGET is the same as one of the operands, the REG_EQUAL note
516          won't be accurate, so use a new target.  */
517       if (target == 0 || target == op0 || target == op1)
518         target = gen_reg_rtx (mode);
519
520       start_sequence ();
521
522       /* Do the actual arithmetic.  */
523       for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
524         {
525           rtx target_piece = operand_subword (target, i, 1, mode);
526           rtx x = expand_binop (word_mode, binoptab,
527                                 operand_subword_force (op0, i, mode),
528                                 operand_subword_force (op1, i, mode),
529                                 target_piece, unsignedp, methods);
530           if (target_piece != x)
531             emit_move_insn (target_piece, x);
532         }
533
534       insns = get_insns ();
535       end_sequence ();
536
537       if (binoptab->code != UNKNOWN)
538         equiv_value = gen_rtx (binoptab->code, mode, op0, op1);
539       else
540         equiv_value = 0;
541
542       emit_no_conflict_block (insns, target, op0, op1, equiv_value);
543       return target;
544     }
545
546   /* These can be done a word at a time by propagating carries.  */
547   if ((binoptab == add_optab || binoptab == sub_optab)
548       && class == MODE_INT
549       && GET_MODE_SIZE (mode) >= 2 * UNITS_PER_WORD
550       && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
551     {
552       int i;
553       rtx carry_tmp = gen_reg_rtx (word_mode);
554       optab otheroptab = binoptab == add_optab ? sub_optab : add_optab;
555       int nwords = GET_MODE_BITSIZE (mode) / BITS_PER_WORD;
556       rtx carry_in, carry_out;
557
558       /* We can handle either a 1 or -1 value for the carry.  If STORE_FLAG
559          value is one of those, use it.  Otherwise, use 1 since it is the
560          one easiest to get.  */
561 #if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
562       int normalizep = STORE_FLAG_VALUE;
563 #else
564       int normalizep = 1;
565 #endif
566
567       /* Prepare the operands.  */
568       op0 = force_reg (mode, op0);
569       op1 = force_reg (mode, op1);
570
571       if (target == 0 || GET_CODE (target) != REG
572           || target == op0 || target == op1)
573         target = gen_reg_rtx (mode);
574
575       /* Do the actual arithmetic.  */
576       for (i = 0; i < nwords; i++)
577         {
578           int index = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i);
579           rtx target_piece = operand_subword (target, index, 1, mode);
580           rtx op0_piece = operand_subword_force (op0, index, mode);
581           rtx op1_piece = operand_subword_force (op1, index, mode);
582           rtx x;
583
584           /* Main add/subtract of the input operands.  */
585           x = expand_binop (word_mode, binoptab,
586                             op0_piece, op1_piece,
587                             target_piece, unsignedp, methods);
588           if (x == 0)
589             break;
590
591           if (i + 1 < nwords)
592             {
593               /* Store carry from main add/subtract.  */
594               carry_out = gen_reg_rtx (word_mode);
595               carry_out = emit_store_flag (carry_out,
596                                            binoptab == add_optab ? LTU : GTU,
597                                            x, op0_piece,
598                                            word_mode, 1, normalizep);
599               if (!carry_out)
600                 break;
601             }
602
603           if (i > 0)
604             {
605               /* Add/subtract previous carry to main result.  */
606               x = expand_binop (word_mode,
607                                 normalizep == 1 ? binoptab : otheroptab,
608                                 x, carry_in,
609                                 target_piece, 1, methods);
610               if (target_piece != x)
611                 emit_move_insn (target_piece, x);
612
613               if (i + 1 < nwords)
614                 {
615                   /* THIS CODE HAS NOT BEEN TESTED.  */
616                   /* Get out carry from adding/subtracting carry in.  */
617                   carry_tmp = emit_store_flag (carry_tmp,
618                                                binoptab == add_optab
619                                                  ? LTU : GTU,
620                                                x, carry_in,
621                                                word_mode, 1, normalizep);
622                   /* Logical-ior the two poss. carry together.  */
623                   carry_out = expand_binop (word_mode, ior_optab,
624                                             carry_out, carry_tmp,
625                                             carry_out, 0, methods);
626                   if (!carry_out)
627                     break;
628                 }
629             }
630
631           carry_in = carry_out;
632         }       
633
634       if (i == GET_MODE_BITSIZE (mode) / BITS_PER_WORD)
635         {
636           rtx temp;
637           
638           temp = emit_move_insn (target, target);
639           REG_NOTES (temp) = gen_rtx (EXPR_LIST, REG_EQUAL,
640                                       gen_rtx (binoptab->code, mode, op0, op1),
641                                       REG_NOTES (temp));
642           return target;
643         }
644       else
645         delete_insns_since (last);
646     }
647
648   /* If we want to multiply two two-word values and have normal and widening
649      multiplies of single-word values, we can do this with three smaller
650      multiplications.  Note that we do not make a REG_NO_CONFLICT block here
651      because we are not operating on one word at a time. 
652
653      The multiplication proceeds as follows:
654                                  _______________________
655                                 [__op0_high_|__op0_low__]
656                                  _______________________
657         *                           [__op1_high_|__op1_low__]
658         _______________________________________________
659                                  _______________________
660     (1)                     [__op0_low__*__op1_low__]
661                      _______________________
662     (2a)                [__op0_low__*__op1_high_]
663                      _______________________
664     (2b)                [__op0_high_*__op1_low__]
665          _______________________
666     (3) [__op0_high_*__op1_high_]
667
668
669     This gives a 4-word result.  Since we are only interested in the
670     lower 2 words, partial result (3) and the upper words of (2a) and
671     (2b) don't need to be calculated.  Hence (2a) and (2b) can be
672     calculated using non-widening multiplication.
673
674     (1), however, needs to be calculated with an unsigned widening
675     multiplication.  If this operation is not directly supported we
676     try using a signed widening multiplication and adjust the result.
677     This adjustment works as follows:
678
679       If both operands are positive then no adjustment is needed.
680
681       If the operands have different signs, for example op0_low < 0 and
682       op1_low >= 0, the instruction treats the most significant bit of
683       op0_low as a sign bit instead of a bit with significance
684       2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low
685       with 2**BITS_PER_WORD - op0_low, and two's complements the
686       result.  Conclusion: We need to add op1_low * 2**BITS_PER_WORD to
687       the result.
688
689       Similarly, if both operands are negative, we need to add
690       (op0_low + op1_low) * 2**BITS_PER_WORD.
691
692       We use a trick to adjust quickly.  We logically shift op0_low right
693       (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to
694       op0_high (op1_high) before it is used to calculate 2b (2a).  If no
695       logical shift exists, we do an arithmetic right shift and subtract
696       the 0 or -1.  */
697
698   if (binoptab == smul_optab
699       && class == MODE_INT
700       && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
701       && smul_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
702       && add_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
703       && ((umul_widen_optab->handlers[(int) mode].insn_code
704            != CODE_FOR_nothing)
705           || (smul_widen_optab->handlers[(int) mode].insn_code
706               != CODE_FOR_nothing)))
707     {
708       int low = (WORDS_BIG_ENDIAN ? 1 : 0);
709       int high = (WORDS_BIG_ENDIAN ? 0 : 1);
710       rtx op0_high = operand_subword_force (op0, high, mode);
711       rtx op0_low = operand_subword_force (op0, low, mode);
712       rtx op1_high = operand_subword_force (op1, high, mode);
713       rtx op1_low = operand_subword_force (op1, low, mode);
714       rtx product = 0;
715       rtx op0_xhigh;
716       rtx op1_xhigh;
717
718       /* If the target is the same as one of the inputs, don't use it.  This
719          prevents problems with the REG_EQUAL note.  */
720       if (target == op0 || target == op1)
721         target = 0;
722
723       /* Multiply the two lower words to get a double-word product.
724          If unsigned widening multiplication is available, use that;
725          otherwise use the signed form and compensate.  */
726
727       if (umul_widen_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
728         {
729           product = expand_binop (mode, umul_widen_optab, op0_low, op1_low,
730                                   target, 1, OPTAB_DIRECT);
731
732           /* If we didn't succeed, delete everything we did so far.  */
733           if (product == 0)
734             delete_insns_since (last);
735           else
736             op0_xhigh = op0_high, op1_xhigh = op1_high;
737         }
738
739       if (product == 0
740           && smul_widen_optab->handlers[(int) mode].insn_code
741                != CODE_FOR_nothing)
742         {
743           rtx wordm1 = GEN_INT (BITS_PER_WORD - 1);
744           product = expand_binop (mode, smul_widen_optab, op0_low, op1_low,
745                                   target, 1, OPTAB_DIRECT);
746           op0_xhigh = expand_binop (word_mode, lshr_optab, op0_low, wordm1,
747                                     NULL_RTX, 1, OPTAB_DIRECT);
748           if (op0_xhigh)
749             op0_xhigh = expand_binop (word_mode, add_optab, op0_high,
750                                       op0_xhigh, op0_xhigh, 0, OPTAB_DIRECT);
751           else
752             {
753               op0_xhigh = expand_binop (word_mode, ashr_optab, op0_low, wordm1,
754                                         NULL_RTX, 0, OPTAB_DIRECT);
755               if (op0_xhigh)
756                 op0_xhigh = expand_binop (word_mode, sub_optab, op0_high,
757                                           op0_xhigh, op0_xhigh, 0,
758                                           OPTAB_DIRECT);
759             }
760
761           op1_xhigh = expand_binop (word_mode, lshr_optab, op1_low, wordm1,
762                                     NULL_RTX, 1, OPTAB_DIRECT);
763           if (op1_xhigh)
764             op1_xhigh = expand_binop (word_mode, add_optab, op1_high,
765                                       op1_xhigh, op1_xhigh, 0, OPTAB_DIRECT);
766           else
767             {
768               op1_xhigh = expand_binop (word_mode, ashr_optab, op1_low, wordm1,
769                                         NULL_RTX, 0, OPTAB_DIRECT);
770               if (op1_xhigh)
771                 op1_xhigh = expand_binop (word_mode, sub_optab, op1_high,
772                                           op1_xhigh, op1_xhigh, 0,
773                                           OPTAB_DIRECT);
774             }
775         }
776
777       /* If we have been able to directly compute the product of the
778          low-order words of the operands and perform any required adjustments
779          of the operands, we proceed by trying two more multiplications
780          and then computing the appropriate sum.
781
782          We have checked above that the required addition is provided.
783          Full-word addition will normally always succeed, especially if
784          it is provided at all, so we don't worry about its failure.  The
785          multiplication may well fail, however, so we do handle that.  */
786
787       if (product && op0_xhigh && op1_xhigh)
788         {
789           rtx product_piece;
790           rtx product_high = operand_subword (product, high, 1, mode);
791           rtx temp = expand_binop (word_mode, binoptab, op0_low, op1_xhigh,
792                                    NULL_RTX, 0, OPTAB_DIRECT);
793
794           if (temp)
795             {
796               product_piece = expand_binop (word_mode, add_optab, temp,
797                                             product_high, product_high,
798                                             0, OPTAB_LIB_WIDEN);
799               if (product_piece != product_high)
800                 emit_move_insn (product_high, product_piece);
801
802               temp = expand_binop (word_mode, binoptab, op1_low, op0_xhigh, 
803                                    NULL_RTX, 0, OPTAB_DIRECT);
804
805               product_piece = expand_binop (word_mode, add_optab, temp,
806                                             product_high, product_high,
807                                             0, OPTAB_LIB_WIDEN);
808               if (product_piece != product_high)
809                 emit_move_insn (product_high, product_piece);
810
811               temp = emit_move_insn (product, product);
812               REG_NOTES (temp) = gen_rtx (EXPR_LIST, REG_EQUAL,
813                                           gen_rtx (MULT, mode, op0, op1),
814                                           REG_NOTES (temp));
815
816               return product;
817             }
818         }
819
820       /* If we get here, we couldn't do it for some reason even though we
821          originally thought we could.  Delete anything we've emitted in
822          trying to do it.  */
823
824       delete_insns_since (last);
825     }
826
827   /* It can't be open-coded in this mode.
828      Use a library call if one is available and caller says that's ok.  */
829
830   if (binoptab->handlers[(int) mode].libfunc
831       && (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN))
832     {
833       rtx insns;
834       rtx funexp = binoptab->handlers[(int) mode].libfunc;
835
836       start_sequence ();
837
838       /* Pass 1 for NO_QUEUE so we don't lose any increments
839          if the libcall is cse'd or moved.  */
840       emit_library_call (binoptab->handlers[(int) mode].libfunc,
841                          1, mode, 2, op0, mode, op1,
842                          (shift_op ? word_mode : mode));
843
844       insns = get_insns ();
845       end_sequence ();
846
847       target = gen_reg_rtx (mode);
848       emit_libcall_block (insns, target, hard_libcall_value (mode),
849                           gen_rtx (binoptab->code, mode, op0, op1));
850
851       return target;
852     }
853
854   delete_insns_since (last);
855
856   /* It can't be done in this mode.  Can we do it in a wider mode?  */
857
858   if (! (methods == OPTAB_WIDEN || methods == OPTAB_LIB_WIDEN
859          || methods == OPTAB_MUST_WIDEN))
860     return 0;                   /* Caller says, don't even try.  */
861
862   /* Compute the value of METHODS to pass to recursive calls.
863      Don't allow widening to be tried recursively.  */
864
865   methods = (methods == OPTAB_LIB_WIDEN ? OPTAB_LIB : OPTAB_DIRECT);
866
867   /* Look for a wider mode of the same class for which it appears we can do
868      the operation.  */
869
870   if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
871     {
872       for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
873            wider_mode = GET_MODE_WIDER_MODE (wider_mode))
874         {
875           if ((binoptab->handlers[(int) wider_mode].insn_code
876                != CODE_FOR_nothing)
877               || (methods == OPTAB_LIB
878                   && binoptab->handlers[(int) wider_mode].libfunc))
879             {
880               rtx xop0 = op0, xop1 = op1;
881               int no_extend = 0;
882
883               /* For certain integer operations, we need not actually extend
884                  the narrow operands, as long as we will truncate
885                  the results to the same narrowness.  Don't do this when
886                  WIDER_MODE is wider than a word since a paradoxical SUBREG
887                  isn't valid for such modes.  */
888
889               if ((binoptab == ior_optab || binoptab == and_optab
890                    || binoptab == xor_optab
891                    || binoptab == add_optab || binoptab == sub_optab
892                    || binoptab == smul_optab
893                    || binoptab == ashl_optab || binoptab == lshl_optab)
894                   && class == MODE_INT
895                   && GET_MODE_SIZE (wider_mode) <= UNITS_PER_WORD)
896                 no_extend = 1;
897
898               /* If an operand is a constant integer, we might as well
899                  convert it since that is more efficient than using a SUBREG,
900                  unlike the case for other operands.  */
901
902               if (no_extend && GET_MODE (xop0) != VOIDmode)
903                 xop0 = gen_rtx (SUBREG, wider_mode,
904                                 force_reg (GET_MODE (xop0), xop0), 0);
905               else
906                 xop0 = convert_to_mode (wider_mode, xop0, unsignedp);
907
908               if (no_extend && GET_MODE (xop1) != VOIDmode)
909                 xop1 = gen_rtx (SUBREG, wider_mode,
910                                 force_reg (GET_MODE (xop1), xop1), 0);
911               else
912                 xop1 = convert_to_mode (wider_mode, xop1, unsignedp);
913
914               temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
915                                    unsignedp, methods);
916               if (temp)
917                 {
918                   if (class != MODE_INT)
919                     {
920                       if (target == 0)
921                         target = gen_reg_rtx (mode);
922                       convert_move (target, temp, 0);
923                       return target;
924                     }
925                   else
926                     return gen_lowpart (mode, temp);
927                 }
928               else
929                 delete_insns_since (last);
930             }
931         }
932     }
933
934   return 0;
935 }
936 \f
937 /* Expand a binary operator which has both signed and unsigned forms.
938    UOPTAB is the optab for unsigned operations, and SOPTAB is for
939    signed operations.
940
941    If we widen unsigned operands, we may use a signed wider operation instead
942    of an unsigned wider operation, since the result would be the same.  */
943
944 rtx
945 sign_expand_binop (mode, uoptab, soptab, op0, op1, target, unsignedp, methods)
946     enum machine_mode mode;
947     optab uoptab, soptab;
948     rtx op0, op1, target;
949     int unsignedp;
950     enum optab_methods methods;
951 {
952   register rtx temp;
953   optab direct_optab = unsignedp ? uoptab : soptab;
954   struct optab wide_soptab;
955
956   /* Do it without widening, if possible.  */
957   temp = expand_binop (mode, direct_optab, op0, op1, target,
958                        unsignedp, OPTAB_DIRECT);
959   if (temp || methods == OPTAB_DIRECT)
960     return temp;
961
962   /* Try widening to a signed int.  Make a fake signed optab that
963      hides any signed insn for direct use.  */
964   wide_soptab = *soptab;
965   wide_soptab.handlers[(int) mode].insn_code = CODE_FOR_nothing;
966   wide_soptab.handlers[(int) mode].libfunc = 0;
967
968   temp = expand_binop (mode, &wide_soptab, op0, op1, target,
969                        unsignedp, OPTAB_WIDEN);
970
971   /* For unsigned operands, try widening to an unsigned int.  */
972   if (temp == 0 && unsignedp)
973     temp = expand_binop (mode, uoptab, op0, op1, target,
974                          unsignedp, OPTAB_WIDEN);
975   if (temp || methods == OPTAB_WIDEN)
976     return temp;
977
978   /* Use the right width lib call if that exists.  */
979   temp = expand_binop (mode, direct_optab, op0, op1, target, unsignedp, OPTAB_LIB);
980   if (temp || methods == OPTAB_LIB)
981     return temp;
982
983   /* Must widen and use a lib call, use either signed or unsigned.  */
984   temp = expand_binop (mode, &wide_soptab, op0, op1, target,
985                        unsignedp, methods);
986   if (temp != 0)
987     return temp;
988   if (unsignedp)
989     return expand_binop (mode, uoptab, op0, op1, target,
990                          unsignedp, methods);
991   return 0;
992 }
993 \f
994 /* Generate code to perform an operation specified by BINOPTAB
995    on operands OP0 and OP1, with two results to TARG1 and TARG2.
996    We assume that the order of the operands for the instruction
997    is TARG0, OP0, OP1, TARG1, which would fit a pattern like
998    [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
999
1000    Either TARG0 or TARG1 may be zero, but what that means is that
1001    that result is not actually wanted.  We will generate it into
1002    a dummy pseudo-reg and discard it.  They may not both be zero.
1003
1004    Returns 1 if this operation can be performed; 0 if not.  */
1005
1006 int
1007 expand_twoval_binop (binoptab, op0, op1, targ0, targ1, unsignedp)
1008      optab binoptab;
1009      rtx op0, op1;
1010      rtx targ0, targ1;
1011      int unsignedp;
1012 {
1013   enum machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
1014   enum mode_class class;
1015   enum machine_mode wider_mode;
1016   rtx last;
1017
1018   class = GET_MODE_CLASS (mode);
1019
1020   op0 = protect_from_queue (op0, 0);
1021   op1 = protect_from_queue (op1, 0);
1022
1023   if (flag_force_mem)
1024     {
1025       op0 = force_not_mem (op0);
1026       op1 = force_not_mem (op1);
1027     }
1028
1029   /* If we are inside an appropriately-short loop and one operand is an
1030      expensive constant, force it into a register.  */
1031   if (CONSTANT_P (op0) && preserve_subexpressions_p ()
1032       && rtx_cost (op0, binoptab->code) > 2)
1033     op0 = force_reg (mode, op0);
1034
1035   if (CONSTANT_P (op1) && preserve_subexpressions_p ()
1036       && rtx_cost (op1, binoptab->code) > 2)
1037     op1 = force_reg (mode, op1);
1038
1039   if (targ0)
1040     targ0 = protect_from_queue (targ0, 1);
1041   else
1042     targ0 = gen_reg_rtx (mode);
1043   if (targ1)
1044     targ1 = protect_from_queue (targ1, 1);
1045   else
1046     targ1 = gen_reg_rtx (mode);
1047
1048   /* Record where to go back to if we fail.  */
1049   last = get_last_insn ();
1050
1051   if (binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1052     {
1053       int icode = (int) binoptab->handlers[(int) mode].insn_code;
1054       enum machine_mode mode0 = insn_operand_mode[icode][1];
1055       enum machine_mode mode1 = insn_operand_mode[icode][2];
1056       rtx pat;
1057       rtx xop0 = op0, xop1 = op1;
1058
1059       /* In case this insn wants input operands in modes different from the
1060          result, convert the operands.  */
1061       if (GET_MODE (op0) != VOIDmode && GET_MODE (op0) != mode0)
1062         xop0 = convert_to_mode (mode0, xop0, unsignedp);
1063
1064       if (GET_MODE (op1) != VOIDmode && GET_MODE (op1) != mode1)
1065         xop1 = convert_to_mode (mode1, xop1, unsignedp);
1066
1067       /* Now, if insn doesn't accept these operands, put them into pseudos.  */
1068       if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
1069         xop0 = copy_to_mode_reg (mode0, xop0);
1070
1071       if (! (*insn_operand_predicate[icode][2]) (xop1, mode1))
1072         xop1 = copy_to_mode_reg (mode1, xop1);
1073
1074       /* We could handle this, but we should always be called with a pseudo
1075          for our targets and all insns should take them as outputs.  */
1076       if (! (*insn_operand_predicate[icode][0]) (targ0, mode)
1077           || ! (*insn_operand_predicate[icode][3]) (targ1, mode))
1078         abort ();
1079         
1080       pat = GEN_FCN (icode) (targ0, xop0, xop1, targ1);
1081       if (pat)
1082         {
1083           emit_insn (pat);
1084           return 1;
1085         }
1086       else
1087         delete_insns_since (last);
1088     }
1089
1090   /* It can't be done in this mode.  Can we do it in a wider mode?  */
1091
1092   if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1093     {
1094       for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1095            wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1096         {
1097           if (binoptab->handlers[(int) wider_mode].insn_code
1098               != CODE_FOR_nothing)
1099             {
1100               register rtx t0 = gen_reg_rtx (wider_mode);
1101               register rtx t1 = gen_reg_rtx (wider_mode);
1102
1103               if (expand_twoval_binop (binoptab,
1104                                        convert_to_mode (wider_mode, op0,
1105                                                         unsignedp),
1106                                        convert_to_mode (wider_mode, op1,
1107                                                         unsignedp),
1108                                        t0, t1, unsignedp))
1109                 {
1110                   convert_move (targ0, t0, unsignedp);
1111                   convert_move (targ1, t1, unsignedp);
1112                   return 1;
1113                 }
1114               else
1115                 delete_insns_since (last);
1116             }
1117         }
1118     }
1119
1120   return 0;
1121 }
1122 \f
1123 /* Generate code to perform an operation specified by UNOPTAB
1124    on operand OP0, with result having machine-mode MODE.
1125
1126    UNSIGNEDP is for the case where we have to widen the operands
1127    to perform the operation.  It says to use zero-extension.
1128
1129    If TARGET is nonzero, the value
1130    is generated there, if it is convenient to do so.
1131    In all cases an rtx is returned for the locus of the value;
1132    this may or may not be TARGET.  */
1133
1134 rtx
1135 expand_unop (mode, unoptab, op0, target, unsignedp)
1136      enum machine_mode mode;
1137      optab unoptab;
1138      rtx op0;
1139      rtx target;
1140      int unsignedp;
1141 {
1142   enum mode_class class;
1143   enum machine_mode wider_mode;
1144   register rtx temp;
1145   rtx last = get_last_insn ();
1146   rtx pat;
1147
1148   class = GET_MODE_CLASS (mode);
1149
1150   op0 = protect_from_queue (op0, 0);
1151
1152   if (flag_force_mem)
1153     {
1154       op0 = force_not_mem (op0);
1155     }
1156
1157   if (target)
1158     target = protect_from_queue (target, 1);
1159
1160   if (unoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1161     {
1162       int icode = (int) unoptab->handlers[(int) mode].insn_code;
1163       enum machine_mode mode0 = insn_operand_mode[icode][1];
1164       rtx xop0 = op0;
1165
1166       if (target)
1167         temp = target;
1168       else
1169         temp = gen_reg_rtx (mode);
1170
1171       if (GET_MODE (xop0) != VOIDmode
1172           && GET_MODE (xop0) != mode0)
1173         xop0 = convert_to_mode (mode0, xop0, unsignedp);
1174
1175       /* Now, if insn doesn't accept our operand, put it into a pseudo.  */
1176
1177       if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
1178         xop0 = copy_to_mode_reg (mode0, xop0);
1179
1180       if (! (*insn_operand_predicate[icode][0]) (temp, mode))
1181         temp = gen_reg_rtx (mode);
1182
1183       pat = GEN_FCN (icode) (temp, xop0);
1184       if (pat)
1185         {
1186           if (GET_CODE (pat) == SEQUENCE
1187               && ! add_equal_note (pat, temp, unoptab->code, xop0, NULL_RTX))
1188             {
1189               delete_insns_since (last);
1190               return expand_unop (mode, unoptab, op0, NULL_RTX, unsignedp);
1191             }
1192
1193           emit_insn (pat);
1194           
1195           return temp;
1196         }
1197       else
1198         delete_insns_since (last);
1199     }
1200
1201   /* It can't be done in this mode.  Can we open-code it in a wider mode?  */
1202
1203   if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1204     for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1205          wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1206       {
1207         if (unoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing)
1208           {
1209             rtx xop0 = op0;
1210
1211             /* For certain operations, we need not actually extend
1212                the narrow operand, as long as we will truncate the
1213                results to the same narrowness.  */
1214
1215             if ((unoptab == neg_optab || unoptab == one_cmpl_optab)
1216                 && GET_MODE_SIZE (wider_mode) <= UNITS_PER_WORD
1217                 && class == MODE_INT)
1218               xop0 = gen_rtx (SUBREG, wider_mode, force_reg (mode, xop0), 0);
1219             else
1220               xop0 = convert_to_mode (wider_mode, xop0, unsignedp);
1221               
1222             temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
1223                                 unsignedp);
1224
1225             if (temp)
1226               {
1227                 if (class != MODE_INT)
1228                   {
1229                     if (target == 0)
1230                       target = gen_reg_rtx (mode);
1231                     convert_move (target, temp, 0);
1232                     return target;
1233                   }
1234                 else
1235                   return gen_lowpart (mode, temp);
1236               }
1237             else
1238               delete_insns_since (last);
1239           }
1240       }
1241
1242   /* These can be done a word at a time.  */
1243   if (unoptab == one_cmpl_optab
1244       && class == MODE_INT
1245       && GET_MODE_SIZE (mode) > UNITS_PER_WORD
1246       && unoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
1247     {
1248       int i;
1249       rtx insns;
1250
1251       if (target == 0 || target == op0)
1252         target = gen_reg_rtx (mode);
1253
1254       start_sequence ();
1255
1256       /* Do the actual arithmetic.  */
1257       for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
1258         {
1259           rtx target_piece = operand_subword (target, i, 1, mode);
1260           rtx x = expand_unop (word_mode, unoptab,
1261                                operand_subword_force (op0, i, mode),
1262                                target_piece, unsignedp);
1263           if (target_piece != x)
1264             emit_move_insn (target_piece, x);
1265         }
1266
1267       insns = get_insns ();
1268       end_sequence ();
1269
1270       emit_no_conflict_block (insns, target, op0, NULL_RTX,
1271                               gen_rtx (unoptab->code, mode, op0));
1272       return target;
1273     }
1274
1275   if (unoptab->handlers[(int) mode].libfunc)
1276     {
1277       rtx insns;
1278       rtx funexp = unoptab->handlers[(int) mode].libfunc;
1279
1280       start_sequence ();
1281
1282       /* Pass 1 for NO_QUEUE so we don't lose any increments
1283          if the libcall is cse'd or moved.  */
1284       emit_library_call (unoptab->handlers[(int) mode].libfunc,
1285                          1, mode, 1, op0, mode);
1286       insns = get_insns ();
1287       end_sequence ();
1288
1289       target = gen_reg_rtx (mode);
1290       emit_libcall_block (insns, target, hard_libcall_value (mode),
1291                           gen_rtx (unoptab->code, mode, op0));
1292
1293       return target;
1294     }
1295
1296   /* It can't be done in this mode.  Can we do it in a wider mode?  */
1297
1298   if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1299     {
1300       for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1301            wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1302         {
1303           if ((unoptab->handlers[(int) wider_mode].insn_code
1304                != CODE_FOR_nothing)
1305               || unoptab->handlers[(int) wider_mode].libfunc)
1306             {
1307               rtx xop0 = op0;
1308
1309               /* For certain operations, we need not actually extend
1310                  the narrow operand, as long as we will truncate the
1311                  results to the same narrowness.  */
1312
1313               if ((unoptab == neg_optab || unoptab == one_cmpl_optab)
1314                   && GET_MODE_SIZE (wider_mode) <= UNITS_PER_WORD
1315                   && class == MODE_INT)
1316                 xop0 = gen_rtx (SUBREG, wider_mode, force_reg (mode, xop0), 0);
1317               else
1318                 xop0 = convert_to_mode (wider_mode, xop0, unsignedp);
1319               
1320               temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
1321                                   unsignedp);
1322
1323               if (temp)
1324                 {
1325                   if (class != MODE_INT)
1326                     {
1327                       if (target == 0)
1328                         target = gen_reg_rtx (mode);
1329                       convert_move (target, temp, 0);
1330                       return target;
1331                     }
1332                   else
1333                     return gen_lowpart (mode, temp);
1334                 }
1335               else
1336                 delete_insns_since (last);
1337             }
1338         }
1339     }
1340
1341   return 0;
1342 }
1343 \f
1344 /* Generate an instruction whose insn-code is INSN_CODE,
1345    with two operands: an output TARGET and an input OP0.
1346    TARGET *must* be nonzero, and the output is always stored there.
1347    CODE is an rtx code such that (CODE OP0) is an rtx that describes
1348    the value that is stored into TARGET.  */
1349
1350 void
1351 emit_unop_insn (icode, target, op0, code)
1352      int icode;
1353      rtx target;
1354      rtx op0;
1355      enum rtx_code code;
1356 {
1357   register rtx temp;
1358   enum machine_mode mode0 = insn_operand_mode[icode][1];
1359   rtx pat;
1360
1361   temp = target = protect_from_queue (target, 1);
1362
1363   op0 = protect_from_queue (op0, 0);
1364
1365   if (flag_force_mem)
1366     op0 = force_not_mem (op0);
1367
1368   /* Now, if insn does not accept our operands, put them into pseudos.  */
1369
1370   if (! (*insn_operand_predicate[icode][1]) (op0, mode0))
1371     op0 = copy_to_mode_reg (mode0, op0);
1372
1373   if (! (*insn_operand_predicate[icode][0]) (temp, GET_MODE (temp))
1374       || (flag_force_mem && GET_CODE (temp) == MEM))
1375     temp = gen_reg_rtx (GET_MODE (temp));
1376
1377   pat = GEN_FCN (icode) (temp, op0);
1378
1379   if (GET_CODE (pat) == SEQUENCE && code != UNKNOWN)
1380     add_equal_note (pat, temp, code, op0, NULL_RTX);
1381   
1382   emit_insn (pat);
1383
1384   if (temp != target)
1385     emit_move_insn (target, temp);
1386 }
1387 \f
1388 /* Emit code to perform a series of operations on a multi-word quantity, one
1389    word at a time.
1390
1391    Such a block is preceded by a CLOBBER of the output, consists of multiple
1392    insns, each setting one word of the output, and followed by a SET copying
1393    the output to itself.
1394
1395    Each of the insns setting words of the output receives a REG_NO_CONFLICT
1396    note indicating that it doesn't conflict with the (also multi-word)
1397    inputs.  The entire block is surrounded by REG_LIBCALL and REG_RETVAL
1398    notes.
1399
1400    INSNS is a block of code generated to perform the operation, not including
1401    the CLOBBER and final copy.  All insns that compute intermediate values
1402    are first emitted, followed by the block as described above.  Only
1403    INSNs are allowed in the block; no library calls or jumps may be
1404    present.
1405
1406    TARGET, OP0, and OP1 are the output and inputs of the operations,
1407    respectively.  OP1 may be zero for a unary operation.
1408
1409    EQUIV, if non-zero, is an expression to be placed into a REG_EQUAL note
1410    on the last insn.
1411
1412    If TARGET is not a register, INSNS is simply emitted with no special
1413    processing.
1414
1415    The final insn emitted is returned.  */
1416
1417 rtx
1418 emit_no_conflict_block (insns, target, op0, op1, equiv)
1419      rtx insns;
1420      rtx target;
1421      rtx op0, op1;
1422      rtx equiv;
1423 {
1424   rtx prev, next, first, last, insn;
1425
1426   if (GET_CODE (target) != REG || reload_in_progress)
1427     return emit_insns (insns);
1428
1429   /* First emit all insns that do not store into words of the output and remove
1430      these from the list.  */
1431   for (insn = insns; insn; insn = next)
1432     {
1433       rtx set = 0;
1434       int i;
1435
1436       next = NEXT_INSN (insn);
1437
1438       if (GET_CODE (insn) != INSN)
1439         abort ();
1440
1441       if (GET_CODE (PATTERN (insn)) == SET)
1442         set = PATTERN (insn);
1443       else if (GET_CODE (PATTERN (insn)) == PARALLEL)
1444         {
1445           for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
1446             if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET)
1447               {
1448                 set = XVECEXP (PATTERN (insn), 0, i);
1449                 break;
1450               }
1451         }
1452
1453       if (set == 0)
1454         abort ();
1455
1456       if (! reg_overlap_mentioned_p (target, SET_DEST (set)))
1457         {
1458           if (PREV_INSN (insn))
1459             NEXT_INSN (PREV_INSN (insn)) = next;
1460           else
1461             insns = next;
1462
1463           if (next)
1464             PREV_INSN (next) = PREV_INSN (insn);
1465
1466           add_insn (insn);
1467         }
1468     }
1469
1470   prev = get_last_insn ();
1471
1472   /* Now write the CLOBBER of the output, followed by the setting of each
1473      of the words, followed by the final copy.  */
1474   if (target != op0 && target != op1)
1475     emit_insn (gen_rtx (CLOBBER, VOIDmode, target));
1476
1477   for (insn = insns; insn; insn = next)
1478     {
1479       next = NEXT_INSN (insn);
1480       add_insn (insn);
1481
1482       if (op1 && GET_CODE (op1) == REG)
1483         REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_NO_CONFLICT, op1,
1484                                     REG_NOTES (insn));
1485
1486       if (op0 && GET_CODE (op0) == REG)
1487         REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_NO_CONFLICT, op0,
1488                                     REG_NOTES (insn));
1489     }
1490
1491   last = emit_move_insn (target, target);
1492   if (equiv)
1493     REG_NOTES (last) = gen_rtx (EXPR_LIST, REG_EQUAL, equiv, REG_NOTES (last));
1494
1495   if (prev == 0)
1496     first = get_insns ();
1497   else
1498     first = NEXT_INSN (prev);
1499
1500   /* Encapsulate the block so it gets manipulated as a unit.  */
1501   REG_NOTES (first) = gen_rtx (INSN_LIST, REG_LIBCALL, last,
1502                                REG_NOTES (first));
1503   REG_NOTES (last) = gen_rtx (INSN_LIST, REG_RETVAL, first, REG_NOTES (last));
1504
1505   return last;
1506 }
1507 \f
1508 /* Emit code to make a call to a constant function or a library call.
1509
1510    INSNS is a list containing all insns emitted in the call.
1511    These insns leave the result in RESULT.  Our block is to copy RESULT
1512    to TARGET, which is logically equivalent to EQUIV.
1513
1514    We first emit any insns that set a pseudo on the assumption that these are
1515    loading constants into registers; doing so allows them to be safely cse'ed
1516    between blocks.  Then we emit all the other insns in the block, followed by
1517    an insn to move RESULT to TARGET.  This last insn will have a REQ_EQUAL
1518    note with an operand of EQUIV.
1519
1520    Moving assignments to pseudos outside of the block is done to improve
1521    the generated code, but is not required to generate correct code,
1522    hence being unable to move an assignment is not grounds for not making
1523    a libcall block.  There are two reasons why it is safe to leave these
1524    insns inside the block: First, we know that these pseudos cannot be
1525    used in generated RTL outside the block since they are created for
1526    temporary purposes within the block.  Second, CSE will not record the
1527    values of anything set inside a libcall block, so we know they must
1528    be dead at the end of the block.
1529
1530    Except for the first group of insns (the ones setting pseudos), the
1531    block is delimited by REG_RETVAL and REG_LIBCALL notes.  */
1532
1533 void
1534 emit_libcall_block (insns, target, result, equiv)
1535      rtx insns;
1536      rtx target;
1537      rtx result;
1538      rtx equiv;
1539 {
1540   rtx prev, next, first, last, insn;
1541
1542   /* First emit all insns that set pseudos.  Remove them from the list as
1543      we go.  Avoid insns that set pseudo which were referenced in previous
1544      insns.  These can be generated by move_by_pieces, for example,
1545      to update an address.  */
1546
1547   for (insn = insns; insn; insn = next)
1548     {
1549       rtx set = single_set (insn);
1550
1551       next = NEXT_INSN (insn);
1552
1553       if (set != 0 && GET_CODE (SET_DEST (set)) == REG
1554           && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER
1555           && (insn == insns
1556               || (! reg_mentioned_p (SET_DEST (set), PATTERN (insns))
1557                   && ! reg_used_between_p (SET_DEST (set), insns, insn))))
1558         {
1559           if (PREV_INSN (insn))
1560             NEXT_INSN (PREV_INSN (insn)) = next;
1561           else
1562             insns = next;
1563
1564           if (next)
1565             PREV_INSN (next) = PREV_INSN (insn);
1566
1567           add_insn (insn);
1568         }
1569     }
1570
1571   prev = get_last_insn ();
1572
1573   /* Write the remaining insns followed by the final copy.  */
1574
1575   for (insn = insns; insn; insn = next)
1576     {
1577       next = NEXT_INSN (insn);
1578
1579       add_insn (insn);
1580     }
1581
1582   last = emit_move_insn (target, result);
1583   REG_NOTES (last) = gen_rtx (EXPR_LIST, REG_EQUAL, equiv, REG_NOTES (last));
1584
1585   if (prev == 0)
1586     first = get_insns ();
1587   else
1588     first = NEXT_INSN (prev);
1589
1590   /* Encapsulate the block so it gets manipulated as a unit.  */
1591   REG_NOTES (first) = gen_rtx (INSN_LIST, REG_LIBCALL, last,
1592                                REG_NOTES (first));
1593   REG_NOTES (last) = gen_rtx (INSN_LIST, REG_RETVAL, first, REG_NOTES (last));
1594 }
1595 \f
1596 /* Generate code to store zero in X.  */
1597
1598 void
1599 emit_clr_insn (x)
1600      rtx x;
1601 {
1602   emit_move_insn (x, const0_rtx);
1603 }
1604
1605 /* Generate code to store 1 in X
1606    assuming it contains zero beforehand.  */
1607
1608 void
1609 emit_0_to_1_insn (x)
1610      rtx x;
1611 {
1612   emit_move_insn (x, const1_rtx);
1613 }
1614
1615 /* Generate code to compare X with Y
1616    so that the condition codes are set.
1617
1618    MODE is the mode of the inputs (in case they are const_int).
1619    UNSIGNEDP nonzero says that X and Y are unsigned;
1620    this matters if they need to be widened.
1621
1622    If they have mode BLKmode, then SIZE specifies the size of both X and Y,
1623    and ALIGN specifies the known shared alignment of X and Y.
1624
1625    COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).
1626    It is ignored for fixed-point and block comparisons;
1627    it is used only for floating-point comparisons.  */
1628
1629 void
1630 emit_cmp_insn (x, y, comparison, size, mode, unsignedp, align)
1631      rtx x, y;
1632      enum rtx_code comparison;
1633      rtx size;
1634      enum machine_mode mode;
1635      int unsignedp;
1636      int align;
1637 {
1638   enum mode_class class;
1639   enum machine_mode wider_mode;
1640
1641   class = GET_MODE_CLASS (mode);
1642
1643   /* They could both be VOIDmode if both args are immediate constants,
1644      but we should fold that at an earlier stage.
1645      With no special code here, this will call abort,
1646      reminding the programmer to implement such folding.  */
1647
1648   if (mode != BLKmode && flag_force_mem)
1649     {
1650       x = force_not_mem (x);
1651       y = force_not_mem (y);
1652     }
1653
1654   /* If we are inside an appropriately-short loop and one operand is an
1655      expensive constant, force it into a register.  */
1656   if (CONSTANT_P (x) && preserve_subexpressions_p () && rtx_cost (x, COMPARE) > 2)
1657     x = force_reg (mode, x);
1658
1659   if (CONSTANT_P (y) && preserve_subexpressions_p () && rtx_cost (y, COMPARE) > 2)
1660     y = force_reg (mode, y);
1661
1662   /* Don't let both operands fail to indicate the mode.  */
1663   if (GET_MODE (x) == VOIDmode && GET_MODE (y) == VOIDmode)
1664     x = force_reg (mode, x);
1665
1666   /* Handle all BLKmode compares.  */
1667
1668   if (mode == BLKmode)
1669     {
1670       emit_queue ();
1671       x = protect_from_queue (x, 0);
1672       y = protect_from_queue (y, 0);
1673
1674       if (size == 0)
1675         abort ();
1676 #ifdef HAVE_cmpstrqi
1677       if (HAVE_cmpstrqi
1678           && GET_CODE (size) == CONST_INT
1679           && INTVAL (size) < (1 << GET_MODE_BITSIZE (QImode)))
1680         {
1681           enum machine_mode result_mode
1682             = insn_operand_mode[(int) CODE_FOR_cmpstrqi][0];
1683           rtx result = gen_reg_rtx (result_mode);
1684           emit_insn (gen_cmpstrqi (result, x, y, size, GEN_INT (align)));
1685           emit_cmp_insn (result, const0_rtx, comparison, NULL_RTX,
1686                          result_mode, 0, 0);
1687         }
1688       else
1689 #endif
1690 #ifdef HAVE_cmpstrhi
1691       if (HAVE_cmpstrhi
1692           && GET_CODE (size) == CONST_INT
1693           && INTVAL (size) < (1 << GET_MODE_BITSIZE (HImode)))
1694         {
1695           enum machine_mode result_mode
1696             = insn_operand_mode[(int) CODE_FOR_cmpstrhi][0];
1697           rtx result = gen_reg_rtx (result_mode);
1698           emit_insn (gen_cmpstrhi (result, x, y, size, GEN_INT (align)));
1699           emit_cmp_insn (result, const0_rtx, comparison, NULL_RTX,
1700                          result_mode, 0, 0);
1701         }
1702       else
1703 #endif
1704 #ifdef HAVE_cmpstrsi
1705       if (HAVE_cmpstrsi)
1706         {
1707           enum machine_mode result_mode
1708             = insn_operand_mode[(int) CODE_FOR_cmpstrsi][0];
1709           rtx result = gen_reg_rtx (result_mode);
1710           size = protect_from_queue (size, 0);
1711           emit_insn (gen_cmpstrsi (result, x, y,
1712                                    convert_to_mode (SImode, size, 1),
1713                                    GEN_INT (align)));
1714           emit_cmp_insn (result, const0_rtx, comparison, NULL_RTX,
1715                          result_mode, 0, 0);
1716         }
1717       else
1718 #endif
1719         {
1720 #ifdef TARGET_MEM_FUNCTIONS
1721           emit_library_call (memcmp_libfunc, 0,
1722                              TYPE_MODE (integer_type_node), 3,
1723                              XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
1724                              size, Pmode);
1725 #else
1726           emit_library_call (bcmp_libfunc, 0,
1727                              TYPE_MODE (integer_type_node), 3,
1728                              XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
1729                              size, Pmode);
1730 #endif
1731           emit_cmp_insn (hard_libcall_value (TYPE_MODE (integer_type_node)),
1732                          const0_rtx, comparison, NULL_RTX,
1733                          TYPE_MODE (integer_type_node), 0, 0);
1734         }
1735       return;
1736     }
1737
1738   /* Handle some compares against zero.  */
1739
1740   if (y == CONST0_RTX (mode)
1741       && tst_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1742     {
1743       int icode = (int) tst_optab->handlers[(int) mode].insn_code;
1744
1745       emit_queue ();
1746       x = protect_from_queue (x, 0);
1747       y = protect_from_queue (y, 0);
1748
1749       /* Now, if insn does accept these operands, put them into pseudos.  */
1750       if (! (*insn_operand_predicate[icode][0])
1751           (x, insn_operand_mode[icode][0]))
1752         x = copy_to_mode_reg (insn_operand_mode[icode][0], x);
1753
1754       emit_insn (GEN_FCN (icode) (x));
1755       return;
1756     }
1757
1758   /* Handle compares for which there is a directly suitable insn.  */
1759
1760   if (cmp_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1761     {
1762       int icode = (int) cmp_optab->handlers[(int) mode].insn_code;
1763
1764       emit_queue ();
1765       x = protect_from_queue (x, 0);
1766       y = protect_from_queue (y, 0);
1767
1768       /* Now, if insn doesn't accept these operands, put them into pseudos.  */
1769       if (! (*insn_operand_predicate[icode][0])
1770           (x, insn_operand_mode[icode][0]))
1771         x = copy_to_mode_reg (insn_operand_mode[icode][0], x);
1772
1773       if (! (*insn_operand_predicate[icode][1])
1774           (y, insn_operand_mode[icode][1]))
1775         y = copy_to_mode_reg (insn_operand_mode[icode][1], y);
1776
1777       emit_insn (GEN_FCN (icode) (x, y));
1778       return;
1779     }
1780
1781   /* Try widening if we can find a direct insn that way.  */
1782
1783   if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1784     {
1785       for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1786            wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1787         {
1788           if (cmp_optab->handlers[(int) wider_mode].insn_code
1789               != CODE_FOR_nothing)
1790             {
1791               x = protect_from_queue (x, 0);
1792               y = protect_from_queue (y, 0);
1793               x = convert_to_mode (wider_mode, x, unsignedp);
1794               y = convert_to_mode (wider_mode, y, unsignedp);
1795               emit_cmp_insn (x, y, comparison, NULL_RTX,
1796                              wider_mode, unsignedp, align);
1797               return;
1798             }
1799         }
1800     }
1801
1802   /* Handle a lib call just for the mode we are using.  */
1803
1804   if (cmp_optab->handlers[(int) mode].libfunc
1805       && class != MODE_FLOAT)
1806     {
1807       rtx libfunc = cmp_optab->handlers[(int) mode].libfunc;
1808       /* If we want unsigned, and this mode has a distinct unsigned
1809          comparison routine, use that.  */
1810       if (unsignedp && ucmp_optab->handlers[(int) mode].libfunc)
1811         libfunc = ucmp_optab->handlers[(int) mode].libfunc;
1812
1813       emit_library_call (libfunc, 1,
1814                          SImode, 2, x, mode, y, mode);
1815
1816       /* Integer comparison returns a result that must be compared against 1,
1817          so that even if we do an unsigned compare afterward,
1818          there is still a value that can represent the result "less than".  */
1819
1820       emit_cmp_insn (hard_libcall_value (SImode), const1_rtx,
1821                      comparison, NULL_RTX, SImode, unsignedp, 0);
1822       return;
1823     }
1824
1825   if (class == MODE_FLOAT)
1826     emit_float_lib_cmp (x, y, comparison);
1827
1828   else
1829     abort ();
1830 }
1831
1832 /* Nonzero if a compare of mode MODE can be done straightforwardly
1833    (without splitting it into pieces).  */
1834
1835 int
1836 can_compare_p (mode)
1837      enum machine_mode mode;
1838 {
1839   do
1840     {
1841       if (cmp_optab->handlers[(int)mode].insn_code != CODE_FOR_nothing)
1842         return 1;
1843       mode = GET_MODE_WIDER_MODE (mode);
1844     } while (mode != VOIDmode);
1845
1846   return 0;
1847 }
1848 \f
1849 /* Emit a library call comparison between floating point X and Y.
1850    COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).  */
1851
1852 static void
1853 emit_float_lib_cmp (x, y, comparison)
1854      rtx x, y;
1855      enum rtx_code comparison;
1856 {
1857   enum machine_mode mode = GET_MODE (x);
1858   rtx libfunc;
1859
1860   if (mode == SFmode)
1861     switch (comparison)
1862       {
1863       case EQ:
1864         libfunc = eqsf2_libfunc;
1865         break;
1866
1867       case NE:
1868         libfunc = nesf2_libfunc;
1869         break;
1870
1871       case GT:
1872         libfunc = gtsf2_libfunc;
1873         break;
1874
1875       case GE:
1876         libfunc = gesf2_libfunc;
1877         break;
1878
1879       case LT:
1880         libfunc = ltsf2_libfunc;
1881         break;
1882
1883       case LE:
1884         libfunc = lesf2_libfunc;
1885         break;
1886       }
1887   else if (mode == DFmode)
1888     switch (comparison)
1889       {
1890       case EQ:
1891         libfunc = eqdf2_libfunc;
1892         break;
1893
1894       case NE:
1895         libfunc = nedf2_libfunc;
1896         break;
1897
1898       case GT:
1899         libfunc = gtdf2_libfunc;
1900         break;
1901
1902       case GE:
1903         libfunc = gedf2_libfunc;
1904         break;
1905
1906       case LT:
1907         libfunc = ltdf2_libfunc;
1908         break;
1909
1910       case LE:
1911         libfunc = ledf2_libfunc;
1912         break;
1913       }
1914   else if (mode == XFmode)
1915     switch (comparison)
1916       {
1917       case EQ:
1918         libfunc = eqxf2_libfunc;
1919         break;
1920
1921       case NE:
1922         libfunc = nexf2_libfunc;
1923         break;
1924
1925       case GT:
1926         libfunc = gtxf2_libfunc;
1927         break;
1928
1929       case GE:
1930         libfunc = gexf2_libfunc;
1931         break;
1932
1933       case LT:
1934         libfunc = ltxf2_libfunc;
1935         break;
1936
1937       case LE:
1938         libfunc = lexf2_libfunc;
1939         break;
1940       }
1941   else if (mode == TFmode)
1942     switch (comparison)
1943       {
1944       case EQ:
1945         libfunc = eqtf2_libfunc;
1946         break;
1947
1948       case NE:
1949         libfunc = netf2_libfunc;
1950         break;
1951
1952       case GT:
1953         libfunc = gttf2_libfunc;
1954         break;
1955
1956       case GE:
1957         libfunc = getf2_libfunc;
1958         break;
1959
1960       case LT:
1961         libfunc = lttf2_libfunc;
1962         break;
1963
1964       case LE:
1965         libfunc = letf2_libfunc;
1966         break;
1967       }
1968   else
1969     {
1970       enum machine_mode wider_mode;
1971
1972       for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1973            wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1974         {
1975           if ((cmp_optab->handlers[(int) wider_mode].insn_code
1976                != CODE_FOR_nothing)
1977               || (cmp_optab->handlers[(int) wider_mode].libfunc != 0))
1978             {
1979               x = protect_from_queue (x, 0);
1980               y = protect_from_queue (y, 0);
1981               x = convert_to_mode (wider_mode, x, 0);
1982               y = convert_to_mode (wider_mode, y, 0);
1983               emit_float_lib_cmp (x, y, comparison);
1984               return;
1985             }
1986         }
1987       abort ();
1988     }
1989
1990   emit_library_call (libfunc, 1,
1991                      SImode, 2, x, mode, y, mode);
1992
1993   emit_cmp_insn (hard_libcall_value (SImode), const0_rtx, comparison,
1994                  NULL_RTX, SImode, 0, 0);
1995 }
1996 \f
1997 /* Generate code to indirectly jump to a location given in the rtx LOC.  */
1998
1999 void
2000 emit_indirect_jump (loc)
2001      rtx loc;
2002 {
2003   if (! ((*insn_operand_predicate[(int)CODE_FOR_indirect_jump][0])
2004          (loc, VOIDmode)))
2005     loc = copy_to_mode_reg (insn_operand_mode[(int)CODE_FOR_indirect_jump][0],
2006                             loc);
2007
2008   emit_jump_insn (gen_indirect_jump (loc));
2009   emit_barrier ();
2010 }
2011 \f
2012 /* These three functions generate an insn body and return it
2013    rather than emitting the insn.
2014
2015    They do not protect from queued increments,
2016    because they may be used 1) in protect_from_queue itself
2017    and 2) in other passes where there is no queue.  */
2018
2019 /* Generate and return an insn body to add Y to X.  */
2020
2021 rtx
2022 gen_add2_insn (x, y)
2023      rtx x, y;
2024 {
2025   int icode = (int) add_optab->handlers[(int) GET_MODE (x)].insn_code; 
2026
2027   if (! (*insn_operand_predicate[icode][0]) (x, insn_operand_mode[icode][0])
2028       || ! (*insn_operand_predicate[icode][1]) (x, insn_operand_mode[icode][1])
2029       || ! (*insn_operand_predicate[icode][2]) (y, insn_operand_mode[icode][2]))
2030     abort ();
2031
2032   return (GEN_FCN (icode) (x, x, y));
2033 }
2034
2035 int
2036 have_add2_insn (mode)
2037      enum machine_mode mode;
2038 {
2039   return add_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
2040 }
2041
2042 /* Generate and return an insn body to subtract Y from X.  */
2043
2044 rtx
2045 gen_sub2_insn (x, y)
2046      rtx x, y;
2047 {
2048   int icode = (int) sub_optab->handlers[(int) GET_MODE (x)].insn_code; 
2049
2050   if (! (*insn_operand_predicate[icode][0]) (x, insn_operand_mode[icode][0])
2051       || ! (*insn_operand_predicate[icode][1]) (x, insn_operand_mode[icode][1])
2052       || ! (*insn_operand_predicate[icode][2]) (y, insn_operand_mode[icode][2]))
2053     abort ();
2054
2055   return (GEN_FCN (icode) (x, x, y));
2056 }
2057
2058 int
2059 have_sub2_insn (mode)
2060      enum machine_mode mode;
2061 {
2062   return sub_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
2063 }
2064
2065 /* Generate the body of an instruction to copy Y into X.  */
2066
2067 rtx
2068 gen_move_insn (x, y)
2069      rtx x, y;
2070 {
2071   register enum machine_mode mode = GET_MODE (x);
2072   enum insn_code insn_code;
2073
2074   if (mode == VOIDmode)
2075     mode = GET_MODE (y); 
2076
2077   insn_code = mov_optab->handlers[(int) mode].insn_code;
2078
2079   /* Handle MODE_CC modes:  If we don't have a special move insn for this mode,
2080      find a mode to do it in.  If we have a movcc, use it.  Otherwise,
2081      find the MODE_INT mode of the same width.  */
2082
2083   if (insn_code == CODE_FOR_nothing)
2084     {
2085       enum machine_mode tmode = VOIDmode;
2086       rtx x1 = x, y1 = y;
2087
2088       if (GET_MODE_CLASS (mode) == MODE_CC && mode != CCmode
2089           && mov_optab->handlers[(int) CCmode].insn_code != CODE_FOR_nothing)
2090         tmode = CCmode;
2091       else if (GET_MODE_CLASS (mode) == MODE_CC)
2092         for (tmode = QImode; tmode != VOIDmode;
2093              tmode = GET_MODE_WIDER_MODE (tmode))
2094           if (GET_MODE_SIZE (tmode) == GET_MODE_SIZE (mode))
2095             break;
2096
2097       if (tmode == VOIDmode)
2098         abort ();
2099
2100       /* Get X and Y in TMODE.  We can't use gen_lowpart here because it
2101          may call change_address which is not appropriate if we were
2102          called when a reload was in progress.  We don't have to worry
2103          about changing the address since the size in bytes is supposed to
2104          be the same.  Copy the MEM to change the mode and move any
2105          substitutions from the old MEM to the new one.  */
2106
2107       if (reload_in_progress)
2108         {
2109           x = gen_lowpart_common (tmode, x1);
2110           if (x == 0 && GET_CODE (x1) == MEM)
2111             {
2112               x = gen_rtx (MEM, tmode, XEXP (x1, 0));
2113               RTX_UNCHANGING_P (x) = RTX_UNCHANGING_P (x1);
2114               MEM_IN_STRUCT_P (x) = MEM_IN_STRUCT_P (x1);
2115               MEM_VOLATILE_P (x) = MEM_VOLATILE_P (x1);
2116               copy_replacements (x1, x);
2117             }
2118
2119           y = gen_lowpart_common (tmode, y1);
2120           if (y == 0 && GET_CODE (y1) == MEM)
2121             {
2122               y = gen_rtx (MEM, tmode, XEXP (y1, 0));
2123               RTX_UNCHANGING_P (y) = RTX_UNCHANGING_P (y1);
2124               MEM_IN_STRUCT_P (y) = MEM_IN_STRUCT_P (y1);
2125               MEM_VOLATILE_P (y) = MEM_VOLATILE_P (y1);
2126               copy_replacements (y1, y);
2127             }
2128         }
2129       else
2130         {
2131           x = gen_lowpart (tmode, x);
2132           y = gen_lowpart (tmode, y);
2133         }
2134           
2135       insn_code = mov_optab->handlers[(int) tmode].insn_code;
2136     }
2137
2138   return (GEN_FCN (insn_code) (x, y));
2139 }
2140 \f
2141 /* Tables of patterns for extending one integer mode to another.  */
2142 static enum insn_code extendtab[MAX_MACHINE_MODE][MAX_MACHINE_MODE][2];
2143
2144 /* Return the insn code used to extend FROM_MODE to TO_MODE.
2145    UNSIGNEDP specifies zero-extension instead of sign-extension.  If
2146    no such operation exists, CODE_FOR_nothing will be returned.  */
2147
2148 enum insn_code
2149 can_extend_p (to_mode, from_mode, unsignedp)
2150      enum machine_mode to_mode, from_mode;
2151      int unsignedp;
2152 {
2153   return extendtab[(int) to_mode][(int) from_mode][unsignedp];
2154 }
2155
2156 /* Generate the body of an insn to extend Y (with mode MFROM)
2157    into X (with mode MTO).  Do zero-extension if UNSIGNEDP is nonzero.  */
2158
2159 rtx
2160 gen_extend_insn (x, y, mto, mfrom, unsignedp)
2161      rtx x, y;
2162      enum machine_mode mto, mfrom;
2163      int unsignedp;
2164 {
2165   return (GEN_FCN (extendtab[(int) mto][(int) mfrom][unsignedp]) (x, y));
2166 }
2167
2168 static void
2169 init_extends ()
2170 {
2171   enum insn_code *p;
2172
2173   for (p = extendtab[0][0];
2174        p < extendtab[0][0] + sizeof extendtab / sizeof extendtab[0][0][0];
2175        p++)
2176     *p = CODE_FOR_nothing;
2177
2178 #ifdef HAVE_extendditi2
2179   if (HAVE_extendditi2)
2180     extendtab[(int) TImode][(int) DImode][0] = CODE_FOR_extendditi2;
2181 #endif
2182 #ifdef HAVE_extendsiti2
2183   if (HAVE_extendsiti2)
2184     extendtab[(int) TImode][(int) SImode][0] = CODE_FOR_extendsiti2;
2185 #endif
2186 #ifdef HAVE_extendhiti2
2187   if (HAVE_extendhiti2)
2188     extendtab[(int) TImode][(int) HImode][0] = CODE_FOR_extendhiti2;
2189 #endif
2190 #ifdef HAVE_extendqiti2
2191   if (HAVE_extendqiti2)
2192     extendtab[(int) TImode][(int) QImode][0] = CODE_FOR_extendqiti2;
2193 #endif
2194 #ifdef HAVE_extendsidi2
2195   if (HAVE_extendsidi2)
2196     extendtab[(int) DImode][(int) SImode][0] = CODE_FOR_extendsidi2;
2197 #endif
2198 #ifdef HAVE_extendhidi2
2199   if (HAVE_extendhidi2)
2200     extendtab[(int) DImode][(int) HImode][0] = CODE_FOR_extendhidi2;
2201 #endif
2202 #ifdef HAVE_extendqidi2
2203   if (HAVE_extendqidi2)
2204     extendtab[(int) DImode][(int) QImode][0] = CODE_FOR_extendqidi2;
2205 #endif
2206 #ifdef HAVE_extendhisi2
2207   if (HAVE_extendhisi2)
2208     extendtab[(int) SImode][(int) HImode][0] = CODE_FOR_extendhisi2;
2209 #endif
2210 #ifdef HAVE_extendqisi2
2211   if (HAVE_extendqisi2)
2212     extendtab[(int) SImode][(int) QImode][0] = CODE_FOR_extendqisi2;
2213 #endif
2214 #ifdef HAVE_extendqihi2
2215   if (HAVE_extendqihi2)
2216     extendtab[(int) HImode][(int) QImode][0] = CODE_FOR_extendqihi2;
2217 #endif
2218
2219 #ifdef HAVE_zero_extendditi2
2220   if (HAVE_zero_extendsiti2)
2221     extendtab[(int) TImode][(int) DImode][1] = CODE_FOR_zero_extendditi2;
2222 #endif
2223 #ifdef HAVE_zero_extendsiti2
2224   if (HAVE_zero_extendsiti2)
2225     extendtab[(int) TImode][(int) SImode][1] = CODE_FOR_zero_extendsiti2;
2226 #endif
2227 #ifdef HAVE_zero_extendhiti2
2228   if (HAVE_zero_extendhiti2)
2229     extendtab[(int) TImode][(int) HImode][1] = CODE_FOR_zero_extendhiti2;
2230 #endif
2231 #ifdef HAVE_zero_extendqiti2
2232   if (HAVE_zero_extendqiti2)
2233     extendtab[(int) TImode][(int) QImode][1] = CODE_FOR_zero_extendqiti2;
2234 #endif
2235 #ifdef HAVE_zero_extendsidi2
2236   if (HAVE_zero_extendsidi2)
2237     extendtab[(int) DImode][(int) SImode][1] = CODE_FOR_zero_extendsidi2;
2238 #endif
2239 #ifdef HAVE_zero_extendhidi2
2240   if (HAVE_zero_extendhidi2)
2241     extendtab[(int) DImode][(int) HImode][1] = CODE_FOR_zero_extendhidi2;
2242 #endif
2243 #ifdef HAVE_zero_extendqidi2
2244   if (HAVE_zero_extendqidi2)
2245     extendtab[(int) DImode][(int) QImode][1] = CODE_FOR_zero_extendqidi2;
2246 #endif
2247 #ifdef HAVE_zero_extendhisi2
2248   if (HAVE_zero_extendhisi2)
2249     extendtab[(int) SImode][(int) HImode][1] = CODE_FOR_zero_extendhisi2;
2250 #endif
2251 #ifdef HAVE_zero_extendqisi2
2252   if (HAVE_zero_extendqisi2)
2253     extendtab[(int) SImode][(int) QImode][1] = CODE_FOR_zero_extendqisi2;
2254 #endif
2255 #ifdef HAVE_zero_extendqihi2
2256   if (HAVE_zero_extendqihi2)
2257     extendtab[(int) HImode][(int) QImode][1] = CODE_FOR_zero_extendqihi2;
2258 #endif
2259 }
2260 \f
2261 /* can_fix_p and can_float_p say whether the target machine
2262    can directly convert a given fixed point type to
2263    a given floating point type, or vice versa.
2264    The returned value is the CODE_FOR_... value to use,
2265    or CODE_FOR_nothing if these modes cannot be directly converted.  */
2266
2267 static enum insn_code fixtab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
2268 static enum insn_code fixtrunctab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
2269 static enum insn_code floattab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
2270
2271 /* *TRUNCP_PTR is set to 1 if it is necessary to output
2272    an explicit FTRUNC insn before the fix insn; otherwise 0.  */
2273
2274 static enum insn_code
2275 can_fix_p (fixmode, fltmode, unsignedp, truncp_ptr)
2276      enum machine_mode fltmode, fixmode;
2277      int unsignedp;
2278      int *truncp_ptr;
2279 {
2280   *truncp_ptr = 0;
2281   if (fixtrunctab[(int) fltmode][(int) fixmode][unsignedp] != CODE_FOR_nothing)
2282     return fixtrunctab[(int) fltmode][(int) fixmode][unsignedp];
2283
2284   if (ftrunc_optab->handlers[(int) fltmode].insn_code != CODE_FOR_nothing)
2285     {
2286       *truncp_ptr = 1;
2287       return fixtab[(int) fltmode][(int) fixmode][unsignedp];
2288     }
2289   return CODE_FOR_nothing;
2290 }
2291
2292 static enum insn_code
2293 can_float_p (fltmode, fixmode, unsignedp)
2294      enum machine_mode fixmode, fltmode;
2295      int unsignedp;
2296 {
2297   return floattab[(int) fltmode][(int) fixmode][unsignedp];
2298 }
2299
2300 void
2301 init_fixtab ()
2302 {
2303   enum insn_code *p;
2304   for (p = fixtab[0][0];
2305        p < fixtab[0][0] + sizeof fixtab / sizeof (fixtab[0][0][0]); 
2306        p++)
2307     *p = CODE_FOR_nothing;
2308   for (p = fixtrunctab[0][0];
2309        p < fixtrunctab[0][0] + sizeof fixtrunctab / sizeof (fixtrunctab[0][0][0]); 
2310        p++)
2311     *p = CODE_FOR_nothing;
2312
2313 #ifdef HAVE_fixsfqi2
2314   if (HAVE_fixsfqi2)
2315     fixtab[(int) SFmode][(int) QImode][0] = CODE_FOR_fixsfqi2;
2316 #endif
2317 #ifdef HAVE_fixsfhi2
2318   if (HAVE_fixsfhi2)
2319     fixtab[(int) SFmode][(int) HImode][0] = CODE_FOR_fixsfhi2;
2320 #endif
2321 #ifdef HAVE_fixsfsi2
2322   if (HAVE_fixsfsi2)
2323     fixtab[(int) SFmode][(int) SImode][0] = CODE_FOR_fixsfsi2;
2324 #endif
2325 #ifdef HAVE_fixsfdi2
2326   if (HAVE_fixsfdi2)
2327     fixtab[(int) SFmode][(int) DImode][0] = CODE_FOR_fixsfdi2;
2328 #endif
2329
2330 #ifdef HAVE_fixdfqi2
2331   if (HAVE_fixdfqi2)
2332     fixtab[(int) DFmode][(int) QImode][0] = CODE_FOR_fixdfqi2;
2333 #endif
2334 #ifdef HAVE_fixdfhi2
2335   if (HAVE_fixdfhi2)
2336     fixtab[(int) DFmode][(int) HImode][0] = CODE_FOR_fixdfhi2;
2337 #endif
2338 #ifdef HAVE_fixdfsi2
2339   if (HAVE_fixdfsi2)
2340     fixtab[(int) DFmode][(int) SImode][0] = CODE_FOR_fixdfsi2;
2341 #endif
2342 #ifdef HAVE_fixdfdi2
2343   if (HAVE_fixdfdi2)
2344     fixtab[(int) DFmode][(int) DImode][0] = CODE_FOR_fixdfdi2;
2345 #endif
2346 #ifdef HAVE_fixdfti2
2347   if (HAVE_fixdfti2)
2348     fixtab[(int) DFmode][(int) TImode][0] = CODE_FOR_fixdfti2;
2349 #endif
2350
2351 #ifdef HAVE_fixxfqi2
2352   if (HAVE_fixxfqi2)
2353     fixtab[(int) XFmode][(int) QImode][0] = CODE_FOR_fixxfqi2;
2354 #endif
2355 #ifdef HAVE_fixxfhi2
2356   if (HAVE_fixxfhi2)
2357     fixtab[(int) XFmode][(int) HImode][0] = CODE_FOR_fixxfhi2;
2358 #endif
2359 #ifdef HAVE_fixxfsi2
2360   if (HAVE_fixxfsi2)
2361     fixtab[(int) XFmode][(int) SImode][0] = CODE_FOR_fixxfsi2;
2362 #endif
2363 #ifdef HAVE_fixxfdi2
2364   if (HAVE_fixxfdi2)
2365     fixtab[(int) XFmode][(int) DImode][0] = CODE_FOR_fixxfdi2;
2366 #endif
2367 #ifdef HAVE_fixxfti2
2368   if (HAVE_fixxfti2)
2369     fixtab[(int) XFmode][(int) TImode][0] = CODE_FOR_fixxfti2;
2370 #endif
2371
2372 #ifdef HAVE_fixtfqi2
2373   if (HAVE_fixtfqi2)
2374     fixtab[(int) TFmode][(int) QImode][0] = CODE_FOR_fixtfqi2;
2375 #endif
2376 #ifdef HAVE_fixtfhi2
2377   if (HAVE_fixtfhi2)
2378     fixtab[(int) TFmode][(int) HImode][0] = CODE_FOR_fixtfhi2;
2379 #endif
2380 #ifdef HAVE_fixtfsi2
2381   if (HAVE_fixtfsi2)
2382     fixtab[(int) TFmode][(int) SImode][0] = CODE_FOR_fixtfsi2;
2383 #endif
2384 #ifdef HAVE_fixtfdi2
2385   if (HAVE_fixtfdi2)
2386     fixtab[(int) TFmode][(int) DImode][0] = CODE_FOR_fixtfdi2;
2387 #endif
2388 #ifdef HAVE_fixtfti2
2389   if (HAVE_fixtfti2)
2390     fixtab[(int) TFmode][(int) TImode][0] = CODE_FOR_fixtfti2;
2391 #endif
2392
2393 #ifdef HAVE_fixunssfqi2
2394   if (HAVE_fixunssfqi2)
2395     fixtab[(int) SFmode][(int) QImode][1] = CODE_FOR_fixunssfqi2;
2396 #endif
2397 #ifdef HAVE_fixunssfhi2
2398   if (HAVE_fixunssfhi2)
2399     fixtab[(int) SFmode][(int) HImode][1] = CODE_FOR_fixunssfhi2;
2400 #endif
2401 #ifdef HAVE_fixunssfsi2
2402   if (HAVE_fixunssfsi2)
2403     fixtab[(int) SFmode][(int) SImode][1] = CODE_FOR_fixunssfsi2;
2404 #endif
2405 #ifdef HAVE_fixunssfdi2
2406   if (HAVE_fixunssfdi2)
2407     fixtab[(int) SFmode][(int) DImode][1] = CODE_FOR_fixunssfdi2;
2408 #endif
2409
2410 #ifdef HAVE_fixunsdfqi2
2411   if (HAVE_fixunsdfqi2)
2412     fixtab[(int) DFmode][(int) QImode][1] = CODE_FOR_fixunsdfqi2;
2413 #endif
2414 #ifdef HAVE_fixunsdfhi2
2415   if (HAVE_fixunsdfhi2)
2416     fixtab[(int) DFmode][(int) HImode][1] = CODE_FOR_fixunsdfhi2;
2417 #endif
2418 #ifdef HAVE_fixunsdfsi2
2419   if (HAVE_fixunsdfsi2)
2420     fixtab[(int) DFmode][(int) SImode][1] = CODE_FOR_fixunsdfsi2;
2421 #endif
2422 #ifdef HAVE_fixunsdfdi2
2423   if (HAVE_fixunsdfdi2)
2424     fixtab[(int) DFmode][(int) DImode][1] = CODE_FOR_fixunsdfdi2;
2425 #endif
2426 #ifdef HAVE_fixunsdfti2
2427   if (HAVE_fixunsdfti2)
2428     fixtab[(int) DFmode][(int) TImode][1] = CODE_FOR_fixunsdfti2;
2429 #endif
2430
2431 #ifdef HAVE_fixunsxfqi2
2432   if (HAVE_fixunsxfqi2)
2433     fixtab[(int) XFmode][(int) QImode][1] = CODE_FOR_fixunsxfqi2;
2434 #endif
2435 #ifdef HAVE_fixunsxfhi2
2436   if (HAVE_fixunsxfhi2)
2437     fixtab[(int) XFmode][(int) HImode][1] = CODE_FOR_fixunsxfhi2;
2438 #endif
2439 #ifdef HAVE_fixunsxfsi2
2440   if (HAVE_fixunsxfsi2)
2441     fixtab[(int) XFmode][(int) SImode][1] = CODE_FOR_fixunsxfsi2;
2442 #endif
2443 #ifdef HAVE_fixunsxfdi2
2444   if (HAVE_fixunsxfdi2)
2445     fixtab[(int) XFmode][(int) DImode][1] = CODE_FOR_fixunsxfdi2;
2446 #endif
2447 #ifdef HAVE_fixunsxfti2
2448   if (HAVE_fixunsxfti2)
2449     fixtab[(int) XFmode][(int) TImode][1] = CODE_FOR_fixunsxfti2;
2450 #endif
2451
2452 #ifdef HAVE_fixunstfqi2
2453   if (HAVE_fixunstfqi2)
2454     fixtab[(int) TFmode][(int) QImode][1] = CODE_FOR_fixunstfqi2;
2455 #endif
2456 #ifdef HAVE_fixunstfhi2
2457   if (HAVE_fixunstfhi2)
2458     fixtab[(int) TFmode][(int) HImode][1] = CODE_FOR_fixunstfhi2;
2459 #endif
2460 #ifdef HAVE_fixunstfsi2
2461   if (HAVE_fixunstfsi2)
2462     fixtab[(int) TFmode][(int) SImode][1] = CODE_FOR_fixunstfsi2;
2463 #endif
2464 #ifdef HAVE_fixunstfdi2
2465   if (HAVE_fixunstfdi2)
2466     fixtab[(int) TFmode][(int) DImode][1] = CODE_FOR_fixunstfdi2;
2467 #endif
2468 #ifdef HAVE_fixunstfti2
2469   if (HAVE_fixunstfti2)
2470     fixtab[(int) TFmode][(int) TImode][1] = CODE_FOR_fixunstfti2;
2471 #endif
2472
2473 #ifdef HAVE_fix_truncsfqi2
2474   if (HAVE_fix_truncsfqi2)
2475     fixtrunctab[(int) SFmode][(int) QImode][0] = CODE_FOR_fix_truncsfqi2;
2476 #endif
2477 #ifdef HAVE_fix_truncsfhi2
2478   if (HAVE_fix_truncsfhi2)
2479     fixtrunctab[(int) SFmode][(int) HImode][0] = CODE_FOR_fix_truncsfhi2;
2480 #endif
2481 #ifdef HAVE_fix_truncsfsi2
2482   if (HAVE_fix_truncsfsi2)
2483     fixtrunctab[(int) SFmode][(int) SImode][0] = CODE_FOR_fix_truncsfsi2;
2484 #endif
2485 #ifdef HAVE_fix_truncsfdi2
2486   if (HAVE_fix_truncsfdi2)
2487     fixtrunctab[(int) SFmode][(int) DImode][0] = CODE_FOR_fix_truncsfdi2;
2488 #endif
2489
2490 #ifdef HAVE_fix_truncdfqi2
2491   if (HAVE_fix_truncdfsi2)
2492     fixtrunctab[(int) DFmode][(int) QImode][0] = CODE_FOR_fix_truncdfqi2;
2493 #endif
2494 #ifdef HAVE_fix_truncdfhi2
2495   if (HAVE_fix_truncdfhi2)
2496     fixtrunctab[(int) DFmode][(int) HImode][0] = CODE_FOR_fix_truncdfhi2;
2497 #endif
2498 #ifdef HAVE_fix_truncdfsi2
2499   if (HAVE_fix_truncdfsi2)
2500     fixtrunctab[(int) DFmode][(int) SImode][0] = CODE_FOR_fix_truncdfsi2;
2501 #endif
2502 #ifdef HAVE_fix_truncdfdi2
2503   if (HAVE_fix_truncdfdi2)
2504     fixtrunctab[(int) DFmode][(int) DImode][0] = CODE_FOR_fix_truncdfdi2;
2505 #endif
2506 #ifdef HAVE_fix_truncdfti2
2507   if (HAVE_fix_truncdfti2)
2508     fixtrunctab[(int) DFmode][(int) TImode][0] = CODE_FOR_fix_truncdfti2;
2509 #endif
2510
2511 #ifdef HAVE_fix_truncxfqi2
2512   if (HAVE_fix_truncxfqi2)
2513     fixtrunctab[(int) XFmode][(int) QImode][0] = CODE_FOR_fix_truncxfqi2;
2514 #endif
2515 #ifdef HAVE_fix_truncxfhi2
2516   if (HAVE_fix_truncxfhi2)
2517     fixtrunctab[(int) XFmode][(int) HImode][0] = CODE_FOR_fix_truncxfhi2;
2518 #endif
2519 #ifdef HAVE_fix_truncxfsi2
2520   if (HAVE_fix_truncxfsi2)
2521     fixtrunctab[(int) XFmode][(int) SImode][0] = CODE_FOR_fix_truncxfsi2;
2522 #endif
2523 #ifdef HAVE_fix_truncxfdi2
2524   if (HAVE_fix_truncxfdi2)
2525     fixtrunctab[(int) XFmode][(int) DImode][0] = CODE_FOR_fix_truncxfdi2;
2526 #endif
2527 #ifdef HAVE_fix_truncxfti2
2528   if (HAVE_fix_truncxfti2)
2529     fixtrunctab[(int) XFmode][(int) TImode][0] = CODE_FOR_fix_truncxfti2;
2530 #endif
2531
2532 #ifdef HAVE_fix_trunctfqi2
2533   if (HAVE_fix_trunctfqi2)
2534     fixtrunctab[(int) TFmode][(int) QImode][0] = CODE_FOR_fix_trunctfqi2;
2535 #endif
2536 #ifdef HAVE_fix_trunctfhi2
2537   if (HAVE_fix_trunctfhi2)
2538     fixtrunctab[(int) TFmode][(int) HImode][0] = CODE_FOR_fix_trunctfhi2;
2539 #endif
2540 #ifdef HAVE_fix_trunctfsi2
2541   if (HAVE_fix_trunctfsi2)
2542     fixtrunctab[(int) TFmode][(int) SImode][0] = CODE_FOR_fix_trunctfsi2;
2543 #endif
2544 #ifdef HAVE_fix_trunctfdi2
2545   if (HAVE_fix_trunctfdi2)
2546     fixtrunctab[(int) TFmode][(int) DImode][0] = CODE_FOR_fix_trunctfdi2;
2547 #endif
2548 #ifdef HAVE_fix_trunctfti2
2549   if (HAVE_fix_trunctfti2)
2550     fixtrunctab[(int) TFmode][(int) TImode][0] = CODE_FOR_fix_trunctfti2;
2551 #endif
2552
2553 #ifdef HAVE_fixuns_truncsfqi2
2554   if (HAVE_fixuns_truncsfqi2)
2555     fixtrunctab[(int) SFmode][(int) QImode][1] = CODE_FOR_fixuns_truncsfqi2;
2556 #endif
2557 #ifdef HAVE_fixuns_truncsfhi2
2558   if (HAVE_fixuns_truncsfhi2)
2559     fixtrunctab[(int) SFmode][(int) HImode][1] = CODE_FOR_fixuns_truncsfhi2;
2560 #endif
2561 #ifdef HAVE_fixuns_truncsfsi2
2562   if (HAVE_fixuns_truncsfsi2)
2563     fixtrunctab[(int) SFmode][(int) SImode][1] = CODE_FOR_fixuns_truncsfsi2;
2564 #endif
2565 #ifdef HAVE_fixuns_truncsfdi2
2566   if (HAVE_fixuns_truncsfdi2)
2567     fixtrunctab[(int) SFmode][(int) DImode][1] = CODE_FOR_fixuns_truncsfdi2;
2568 #endif
2569
2570 #ifdef HAVE_fixuns_truncdfqi2
2571   if (HAVE_fixuns_truncdfqi2)
2572     fixtrunctab[(int) DFmode][(int) QImode][1] = CODE_FOR_fixuns_truncdfqi2;
2573 #endif
2574 #ifdef HAVE_fixuns_truncdfhi2
2575   if (HAVE_fixuns_truncdfhi2)
2576     fixtrunctab[(int) DFmode][(int) HImode][1] = CODE_FOR_fixuns_truncdfhi2;
2577 #endif
2578 #ifdef HAVE_fixuns_truncdfsi2
2579   if (HAVE_fixuns_truncdfsi2)
2580     fixtrunctab[(int) DFmode][(int) SImode][1] = CODE_FOR_fixuns_truncdfsi2;
2581 #endif
2582 #ifdef HAVE_fixuns_truncdfdi2
2583   if (HAVE_fixuns_truncdfdi2)
2584     fixtrunctab[(int) DFmode][(int) DImode][1] = CODE_FOR_fixuns_truncdfdi2;
2585 #endif
2586 #ifdef HAVE_fixuns_truncdfti2
2587   if (HAVE_fixuns_truncdfti2)
2588     fixtrunctab[(int) DFmode][(int) TImode][1] = CODE_FOR_fixuns_truncdfti2;
2589 #endif
2590
2591 #ifdef HAVE_fixuns_truncxfqi2
2592   if (HAVE_fixuns_truncxfqi2)
2593     fixtrunctab[(int) XFmode][(int) QImode][1] = CODE_FOR_fixuns_truncxfqi2;
2594 #endif
2595 #ifdef HAVE_fixuns_truncxfhi2
2596   if (HAVE_fixuns_truncxfhi2)
2597     fixtrunctab[(int) XFmode][(int) HImode][1] = CODE_FOR_fixuns_truncxfhi2;
2598 #endif
2599 #ifdef HAVE_fixuns_truncxfsi2
2600   if (HAVE_fixuns_truncxfsi2)
2601     fixtrunctab[(int) XFmode][(int) SImode][1] = CODE_FOR_fixuns_truncxfsi2;
2602 #endif
2603 #ifdef HAVE_fixuns_truncxfdi2
2604   if (HAVE_fixuns_truncxfdi2)
2605     fixtrunctab[(int) XFmode][(int) DImode][1] = CODE_FOR_fixuns_truncxfdi2;
2606 #endif
2607 #ifdef HAVE_fixuns_truncxfti2
2608   if (HAVE_fixuns_truncxfti2)
2609     fixtrunctab[(int) XFmode][(int) TImode][1] = CODE_FOR_fixuns_truncxfti2;
2610 #endif
2611
2612 #ifdef HAVE_fixuns_trunctfqi2
2613   if (HAVE_fixuns_trunctfqi2)
2614     fixtrunctab[(int) TFmode][(int) QImode][1] = CODE_FOR_fixuns_trunctfqi2;
2615 #endif
2616 #ifdef HAVE_fixuns_trunctfhi2
2617   if (HAVE_fixuns_trunctfhi2)
2618     fixtrunctab[(int) TFmode][(int) HImode][1] = CODE_FOR_fixuns_trunctfhi2;
2619 #endif
2620 #ifdef HAVE_fixuns_trunctfsi2
2621   if (HAVE_fixuns_trunctfsi2)
2622     fixtrunctab[(int) TFmode][(int) SImode][1] = CODE_FOR_fixuns_trunctfsi2;
2623 #endif
2624 #ifdef HAVE_fixuns_trunctfdi2
2625   if (HAVE_fixuns_trunctfdi2)
2626     fixtrunctab[(int) TFmode][(int) DImode][1] = CODE_FOR_fixuns_trunctfdi2;
2627 #endif
2628 #ifdef HAVE_fixuns_trunctfti2
2629   if (HAVE_fixuns_trunctfti2)
2630     fixtrunctab[(int) TFmode][(int) TImode][1] = CODE_FOR_fixuns_trunctfti2;
2631 #endif
2632
2633 #ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC
2634   /* This flag says the same insns that convert to a signed fixnum
2635      also convert validly to an unsigned one.  */
2636   {
2637     int i;
2638     int j;
2639     for (i = 0; i < NUM_MACHINE_MODES; i++)
2640       for (j = 0; j < NUM_MACHINE_MODES; j++)
2641         fixtrunctab[i][j][1] = fixtrunctab[i][j][0];
2642   }
2643 #endif
2644 }
2645
2646 void
2647 init_floattab ()
2648 {
2649   enum insn_code *p;
2650   for (p = floattab[0][0];
2651        p < floattab[0][0] + sizeof floattab / sizeof (floattab[0][0][0]); 
2652        p++)
2653     *p = CODE_FOR_nothing;
2654
2655 #ifdef HAVE_floatqisf2
2656   if (HAVE_floatqisf2)
2657     floattab[(int) SFmode][(int) QImode][0] = CODE_FOR_floatqisf2;
2658 #endif
2659 #ifdef HAVE_floathisf2
2660   if (HAVE_floathisf2)
2661     floattab[(int) SFmode][(int) HImode][0] = CODE_FOR_floathisf2;
2662 #endif
2663 #ifdef HAVE_floatsisf2
2664   if (HAVE_floatsisf2)
2665     floattab[(int) SFmode][(int) SImode][0] = CODE_FOR_floatsisf2;
2666 #endif
2667 #ifdef HAVE_floatdisf2
2668   if (HAVE_floatdisf2)
2669     floattab[(int) SFmode][(int) DImode][0] = CODE_FOR_floatdisf2;
2670 #endif
2671 #ifdef HAVE_floattisf2
2672   if (HAVE_floattisf2)
2673     floattab[(int) SFmode][(int) TImode][0] = CODE_FOR_floattisf2;
2674 #endif
2675
2676 #ifdef HAVE_floatqidf2
2677   if (HAVE_floatqidf2)
2678     floattab[(int) DFmode][(int) QImode][0] = CODE_FOR_floatqidf2;
2679 #endif
2680 #ifdef HAVE_floathidf2
2681   if (HAVE_floathidf2)
2682     floattab[(int) DFmode][(int) HImode][0] = CODE_FOR_floathidf2;
2683 #endif
2684 #ifdef HAVE_floatsidf2
2685   if (HAVE_floatsidf2)
2686     floattab[(int) DFmode][(int) SImode][0] = CODE_FOR_floatsidf2;
2687 #endif
2688 #ifdef HAVE_floatdidf2
2689   if (HAVE_floatdidf2)
2690     floattab[(int) DFmode][(int) DImode][0] = CODE_FOR_floatdidf2;
2691 #endif
2692 #ifdef HAVE_floattidf2
2693   if (HAVE_floattidf2)
2694     floattab[(int) DFmode][(int) TImode][0] = CODE_FOR_floattidf2;
2695 #endif
2696
2697 #ifdef HAVE_floatqixf2
2698   if (HAVE_floatqixf2)
2699     floattab[(int) XFmode][(int) QImode][0] = CODE_FOR_floatqixf2;
2700 #endif
2701 #ifdef HAVE_floathixf2
2702   if (HAVE_floathixf2)
2703     floattab[(int) XFmode][(int) HImode][0] = CODE_FOR_floathixf2;
2704 #endif
2705 #ifdef HAVE_floatsixf2
2706   if (HAVE_floatsixf2)
2707     floattab[(int) XFmode][(int) SImode][0] = CODE_FOR_floatsixf2;
2708 #endif
2709 #ifdef HAVE_floatdixf2
2710   if (HAVE_floatdixf2)
2711     floattab[(int) XFmode][(int) DImode][0] = CODE_FOR_floatdixf2;
2712 #endif
2713 #ifdef HAVE_floattixf2
2714   if (HAVE_floattixf2)
2715     floattab[(int) XFmode][(int) TImode][0] = CODE_FOR_floattixf2;
2716 #endif
2717
2718 #ifdef HAVE_floatqitf2
2719   if (HAVE_floatqitf2)
2720     floattab[(int) TFmode][(int) QImode][0] = CODE_FOR_floatqitf2;
2721 #endif
2722 #ifdef HAVE_floathitf2
2723   if (HAVE_floathitf2)
2724     floattab[(int) TFmode][(int) HImode][0] = CODE_FOR_floathitf2;
2725 #endif
2726 #ifdef HAVE_floatsitf2
2727   if (HAVE_floatsitf2)
2728     floattab[(int) TFmode][(int) SImode][0] = CODE_FOR_floatsitf2;
2729 #endif
2730 #ifdef HAVE_floatditf2
2731   if (HAVE_floatditf2)
2732     floattab[(int) TFmode][(int) DImode][0] = CODE_FOR_floatditf2;
2733 #endif
2734 #ifdef HAVE_floattitf2
2735   if (HAVE_floattitf2)
2736     floattab[(int) TFmode][(int) TImode][0] = CODE_FOR_floattitf2;
2737 #endif
2738
2739 #ifdef HAVE_floatunsqisf2
2740   if (HAVE_floatunsqisf2)
2741     floattab[(int) SFmode][(int) QImode][1] = CODE_FOR_floatunsqisf2;
2742 #endif
2743 #ifdef HAVE_floatunshisf2
2744   if (HAVE_floatunshisf2)
2745     floattab[(int) SFmode][(int) HImode][1] = CODE_FOR_floatunshisf2;
2746 #endif
2747 #ifdef HAVE_floatunssisf2
2748   if (HAVE_floatunssisf2)
2749     floattab[(int) SFmode][(int) SImode][1] = CODE_FOR_floatunssisf2;
2750 #endif
2751 #ifdef HAVE_floatunsdisf2
2752   if (HAVE_floatunsdisf2)
2753     floattab[(int) SFmode][(int) DImode][1] = CODE_FOR_floatunsdisf2;
2754 #endif
2755 #ifdef HAVE_floatunstisf2
2756   if (HAVE_floatunstisf2)
2757     floattab[(int) SFmode][(int) TImode][1] = CODE_FOR_floatunstisf2;
2758 #endif
2759
2760 #ifdef HAVE_floatunsqidf2
2761   if (HAVE_floatunsqidf2)
2762     floattab[(int) DFmode][(int) QImode][1] = CODE_FOR_floatunsqidf2;
2763 #endif
2764 #ifdef HAVE_floatunshidf2
2765   if (HAVE_floatunshidf2)
2766     floattab[(int) DFmode][(int) HImode][1] = CODE_FOR_floatunshidf2;
2767 #endif
2768 #ifdef HAVE_floatunssidf2
2769   if (HAVE_floatunssidf2)
2770     floattab[(int) DFmode][(int) SImode][1] = CODE_FOR_floatunssidf2;
2771 #endif
2772 #ifdef HAVE_floatunsdidf2
2773   if (HAVE_floatunsdidf2)
2774     floattab[(int) DFmode][(int) DImode][1] = CODE_FOR_floatunsdidf2;
2775 #endif
2776 #ifdef HAVE_floatunstidf2
2777   if (HAVE_floatunstidf2)
2778     floattab[(int) DFmode][(int) TImode][1] = CODE_FOR_floatunstidf2;
2779 #endif
2780
2781 #ifdef HAVE_floatunsqixf2
2782   if (HAVE_floatunsqixf2)
2783     floattab[(int) XFmode][(int) QImode][1] = CODE_FOR_floatunsqixf2;
2784 #endif
2785 #ifdef HAVE_floatunshixf2
2786   if (HAVE_floatunshixf2)
2787     floattab[(int) XFmode][(int) HImode][1] = CODE_FOR_floatunshixf2;
2788 #endif
2789 #ifdef HAVE_floatunssixf2
2790   if (HAVE_floatunssixf2)
2791     floattab[(int) XFmode][(int) SImode][1] = CODE_FOR_floatunssixf2;
2792 #endif
2793 #ifdef HAVE_floatunsdixf2
2794   if (HAVE_floatunsdixf2)
2795     floattab[(int) XFmode][(int) DImode][1] = CODE_FOR_floatunsdixf2;
2796 #endif
2797 #ifdef HAVE_floatunstixf2
2798   if (HAVE_floatunstixf2)
2799     floattab[(int) XFmode][(int) TImode][1] = CODE_FOR_floatunstixf2;
2800 #endif
2801
2802 #ifdef HAVE_floatunsqitf2
2803   if (HAVE_floatunsqitf2)
2804     floattab[(int) TFmode][(int) QImode][1] = CODE_FOR_floatunsqitf2;
2805 #endif
2806 #ifdef HAVE_floatunshitf2
2807   if (HAVE_floatunshitf2)
2808     floattab[(int) TFmode][(int) HImode][1] = CODE_FOR_floatunshitf2;
2809 #endif
2810 #ifdef HAVE_floatunssitf2
2811   if (HAVE_floatunssitf2)
2812     floattab[(int) TFmode][(int) SImode][1] = CODE_FOR_floatunssitf2;
2813 #endif
2814 #ifdef HAVE_floatunsditf2
2815   if (HAVE_floatunsditf2)
2816     floattab[(int) TFmode][(int) DImode][1] = CODE_FOR_floatunsditf2;
2817 #endif
2818 #ifdef HAVE_floatunstitf2
2819   if (HAVE_floatunstitf2)
2820     floattab[(int) TFmode][(int) TImode][1] = CODE_FOR_floatunstitf2;
2821 #endif
2822 }
2823 \f
2824 /* Generate code to convert FROM to floating point
2825    and store in TO.  FROM must be fixed point and not VOIDmode.
2826    UNSIGNEDP nonzero means regard FROM as unsigned.
2827    Normally this is done by correcting the final value
2828    if it is negative.  */
2829
2830 void
2831 expand_float (to, from, unsignedp)
2832      rtx to, from;
2833      int unsignedp;
2834 {
2835   enum insn_code icode;
2836   register rtx target = to;
2837   enum machine_mode fmode, imode;
2838
2839   /* Crash now, because we won't be able to decide which mode to use.  */
2840   if (GET_MODE (from) == VOIDmode)
2841     abort ();
2842
2843   /* Look for an insn to do the conversion.  Do it in the specified
2844      modes if possible; otherwise convert either input, output or both to
2845      wider mode.  If the integer mode is wider than the mode of FROM,
2846      we can do the conversion signed even if the input is unsigned.  */
2847
2848   for (imode = GET_MODE (from); imode != VOIDmode;
2849        imode = GET_MODE_WIDER_MODE (imode))
2850     for (fmode = GET_MODE (to); fmode != VOIDmode;
2851          fmode = GET_MODE_WIDER_MODE (fmode))
2852       {
2853         int doing_unsigned = unsignedp;
2854
2855         icode = can_float_p (fmode, imode, unsignedp);
2856         if (icode == CODE_FOR_nothing && imode != GET_MODE (from) && unsignedp)
2857           icode = can_float_p (fmode, imode, 0), doing_unsigned = 0;
2858
2859         if (icode != CODE_FOR_nothing)
2860           {
2861             to = protect_from_queue (to, 1);
2862             from = protect_from_queue (from, 0);
2863
2864             if (imode != GET_MODE (from))
2865               from = convert_to_mode (imode, from, unsignedp);
2866
2867             if (fmode != GET_MODE (to))
2868               target = gen_reg_rtx (fmode);
2869
2870             emit_unop_insn (icode, target, from,
2871                             doing_unsigned ? UNSIGNED_FLOAT : FLOAT);
2872
2873             if (target != to)
2874               convert_move (to, target, 0);
2875             return;
2876           }
2877     }
2878
2879 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
2880
2881   /* Unsigned integer, and no way to convert directly.
2882      Convert as signed, then conditionally adjust the result.  */
2883   if (unsignedp)
2884     {
2885       rtx label = gen_label_rtx ();
2886       rtx temp;
2887       REAL_VALUE_TYPE offset;
2888
2889       emit_queue ();
2890
2891       to = protect_from_queue (to, 1);
2892       from = protect_from_queue (from, 0);
2893
2894       if (flag_force_mem)
2895         from = force_not_mem (from);
2896
2897       /* If we are about to do some arithmetic to correct for an
2898          unsigned operand, do it in a pseudo-register.  */
2899
2900       if (GET_CODE (to) != REG || REGNO (to) <= LAST_VIRTUAL_REGISTER)
2901         target = gen_reg_rtx (GET_MODE (to));
2902
2903       /* Convert as signed integer to floating.  */
2904       expand_float (target, from, 0);
2905
2906       /* If FROM is negative (and therefore TO is negative),
2907          correct its value by 2**bitwidth.  */
2908
2909       do_pending_stack_adjust ();
2910       emit_cmp_insn (from, const0_rtx, GE, NULL_RTX, GET_MODE (from), 0, 0);
2911       emit_jump_insn (gen_bge (label));
2912       /* On SCO 3.2.1, ldexp rejects values outside [0.5, 1).
2913          Rather than setting up a dconst_dot_5, let's hope SCO
2914          fixes the bug.  */
2915       offset = REAL_VALUE_LDEXP (dconst1, GET_MODE_BITSIZE (GET_MODE (from)));
2916       temp = expand_binop (GET_MODE (to), add_optab, target,
2917                            immed_real_const_1 (offset, GET_MODE (to)),
2918                            target, 0, OPTAB_LIB_WIDEN);
2919       if (temp != target)
2920         emit_move_insn (target, temp);
2921       do_pending_stack_adjust ();
2922       emit_label (label);
2923     }
2924   else
2925 #endif
2926
2927   /* No hardware instruction available; call a library rotine to convert from
2928      SImode, DImode, or TImode into SFmode, DFmode, XFmode, or TFmode.  */
2929     {
2930       rtx libfcn;
2931       rtx insns;
2932
2933       to = protect_from_queue (to, 1);
2934       from = protect_from_queue (from, 0);
2935
2936       if (GET_MODE_SIZE (GET_MODE (from)) < GET_MODE_SIZE (SImode))
2937         from = convert_to_mode (SImode, from, unsignedp);
2938
2939       if (flag_force_mem)
2940         from = force_not_mem (from);
2941
2942       if (GET_MODE (to) == SFmode)
2943         {
2944           if (GET_MODE (from) == SImode)
2945             libfcn = floatsisf_libfunc;
2946           else if (GET_MODE (from) == DImode)
2947             libfcn = floatdisf_libfunc;
2948           else if (GET_MODE (from) == TImode)
2949             libfcn = floattisf_libfunc;
2950           else
2951             abort ();
2952         }
2953       else if (GET_MODE (to) == DFmode)
2954         {
2955           if (GET_MODE (from) == SImode)
2956             libfcn = floatsidf_libfunc;
2957           else if (GET_MODE (from) == DImode)
2958             libfcn = floatdidf_libfunc;
2959           else if (GET_MODE (from) == TImode)
2960             libfcn = floattidf_libfunc;
2961           else
2962             abort ();
2963         }
2964       else if (GET_MODE (to) == XFmode)
2965         {
2966           if (GET_MODE (from) == SImode)
2967             libfcn = floatsixf_libfunc;
2968           else if (GET_MODE (from) == DImode)
2969             libfcn = floatdixf_libfunc;
2970           else if (GET_MODE (from) == TImode)
2971             libfcn = floattixf_libfunc;
2972           else
2973             abort ();
2974         }
2975       else if (GET_MODE (to) == TFmode)
2976         {
2977           if (GET_MODE (from) == SImode)
2978             libfcn = floatsitf_libfunc;
2979           else if (GET_MODE (from) == DImode)
2980             libfcn = floatditf_libfunc;
2981           else if (GET_MODE (from) == TImode)
2982             libfcn = floattitf_libfunc;
2983           else
2984             abort ();
2985         }
2986       else
2987         abort ();
2988
2989       start_sequence ();
2990
2991       emit_library_call (libfcn, 1, GET_MODE (to), 1, from, GET_MODE (from));
2992       insns = get_insns ();
2993       end_sequence ();
2994
2995       emit_libcall_block (insns, target, hard_libcall_value (GET_MODE (to)),
2996                           gen_rtx (FLOAT, GET_MODE (to), from));
2997     }
2998
2999   /* Copy result to requested destination
3000      if we have been computing in a temp location.  */
3001
3002   if (target != to)
3003     {
3004       if (GET_MODE (target) == GET_MODE (to))
3005         emit_move_insn (to, target);
3006       else
3007         convert_move (to, target, 0);
3008     }
3009 }
3010 \f
3011 /* expand_fix: generate code to convert FROM to fixed point
3012    and store in TO.  FROM must be floating point.  */
3013
3014 static rtx
3015 ftruncify (x)
3016      rtx x;
3017 {
3018   rtx temp = gen_reg_rtx (GET_MODE (x));
3019   return expand_unop (GET_MODE (x), ftrunc_optab, x, temp, 0);
3020 }
3021
3022 void
3023 expand_fix (to, from, unsignedp)
3024      register rtx to, from;
3025      int unsignedp;
3026 {
3027   enum insn_code icode;
3028   register rtx target = to;
3029   enum machine_mode fmode, imode;
3030   int must_trunc = 0;
3031   rtx libfcn = 0;
3032
3033   /* We first try to find a pair of modes, one real and one integer, at
3034      least as wide as FROM and TO, respectively, in which we can open-code
3035      this conversion.  If the integer mode is wider than the mode of TO,
3036      we can do the conversion either signed or unsigned.  */
3037
3038   for (imode = GET_MODE (to); imode != VOIDmode;
3039        imode = GET_MODE_WIDER_MODE (imode))
3040     for (fmode = GET_MODE (from); fmode != VOIDmode;
3041          fmode = GET_MODE_WIDER_MODE (fmode))
3042       {
3043         int doing_unsigned = unsignedp;
3044
3045         icode = can_fix_p (imode, fmode, unsignedp, &must_trunc);
3046         if (icode == CODE_FOR_nothing && imode != GET_MODE (to) && unsignedp)
3047           icode = can_fix_p (imode, fmode, 0, &must_trunc), doing_unsigned = 0;
3048
3049         if (icode != CODE_FOR_nothing)
3050           {
3051             to = protect_from_queue (to, 1);
3052             from = protect_from_queue (from, 0);
3053
3054             if (fmode != GET_MODE (from))
3055               from = convert_to_mode (fmode, from, 0);
3056
3057             if (must_trunc)
3058               from = ftruncify (from);
3059
3060             if (imode != GET_MODE (to))
3061               target = gen_reg_rtx (imode);
3062
3063             emit_unop_insn (icode, target, from,
3064                             doing_unsigned ? UNSIGNED_FIX : FIX);
3065             if (target != to)
3066               convert_move (to, target, unsignedp);
3067             return;
3068           }
3069       }
3070
3071 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
3072   /* For an unsigned conversion, there is one more way to do it.
3073      If we have a signed conversion, we generate code that compares
3074      the real value to the largest representable positive number.  If if
3075      is smaller, the conversion is done normally.  Otherwise, subtract
3076      one plus the highest signed number, convert, and add it back.
3077
3078      We only need to check all real modes, since we know we didn't find
3079      anything with a wider integer mode.  */
3080
3081   if (unsignedp && GET_MODE_BITSIZE (GET_MODE (to)) <= HOST_BITS_PER_WIDE_INT)
3082     for (fmode = GET_MODE (from); fmode != VOIDmode;
3083          fmode = GET_MODE_WIDER_MODE (fmode))
3084       /* Make sure we won't lose significant bits doing this.  */
3085       if (GET_MODE_BITSIZE (fmode) > GET_MODE_BITSIZE (GET_MODE (to))
3086           && CODE_FOR_nothing != can_fix_p (GET_MODE (to), fmode, 0,
3087                                             &must_trunc))
3088         {
3089           int bitsize = GET_MODE_BITSIZE (GET_MODE (to));
3090           REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (dconst1, bitsize - 1);
3091           rtx limit = immed_real_const_1 (offset, fmode);
3092           rtx lab1 = gen_label_rtx ();
3093           rtx lab2 = gen_label_rtx ();
3094           rtx insn;
3095
3096           emit_queue ();
3097           to = protect_from_queue (to, 1);
3098           from = protect_from_queue (from, 0);
3099
3100           if (flag_force_mem)
3101             from = force_not_mem (from);
3102
3103           if (fmode != GET_MODE (from))
3104             from = convert_to_mode (fmode, from, 0);
3105
3106           /* See if we need to do the subtraction.  */
3107           do_pending_stack_adjust ();
3108           emit_cmp_insn (from, limit, GE, NULL_RTX, GET_MODE (from), 0, 0);
3109           emit_jump_insn (gen_bge (lab1));
3110
3111           /* If not, do the signed "fix" and branch around fixup code.  */
3112           expand_fix (to, from, 0);
3113           emit_jump_insn (gen_jump (lab2));
3114           emit_barrier ();
3115
3116           /* Otherwise, subtract 2**(N-1), convert to signed number,
3117              then add 2**(N-1).  Do the addition using XOR since this
3118              will often generate better code.  */
3119           emit_label (lab1);
3120           target = expand_binop (GET_MODE (from), sub_optab, from, limit,
3121                                  NULL_RTX, 0, OPTAB_LIB_WIDEN);
3122           expand_fix (to, target, 0);
3123           target = expand_binop (GET_MODE (to), xor_optab, to,
3124                                  GEN_INT ((HOST_WIDE_INT) 1 << (bitsize - 1)),
3125                                  to, 1, OPTAB_LIB_WIDEN);
3126
3127           if (target != to)
3128             emit_move_insn (to, target);
3129
3130           emit_label (lab2);
3131
3132           /* Make a place for a REG_NOTE and add it.  */
3133           insn = emit_move_insn (to, to);
3134           REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL,
3135                                       gen_rtx (UNSIGNED_FIX, GET_MODE (to),
3136                                                from), REG_NOTES (insn));
3137
3138           return;
3139         }
3140 #endif
3141
3142   /* We can't do it with an insn, so use a library call.  But first ensure
3143      that the mode of TO is at least as wide as SImode, since those are the
3144      only library calls we know about.  */
3145
3146   if (GET_MODE_SIZE (GET_MODE (to)) < GET_MODE_SIZE (SImode))
3147     {
3148       target = gen_reg_rtx (SImode);
3149
3150       expand_fix (target, from, unsignedp);
3151     }
3152   else if (GET_MODE (from) == SFmode)
3153     {
3154       if (GET_MODE (to) == SImode)
3155         libfcn = unsignedp ? fixunssfsi_libfunc : fixsfsi_libfunc;
3156       else if (GET_MODE (to) == DImode)
3157         libfcn = unsignedp ? fixunssfdi_libfunc : fixsfdi_libfunc;
3158       else if (GET_MODE (to) == TImode)
3159         libfcn = unsignedp ? fixunssfti_libfunc : fixsfti_libfunc;
3160       else
3161         abort ();
3162     }
3163   else if (GET_MODE (from) == DFmode)
3164     {
3165       if (GET_MODE (to) == SImode)
3166         libfcn = unsignedp ? fixunsdfsi_libfunc : fixdfsi_libfunc;
3167       else if (GET_MODE (to) == DImode)
3168         libfcn = unsignedp ? fixunsdfdi_libfunc : fixdfdi_libfunc;
3169       else if (GET_MODE (to) == TImode)
3170         libfcn = unsignedp ? fixunsdfti_libfunc : fixdfti_libfunc;
3171       else
3172         abort ();
3173     }
3174   else if (GET_MODE (from) == XFmode)
3175     {
3176       if (GET_MODE (to) == SImode)
3177         libfcn = unsignedp ? fixunsxfsi_libfunc : fixxfsi_libfunc;
3178       else if (GET_MODE (to) == DImode)
3179         libfcn = unsignedp ? fixunsxfdi_libfunc : fixxfdi_libfunc;
3180       else if (GET_MODE (to) == TImode)
3181         libfcn = unsignedp ? fixunsxfti_libfunc : fixxfti_libfunc;
3182       else
3183         abort ();
3184     }
3185   else if (GET_MODE (from) == TFmode)
3186     {
3187       if (GET_MODE (to) == SImode)
3188         libfcn = unsignedp ? fixunstfsi_libfunc : fixtfsi_libfunc;
3189       else if (GET_MODE (to) == DImode)
3190         libfcn = unsignedp ? fixunstfdi_libfunc : fixtfdi_libfunc;
3191       else if (GET_MODE (to) == TImode)
3192         libfcn = unsignedp ? fixunstfti_libfunc : fixtfti_libfunc;
3193       else
3194         abort ();
3195     }
3196   else
3197     abort ();
3198
3199   if (libfcn)
3200     {
3201       rtx insns;
3202
3203       to = protect_from_queue (to, 1);
3204       from = protect_from_queue (from, 0);
3205
3206       if (flag_force_mem)
3207         from = force_not_mem (from);
3208
3209       start_sequence ();
3210
3211       emit_library_call (libfcn, 1, GET_MODE (to), 1, from, GET_MODE (from));
3212       insns = get_insns ();
3213       end_sequence ();
3214
3215       emit_libcall_block (insns, target, hard_libcall_value (GET_MODE (to)),
3216                           gen_rtx (unsignedp ? FIX : UNSIGNED_FIX,
3217                                    GET_MODE (to), from));
3218     }
3219       
3220   if (GET_MODE (to) == GET_MODE (target))
3221     emit_move_insn (to, target);
3222   else
3223     convert_move (to, target, 0);
3224 }
3225 \f
3226 static optab
3227 init_optab (code)
3228      enum rtx_code code;
3229 {
3230   int i;
3231   optab op = (optab) xmalloc (sizeof (struct optab));
3232   op->code = code;
3233   for (i = 0; i < NUM_MACHINE_MODES; i++)
3234     {
3235       op->handlers[i].insn_code = CODE_FOR_nothing;
3236       op->handlers[i].libfunc = 0;
3237     }
3238   return op;
3239 }
3240
3241 /* Initialize the libfunc fields of an entire group of entries in some
3242    optab.  Each entry is set equal to a string consisting of a leading
3243    pair of underscores followed by a generic operation name followed by
3244    a mode name (downshifted to lower case) followed by a single character
3245    representing the number of operands for the given operation (which is
3246    usually one of the characters '2', '3', or '4').
3247
3248    OPTABLE is the table in which libfunc fields are to be initialized.
3249    FIRST_MODE is the first machine mode index in the given optab to
3250      initialize.
3251    LAST_MODE is the last machine mode index in the given optab to
3252      initialize.
3253    OPNAME is the generic (string) name of the operation.
3254    SUFFIX is the character which specifies the number of operands for
3255      the given generic operation.
3256 */
3257
3258 static void
3259 init_libfuncs (optable, first_mode, last_mode, opname, suffix)
3260     register optab optable;
3261     register char *opname;
3262     register enum machine_mode first_mode;
3263     register enum machine_mode last_mode;
3264     register char suffix;
3265 {
3266   register enum machine_mode mode;
3267   register unsigned opname_len = strlen (opname);
3268
3269   for (mode = first_mode; mode <= last_mode; mode++)
3270     {
3271       register char *mname = mode_name[(int) mode];
3272       register unsigned mname_len = strlen (mname);
3273       register char *libfunc_name
3274         = (char *) xmalloc (2 + opname_len + mname_len + 1 + 1);
3275       register char *p;
3276       register char *q;
3277
3278       p = libfunc_name;
3279       *p++ = '_';
3280       *p++ = '_';
3281       for (q = opname; *q; )
3282         *p++ = *q++;
3283       for (q = mname; *q; q++)
3284         *p++ = tolower (*q);
3285       *p++ = suffix;
3286       *p++ = '\0';
3287       optable->handlers[(int) mode].libfunc
3288         = gen_rtx (SYMBOL_REF, Pmode, libfunc_name);
3289     }
3290 }
3291
3292 /* Initialize the libfunc fields of an entire group of entries in some
3293    optab which correspond to all integer mode operations.  The parameters
3294    have the same meaning as similarly named ones for the `init_libfuncs'
3295    routine.  (See above).  */
3296
3297 static void
3298 init_integral_libfuncs (optable, opname, suffix)
3299     register optab optable;
3300     register char *opname;
3301     register char suffix;
3302 {
3303   init_libfuncs (optable, SImode, TImode, opname, suffix);
3304 }
3305
3306 /* Initialize the libfunc fields of an entire group of entries in some
3307    optab which correspond to all real mode operations.  The parameters
3308    have the same meaning as similarly named ones for the `init_libfuncs'
3309    routine.  (See above).  */
3310
3311 static void
3312 init_floating_libfuncs (optable, opname, suffix)
3313     register optab optable;
3314     register char *opname;
3315     register char suffix;
3316 {
3317   init_libfuncs (optable, SFmode, TFmode, opname, suffix);
3318 }
3319
3320 /* Call this once to initialize the contents of the optabs
3321    appropriately for the current target machine.  */
3322
3323 void
3324 init_optabs ()
3325 {
3326   int i;
3327
3328   init_fixtab ();
3329   init_floattab ();
3330   init_extends ();
3331
3332   add_optab = init_optab (PLUS);
3333   sub_optab = init_optab (MINUS);
3334   smul_optab = init_optab (MULT);
3335   smul_widen_optab = init_optab (UNKNOWN);
3336   umul_widen_optab = init_optab (UNKNOWN);
3337   sdiv_optab = init_optab (DIV);
3338   sdivmod_optab = init_optab (UNKNOWN);
3339   udiv_optab = init_optab (UDIV);
3340   udivmod_optab = init_optab (UNKNOWN);
3341   smod_optab = init_optab (MOD);
3342   umod_optab = init_optab (UMOD);
3343   flodiv_optab = init_optab (DIV);
3344   ftrunc_optab = init_optab (UNKNOWN);
3345   and_optab = init_optab (AND);
3346   ior_optab = init_optab (IOR);
3347   xor_optab = init_optab (XOR);
3348   ashl_optab = init_optab (ASHIFT);
3349   ashr_optab = init_optab (ASHIFTRT);
3350   lshl_optab = init_optab (LSHIFT);
3351   lshr_optab = init_optab (LSHIFTRT);
3352   rotl_optab = init_optab (ROTATE);
3353   rotr_optab = init_optab (ROTATERT);
3354   smin_optab = init_optab (SMIN);
3355   smax_optab = init_optab (SMAX);
3356   umin_optab = init_optab (UMIN);
3357   umax_optab = init_optab (UMAX);
3358   mov_optab = init_optab (UNKNOWN);
3359   movstrict_optab = init_optab (UNKNOWN);
3360   cmp_optab = init_optab (UNKNOWN);
3361   ucmp_optab = init_optab (UNKNOWN);
3362   tst_optab = init_optab (UNKNOWN);
3363   neg_optab = init_optab (NEG);
3364   abs_optab = init_optab (ABS);
3365   one_cmpl_optab = init_optab (NOT);
3366   ffs_optab = init_optab (FFS);
3367   sqrt_optab = init_optab (SQRT);
3368   sin_optab = init_optab (UNKNOWN);
3369   cos_optab = init_optab (UNKNOWN);
3370   strlen_optab = init_optab (UNKNOWN);
3371
3372 #ifdef HAVE_addqi3
3373   if (HAVE_addqi3)
3374     add_optab->handlers[(int) QImode].insn_code = CODE_FOR_addqi3;
3375 #endif
3376 #ifdef HAVE_addhi3
3377   if (HAVE_addhi3)
3378     add_optab->handlers[(int) HImode].insn_code = CODE_FOR_addhi3;
3379 #endif
3380 #ifdef HAVE_addpsi3
3381   if (HAVE_addpsi3)
3382     add_optab->handlers[(int) PSImode].insn_code = CODE_FOR_addpsi3;
3383 #endif
3384 #ifdef HAVE_addsi3
3385   if (HAVE_addsi3)
3386     add_optab->handlers[(int) SImode].insn_code = CODE_FOR_addsi3;
3387 #endif
3388 #ifdef HAVE_adddi3
3389   if (HAVE_adddi3)
3390     add_optab->handlers[(int) DImode].insn_code = CODE_FOR_adddi3;
3391 #endif
3392 #ifdef HAVE_addti3
3393   if (HAVE_addti3)
3394     add_optab->handlers[(int) TImode].insn_code = CODE_FOR_addti3;
3395 #endif
3396 #ifdef HAVE_addsf3
3397   if (HAVE_addsf3)
3398     add_optab->handlers[(int) SFmode].insn_code = CODE_FOR_addsf3;
3399 #endif
3400 #ifdef HAVE_adddf3
3401   if (HAVE_adddf3)
3402     add_optab->handlers[(int) DFmode].insn_code = CODE_FOR_adddf3;
3403 #endif
3404 #ifdef HAVE_addxf3
3405   if (HAVE_addxf3)
3406     add_optab->handlers[(int) XFmode].insn_code = CODE_FOR_addxf3;
3407 #endif
3408 #ifdef HAVE_addtf3
3409   if (HAVE_addtf3)
3410     add_optab->handlers[(int) TFmode].insn_code = CODE_FOR_addtf3;
3411 #endif
3412   init_integral_libfuncs (add_optab, "add", '3');
3413   init_floating_libfuncs (add_optab, "add", '3');
3414
3415 #ifdef HAVE_subqi3
3416   if (HAVE_subqi3)
3417     sub_optab->handlers[(int) QImode].insn_code = CODE_FOR_subqi3;
3418 #endif
3419 #ifdef HAVE_subhi3
3420   if (HAVE_subhi3)
3421     sub_optab->handlers[(int) HImode].insn_code = CODE_FOR_subhi3;
3422 #endif
3423 #ifdef HAVE_subpsi3
3424   if (HAVE_subpsi3)
3425     sub_optab->handlers[(int) PSImode].insn_code = CODE_FOR_subpsi3;
3426 #endif
3427 #ifdef HAVE_subsi3
3428   if (HAVE_subsi3)
3429     sub_optab->handlers[(int) SImode].insn_code = CODE_FOR_subsi3;
3430 #endif
3431 #ifdef HAVE_subdi3
3432   if (HAVE_subdi3)
3433     sub_optab->handlers[(int) DImode].insn_code = CODE_FOR_subdi3;
3434 #endif
3435 #ifdef HAVE_subti3
3436   if (HAVE_subti3)
3437     sub_optab->handlers[(int) TImode].insn_code = CODE_FOR_subti3;
3438 #endif
3439 #ifdef HAVE_subsf3
3440   if (HAVE_subsf3)
3441     sub_optab->handlers[(int) SFmode].insn_code = CODE_FOR_subsf3;
3442 #endif
3443 #ifdef HAVE_subdf3
3444   if (HAVE_subdf3)
3445     sub_optab->handlers[(int) DFmode].insn_code = CODE_FOR_subdf3;
3446 #endif
3447 #ifdef HAVE_subxf3
3448   if (HAVE_subxf3)
3449     sub_optab->handlers[(int) XFmode].insn_code = CODE_FOR_subxf3;
3450 #endif
3451 #ifdef HAVE_subtf3
3452   if (HAVE_subtf3)
3453     sub_optab->handlers[(int) TFmode].insn_code = CODE_FOR_subtf3;
3454 #endif
3455   init_integral_libfuncs (sub_optab, "sub", '3');
3456   init_floating_libfuncs (sub_optab, "sub", '3');
3457
3458 #ifdef HAVE_mulqi3
3459   if (HAVE_mulqi3)
3460     smul_optab->handlers[(int) QImode].insn_code = CODE_FOR_mulqi3;
3461 #endif
3462 #ifdef HAVE_mulhi3
3463   if (HAVE_mulhi3)
3464     smul_optab->handlers[(int) HImode].insn_code = CODE_FOR_mulhi3;
3465 #endif
3466 #ifdef HAVE_mulpsi3
3467   if (HAVE_mulpsi3)
3468     smul_optab->handlers[(int) PSImode].insn_code = CODE_FOR_mulpsi3;
3469 #endif
3470 #ifdef HAVE_mulsi3
3471   if (HAVE_mulsi3)
3472     smul_optab->handlers[(int) SImode].insn_code = CODE_FOR_mulsi3;
3473 #endif
3474 #ifdef HAVE_muldi3
3475   if (HAVE_muldi3)
3476     smul_optab->handlers[(int) DImode].insn_code = CODE_FOR_muldi3;
3477 #endif
3478 #ifdef HAVE_multi3
3479   if (HAVE_multi3)
3480     smul_optab->handlers[(int) TImode].insn_code = CODE_FOR_multi3;
3481 #endif
3482 #ifdef HAVE_mulsf3
3483   if (HAVE_mulsf3)
3484     smul_optab->handlers[(int) SFmode].insn_code = CODE_FOR_mulsf3;
3485 #endif
3486 #ifdef HAVE_muldf3
3487   if (HAVE_muldf3)
3488     smul_optab->handlers[(int) DFmode].insn_code = CODE_FOR_muldf3;
3489 #endif
3490 #ifdef HAVE_mulxf3
3491   if (HAVE_mulxf3)
3492     smul_optab->handlers[(int) XFmode].insn_code = CODE_FOR_mulxf3;
3493 #endif
3494 #ifdef HAVE_multf3
3495   if (HAVE_multf3)
3496     smul_optab->handlers[(int) TFmode].insn_code = CODE_FOR_multf3;
3497 #endif
3498   init_integral_libfuncs (smul_optab, "mul", '3');
3499   init_floating_libfuncs (smul_optab, "mul", '3');
3500
3501 #ifdef MULSI3_LIBCALL
3502   smul_optab->handlers[(int) SImode].libfunc
3503     = gen_rtx (SYMBOL_REF, Pmode, MULSI3_LIBCALL);
3504 #endif
3505 #ifdef MULDI3_LIBCALL
3506   smul_optab->handlers[(int) DImode].libfunc
3507     = gen_rtx (SYMBOL_REF, Pmode, MULDI3_LIBCALL);
3508 #endif
3509 #ifdef MULTI3_LIBCALL
3510   smul_optab->handlers[(int) TImode].libfunc
3511     = gen_rtx (SYMBOL_REF, Pmode, MULTI3_LIBCALL);
3512 #endif
3513
3514 #ifdef HAVE_mulqihi3
3515   if (HAVE_mulqihi3)
3516     smul_widen_optab->handlers[(int) HImode].insn_code = CODE_FOR_mulqihi3;
3517 #endif
3518 #ifdef HAVE_mulhisi3
3519   if (HAVE_mulhisi3)
3520     smul_widen_optab->handlers[(int) SImode].insn_code = CODE_FOR_mulhisi3;
3521 #endif
3522 #ifdef HAVE_mulsidi3
3523   if (HAVE_mulsidi3)
3524     smul_widen_optab->handlers[(int) DImode].insn_code = CODE_FOR_mulsidi3;
3525 #endif
3526 #ifdef HAVE_mulditi3
3527   if (HAVE_mulditi3)
3528     smul_widen_optab->handlers[(int) TImode].insn_code = CODE_FOR_mulditi3;
3529 #endif
3530
3531 #ifdef HAVE_umulqihi3
3532   if (HAVE_umulqihi3)
3533     umul_widen_optab->handlers[(int) HImode].insn_code = CODE_FOR_umulqihi3;
3534 #endif
3535 #ifdef HAVE_umulhisi3
3536   if (HAVE_umulhisi3)
3537     umul_widen_optab->handlers[(int) SImode].insn_code = CODE_FOR_umulhisi3;
3538 #endif
3539 #ifdef HAVE_umulsidi3
3540   if (HAVE_umulsidi3)
3541     umul_widen_optab->handlers[(int) DImode].insn_code = CODE_FOR_umulsidi3;
3542 #endif
3543 #ifdef HAVE_umulditi3
3544   if (HAVE_umulditi3)
3545     umul_widen_optab->handlers[(int) TImode].insn_code = CODE_FOR_umulditi3;
3546 #endif
3547
3548 #ifdef HAVE_divqi3
3549   if (HAVE_divqi3)
3550     sdiv_optab->handlers[(int) QImode].insn_code = CODE_FOR_divqi3;
3551 #endif
3552 #ifdef HAVE_divhi3
3553   if (HAVE_divhi3)
3554     sdiv_optab->handlers[(int) HImode].insn_code = CODE_FOR_divhi3;
3555 #endif
3556 #ifdef HAVE_divpsi3
3557   if (HAVE_divpsi3)
3558     sdiv_optab->handlers[(int) PSImode].insn_code = CODE_FOR_divpsi3;
3559 #endif
3560 #ifdef HAVE_divsi3
3561   if (HAVE_divsi3)
3562     sdiv_optab->handlers[(int) SImode].insn_code = CODE_FOR_divsi3;
3563 #endif
3564 #ifdef HAVE_divdi3
3565   if (HAVE_divdi3)
3566     sdiv_optab->handlers[(int) DImode].insn_code = CODE_FOR_divdi3;
3567 #endif
3568 #ifdef HAVE_divti3
3569   if (HAVE_divti3)
3570     sdiv_optab->handlers[(int) TImode].insn_code = CODE_FOR_divti3;
3571 #endif
3572   init_integral_libfuncs (sdiv_optab, "div", '3');
3573
3574 #ifdef DIVSI3_LIBCALL
3575   sdiv_optab->handlers[(int) SImode].libfunc
3576     = gen_rtx (SYMBOL_REF, Pmode, DIVSI3_LIBCALL);
3577 #endif
3578 #ifdef DIVDI3_LIBCALL
3579   sdiv_optab->handlers[(int) DImode].libfunc
3580     = gen_rtx (SYMBOL_REF, Pmode, DIVDI3_LIBCALL);
3581 #endif
3582 #ifdef DIVTI3_LIBCALL
3583   sdiv_optab->handlers[(int) TImode].libfunc
3584     = gen_rtx (SYMBOL_REF, Pmode, DIVTI3_LIBCALL);
3585 #endif
3586
3587 #ifdef HAVE_udivqi3
3588   if (HAVE_udivqi3)
3589     udiv_optab->handlers[(int) QImode].insn_code = CODE_FOR_udivqi3;
3590 #endif
3591 #ifdef HAVE_udivhi3
3592   if (HAVE_udivhi3)
3593     udiv_optab->handlers[(int) HImode].insn_code = CODE_FOR_udivhi3;
3594 #endif
3595 #ifdef HAVE_udivpsi3
3596   if (HAVE_udivpsi3)
3597     udiv_optab->handlers[(int) PSImode].insn_code = CODE_FOR_udivpsi3;
3598 #endif
3599 #ifdef HAVE_udivsi3
3600   if (HAVE_udivsi3)
3601     udiv_optab->handlers[(int) SImode].insn_code = CODE_FOR_udivsi3;
3602 #endif
3603 #ifdef HAVE_udivdi3
3604   if (HAVE_udivdi3)
3605     udiv_optab->handlers[(int) DImode].insn_code = CODE_FOR_udivdi3;
3606 #endif
3607 #ifdef HAVE_udivti3
3608   if (HAVE_udivti3)
3609     udiv_optab->handlers[(int) TImode].insn_code = CODE_FOR_udivti3;
3610 #endif
3611   init_integral_libfuncs (udiv_optab, "udiv", '3');
3612
3613 #ifdef UDIVSI3_LIBCALL
3614   udiv_optab->handlers[(int) SImode].libfunc
3615     = gen_rtx (SYMBOL_REF, Pmode, UDIVSI3_LIBCALL);
3616 #endif
3617 #ifdef UDIVDI3_LIBCALL
3618   udiv_optab->handlers[(int) DImode].libfunc
3619     = gen_rtx (SYMBOL_REF, Pmode, UDIVDI3_LIBCALL);
3620 #endif
3621 #ifdef UDIVTI3_LIBCALL
3622   udiv_optab->handlers[(int) TImode].libfunc
3623     = gen_rtx (SYMBOL_REF, Pmode, UDIVTI3_LIBCALL);
3624 #endif
3625
3626 #ifdef HAVE_divmodqi4
3627   if (HAVE_divmodqi4)
3628     sdivmod_optab->handlers[(int) QImode].insn_code = CODE_FOR_divmodqi4;
3629 #endif
3630 #ifdef HAVE_divmodhi4
3631   if (HAVE_divmodhi4)
3632     sdivmod_optab->handlers[(int) HImode].insn_code = CODE_FOR_divmodhi4;
3633 #endif
3634 #ifdef HAVE_divmodsi4
3635   if (HAVE_divmodsi4)
3636     sdivmod_optab->handlers[(int) SImode].insn_code = CODE_FOR_divmodsi4;
3637 #endif
3638 #ifdef HAVE_divmoddi4
3639   if (HAVE_divmoddi4)
3640     sdivmod_optab->handlers[(int) DImode].insn_code = CODE_FOR_divmoddi4;
3641 #endif
3642 #ifdef HAVE_divmodti4
3643   if (HAVE_divmodti4)
3644     sdivmod_optab->handlers[(int) TImode].insn_code = CODE_FOR_divmodti4;
3645 #endif
3646   init_integral_libfuncs (sdivmod_optab, "divmod", '4');
3647
3648 #ifdef HAVE_udivmodqi4
3649   if (HAVE_udivmodqi4)
3650     udivmod_optab->handlers[(int) QImode].insn_code = CODE_FOR_udivmodqi4;
3651 #endif
3652 #ifdef HAVE_udivmodhi4
3653   if (HAVE_udivmodhi4)
3654     udivmod_optab->handlers[(int) HImode].insn_code = CODE_FOR_udivmodhi4;
3655 #endif
3656 #ifdef HAVE_udivmodsi4
3657   if (HAVE_udivmodsi4)
3658     udivmod_optab->handlers[(int) SImode].insn_code = CODE_FOR_udivmodsi4;
3659 #endif
3660 #ifdef HAVE_udivmoddi4
3661   if (HAVE_udivmoddi4)
3662     udivmod_optab->handlers[(int) DImode].insn_code = CODE_FOR_udivmoddi4;
3663 #endif
3664 #ifdef HAVE_udivmodti4
3665   if (HAVE_udivmodti4)
3666     udivmod_optab->handlers[(int) TImode].insn_code = CODE_FOR_udivmodti4;
3667 #endif
3668   init_integral_libfuncs (udivmod_optab, "udivmod", '4');
3669
3670 #ifdef HAVE_modqi3
3671   if (HAVE_modqi3)
3672     smod_optab->handlers[(int) QImode].insn_code = CODE_FOR_modqi3;
3673 #endif
3674 #ifdef HAVE_modhi3
3675   if (HAVE_modhi3)
3676     smod_optab->handlers[(int) HImode].insn_code = CODE_FOR_modhi3;
3677 #endif
3678 #ifdef HAVE_modpsi3
3679   if (HAVE_modpsi3)
3680     smod_optab->handlers[(int) PSImode].insn_code = CODE_FOR_modpsi3;
3681 #endif
3682 #ifdef HAVE_modsi3
3683   if (HAVE_modsi3)
3684     smod_optab->handlers[(int) SImode].insn_code = CODE_FOR_modsi3;
3685 #endif
3686 #ifdef HAVE_moddi3
3687   if (HAVE_moddi3)
3688     smod_optab->handlers[(int) DImode].insn_code = CODE_FOR_moddi3;
3689 #endif
3690 #ifdef HAVE_modti3
3691   if (HAVE_modti3)
3692     smod_optab->handlers[(int) TImode].insn_code = CODE_FOR_modti3;
3693 #endif
3694   init_integral_libfuncs (smod_optab, "mod", '3');
3695
3696 #ifdef MODSI3_LIBCALL
3697   smod_optab->handlers[(int) SImode].libfunc
3698     = gen_rtx (SYMBOL_REF, Pmode, MODSI3_LIBCALL);
3699 #endif
3700 #ifdef MODDI3_LIBCALL
3701   smod_optab->handlers[(int) DImode].libfunc
3702     = gen_rtx (SYMBOL_REF, Pmode, MODDI3_LIBCALL);
3703 #endif
3704 #ifdef MODTI3_LIBCALL
3705   smod_optab->handlers[(int) TImode].libfunc
3706     = gen_rtx (SYMBOL_REF, Pmode, MODTI3_LIBCALL);
3707 #endif
3708
3709 #ifdef HAVE_umodqi3
3710   if (HAVE_umodqi3)
3711     umod_optab->handlers[(int) QImode].insn_code = CODE_FOR_umodqi3;
3712 #endif
3713 #ifdef HAVE_umodhi3
3714   if (HAVE_umodhi3)
3715     umod_optab->handlers[(int) HImode].insn_code = CODE_FOR_umodhi3;
3716 #endif
3717 #ifdef HAVE_umodpsi3
3718   if (HAVE_umodpsi3)
3719     umod_optab->handlers[(int) PSImode].insn_code = CODE_FOR_umodpsi3;
3720 #endif
3721 #ifdef HAVE_umodsi3
3722   if (HAVE_umodsi3)
3723     umod_optab->handlers[(int) SImode].insn_code = CODE_FOR_umodsi3;
3724 #endif
3725 #ifdef HAVE_umoddi3
3726   if (HAVE_umoddi3)
3727     umod_optab->handlers[(int) DImode].insn_code = CODE_FOR_umoddi3;
3728 #endif
3729 #ifdef HAVE_umodti3
3730   if (HAVE_umodti3)
3731     umod_optab->handlers[(int) TImode].insn_code = CODE_FOR_umodti3;
3732 #endif
3733   init_integral_libfuncs (umod_optab, "umod", '3');
3734
3735 #ifdef UMODSI3_LIBCALL
3736   umod_optab->handlers[(int) SImode].libfunc
3737     = gen_rtx (SYMBOL_REF, Pmode, UMODSI3_LIBCALL);
3738 #endif
3739 #ifdef UMODDI3_LIBCALL
3740   umod_optab->handlers[(int) DImode].libfunc
3741     = gen_rtx (SYMBOL_REF, Pmode, UMODDI3_LIBCALL);
3742 #endif
3743 #ifdef UMODTI3_LIBCALL
3744   umod_optab->handlers[(int) TImode].libfunc
3745     = gen_rtx (SYMBOL_REF, Pmode, UMODTI3_LIBCALL);
3746 #endif
3747
3748 #ifdef HAVE_divsf3
3749   if (HAVE_divsf3)
3750     flodiv_optab->handlers[(int) SFmode].insn_code = CODE_FOR_divsf3;
3751 #endif
3752 #ifdef HAVE_divdf3
3753   if (HAVE_divdf3)
3754     flodiv_optab->handlers[(int) DFmode].insn_code = CODE_FOR_divdf3;
3755 #endif
3756 #ifdef HAVE_divxf3
3757   if (HAVE_divxf3)
3758     flodiv_optab->handlers[(int) XFmode].insn_code = CODE_FOR_divxf3;
3759 #endif
3760 #ifdef HAVE_divtf3
3761   if (HAVE_divtf3)
3762     flodiv_optab->handlers[(int) TFmode].insn_code = CODE_FOR_divtf3;
3763 #endif
3764   init_floating_libfuncs (flodiv_optab, "div", '3');
3765
3766 #ifdef HAVE_ftruncsf2
3767   if (HAVE_ftruncsf2)
3768     ftrunc_optab->handlers[(int) SFmode].insn_code = CODE_FOR_ftruncsf2;
3769 #endif
3770 #ifdef HAVE_ftruncdf2
3771   if (HAVE_ftruncdf2)
3772     ftrunc_optab->handlers[(int) DFmode].insn_code = CODE_FOR_ftruncdf2;
3773 #endif
3774 #ifdef HAVE_ftruncxf2
3775   if (HAVE_ftruncxf2)
3776     ftrunc_optab->handlers[(int) XFmode].insn_code = CODE_FOR_ftruncxf2;
3777 #endif
3778 #ifdef HAVE_ftrunctf2
3779   if (HAVE_ftrunctf2)
3780     ftrunc_optab->handlers[(int) TFmode].insn_code = CODE_FOR_ftrunctf2;
3781 #endif
3782   init_floating_libfuncs (ftrunc_optab, "ftrunc", '2');
3783
3784 #ifdef HAVE_andqi3
3785   if (HAVE_andqi3)
3786     and_optab->handlers[(int) QImode].insn_code = CODE_FOR_andqi3;
3787 #endif
3788 #ifdef HAVE_andhi3
3789   if (HAVE_andhi3)
3790     and_optab->handlers[(int) HImode].insn_code = CODE_FOR_andhi3;
3791 #endif
3792 #ifdef HAVE_andpsi3
3793   if (HAVE_andpsi3)
3794     and_optab->handlers[(int) PSImode].insn_code = CODE_FOR_andpsi3;
3795 #endif
3796 #ifdef HAVE_andsi3
3797   if (HAVE_andsi3)
3798     and_optab->handlers[(int) SImode].insn_code = CODE_FOR_andsi3;
3799 #endif
3800 #ifdef HAVE_anddi3
3801   if (HAVE_anddi3)
3802     and_optab->handlers[(int) DImode].insn_code = CODE_FOR_anddi3;
3803 #endif
3804 #ifdef HAVE_andti3
3805   if (HAVE_andti3)
3806     and_optab->handlers[(int) TImode].insn_code = CODE_FOR_andti3;
3807 #endif
3808   init_integral_libfuncs (and_optab, "and", '3');
3809
3810 #ifdef HAVE_iorqi3
3811   if (HAVE_iorqi3)
3812     ior_optab->handlers[(int) QImode].insn_code = CODE_FOR_iorqi3;
3813 #endif
3814 #ifdef HAVE_iorhi3
3815   if (HAVE_iorhi3)
3816     ior_optab->handlers[(int) HImode].insn_code = CODE_FOR_iorhi3;
3817 #endif
3818 #ifdef HAVE_iorpsi3
3819   if (HAVE_iorpsi3)
3820     ior_optab->handlers[(int) PSImode].insn_code = CODE_FOR_iorpsi3;
3821 #endif
3822 #ifdef HAVE_iorsi3
3823   if (HAVE_iorsi3)
3824     ior_optab->handlers[(int) SImode].insn_code = CODE_FOR_iorsi3;
3825 #endif
3826 #ifdef HAVE_iordi3
3827   if (HAVE_iordi3)
3828     ior_optab->handlers[(int) DImode].insn_code = CODE_FOR_iordi3;
3829 #endif
3830 #ifdef HAVE_iorti3
3831   if (HAVE_iorti3)
3832     ior_optab->handlers[(int) TImode].insn_code = CODE_FOR_iorti3;
3833 #endif
3834   init_integral_libfuncs (ior_optab, "ior", '3');
3835
3836 #ifdef HAVE_xorqi3
3837   if (HAVE_xorqi3)
3838     xor_optab->handlers[(int) QImode].insn_code = CODE_FOR_xorqi3;
3839 #endif
3840 #ifdef HAVE_xorhi3
3841   if (HAVE_xorhi3)
3842     xor_optab->handlers[(int) HImode].insn_code = CODE_FOR_xorhi3;
3843 #endif
3844 #ifdef HAVE_xorpsi3
3845   if (HAVE_xorpsi3)
3846     xor_optab->handlers[(int) PSImode].insn_code = CODE_FOR_xorpsi3;
3847 #endif
3848 #ifdef HAVE_xorsi3
3849   if (HAVE_xorsi3)
3850     xor_optab->handlers[(int) SImode].insn_code = CODE_FOR_xorsi3;
3851 #endif
3852 #ifdef HAVE_xordi3
3853   if (HAVE_xordi3)
3854     xor_optab->handlers[(int) DImode].insn_code = CODE_FOR_xordi3;
3855 #endif
3856 #ifdef HAVE_xorti3
3857   if (HAVE_xorti3)
3858     xor_optab->handlers[(int) TImode].insn_code = CODE_FOR_xorti3;
3859 #endif
3860   init_integral_libfuncs (xor_optab, "xor", '3');
3861
3862 #ifdef HAVE_ashlqi3
3863   if (HAVE_ashlqi3)
3864     ashl_optab->handlers[(int) QImode].insn_code = CODE_FOR_ashlqi3;
3865 #endif
3866 #ifdef HAVE_ashlhi3
3867   if (HAVE_ashlhi3)
3868     ashl_optab->handlers[(int) HImode].insn_code = CODE_FOR_ashlhi3;
3869 #endif
3870 #ifdef HAVE_ashlpsi3
3871   if (HAVE_ashlpsi3)
3872     ashl_optab->handlers[(int) PSImode].insn_code = CODE_FOR_ashlpsi3;
3873 #endif
3874 #ifdef HAVE_ashlsi3
3875   if (HAVE_ashlsi3)
3876     ashl_optab->handlers[(int) SImode].insn_code = CODE_FOR_ashlsi3;
3877 #endif
3878 #ifdef HAVE_ashldi3
3879   if (HAVE_ashldi3)
3880     ashl_optab->handlers[(int) DImode].insn_code = CODE_FOR_ashldi3;
3881 #endif
3882 #ifdef HAVE_ashlti3
3883   if (HAVE_ashlti3)
3884     ashl_optab->handlers[(int) TImode].insn_code = CODE_FOR_ashlti3;
3885 #endif
3886   init_integral_libfuncs (ashl_optab, "ashl", '3');
3887
3888 #ifdef HAVE_ashrqi3
3889   if (HAVE_ashrqi3)
3890     ashr_optab->handlers[(int) QImode].insn_code = CODE_FOR_ashrqi3;
3891 #endif
3892 #ifdef HAVE_ashrhi3
3893   if (HAVE_ashrhi3)
3894     ashr_optab->handlers[(int) HImode].insn_code = CODE_FOR_ashrhi3;
3895 #endif
3896 #ifdef HAVE_ashrpsi3
3897   if (HAVE_ashrpsi3)
3898     ashr_optab->handlers[(int) PSImode].insn_code = CODE_FOR_ashrpsi3;
3899 #endif
3900 #ifdef HAVE_ashrsi3
3901   if (HAVE_ashrsi3)
3902     ashr_optab->handlers[(int) SImode].insn_code = CODE_FOR_ashrsi3;
3903 #endif
3904 #ifdef HAVE_ashrdi3
3905   if (HAVE_ashrdi3)
3906     ashr_optab->handlers[(int) DImode].insn_code = CODE_FOR_ashrdi3;
3907 #endif
3908 #ifdef HAVE_ashrti3
3909   if (HAVE_ashrti3)
3910     ashr_optab->handlers[(int) TImode].insn_code = CODE_FOR_ashrti3;
3911 #endif
3912   init_integral_libfuncs (ashr_optab, "ashr", '3');
3913
3914 #ifdef HAVE_lshlqi3
3915   if (HAVE_lshlqi3)
3916     lshl_optab->handlers[(int) QImode].insn_code = CODE_FOR_lshlqi3;
3917 #endif
3918 #ifdef HAVE_lshlhi3
3919   if (HAVE_lshlhi3)
3920     lshl_optab->handlers[(int) HImode].insn_code = CODE_FOR_lshlhi3;
3921 #endif
3922 #ifdef HAVE_lshlpsi3
3923   if (HAVE_lshlpsi3)
3924     lshl_optab->handlers[(int) PSImode].insn_code = CODE_FOR_lshlpsi3;
3925 #endif
3926 #ifdef HAVE_lshlsi3
3927   if (HAVE_lshlsi3)
3928     lshl_optab->handlers[(int) SImode].insn_code = CODE_FOR_lshlsi3;
3929 #endif
3930 #ifdef HAVE_lshldi3
3931   if (HAVE_lshldi3)
3932     lshl_optab->handlers[(int) DImode].insn_code = CODE_FOR_lshldi3;
3933 #endif
3934 #ifdef HAVE_lshlti3
3935   if (HAVE_lshlti3)
3936     lshl_optab->handlers[(int) TImode].insn_code = CODE_FOR_lshlti3;
3937 #endif
3938   init_integral_libfuncs (lshl_optab, "lshl", '3');
3939
3940 #ifdef HAVE_lshrqi3
3941   if (HAVE_lshrqi3)
3942     lshr_optab->handlers[(int) QImode].insn_code = CODE_FOR_lshrqi3;
3943 #endif
3944 #ifdef HAVE_lshrhi3
3945   if (HAVE_lshrhi3)
3946     lshr_optab->handlers[(int) HImode].insn_code = CODE_FOR_lshrhi3;
3947 #endif
3948 #ifdef HAVE_lshrpsi3
3949   if (HAVE_lshrpsi3)
3950     lshr_optab->handlers[(int) PSImode].insn_code = CODE_FOR_lshrpsi3;
3951 #endif
3952 #ifdef HAVE_lshrsi3
3953   if (HAVE_lshrsi3)
3954     lshr_optab->handlers[(int) SImode].insn_code = CODE_FOR_lshrsi3;
3955 #endif
3956 #ifdef HAVE_lshrdi3
3957   if (HAVE_lshrdi3)
3958     lshr_optab->handlers[(int) DImode].insn_code = CODE_FOR_lshrdi3;
3959 #endif
3960 #ifdef HAVE_lshrti3
3961   if (HAVE_lshrti3)
3962     lshr_optab->handlers[(int) TImode].insn_code = CODE_FOR_lshrti3;
3963 #endif
3964   init_integral_libfuncs (lshr_optab, "lshr", '3');
3965
3966 #ifdef HAVE_rotlqi3
3967   if (HAVE_rotlqi3)
3968     rotl_optab->handlers[(int) QImode].insn_code = CODE_FOR_rotlqi3;
3969 #endif
3970 #ifdef HAVE_rotlhi3
3971   if (HAVE_rotlhi3)
3972     rotl_optab->handlers[(int) HImode].insn_code = CODE_FOR_rotlhi3;
3973 #endif
3974 #ifdef HAVE_rotlpsi3
3975   if (HAVE_rotlpsi3)
3976     rotl_optab->handlers[(int) PSImode].insn_code = CODE_FOR_rotlpsi3;
3977 #endif
3978 #ifdef HAVE_rotlsi3
3979   if (HAVE_rotlsi3)
3980     rotl_optab->handlers[(int) SImode].insn_code = CODE_FOR_rotlsi3;
3981 #endif
3982 #ifdef HAVE_rotldi3
3983   if (HAVE_rotldi3)
3984     rotl_optab->handlers[(int) DImode].insn_code = CODE_FOR_rotldi3;
3985 #endif
3986 #ifdef HAVE_rotlti3
3987   if (HAVE_rotlti3)
3988     rotl_optab->handlers[(int) TImode].insn_code = CODE_FOR_rotlti3;
3989 #endif
3990   init_integral_libfuncs (rotl_optab, "rotl", '3');
3991
3992 #ifdef HAVE_rotrqi3
3993   if (HAVE_rotrqi3)
3994     rotr_optab->handlers[(int) QImode].insn_code = CODE_FOR_rotrqi3;
3995 #endif
3996 #ifdef HAVE_rotrhi3
3997   if (HAVE_rotrhi3)
3998     rotr_optab->handlers[(int) HImode].insn_code = CODE_FOR_rotrhi3;
3999 #endif
4000 #ifdef HAVE_rotrpsi3
4001   if (HAVE_rotrpsi3)
4002     rotr_optab->handlers[(int) PSImode].insn_code = CODE_FOR_rotrpsi3;
4003 #endif
4004 #ifdef HAVE_rotrsi3
4005   if (HAVE_rotrsi3)
4006     rotr_optab->handlers[(int) SImode].insn_code = CODE_FOR_rotrsi3;
4007 #endif
4008 #ifdef HAVE_rotrdi3
4009   if (HAVE_rotrdi3)
4010     rotr_optab->handlers[(int) DImode].insn_code = CODE_FOR_rotrdi3;
4011 #endif
4012 #ifdef HAVE_rotrti3
4013   if (HAVE_rotrti3)
4014     rotr_optab->handlers[(int) TImode].insn_code = CODE_FOR_rotrti3;
4015 #endif
4016   init_integral_libfuncs (rotr_optab, "rotr", '3');
4017
4018 #ifdef HAVE_sminqi3
4019   if (HAVE_sminqi3)
4020     smin_optab->handlers[(int) QImode].insn_code = CODE_FOR_sminqi3;
4021 #endif
4022 #ifdef HAVE_sminhi3
4023   if (HAVE_sminhi3)
4024     smin_optab->handlers[(int) HImode].insn_code = CODE_FOR_sminhi3;
4025 #endif
4026 #ifdef HAVE_sminsi3
4027   if (HAVE_sminsi3)
4028     smin_optab->handlers[(int) SImode].insn_code = CODE_FOR_sminsi3;
4029 #endif
4030 #ifdef HAVE_smindi3
4031   if (HAVE_smindi3)
4032     smin_optab->handlers[(int) DImode].insn_code = CODE_FOR_smindi3;
4033 #endif
4034 #ifdef HAVE_sminti3
4035   if (HAVE_sminti3)
4036     smin_optab->handlers[(int) TImode].insn_code = CODE_FOR_sminti3;
4037 #endif
4038 #ifdef HAVE_minsf3
4039   if (HAVE_minsf3)
4040     smin_optab->handlers[(int) SFmode].insn_code = CODE_FOR_minsf3;
4041 #endif
4042 #ifdef HAVE_mindf3
4043   if (HAVE_mindf3)
4044     smin_optab->handlers[(int) DFmode].insn_code = CODE_FOR_mindf3;
4045 #endif
4046 #ifdef HAVE_minxf3
4047   if (HAVE_minxf3)
4048     smin_optab->handlers[(int) XFmode].insn_code = CODE_FOR_minxf3;
4049 #endif
4050 #ifdef HAVE_mintf3
4051   if (HAVE_mintf3)
4052     smin_optab->handlers[(int) TFmode].insn_code = CODE_FOR_mintf3;
4053 #endif
4054   init_integral_libfuncs (smin_optab, "min", '3');
4055   init_floating_libfuncs (smin_optab, "min", '3');
4056
4057 #ifdef HAVE_smaxqi3
4058   if (HAVE_smaxqi3)
4059     smax_optab->handlers[(int) QImode].insn_code = CODE_FOR_smaxqi3;
4060 #endif
4061 #ifdef HAVE_smaxhi3
4062   if (HAVE_smaxhi3)
4063     smax_optab->handlers[(int) HImode].insn_code = CODE_FOR_smaxhi3;
4064 #endif
4065 #ifdef HAVE_smaxsi3
4066   if (HAVE_smaxsi3)
4067     smax_optab->handlers[(int) SImode].insn_code = CODE_FOR_smaxsi3;
4068 #endif
4069 #ifdef HAVE_smaxdi3
4070   if (HAVE_smaxdi3)
4071     smax_optab->handlers[(int) DImode].insn_code = CODE_FOR_smaxdi3;
4072 #endif
4073 #ifdef HAVE_smaxti3
4074   if (HAVE_smaxti3)
4075     smax_optab->handlers[(int) TImode].insn_code = CODE_FOR_smaxti3;
4076 #endif
4077 #ifdef HAVE_maxsf3
4078   if (HAVE_maxsf3)
4079     smax_optab->handlers[(int) SFmode].insn_code = CODE_FOR_maxsf3;
4080 #endif
4081 #ifdef HAVE_maxdf3
4082   if (HAVE_maxdf3)
4083     smax_optab->handlers[(int) DFmode].insn_code = CODE_FOR_maxdf3;
4084 #endif
4085 #ifdef HAVE_maxxf3
4086   if (HAVE_maxxf3)
4087     smax_optab->handlers[(int) XFmode].insn_code = CODE_FOR_maxxf3;
4088 #endif
4089 #ifdef HAVE_maxtf3
4090   if (HAVE_maxtf3)
4091     smax_optab->handlers[(int) TFmode].insn_code = CODE_FOR_maxtf3;
4092 #endif
4093   init_integral_libfuncs (smax_optab, "max", '3');
4094   init_floating_libfuncs (smax_optab, "max", '3');
4095
4096 #ifdef HAVE_uminqi3
4097   if (HAVE_uminqi3)
4098     umin_optab->handlers[(int) QImode].insn_code = CODE_FOR_uminqi3;
4099 #endif
4100 #ifdef HAVE_uminhi3
4101   if (HAVE_uminhi3)
4102     umin_optab->handlers[(int) HImode].insn_code = CODE_FOR_uminhi3;
4103 #endif
4104 #ifdef HAVE_uminsi3
4105   if (HAVE_uminsi3)
4106     umin_optab->handlers[(int) SImode].insn_code = CODE_FOR_uminsi3;
4107 #endif
4108 #ifdef HAVE_umindi3
4109   if (HAVE_umindi3)
4110     umin_optab->handlers[(int) DImode].insn_code = CODE_FOR_umindi3;
4111 #endif
4112 #ifdef HAVE_uminti3
4113   if (HAVE_uminti3)
4114     umin_optab->handlers[(int) TImode].insn_code = CODE_FOR_uminti3;
4115 #endif
4116   init_integral_libfuncs (umin_optab, "umin", '3');
4117
4118 #ifdef HAVE_umaxqi3
4119   if (HAVE_umaxqi3)
4120     umax_optab->handlers[(int) QImode].insn_code = CODE_FOR_umaxqi3;
4121 #endif
4122 #ifdef HAVE_umaxhi3
4123   if (HAVE_umaxhi3)
4124     umax_optab->handlers[(int) HImode].insn_code = CODE_FOR_umaxhi3;
4125 #endif
4126 #ifdef HAVE_umaxsi3
4127   if (HAVE_umaxsi3)
4128     umax_optab->handlers[(int) SImode].insn_code = CODE_FOR_umaxsi3;
4129 #endif
4130 #ifdef HAVE_umaxdi3
4131   if (HAVE_umaxdi3)
4132     umax_optab->handlers[(int) DImode].insn_code = CODE_FOR_umaxdi3;
4133 #endif
4134 #ifdef HAVE_umaxti3
4135   if (HAVE_umaxti3)
4136     umax_optab->handlers[(int) TImode].insn_code = CODE_FOR_umaxti3;
4137 #endif
4138   init_integral_libfuncs (umax_optab, "umax", '3');
4139
4140 #ifdef HAVE_negqi2
4141   if (HAVE_negqi2)
4142     neg_optab->handlers[(int) QImode].insn_code = CODE_FOR_negqi2;
4143 #endif
4144 #ifdef HAVE_neghi2
4145   if (HAVE_neghi2)
4146     neg_optab->handlers[(int) HImode].insn_code = CODE_FOR_neghi2;
4147 #endif
4148 #ifdef HAVE_negpsi2
4149   if (HAVE_negpsi2)
4150     neg_optab->handlers[(int) PSImode].insn_code = CODE_FOR_negpsi2;
4151 #endif
4152 #ifdef HAVE_negsi2
4153   if (HAVE_negsi2)
4154     neg_optab->handlers[(int) SImode].insn_code = CODE_FOR_negsi2;
4155 #endif
4156 #ifdef HAVE_negdi2
4157   if (HAVE_negdi2)
4158     neg_optab->handlers[(int) DImode].insn_code = CODE_FOR_negdi2;
4159 #endif
4160 #ifdef HAVE_negti2
4161   if (HAVE_negti2)
4162     neg_optab->handlers[(int) TImode].insn_code = CODE_FOR_negti2;
4163 #endif
4164 #ifdef HAVE_negsf2
4165   if (HAVE_negsf2)
4166     neg_optab->handlers[(int) SFmode].insn_code = CODE_FOR_negsf2;
4167 #endif
4168 #ifdef HAVE_negdf2
4169   if (HAVE_negdf2)
4170     neg_optab->handlers[(int) DFmode].insn_code = CODE_FOR_negdf2;
4171 #endif
4172 #ifdef HAVE_negxf2
4173   if (HAVE_negxf2)
4174     neg_optab->handlers[(int) XFmode].insn_code = CODE_FOR_negxf2;
4175 #endif
4176 #ifdef HAVE_negtf2
4177   if (HAVE_negtf2)
4178     neg_optab->handlers[(int) TFmode].insn_code = CODE_FOR_negtf2;
4179 #endif
4180   init_integral_libfuncs (neg_optab, "neg", '2');
4181   init_floating_libfuncs (neg_optab, "neg", '2');
4182
4183 #ifdef HAVE_absqi2
4184   if (HAVE_absqi2)
4185     abs_optab->handlers[(int) QImode].insn_code = CODE_FOR_absqi2;
4186 #endif
4187 #ifdef HAVE_abshi2
4188   if (HAVE_abshi2)
4189     abs_optab->handlers[(int) HImode].insn_code = CODE_FOR_abshi2;
4190 #endif
4191 #ifdef HAVE_abspsi2
4192   if (HAVE_abspsi2)
4193     abs_optab->handlers[(int) PSImode].insn_code = CODE_FOR_abspsi2;
4194 #endif
4195 #ifdef HAVE_abssi2
4196   if (HAVE_abssi2)
4197     abs_optab->handlers[(int) SImode].insn_code = CODE_FOR_abssi2;
4198 #endif
4199 #ifdef HAVE_absdi2
4200   if (HAVE_absdi2)
4201     abs_optab->handlers[(int) DImode].insn_code = CODE_FOR_absdi2;
4202 #endif
4203 #ifdef HAVE_absti2
4204   if (HAVE_absti2)
4205     abs_optab->handlers[(int) TImode].insn_code = CODE_FOR_absti2;
4206 #endif
4207 #ifdef HAVE_abssf2
4208   if (HAVE_abssf2)
4209     abs_optab->handlers[(int) SFmode].insn_code = CODE_FOR_abssf2;
4210 #endif
4211 #ifdef HAVE_absdf2
4212   if (HAVE_absdf2)
4213     abs_optab->handlers[(int) DFmode].insn_code = CODE_FOR_absdf2;
4214 #endif
4215 #ifdef HAVE_absxf2
4216   if (HAVE_absxf2)
4217     abs_optab->handlers[(int) XFmode].insn_code = CODE_FOR_absxf2;
4218 #endif
4219 #ifdef HAVE_abstf2
4220   if (HAVE_abstf2)
4221     abs_optab->handlers[(int) TFmode].insn_code = CODE_FOR_abstf2;
4222 #endif
4223   /* No library calls here!  If there is no abs instruction,
4224      expand_expr will generate a conditional negation.  */
4225
4226 #ifdef HAVE_sqrtqi2
4227   if (HAVE_sqrtqi2)
4228     sqrt_optab->handlers[(int) QImode].insn_code = CODE_FOR_sqrtqi2;
4229 #endif
4230 #ifdef HAVE_sqrthi2
4231   if (HAVE_sqrthi2)
4232     sqrt_optab->handlers[(int) HImode].insn_code = CODE_FOR_sqrthi2;
4233 #endif
4234 #ifdef HAVE_sqrtpsi2
4235   if (HAVE_sqrtpsi2)
4236     sqrt_optab->handlers[(int) PSImode].insn_code = CODE_FOR_sqrtpsi2;
4237 #endif
4238 #ifdef HAVE_sqrtsi2
4239   if (HAVE_sqrtsi2)
4240     sqrt_optab->handlers[(int) SImode].insn_code = CODE_FOR_sqrtsi2;
4241 #endif
4242 #ifdef HAVE_sqrtdi2
4243   if (HAVE_sqrtdi2)
4244     sqrt_optab->handlers[(int) DImode].insn_code = CODE_FOR_sqrtdi2;
4245 #endif
4246 #ifdef HAVE_sqrtti2
4247   if (HAVE_sqrtti2)
4248     sqrt_optab->handlers[(int) TImode].insn_code = CODE_FOR_sqrtti2;
4249 #endif
4250 #ifdef HAVE_sqrtsf2
4251   if (HAVE_sqrtsf2)
4252     sqrt_optab->handlers[(int) SFmode].insn_code = CODE_FOR_sqrtsf2;
4253 #endif
4254 #ifdef HAVE_sqrtdf2
4255   if (HAVE_sqrtdf2)
4256     sqrt_optab->handlers[(int) DFmode].insn_code = CODE_FOR_sqrtdf2;
4257 #endif
4258 #ifdef HAVE_sqrttf2
4259   if (HAVE_sqrttf2)
4260     sqrt_optab->handlers[(int) TFmode].insn_code = CODE_FOR_sqrttf2;
4261 #endif
4262   /* No library calls here!  If there is no sqrt instruction expand_builtin
4263      should force the library call.  */
4264
4265 #ifdef HAVE_sinsf2
4266   if (HAVE_sinsf2)
4267     sin_optab->handlers[(int) SFmode].insn_code = CODE_FOR_sinsf2;
4268 #endif
4269 #ifdef HAVE_sindf2
4270   if (HAVE_sindf2)
4271     sin_optab->handlers[(int) DFmode].insn_code = CODE_FOR_sindf2;
4272 #endif
4273 #ifdef HAVE_sintf2
4274   if (HAVE_sintf2)
4275     sin_optab->handlers[(int) TFmode].insn_code = CODE_FOR_sintf2;
4276 #endif
4277   /* No library calls here!  If there is no sin instruction expand_builtin
4278      should force the library call.  */
4279
4280 #ifdef HAVE_cossf2
4281   if (HAVE_cossf2)
4282     cos_optab->handlers[(int) SFmode].insn_code = CODE_FOR_cossf2;
4283 #endif
4284 #ifdef HAVE_cosdf2
4285   if (HAVE_cosdf2)
4286     cos_optab->handlers[(int) DFmode].insn_code = CODE_FOR_cosdf2;
4287 #endif
4288 #ifdef HAVE_costf2
4289   if (HAVE_costf2)
4290     cos_optab->handlers[(int) TFmode].insn_code = CODE_FOR_costf2;
4291 #endif
4292   /* No library calls here!  If there is no cos instruction expand_builtin
4293      should force the library call.  */
4294
4295 #ifdef HAVE_strlenqi
4296   if (HAVE_strlenqi)
4297     strlen_optab->handlers[(int) QImode].insn_code = CODE_FOR_strlenqi;
4298 #endif
4299 #ifdef HAVE_strlenhi
4300   if (HAVE_strlenhi)
4301     strlen_optab->handlers[(int) HImode].insn_code = CODE_FOR_strlenhi;
4302 #endif
4303 #ifdef HAVE_strlenpsi
4304   if (HAVE_strlenpsi)
4305     strlen_optab->handlers[(int) PSImode].insn_code = CODE_FOR_strlenpsi;
4306 #endif
4307 #ifdef HAVE_strlensi
4308   if (HAVE_strlensi)
4309     strlen_optab->handlers[(int) SImode].insn_code = CODE_FOR_strlensi;
4310 #endif
4311 #ifdef HAVE_strlendi
4312   if (HAVE_strlendi)
4313     strlen_optab->handlers[(int) DImode].insn_code = CODE_FOR_strlendi;
4314 #endif
4315 #ifdef HAVE_strlenti
4316   if (HAVE_strlenti)
4317     strlen_optab->handlers[(int) TImode].insn_code = CODE_FOR_strlenti;
4318 #endif
4319   /* No library calls here!  If there is no strlen instruction expand_builtin
4320      should force the library call.  */
4321
4322 #ifdef HAVE_one_cmplqi2
4323   if (HAVE_one_cmplqi2)
4324     one_cmpl_optab->handlers[(int) QImode].insn_code = CODE_FOR_one_cmplqi2;
4325 #endif
4326 #ifdef HAVE_one_cmplhi2
4327   if (HAVE_one_cmplhi2)
4328     one_cmpl_optab->handlers[(int) HImode].insn_code = CODE_FOR_one_cmplhi2;
4329 #endif
4330 #ifdef HAVE_one_cmplpsi2
4331   if (HAVE_one_cmplpsi2)
4332     one_cmpl_optab->handlers[(int) PSImode].insn_code = CODE_FOR_one_cmplpsi2;
4333 #endif
4334 #ifdef HAVE_one_cmplsi2
4335   if (HAVE_one_cmplsi2)
4336     one_cmpl_optab->handlers[(int) SImode].insn_code = CODE_FOR_one_cmplsi2;
4337 #endif
4338 #ifdef HAVE_one_cmpldi2
4339   if (HAVE_one_cmpldi2)
4340     one_cmpl_optab->handlers[(int) DImode].insn_code = CODE_FOR_one_cmpldi2;
4341 #endif
4342 #ifdef HAVE_one_cmplti2
4343   if (HAVE_one_cmplti2)
4344     one_cmpl_optab->handlers[(int) TImode].insn_code = CODE_FOR_one_cmplti2;
4345 #endif
4346   init_integral_libfuncs (one_cmpl_optab, "one_cmpl", '2');
4347
4348 #ifdef HAVE_ffsqi2
4349   if (HAVE_ffsqi2)
4350     ffs_optab->handlers[(int) QImode].insn_code = CODE_FOR_ffsqi2;
4351 #endif
4352 #ifdef HAVE_ffshi2
4353   if (HAVE_ffshi2)
4354     ffs_optab->handlers[(int) HImode].insn_code = CODE_FOR_ffshi2;
4355 #endif
4356 #ifdef HAVE_ffspsi2
4357   if (HAVE_ffspsi2)
4358     ffs_optab->handlers[(int) PSImode].insn_code = CODE_FOR_ffspsi2;
4359 #endif
4360 #ifdef HAVE_ffssi2
4361   if (HAVE_ffssi2)
4362     ffs_optab->handlers[(int) SImode].insn_code = CODE_FOR_ffssi2;
4363 #endif
4364 #ifdef HAVE_ffsdi2
4365   if (HAVE_ffsdi2)
4366     ffs_optab->handlers[(int) DImode].insn_code = CODE_FOR_ffsdi2;
4367 #endif
4368 #ifdef HAVE_ffsti2
4369   if (HAVE_ffsti2)
4370     ffs_optab->handlers[(int) TImode].insn_code = CODE_FOR_ffsti2;
4371 #endif
4372   init_integral_libfuncs (ffs_optab, "ffs", '2');
4373
4374 #ifdef HAVE_movqi
4375   if (HAVE_movqi)
4376     mov_optab->handlers[(int) QImode].insn_code = CODE_FOR_movqi;
4377 #endif
4378 #ifdef HAVE_movhi
4379   if (HAVE_movhi)
4380     mov_optab->handlers[(int) HImode].insn_code = CODE_FOR_movhi;
4381 #endif
4382 #ifdef HAVE_movpsi
4383   if (HAVE_movpsi)
4384     mov_optab->handlers[(int) PSImode].insn_code = CODE_FOR_movpsi;
4385 #endif
4386 #ifdef HAVE_movsi
4387   if (HAVE_movsi)
4388     mov_optab->handlers[(int) SImode].insn_code = CODE_FOR_movsi;
4389 #endif
4390 #ifdef HAVE_movdi
4391   if (HAVE_movdi)
4392     mov_optab->handlers[(int) DImode].insn_code = CODE_FOR_movdi;
4393 #endif
4394 #ifdef HAVE_movti
4395   if (HAVE_movti)
4396     mov_optab->handlers[(int) TImode].insn_code = CODE_FOR_movti;
4397 #endif
4398 #ifdef HAVE_movsf
4399   if (HAVE_movsf)
4400     mov_optab->handlers[(int) SFmode].insn_code = CODE_FOR_movsf;
4401 #endif
4402 #ifdef HAVE_movdf
4403   if (HAVE_movdf)
4404     mov_optab->handlers[(int) DFmode].insn_code = CODE_FOR_movdf;
4405 #endif
4406 #ifdef HAVE_movxf
4407   if (HAVE_movxf)
4408     mov_optab->handlers[(int) XFmode].insn_code = CODE_FOR_movxf;
4409 #endif
4410 #ifdef HAVE_movtf
4411   if (HAVE_movtf)
4412     mov_optab->handlers[(int) TFmode].insn_code = CODE_FOR_movtf;
4413 #endif
4414 #ifdef HAVE_movcc
4415   if (HAVE_movcc)
4416     mov_optab->handlers[(int) CCmode].insn_code = CODE_FOR_movcc;
4417 #endif
4418
4419 #ifdef EXTRA_CC_MODES
4420   init_mov_optab ();
4421 #endif
4422
4423 #ifdef HAVE_movstrictqi
4424   if (HAVE_movstrictqi)
4425     movstrict_optab->handlers[(int) QImode].insn_code = CODE_FOR_movstrictqi;
4426 #endif
4427 #ifdef HAVE_movstricthi
4428   if (HAVE_movstricthi)
4429     movstrict_optab->handlers[(int) HImode].insn_code = CODE_FOR_movstricthi;
4430 #endif
4431 #ifdef HAVE_movstrictpsi
4432   if (HAVE_movstrictpsi)
4433     movstrict_optab->handlers[(int) PSImode].insn_code = CODE_FOR_movstrictpsi;
4434 #endif
4435 #ifdef HAVE_movstrictsi
4436   if (HAVE_movstrictsi)
4437     movstrict_optab->handlers[(int) SImode].insn_code = CODE_FOR_movstrictsi;
4438 #endif
4439 #ifdef HAVE_movstrictdi
4440   if (HAVE_movstrictdi)
4441     movstrict_optab->handlers[(int) DImode].insn_code = CODE_FOR_movstrictdi;
4442 #endif
4443 #ifdef HAVE_movstrictti
4444   if (HAVE_movstrictti)
4445     movstrict_optab->handlers[(int) TImode].insn_code = CODE_FOR_movstrictti;
4446 #endif
4447
4448 #ifdef HAVE_cmpqi
4449   if (HAVE_cmpqi)
4450     cmp_optab->handlers[(int) QImode].insn_code = CODE_FOR_cmpqi;
4451 #endif
4452 #ifdef HAVE_cmphi
4453   if (HAVE_cmphi)
4454     cmp_optab->handlers[(int) HImode].insn_code = CODE_FOR_cmphi;
4455 #endif
4456 #ifdef HAVE_cmppsi
4457   if (HAVE_cmppsi)
4458     cmp_optab->handlers[(int) PSImode].insn_code = CODE_FOR_cmppsi;
4459 #endif
4460 #ifdef HAVE_cmpsi
4461   if (HAVE_cmpsi)
4462     cmp_optab->handlers[(int) SImode].insn_code = CODE_FOR_cmpsi;
4463 #endif
4464 #ifdef HAVE_cmpdi
4465   if (HAVE_cmpdi)
4466     cmp_optab->handlers[(int) DImode].insn_code = CODE_FOR_cmpdi;
4467 #endif
4468 #ifdef HAVE_cmpti
4469   if (HAVE_cmpti)
4470     cmp_optab->handlers[(int) TImode].insn_code = CODE_FOR_cmpti;
4471 #endif
4472 #ifdef HAVE_cmpsf
4473   if (HAVE_cmpsf)
4474     cmp_optab->handlers[(int) SFmode].insn_code = CODE_FOR_cmpsf;
4475 #endif
4476 #ifdef HAVE_cmpdf
4477   if (HAVE_cmpdf)
4478     cmp_optab->handlers[(int) DFmode].insn_code = CODE_FOR_cmpdf;
4479 #endif
4480 #ifdef HAVE_cmpxf
4481   if (HAVE_cmpxf)
4482     cmp_optab->handlers[(int) XFmode].insn_code = CODE_FOR_cmpxf;
4483 #endif
4484 #ifdef HAVE_cmptf
4485   if (HAVE_cmptf)
4486     cmp_optab->handlers[(int) TFmode].insn_code = CODE_FOR_cmptf;
4487 #endif
4488   /* Comparison libcalls for integers MUST come in pairs, signed/unsigned.  */
4489   init_integral_libfuncs (cmp_optab, "cmp", '2');
4490   init_integral_libfuncs (ucmp_optab, "ucmp", '2');
4491   init_floating_libfuncs (cmp_optab, "cmp", '2');
4492
4493 #ifdef HAVE_tstqi
4494   if (HAVE_tstqi)
4495     tst_optab->handlers[(int) QImode].insn_code = CODE_FOR_tstqi;
4496 #endif
4497 #ifdef HAVE_tsthi
4498   if (HAVE_tsthi)
4499     tst_optab->handlers[(int) HImode].insn_code = CODE_FOR_tsthi;
4500 #endif
4501 #ifdef HAVE_tstpsi
4502   if (HAVE_tstpsi)
4503     tst_optab->handlers[(int) PSImode].insn_code = CODE_FOR_tstpsi;
4504 #endif
4505 #ifdef HAVE_tstsi
4506   if (HAVE_tstsi)
4507     tst_optab->handlers[(int) SImode].insn_code = CODE_FOR_tstsi;
4508 #endif
4509 #ifdef HAVE_tstdi
4510   if (HAVE_tstdi)
4511     tst_optab->handlers[(int) DImode].insn_code = CODE_FOR_tstdi;
4512 #endif
4513 #ifdef HAVE_tstti
4514   if (HAVE_tstti)
4515     tst_optab->handlers[(int) TImode].insn_code = CODE_FOR_tstti;
4516 #endif
4517 #ifdef HAVE_tstsf
4518   if (HAVE_tstsf)
4519     tst_optab->handlers[(int) SFmode].insn_code = CODE_FOR_tstsf;
4520 #endif
4521 #ifdef HAVE_tstdf
4522   if (HAVE_tstdf)
4523     tst_optab->handlers[(int) DFmode].insn_code = CODE_FOR_tstdf;
4524 #endif
4525 #ifdef HAVE_tstxf
4526   if (HAVE_tstxf)
4527     tst_optab->handlers[(int) XFmode].insn_code = CODE_FOR_tstxf;
4528 #endif
4529 #ifdef HAVE_tsttf
4530   if (HAVE_tsttf)
4531     tst_optab->handlers[(int) TFmode].insn_code = CODE_FOR_tsttf;
4532 #endif
4533
4534 #ifdef HAVE_beq
4535   if (HAVE_beq)
4536     bcc_gen_fctn[(int) EQ] = gen_beq;
4537 #endif
4538 #ifdef HAVE_bne
4539   if (HAVE_bne)
4540     bcc_gen_fctn[(int) NE] = gen_bne;
4541 #endif
4542 #ifdef HAVE_bgt
4543   if (HAVE_bgt)
4544     bcc_gen_fctn[(int) GT] = gen_bgt;
4545 #endif
4546 #ifdef HAVE_bge
4547   if (HAVE_bge)
4548     bcc_gen_fctn[(int) GE] = gen_bge;
4549 #endif
4550 #ifdef HAVE_bgtu
4551   if (HAVE_bgtu)
4552     bcc_gen_fctn[(int) GTU] = gen_bgtu;
4553 #endif
4554 #ifdef HAVE_bgeu
4555   if (HAVE_bgeu)
4556     bcc_gen_fctn[(int) GEU] = gen_bgeu;
4557 #endif
4558 #ifdef HAVE_blt
4559   if (HAVE_blt)
4560     bcc_gen_fctn[(int) LT] = gen_blt;
4561 #endif
4562 #ifdef HAVE_ble
4563   if (HAVE_ble)
4564     bcc_gen_fctn[(int) LE] = gen_ble;
4565 #endif
4566 #ifdef HAVE_bltu
4567   if (HAVE_bltu)
4568     bcc_gen_fctn[(int) LTU] = gen_bltu;
4569 #endif
4570 #ifdef HAVE_bleu
4571   if (HAVE_bleu)
4572     bcc_gen_fctn[(int) LEU] = gen_bleu;
4573 #endif
4574
4575   for (i = 0; i < NUM_RTX_CODE; i++)
4576     setcc_gen_code[i] = CODE_FOR_nothing;
4577
4578 #ifdef HAVE_seq
4579   if (HAVE_seq)
4580     setcc_gen_code[(int) EQ] = CODE_FOR_seq;
4581 #endif
4582 #ifdef HAVE_sne
4583   if (HAVE_sne)
4584     setcc_gen_code[(int) NE] = CODE_FOR_sne;
4585 #endif
4586 #ifdef HAVE_sgt
4587   if (HAVE_sgt)
4588     setcc_gen_code[(int) GT] = CODE_FOR_sgt;
4589 #endif
4590 #ifdef HAVE_sge
4591   if (HAVE_sge)
4592     setcc_gen_code[(int) GE] = CODE_FOR_sge;
4593 #endif
4594 #ifdef HAVE_sgtu
4595   if (HAVE_sgtu)
4596     setcc_gen_code[(int) GTU] = CODE_FOR_sgtu;
4597 #endif
4598 #ifdef HAVE_sgeu
4599   if (HAVE_sgeu)
4600     setcc_gen_code[(int) GEU] = CODE_FOR_sgeu;
4601 #endif
4602 #ifdef HAVE_slt
4603   if (HAVE_slt)
4604     setcc_gen_code[(int) LT] = CODE_FOR_slt;
4605 #endif
4606 #ifdef HAVE_sle
4607   if (HAVE_sle)
4608     setcc_gen_code[(int) LE] = CODE_FOR_sle;
4609 #endif
4610 #ifdef HAVE_sltu
4611   if (HAVE_sltu)
4612     setcc_gen_code[(int) LTU] = CODE_FOR_sltu;
4613 #endif
4614 #ifdef HAVE_sleu
4615   if (HAVE_sleu)
4616     setcc_gen_code[(int) LEU] = CODE_FOR_sleu;
4617 #endif
4618
4619   extendsfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extendsfdf2");
4620   extendsfxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extendsfxf2");
4621   extendsftf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extendsftf2");
4622   extenddfxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extenddfxf2");
4623   extenddftf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extenddftf2");
4624
4625   truncdfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__truncdfsf2");
4626   truncxfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__truncxfsf2");
4627   trunctfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__trunctfsf2");
4628   truncxfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__truncxfdf2");
4629   trunctfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__trunctfdf2");
4630
4631   memcpy_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memcpy");
4632   bcopy_libfunc = gen_rtx (SYMBOL_REF, Pmode, "bcopy");
4633   memcmp_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memcmp");
4634   bcmp_libfunc = gen_rtx (SYMBOL_REF, Pmode, "bcmp");
4635   memset_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memset");
4636   bzero_libfunc = gen_rtx (SYMBOL_REF, Pmode, "bzero");
4637
4638   eqsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqsf2");
4639   nesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nesf2");
4640   gtsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtsf2");
4641   gesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gesf2");
4642   ltsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltsf2");
4643   lesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lesf2");
4644
4645   eqdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqdf2");
4646   nedf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nedf2");
4647   gtdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtdf2");
4648   gedf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gedf2");
4649   ltdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltdf2");
4650   ledf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ledf2");
4651
4652   eqxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqxf2");
4653   nexf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nexf2");
4654   gtxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtxf2");
4655   gexf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gexf2");
4656   ltxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltxf2");
4657   lexf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lexf2");
4658
4659   eqtf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqtf2");
4660   netf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__netf2");
4661   gttf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gttf2");
4662   getf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__getf2");
4663   lttf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lttf2");
4664   letf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__letf2");
4665
4666   floatsisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsisf");
4667   floatdisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatdisf");
4668   floattisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattisf");
4669
4670   floatsidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsidf");
4671   floatdidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatdidf");
4672   floattidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattidf");
4673
4674   floatsixf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsixf");
4675   floatdixf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatdixf");
4676   floattixf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattixf");
4677
4678   floatsitf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsitf");
4679   floatditf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatditf");
4680   floattitf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattitf");
4681
4682   fixsfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixsfsi");
4683   fixsfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixsfdi");
4684   fixsfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixsfti");
4685
4686   fixdfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixdfsi");
4687   fixdfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixdfdi");
4688   fixdfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixdfti");
4689
4690   fixxfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixxfsi");
4691   fixxfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixxfdi");
4692   fixxfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixxfti");
4693
4694   fixtfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixtfsi");
4695   fixtfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixtfdi");
4696   fixtfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixtfti");
4697
4698   fixunssfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunssfsi");
4699   fixunssfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunssfdi");
4700   fixunssfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunssfti");
4701
4702   fixunsdfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsdfsi");
4703   fixunsdfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsdfdi");
4704   fixunsdfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsdfti");
4705
4706   fixunsxfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsxfsi");
4707   fixunsxfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsxfdi");
4708   fixunsxfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsxfti");
4709
4710   fixunstfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunstfsi");
4711   fixunstfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunstfdi");
4712   fixunstfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunstfti");
4713 }
4714 \f
4715 #ifdef BROKEN_LDEXP
4716
4717 /* SCO 3.2 apparently has a broken ldexp. */
4718
4719 double
4720 ldexp(x,n)
4721      double x;
4722      int n;
4723 {
4724   if (n > 0)
4725     while (n--)
4726       x *= 2;
4727
4728   return x;
4729 }
4730 #endif /* BROKEN_LDEXP */