OSDN Git Service

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