OSDN Git Service

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