OSDN Git Service

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