OSDN Git Service

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