OSDN Git Service

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