OSDN Git Service

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