OSDN Git Service

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