OSDN Git Service

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