1 /* Expand the basic unary and binary arithmetic operations, for GNU compiler.
2 Copyright (C) 1987, 1988, 1992 Free Software Foundation, Inc.
4 This file is part of GNU CC.
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)
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.
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. */
25 #include "insn-flags.h"
26 #include "insn-codes.h"
28 #include "insn-config.h"
32 /* Each optab contains info on how this target machine
33 can perform a particular operation
34 for all sizes and kinds of operands.
36 The operation to be performed is often specified
37 by passing one of these optabs as an argument.
39 See expr.h for documentation of these optabs. */
44 optab smul_widen_optab;
45 optab umul_widen_optab;
69 optab movstrict_optab;
80 optab ucmp_optab; /* Used only for libcalls for unsigned comparisons. */
85 /* SYMBOL_REF rtx's for the library functions that are called
86 implicitly and not via optabs. */
88 rtx extendsfdf2_libfunc;
89 rtx extendsfxf2_libfunc;
90 rtx extendsftf2_libfunc;
91 rtx extenddfxf2_libfunc;
92 rtx extenddftf2_libfunc;
94 rtx truncdfsf2_libfunc;
95 rtx truncxfsf2_libfunc;
96 rtx trunctfsf2_libfunc;
97 rtx truncxfdf2_libfunc;
98 rtx trunctfdf2_libfunc;
135 rtx floatsisf_libfunc;
136 rtx floatdisf_libfunc;
137 rtx floattisf_libfunc;
139 rtx floatsidf_libfunc;
140 rtx floatdidf_libfunc;
141 rtx floattidf_libfunc;
143 rtx floatsixf_libfunc;
144 rtx floatdixf_libfunc;
145 rtx floattixf_libfunc;
147 rtx floatsitf_libfunc;
148 rtx floatditf_libfunc;
149 rtx floattitf_libfunc;
167 rtx fixunssfsi_libfunc;
168 rtx fixunssfdi_libfunc;
169 rtx fixunssfti_libfunc;
171 rtx fixunsdfsi_libfunc;
172 rtx fixunsdfdi_libfunc;
173 rtx fixunsdfti_libfunc;
175 rtx fixunsxfsi_libfunc;
176 rtx fixunsxfdi_libfunc;
177 rtx fixunsxfti_libfunc;
179 rtx fixunstfsi_libfunc;
180 rtx fixunstfdi_libfunc;
181 rtx fixunstfti_libfunc;
184 /* from emit-rtl.c */
185 extern rtx gen_highpart();
188 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
189 gives the gen_function to make a branch to test that condition. */
191 rtxfun bcc_gen_fctn[NUM_RTX_CODE];
193 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
194 gives the insn code to make a store-condition insn
195 to test that condition. */
197 enum insn_code setcc_gen_code[NUM_RTX_CODE];
199 static void emit_float_lib_cmp ();
201 /* Add a REG_EQUAL note to the last insn in SEQ. TARGET is being set to
202 the result of operation CODE applied to OP0 (and OP1 if it is a binary
205 If the last insn does not set TARGET, don't do anything, but return 1.
207 If a previous insn sets TARGET and TARGET is one of OP0 or OP1,
208 don't add the REG_EQUAL note but return 0. Our caller can then try
209 again, ensuring that TARGET is not one of the operands. */
212 add_equal_note (seq, target, code, op0, op1)
222 if ((GET_RTX_CLASS (code) != '1' && GET_RTX_CLASS (code) != '2'
223 && GET_RTX_CLASS (code) != 'c' && GET_RTX_CLASS (code) != '<')
224 || GET_CODE (seq) != SEQUENCE
225 || (set = single_set (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1))) == 0
226 || GET_CODE (target) == ZERO_EXTRACT
227 || (! rtx_equal_p (SET_DEST (set), target)
228 /* For a STRICT_LOW_PART, the REG_NOTE applies to what is inside the
230 && (GET_CODE (SET_DEST (set)) != STRICT_LOW_PART
231 || ! rtx_equal_p (SUBREG_REG (XEXP (SET_DEST (set), 0)),
235 /* If TARGET is in OP0 or OP1, check if anything in SEQ sets TARGET
236 besides the last insn. */
237 if (reg_overlap_mentioned_p (target, op0)
238 || (op1 && reg_overlap_mentioned_p (target, op1)))
239 for (i = XVECLEN (seq, 0) - 2; i >= 0; i--)
240 if (reg_set_p (target, XVECEXP (seq, 0, i)))
243 if (GET_RTX_CLASS (code) == '1')
244 note = gen_rtx (code, GET_MODE (target), op0);
246 note = gen_rtx (code, GET_MODE (target), op0, op1);
248 REG_NOTES (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1))
249 = gen_rtx (EXPR_LIST, REG_EQUAL, note,
250 REG_NOTES (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1)));
255 /* Generate code to perform an operation specified by BINOPTAB
256 on operands OP0 and OP1, with result having machine-mode MODE.
258 UNSIGNEDP is for the case where we have to widen the operands
259 to perform the operation. It says to use zero-extension.
261 If TARGET is nonzero, the value
262 is generated there, if it is convenient to do so.
263 In all cases an rtx is returned for the locus of the value;
264 this may or may not be TARGET. */
267 expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods)
268 enum machine_mode mode;
273 enum optab_methods methods;
275 enum mode_class class;
276 enum machine_mode wider_mode;
278 int commutative_op = 0;
279 int shift_op = (binoptab->code == ASHIFT
280 || binoptab->code == ASHIFTRT
281 || binoptab->code == LSHIFT
282 || binoptab->code == LSHIFTRT
283 || binoptab->code == ROTATE
284 || binoptab->code == ROTATERT);
287 class = GET_MODE_CLASS (mode);
289 op0 = protect_from_queue (op0, 0);
290 op1 = protect_from_queue (op1, 0);
292 target = protect_from_queue (target, 1);
296 op0 = force_not_mem (op0);
297 op1 = force_not_mem (op1);
300 /* If we are inside an appropriately-short loop and one operand is an
301 expensive constant, force it into a register. */
302 if (CONSTANT_P (op0) && preserve_subexpressions_p ()
303 && rtx_cost (op0, binoptab->code) > 2)
304 op0 = force_reg (mode, op0);
306 if (CONSTANT_P (op1) && preserve_subexpressions_p ()
307 && rtx_cost (op1, binoptab->code) > 2)
308 op1 = force_reg (shift_op ? word_mode : mode, op1);
310 #if 0 /* Turned off because it seems to be a kludgy method. */
311 /* If subtracting integer from pointer, and the pointer has a special mode,
312 then change it to an add. We use the add insn of Pmode for combining
313 integers with pointers, and the sub insn to subtract two pointers. */
315 if (binoptab == sub_optab
316 && GET_MODE (op0) == Pmode && GET_MODE (op1) != Pmode)
318 op1 = negate_rtx (GET_MODE(op1), op1);
319 binoptab = add_optab;
323 /* Record where to delete back to if we backtrack. */
324 last = get_last_insn ();
326 /* If operation is commutative,
327 try to make the first operand a register.
328 Even better, try to make it the same as the target.
329 Also try to make the last operand a constant. */
330 if (GET_RTX_CLASS (binoptab->code) == 'c'
331 || binoptab == smul_widen_optab
332 || binoptab == umul_widen_optab)
336 if (((target == 0 || GET_CODE (target) == REG)
337 ? ((GET_CODE (op1) == REG
338 && GET_CODE (op0) != REG)
340 : rtx_equal_p (op1, target))
341 || GET_CODE (op0) == CONST_INT)
349 /* If we can do it with a three-operand insn, do so. */
351 if (methods != OPTAB_MUST_WIDEN
352 && binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
354 int icode = (int) binoptab->handlers[(int) mode].insn_code;
355 enum machine_mode mode0 = insn_operand_mode[icode][1];
356 enum machine_mode mode1 = insn_operand_mode[icode][2];
358 rtx xop0 = op0, xop1 = op1;
363 temp = gen_reg_rtx (mode);
365 /* If it is a commutative operator and the modes would match
366 if we would swap the operands, we can save the conversions. */
369 if (GET_MODE (op0) != mode0 && GET_MODE (op1) != mode1
370 && GET_MODE (op0) == mode1 && GET_MODE (op1) == mode0)
374 tmp = op0; op0 = op1; op1 = tmp;
375 tmp = xop0; xop0 = xop1; xop1 = tmp;
379 /* In case the insn wants input operands in modes different from
380 the result, convert the operands. */
382 if (GET_MODE (op0) != VOIDmode
383 && GET_MODE (op0) != mode0)
384 xop0 = convert_to_mode (mode0, xop0, unsignedp);
386 if (GET_MODE (xop1) != VOIDmode
387 && GET_MODE (xop1) != mode1)
388 xop1 = convert_to_mode (mode1, xop1, unsignedp);
390 /* Now, if insn's predicates don't allow our operands, put them into
393 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
394 xop0 = copy_to_mode_reg (mode0, xop0);
396 if (! (*insn_operand_predicate[icode][2]) (xop1, mode1))
397 xop1 = copy_to_mode_reg (mode1, xop1);
399 if (! (*insn_operand_predicate[icode][0]) (temp, mode))
400 temp = gen_reg_rtx (mode);
402 pat = GEN_FCN (icode) (temp, xop0, xop1);
405 /* If PAT is a multi-insn sequence, try to add an appropriate
406 REG_EQUAL note to it. If we can't because TEMP conflicts with an
407 operand, call ourselves again, this time without a target. */
408 if (GET_CODE (pat) == SEQUENCE
409 && ! add_equal_note (pat, temp, binoptab->code, xop0, xop1))
411 delete_insns_since (last);
412 return expand_binop (mode, binoptab, op0, op1, NULL_RTX,
420 delete_insns_since (last);
423 /* If this is a multiply, see if we can do a widening operation that
424 takes operands of this mode and makes a wider mode. */
426 if (binoptab == smul_optab && GET_MODE_WIDER_MODE (mode) != VOIDmode
427 && (((unsignedp ? umul_widen_optab : smul_widen_optab)
428 ->handlers[(int) GET_MODE_WIDER_MODE (mode)].insn_code)
429 != CODE_FOR_nothing))
431 temp = expand_binop (GET_MODE_WIDER_MODE (mode),
432 unsignedp ? umul_widen_optab : smul_widen_optab,
433 op0, op1, 0, unsignedp, OPTAB_DIRECT);
435 if (GET_MODE_CLASS (mode) == MODE_INT)
436 return gen_lowpart (mode, temp);
438 return convert_to_mode (mode, temp, unsignedp);
441 /* Look for a wider mode of the same class for which we think we
442 can open-code the operation. Check for a widening multiply at the
443 wider mode as well. */
445 if ((class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
446 && methods != OPTAB_DIRECT && methods != OPTAB_LIB)
447 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
448 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
450 if (binoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing
451 || (binoptab == smul_optab
452 && GET_MODE_WIDER_MODE (wider_mode) != VOIDmode
453 && (((unsignedp ? umul_widen_optab : smul_widen_optab)
454 ->handlers[(int) GET_MODE_WIDER_MODE (wider_mode)].insn_code)
455 != CODE_FOR_nothing)))
457 rtx xop0 = op0, xop1 = op1;
460 /* For certain integer operations, we need not actually extend
461 the narrow operands, as long as we will truncate
462 the results to the same narrowness. Don't do this when
463 WIDER_MODE is wider than a word since a paradoxical SUBREG
464 isn't valid for such modes. */
466 if ((binoptab == ior_optab || binoptab == and_optab
467 || binoptab == xor_optab
468 || binoptab == add_optab || binoptab == sub_optab
469 || binoptab == smul_optab
470 || binoptab == ashl_optab || binoptab == lshl_optab)
472 && GET_MODE_SIZE (wider_mode) <= UNITS_PER_WORD)
475 /* If an operand is a constant integer, we might as well
476 convert it since that is more efficient than using a SUBREG,
477 unlike the case for other operands. Similarly for
478 SUBREGs that were made due to promoted objects. */
480 if (no_extend && GET_MODE (xop0) != VOIDmode
481 && ! (GET_CODE (xop0) == SUBREG
482 && SUBREG_PROMOTED_VAR_P (xop0)))
483 xop0 = gen_rtx (SUBREG, wider_mode,
484 force_reg (GET_MODE (xop0), xop0), 0);
486 xop0 = convert_to_mode (wider_mode, xop0, unsignedp);
488 if (no_extend && GET_MODE (xop1) != VOIDmode
489 && ! (GET_CODE (xop1) == SUBREG
490 && SUBREG_PROMOTED_VAR_P (xop1)))
491 xop1 = gen_rtx (SUBREG, wider_mode,
492 force_reg (GET_MODE (xop1), xop1), 0);
494 xop1 = convert_to_mode (wider_mode, xop1, unsignedp);
496 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
497 unsignedp, OPTAB_DIRECT);
500 if (class != MODE_INT)
503 target = gen_reg_rtx (mode);
504 convert_move (target, temp, 0);
508 return gen_lowpart (mode, temp);
511 delete_insns_since (last);
515 /* These can be done a word at a time. */
516 if ((binoptab == and_optab || binoptab == ior_optab || binoptab == xor_optab)
518 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
519 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
525 /* If TARGET is the same as one of the operands, the REG_EQUAL note
526 won't be accurate, so use a new target. */
527 if (target == 0 || target == op0 || target == op1)
528 target = gen_reg_rtx (mode);
532 /* Do the actual arithmetic. */
533 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
535 rtx target_piece = operand_subword (target, i, 1, mode);
536 rtx x = expand_binop (word_mode, binoptab,
537 operand_subword_force (op0, i, mode),
538 operand_subword_force (op1, i, mode),
539 target_piece, unsignedp, methods);
540 if (target_piece != x)
541 emit_move_insn (target_piece, x);
544 insns = get_insns ();
547 if (binoptab->code != UNKNOWN)
548 equiv_value = gen_rtx (binoptab->code, mode, op0, op1);
552 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
556 /* These can be done a word at a time by propagating carries. */
557 if ((binoptab == add_optab || binoptab == sub_optab)
559 && GET_MODE_SIZE (mode) >= 2 * UNITS_PER_WORD
560 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
563 rtx carry_tmp = gen_reg_rtx (word_mode);
564 optab otheroptab = binoptab == add_optab ? sub_optab : add_optab;
565 int nwords = GET_MODE_BITSIZE (mode) / BITS_PER_WORD;
566 rtx carry_in, carry_out;
568 /* We can handle either a 1 or -1 value for the carry. If STORE_FLAG
569 value is one of those, use it. Otherwise, use 1 since it is the
570 one easiest to get. */
571 #if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
572 int normalizep = STORE_FLAG_VALUE;
577 /* Prepare the operands. */
578 op0 = force_reg (mode, op0);
579 op1 = force_reg (mode, op1);
581 if (target == 0 || GET_CODE (target) != REG
582 || target == op0 || target == op1)
583 target = gen_reg_rtx (mode);
585 /* Do the actual arithmetic. */
586 for (i = 0; i < nwords; i++)
588 int index = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i);
589 rtx target_piece = operand_subword (target, index, 1, mode);
590 rtx op0_piece = operand_subword_force (op0, index, mode);
591 rtx op1_piece = operand_subword_force (op1, index, mode);
594 /* Main add/subtract of the input operands. */
595 x = expand_binop (word_mode, binoptab,
596 op0_piece, op1_piece,
597 target_piece, unsignedp, methods);
603 /* Store carry from main add/subtract. */
604 carry_out = gen_reg_rtx (word_mode);
605 carry_out = emit_store_flag (carry_out,
606 binoptab == add_optab ? LTU : GTU,
608 word_mode, 1, normalizep);
615 /* Add/subtract previous carry to main result. */
616 x = expand_binop (word_mode,
617 normalizep == 1 ? binoptab : otheroptab,
619 target_piece, 1, methods);
620 if (target_piece != x)
621 emit_move_insn (target_piece, x);
625 /* THIS CODE HAS NOT BEEN TESTED. */
626 /* Get out carry from adding/subtracting carry in. */
627 carry_tmp = emit_store_flag (carry_tmp,
628 binoptab == add_optab
631 word_mode, 1, normalizep);
632 /* Logical-ior the two poss. carry together. */
633 carry_out = expand_binop (word_mode, ior_optab,
634 carry_out, carry_tmp,
635 carry_out, 0, methods);
641 carry_in = carry_out;
644 if (i == GET_MODE_BITSIZE (mode) / BITS_PER_WORD)
648 temp = emit_move_insn (target, target);
649 REG_NOTES (temp) = gen_rtx (EXPR_LIST, REG_EQUAL,
650 gen_rtx (binoptab->code, mode, op0, op1),
655 delete_insns_since (last);
658 /* If we want to multiply two two-word values and have normal and widening
659 multiplies of single-word values, we can do this with three smaller
660 multiplications. Note that we do not make a REG_NO_CONFLICT block here
661 because we are not operating on one word at a time.
663 The multiplication proceeds as follows:
664 _______________________
665 [__op0_high_|__op0_low__]
666 _______________________
667 * [__op1_high_|__op1_low__]
668 _______________________________________________
669 _______________________
670 (1) [__op0_low__*__op1_low__]
671 _______________________
672 (2a) [__op0_low__*__op1_high_]
673 _______________________
674 (2b) [__op0_high_*__op1_low__]
675 _______________________
676 (3) [__op0_high_*__op1_high_]
679 This gives a 4-word result. Since we are only interested in the
680 lower 2 words, partial result (3) and the upper words of (2a) and
681 (2b) don't need to be calculated. Hence (2a) and (2b) can be
682 calculated using non-widening multiplication.
684 (1), however, needs to be calculated with an unsigned widening
685 multiplication. If this operation is not directly supported we
686 try using a signed widening multiplication and adjust the result.
687 This adjustment works as follows:
689 If both operands are positive then no adjustment is needed.
691 If the operands have different signs, for example op0_low < 0 and
692 op1_low >= 0, the instruction treats the most significant bit of
693 op0_low as a sign bit instead of a bit with significance
694 2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low
695 with 2**BITS_PER_WORD - op0_low, and two's complements the
696 result. Conclusion: We need to add op1_low * 2**BITS_PER_WORD to
699 Similarly, if both operands are negative, we need to add
700 (op0_low + op1_low) * 2**BITS_PER_WORD.
702 We use a trick to adjust quickly. We logically shift op0_low right
703 (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to
704 op0_high (op1_high) before it is used to calculate 2b (2a). If no
705 logical shift exists, we do an arithmetic right shift and subtract
708 if (binoptab == smul_optab
710 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
711 && smul_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
712 && add_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
713 && ((umul_widen_optab->handlers[(int) mode].insn_code
715 || (smul_widen_optab->handlers[(int) mode].insn_code
716 != CODE_FOR_nothing)))
718 int low = (WORDS_BIG_ENDIAN ? 1 : 0);
719 int high = (WORDS_BIG_ENDIAN ? 0 : 1);
720 rtx op0_high = operand_subword_force (op0, high, mode);
721 rtx op0_low = operand_subword_force (op0, low, mode);
722 rtx op1_high = operand_subword_force (op1, high, mode);
723 rtx op1_low = operand_subword_force (op1, low, mode);
728 /* If the target is the same as one of the inputs, don't use it. This
729 prevents problems with the REG_EQUAL note. */
730 if (target == op0 || target == op1)
733 /* Multiply the two lower words to get a double-word product.
734 If unsigned widening multiplication is available, use that;
735 otherwise use the signed form and compensate. */
737 if (umul_widen_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
739 product = expand_binop (mode, umul_widen_optab, op0_low, op1_low,
740 target, 1, OPTAB_DIRECT);
742 /* If we didn't succeed, delete everything we did so far. */
744 delete_insns_since (last);
746 op0_xhigh = op0_high, op1_xhigh = op1_high;
750 && smul_widen_optab->handlers[(int) mode].insn_code
753 rtx wordm1 = GEN_INT (BITS_PER_WORD - 1);
754 product = expand_binop (mode, smul_widen_optab, op0_low, op1_low,
755 target, 1, OPTAB_DIRECT);
756 op0_xhigh = expand_binop (word_mode, lshr_optab, op0_low, wordm1,
757 NULL_RTX, 1, OPTAB_DIRECT);
759 op0_xhigh = expand_binop (word_mode, add_optab, op0_high,
760 op0_xhigh, op0_xhigh, 0, OPTAB_DIRECT);
763 op0_xhigh = expand_binop (word_mode, ashr_optab, op0_low, wordm1,
764 NULL_RTX, 0, OPTAB_DIRECT);
766 op0_xhigh = expand_binop (word_mode, sub_optab, op0_high,
767 op0_xhigh, op0_xhigh, 0,
771 op1_xhigh = expand_binop (word_mode, lshr_optab, op1_low, wordm1,
772 NULL_RTX, 1, OPTAB_DIRECT);
774 op1_xhigh = expand_binop (word_mode, add_optab, op1_high,
775 op1_xhigh, op1_xhigh, 0, OPTAB_DIRECT);
778 op1_xhigh = expand_binop (word_mode, ashr_optab, op1_low, wordm1,
779 NULL_RTX, 0, OPTAB_DIRECT);
781 op1_xhigh = expand_binop (word_mode, sub_optab, op1_high,
782 op1_xhigh, op1_xhigh, 0,
787 /* If we have been able to directly compute the product of the
788 low-order words of the operands and perform any required adjustments
789 of the operands, we proceed by trying two more multiplications
790 and then computing the appropriate sum.
792 We have checked above that the required addition is provided.
793 Full-word addition will normally always succeed, especially if
794 it is provided at all, so we don't worry about its failure. The
795 multiplication may well fail, however, so we do handle that. */
797 if (product && op0_xhigh && op1_xhigh)
800 rtx product_high = operand_subword (product, high, 1, mode);
801 rtx temp = expand_binop (word_mode, binoptab, op0_low, op1_xhigh,
802 NULL_RTX, 0, OPTAB_DIRECT);
806 product_piece = expand_binop (word_mode, add_optab, temp,
807 product_high, product_high,
809 if (product_piece != product_high)
810 emit_move_insn (product_high, product_piece);
812 temp = expand_binop (word_mode, binoptab, op1_low, op0_xhigh,
813 NULL_RTX, 0, OPTAB_DIRECT);
815 product_piece = expand_binop (word_mode, add_optab, temp,
816 product_high, product_high,
818 if (product_piece != product_high)
819 emit_move_insn (product_high, product_piece);
821 temp = emit_move_insn (product, product);
822 REG_NOTES (temp) = gen_rtx (EXPR_LIST, REG_EQUAL,
823 gen_rtx (MULT, mode, op0, op1),
830 /* If we get here, we couldn't do it for some reason even though we
831 originally thought we could. Delete anything we've emitted in
834 delete_insns_since (last);
837 /* We need to open-code the complex type operations: '+, -, * and /' */
839 /* At this point we allow operations between two similar complex
840 numbers, and also if one of the operands is not a complex number
841 but rather of MODE_FLOAT or MODE_INT. However, the caller
842 must make sure that the MODE of the non-complex operand matches
843 the SUBMODE of the complex operand. */
845 if (class == MODE_COMPLEX_FLOAT || class == MODE_COMPLEX_INT)
857 /* Find the correct mode for the real and imaginary parts */
858 enum machine_mode submode
859 = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
860 class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
863 if (submode == BLKmode)
867 target = gen_reg_rtx (mode);
871 realr = gen_lowpart (submode, target);
872 imagr = gen_highpart (submode, target);
874 if (GET_MODE (op0) == mode)
876 real0 = gen_lowpart (submode, op0);
877 imag0 = gen_highpart (submode, op0);
882 if (GET_MODE (op1) == mode)
884 real1 = gen_lowpart (submode, op1);
885 imag1 = gen_highpart (submode, op1);
890 if (! real0 || ! real1 || ! (imag0 || imag1))
893 switch (binoptab->code)
897 res = expand_binop (submode, binoptab, real0, real1,
898 realr, unsignedp, methods);
900 emit_move_insn (realr, res);
903 res = expand_binop (submode, binoptab, imag0, imag1,
904 imagr, unsignedp, methods);
907 else if (binoptab->code == MINUS)
908 res = expand_unop (submode, neg_optab, imag1, imagr, unsignedp);
913 emit_move_insn (imagr, res);
917 /* (a+ib) * (c+id) = (ac-bd) + i(ad+cb) */
919 res = expand_binop (submode, binoptab, real0, real1,
920 realr, unsignedp, methods);
925 expand_binop (submode, sub_optab, res,
926 expand_binop (submode, binoptab, imag0, imag1,
927 0, unsignedp, methods),
928 realr, unsignedp, methods);
931 emit_move_insn (realr, temp);
933 res = expand_binop (submode, add_optab,
934 expand_binop (submode, binoptab,
936 0, unsignedp, methods),
937 expand_binop (submode, binoptab,
939 0, unsignedp, methods),
940 imagr, unsignedp, methods);
942 emit_move_insn (imagr, res);
947 emit_move_insn (realr, res);
950 res = expand_binop (submode, binoptab,
951 real1, imag0, imagr, unsignedp, methods);
953 res = expand_binop (submode, binoptab,
954 real0, imag1, imagr, unsignedp, methods);
956 emit_move_insn (imagr, res);
961 /* (c+id)/(a+ib) == ((c+id)*(a-ib))/(a*a+b*b) */
965 /* Simply divide the real and imaginary parts by `a' */
966 res = expand_binop (submode, binoptab, real0, real1,
967 realr, unsignedp, methods);
969 emit_move_insn (realr, res);
971 res = expand_binop (submode, binoptab, imag0, real1,
972 imagr, unsignedp, methods);
974 emit_move_insn (imagr, res);
976 else /* Divider is of complex type */
983 optab mulopt = unsignedp ? umul_widen_optab : smul_optab;
985 /* Divider: a*a + b*b */
986 divider = expand_binop (submode, add_optab,
987 expand_binop (submode, mulopt,
989 0, unsignedp, methods),
990 expand_binop (submode, mulopt,
992 0, unsignedp, methods),
993 0, unsignedp, methods);
995 if (! imag0) /* ((c)(a-ib))/divider */
997 /* Calculate the divident */
998 real_t = expand_binop (submode, mulopt, real0, real1,
999 0, unsignedp, methods);
1002 = expand_unop (submode, neg_optab,
1003 expand_binop (submode, mulopt, real0, imag1,
1004 0, unsignedp, methods),
1007 else /* ((c+id)(a-ib))/divider */
1009 /* Calculate the divident */
1010 real_t = expand_binop (submode, add_optab,
1011 expand_binop (submode, mulopt,
1013 0, unsignedp, methods),
1014 expand_binop (submode, mulopt,
1016 0, unsignedp, methods),
1017 0, unsignedp, methods);
1019 imag_t = expand_binop (submode, sub_optab,
1020 expand_binop (submode, mulopt,
1022 0, unsignedp, methods),
1023 expand_binop (submode, mulopt,
1025 0, unsignedp, methods),
1026 0, unsignedp, methods);
1030 res = expand_binop (submode, binoptab, real_t, divider,
1031 realr, unsignedp, methods);
1033 emit_move_insn (realr, res);
1035 res = expand_binop (submode, binoptab, imag_t, divider,
1036 imagr, unsignedp, methods);
1038 emit_move_insn (imagr, res);
1046 seq = gen_sequence ();
1049 if (binoptab->code != UNKNOWN)
1050 equiv_value = gen_rtx (binoptab->code, mode, op0, op1);
1054 emit_no_conflict_block (seq, target, op0, op1, equiv_value);
1059 /* It can't be open-coded in this mode.
1060 Use a library call if one is available and caller says that's ok. */
1062 if (binoptab->handlers[(int) mode].libfunc
1063 && (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN))
1066 rtx funexp = binoptab->handlers[(int) mode].libfunc;
1068 enum machine_mode op1_mode = mode;
1074 op1_mode = word_mode;
1075 /* Specify unsigned here,
1076 since negative shift counts are meaningless. */
1077 op1x = convert_to_mode (word_mode, op1, 1);
1080 /* Pass 1 for NO_QUEUE so we don't lose any increments
1081 if the libcall is cse'd or moved. */
1082 emit_library_call (binoptab->handlers[(int) mode].libfunc,
1083 1, mode, 2, op0, mode, op1x, op1_mode);
1085 insns = get_insns ();
1088 target = gen_reg_rtx (mode);
1089 emit_libcall_block (insns, target, hard_libcall_value (mode),
1090 gen_rtx (binoptab->code, mode, op0, op1));
1095 delete_insns_since (last);
1097 /* It can't be done in this mode. Can we do it in a wider mode? */
1099 if (! (methods == OPTAB_WIDEN || methods == OPTAB_LIB_WIDEN
1100 || methods == OPTAB_MUST_WIDEN))
1101 return 0; /* Caller says, don't even try. */
1103 /* Compute the value of METHODS to pass to recursive calls.
1104 Don't allow widening to be tried recursively. */
1106 methods = (methods == OPTAB_LIB_WIDEN ? OPTAB_LIB : OPTAB_DIRECT);
1108 /* Look for a wider mode of the same class for which it appears we can do
1111 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1113 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1114 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1116 if ((binoptab->handlers[(int) wider_mode].insn_code
1117 != CODE_FOR_nothing)
1118 || (methods == OPTAB_LIB
1119 && binoptab->handlers[(int) wider_mode].libfunc))
1121 rtx xop0 = op0, xop1 = op1;
1124 /* For certain integer operations, we need not actually extend
1125 the narrow operands, as long as we will truncate
1126 the results to the same narrowness. Don't do this when
1127 WIDER_MODE is wider than a word since a paradoxical SUBREG
1128 isn't valid for such modes. */
1130 if ((binoptab == ior_optab || binoptab == and_optab
1131 || binoptab == xor_optab
1132 || binoptab == add_optab || binoptab == sub_optab
1133 || binoptab == smul_optab
1134 || binoptab == ashl_optab || binoptab == lshl_optab)
1135 && class == MODE_INT
1136 && GET_MODE_SIZE (wider_mode) <= UNITS_PER_WORD)
1139 /* If an operand is a constant integer, we might as well
1140 convert it since that is more efficient than using a SUBREG,
1141 unlike the case for other operands. Similarly for
1142 SUBREGs that were made due to promoted objects.*/
1144 if (no_extend && GET_MODE (xop0) != VOIDmode
1145 && ! (GET_CODE (xop0) == SUBREG
1146 && SUBREG_PROMOTED_VAR_P (xop0)))
1147 xop0 = gen_rtx (SUBREG, wider_mode,
1148 force_reg (GET_MODE (xop0), xop0), 0);
1150 xop0 = convert_to_mode (wider_mode, xop0, unsignedp);
1152 if (no_extend && GET_MODE (xop1) != VOIDmode
1153 && ! (GET_CODE (xop1) == SUBREG
1154 && SUBREG_PROMOTED_VAR_P (xop1)))
1155 xop1 = gen_rtx (SUBREG, wider_mode,
1156 force_reg (GET_MODE (xop1), xop1), 0);
1158 xop1 = convert_to_mode (wider_mode, xop1, unsignedp);
1160 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
1161 unsignedp, methods);
1164 if (class != MODE_INT)
1167 target = gen_reg_rtx (mode);
1168 convert_move (target, temp, 0);
1172 return gen_lowpart (mode, temp);
1175 delete_insns_since (last);
1183 /* Expand a binary operator which has both signed and unsigned forms.
1184 UOPTAB is the optab for unsigned operations, and SOPTAB is for
1187 If we widen unsigned operands, we may use a signed wider operation instead
1188 of an unsigned wider operation, since the result would be the same. */
1191 sign_expand_binop (mode, uoptab, soptab, op0, op1, target, unsignedp, methods)
1192 enum machine_mode mode;
1193 optab uoptab, soptab;
1194 rtx op0, op1, target;
1196 enum optab_methods methods;
1199 optab direct_optab = unsignedp ? uoptab : soptab;
1200 struct optab wide_soptab;
1202 /* Do it without widening, if possible. */
1203 temp = expand_binop (mode, direct_optab, op0, op1, target,
1204 unsignedp, OPTAB_DIRECT);
1205 if (temp || methods == OPTAB_DIRECT)
1208 /* Try widening to a signed int. Make a fake signed optab that
1209 hides any signed insn for direct use. */
1210 wide_soptab = *soptab;
1211 wide_soptab.handlers[(int) mode].insn_code = CODE_FOR_nothing;
1212 wide_soptab.handlers[(int) mode].libfunc = 0;
1214 temp = expand_binop (mode, &wide_soptab, op0, op1, target,
1215 unsignedp, OPTAB_WIDEN);
1217 /* For unsigned operands, try widening to an unsigned int. */
1218 if (temp == 0 && unsignedp)
1219 temp = expand_binop (mode, uoptab, op0, op1, target,
1220 unsignedp, OPTAB_WIDEN);
1221 if (temp || methods == OPTAB_WIDEN)
1224 /* Use the right width lib call if that exists. */
1225 temp = expand_binop (mode, direct_optab, op0, op1, target, unsignedp, OPTAB_LIB);
1226 if (temp || methods == OPTAB_LIB)
1229 /* Must widen and use a lib call, use either signed or unsigned. */
1230 temp = expand_binop (mode, &wide_soptab, op0, op1, target,
1231 unsignedp, methods);
1235 return expand_binop (mode, uoptab, op0, op1, target,
1236 unsignedp, methods);
1240 /* Generate code to perform an operation specified by BINOPTAB
1241 on operands OP0 and OP1, with two results to TARG1 and TARG2.
1242 We assume that the order of the operands for the instruction
1243 is TARG0, OP0, OP1, TARG1, which would fit a pattern like
1244 [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
1246 Either TARG0 or TARG1 may be zero, but what that means is that
1247 that result is not actually wanted. We will generate it into
1248 a dummy pseudo-reg and discard it. They may not both be zero.
1250 Returns 1 if this operation can be performed; 0 if not. */
1253 expand_twoval_binop (binoptab, op0, op1, targ0, targ1, unsignedp)
1259 enum machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
1260 enum mode_class class;
1261 enum machine_mode wider_mode;
1264 class = GET_MODE_CLASS (mode);
1266 op0 = protect_from_queue (op0, 0);
1267 op1 = protect_from_queue (op1, 0);
1271 op0 = force_not_mem (op0);
1272 op1 = force_not_mem (op1);
1275 /* If we are inside an appropriately-short loop and one operand is an
1276 expensive constant, force it into a register. */
1277 if (CONSTANT_P (op0) && preserve_subexpressions_p ()
1278 && rtx_cost (op0, binoptab->code) > 2)
1279 op0 = force_reg (mode, op0);
1281 if (CONSTANT_P (op1) && preserve_subexpressions_p ()
1282 && rtx_cost (op1, binoptab->code) > 2)
1283 op1 = force_reg (mode, op1);
1286 targ0 = protect_from_queue (targ0, 1);
1288 targ0 = gen_reg_rtx (mode);
1290 targ1 = protect_from_queue (targ1, 1);
1292 targ1 = gen_reg_rtx (mode);
1294 /* Record where to go back to if we fail. */
1295 last = get_last_insn ();
1297 if (binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1299 int icode = (int) binoptab->handlers[(int) mode].insn_code;
1300 enum machine_mode mode0 = insn_operand_mode[icode][1];
1301 enum machine_mode mode1 = insn_operand_mode[icode][2];
1303 rtx xop0 = op0, xop1 = op1;
1305 /* In case this insn wants input operands in modes different from the
1306 result, convert the operands. */
1307 if (GET_MODE (op0) != VOIDmode && GET_MODE (op0) != mode0)
1308 xop0 = convert_to_mode (mode0, xop0, unsignedp);
1310 if (GET_MODE (op1) != VOIDmode && GET_MODE (op1) != mode1)
1311 xop1 = convert_to_mode (mode1, xop1, unsignedp);
1313 /* Now, if insn doesn't accept these operands, put them into pseudos. */
1314 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
1315 xop0 = copy_to_mode_reg (mode0, xop0);
1317 if (! (*insn_operand_predicate[icode][2]) (xop1, mode1))
1318 xop1 = copy_to_mode_reg (mode1, xop1);
1320 /* We could handle this, but we should always be called with a pseudo
1321 for our targets and all insns should take them as outputs. */
1322 if (! (*insn_operand_predicate[icode][0]) (targ0, mode)
1323 || ! (*insn_operand_predicate[icode][3]) (targ1, mode))
1326 pat = GEN_FCN (icode) (targ0, xop0, xop1, targ1);
1333 delete_insns_since (last);
1336 /* It can't be done in this mode. Can we do it in a wider mode? */
1338 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1340 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1341 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1343 if (binoptab->handlers[(int) wider_mode].insn_code
1344 != CODE_FOR_nothing)
1346 register rtx t0 = gen_reg_rtx (wider_mode);
1347 register rtx t1 = gen_reg_rtx (wider_mode);
1349 if (expand_twoval_binop (binoptab,
1350 convert_to_mode (wider_mode, op0,
1352 convert_to_mode (wider_mode, op1,
1356 convert_move (targ0, t0, unsignedp);
1357 convert_move (targ1, t1, unsignedp);
1361 delete_insns_since (last);
1369 /* Generate code to perform an operation specified by UNOPTAB
1370 on operand OP0, with result having machine-mode MODE.
1372 UNSIGNEDP is for the case where we have to widen the operands
1373 to perform the operation. It says to use zero-extension.
1375 If TARGET is nonzero, the value
1376 is generated there, if it is convenient to do so.
1377 In all cases an rtx is returned for the locus of the value;
1378 this may or may not be TARGET. */
1381 expand_unop (mode, unoptab, op0, target, unsignedp)
1382 enum machine_mode mode;
1388 enum mode_class class;
1389 enum machine_mode wider_mode;
1391 rtx last = get_last_insn ();
1394 enum machine_mode submode;
1397 class = GET_MODE_CLASS (mode);
1400 if (class == MODE_COMPLEX_FLOAT || class == MODE_COMPLEX_INT)
1401 submode = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
1402 class == MODE_COMPLEX_INT ?
1403 MODE_INT : MODE_FLOAT, 0);
1406 op0 = protect_from_queue (op0, 0);
1410 op0 = force_not_mem (op0);
1414 target = protect_from_queue (target, 1);
1416 if (unoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1418 int icode = (int) unoptab->handlers[(int) mode].insn_code;
1419 enum machine_mode mode0 = insn_operand_mode[icode][1];
1425 temp = gen_reg_rtx (mode);
1427 if (GET_MODE (xop0) != VOIDmode
1428 && GET_MODE (xop0) != mode0)
1429 xop0 = convert_to_mode (mode0, xop0, unsignedp);
1431 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
1433 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
1434 xop0 = copy_to_mode_reg (mode0, xop0);
1436 if (! (*insn_operand_predicate[icode][0]) (temp, mode))
1437 temp = gen_reg_rtx (mode);
1439 pat = GEN_FCN (icode) (temp, xop0);
1442 if (GET_CODE (pat) == SEQUENCE
1443 && ! add_equal_note (pat, temp, unoptab->code, xop0, NULL_RTX))
1445 delete_insns_since (last);
1446 return expand_unop (mode, unoptab, op0, NULL_RTX, unsignedp);
1454 delete_insns_since (last);
1457 /* It can't be done in this mode. Can we open-code it in a wider mode? */
1459 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1460 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1461 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1463 if (unoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing)
1467 /* For certain operations, we need not actually extend
1468 the narrow operand, as long as we will truncate the
1469 results to the same narrowness. But it is faster to
1470 convert a SUBREG due to mode promotion. */
1472 if ((unoptab == neg_optab || unoptab == one_cmpl_optab)
1473 && GET_MODE_SIZE (wider_mode) <= UNITS_PER_WORD
1474 && class == MODE_INT
1475 && ! (GET_CODE (xop0) == SUBREG
1476 && SUBREG_PROMOTED_VAR_P (xop0)))
1477 xop0 = gen_rtx (SUBREG, wider_mode, force_reg (mode, xop0), 0);
1479 xop0 = convert_to_mode (wider_mode, xop0, unsignedp);
1481 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
1486 if (class != MODE_INT)
1489 target = gen_reg_rtx (mode);
1490 convert_move (target, temp, 0);
1494 return gen_lowpart (mode, temp);
1497 delete_insns_since (last);
1501 /* These can be done a word at a time. */
1502 if (unoptab == one_cmpl_optab
1503 && class == MODE_INT
1504 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
1505 && unoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
1510 if (target == 0 || target == op0)
1511 target = gen_reg_rtx (mode);
1515 /* Do the actual arithmetic. */
1516 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
1518 rtx target_piece = operand_subword (target, i, 1, mode);
1519 rtx x = expand_unop (word_mode, unoptab,
1520 operand_subword_force (op0, i, mode),
1521 target_piece, unsignedp);
1522 if (target_piece != x)
1523 emit_move_insn (target_piece, x);
1526 insns = get_insns ();
1529 emit_no_conflict_block (insns, target, op0, NULL_RTX,
1530 gen_rtx (unoptab->code, mode, op0));
1534 if (unoptab->handlers[(int) mode].libfunc)
1537 rtx funexp = unoptab->handlers[(int) mode].libfunc;
1541 /* Pass 1 for NO_QUEUE so we don't lose any increments
1542 if the libcall is cse'd or moved. */
1543 emit_library_call (unoptab->handlers[(int) mode].libfunc,
1544 1, mode, 1, op0, mode);
1545 insns = get_insns ();
1548 target = gen_reg_rtx (mode);
1549 emit_libcall_block (insns, target, hard_libcall_value (mode),
1550 gen_rtx (unoptab->code, mode, op0));
1555 /* It can't be done in this mode. Can we do it in a wider mode? */
1557 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1559 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1560 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1562 if ((unoptab->handlers[(int) wider_mode].insn_code
1563 != CODE_FOR_nothing)
1564 || unoptab->handlers[(int) wider_mode].libfunc)
1568 /* For certain operations, we need not actually extend
1569 the narrow operand, as long as we will truncate the
1570 results to the same narrowness. */
1572 if ((unoptab == neg_optab || unoptab == one_cmpl_optab)
1573 && GET_MODE_SIZE (wider_mode) <= UNITS_PER_WORD
1574 && class == MODE_INT
1575 && ! (GET_CODE (xop0) == SUBREG
1576 && SUBREG_PROMOTED_VAR_P (xop0)))
1577 xop0 = gen_rtx (SUBREG, wider_mode, force_reg (mode, xop0), 0);
1579 xop0 = convert_to_mode (wider_mode, xop0, unsignedp);
1581 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
1586 if (class != MODE_INT)
1589 target = gen_reg_rtx (mode);
1590 convert_move (target, temp, 0);
1594 return gen_lowpart (mode, temp);
1597 delete_insns_since (last);
1605 /* Generate an instruction whose insn-code is INSN_CODE,
1606 with two operands: an output TARGET and an input OP0.
1607 TARGET *must* be nonzero, and the output is always stored there.
1608 CODE is an rtx code such that (CODE OP0) is an rtx that describes
1609 the value that is stored into TARGET. */
1612 emit_unop_insn (icode, target, op0, code)
1619 enum machine_mode mode0 = insn_operand_mode[icode][1];
1622 temp = target = protect_from_queue (target, 1);
1624 op0 = protect_from_queue (op0, 0);
1627 op0 = force_not_mem (op0);
1629 /* Now, if insn does not accept our operands, put them into pseudos. */
1631 if (! (*insn_operand_predicate[icode][1]) (op0, mode0))
1632 op0 = copy_to_mode_reg (mode0, op0);
1634 if (! (*insn_operand_predicate[icode][0]) (temp, GET_MODE (temp))
1635 || (flag_force_mem && GET_CODE (temp) == MEM))
1636 temp = gen_reg_rtx (GET_MODE (temp));
1638 pat = GEN_FCN (icode) (temp, op0);
1640 if (GET_CODE (pat) == SEQUENCE && code != UNKNOWN)
1641 add_equal_note (pat, temp, code, op0, NULL_RTX);
1646 emit_move_insn (target, temp);
1649 /* Emit code to perform a series of operations on a multi-word quantity, one
1652 Such a block is preceded by a CLOBBER of the output, consists of multiple
1653 insns, each setting one word of the output, and followed by a SET copying
1654 the output to itself.
1656 Each of the insns setting words of the output receives a REG_NO_CONFLICT
1657 note indicating that it doesn't conflict with the (also multi-word)
1658 inputs. The entire block is surrounded by REG_LIBCALL and REG_RETVAL
1661 INSNS is a block of code generated to perform the operation, not including
1662 the CLOBBER and final copy. All insns that compute intermediate values
1663 are first emitted, followed by the block as described above. Only
1664 INSNs are allowed in the block; no library calls or jumps may be
1667 TARGET, OP0, and OP1 are the output and inputs of the operations,
1668 respectively. OP1 may be zero for a unary operation.
1670 EQUIV, if non-zero, is an expression to be placed into a REG_EQUAL note
1673 If TARGET is not a register, INSNS is simply emitted with no special
1676 The final insn emitted is returned. */
1679 emit_no_conflict_block (insns, target, op0, op1, equiv)
1685 rtx prev, next, first, last, insn;
1687 if (GET_CODE (target) != REG || reload_in_progress)
1688 return emit_insns (insns);
1690 /* First emit all insns that do not store into words of the output and remove
1691 these from the list. */
1692 for (insn = insns; insn; insn = next)
1697 next = NEXT_INSN (insn);
1699 if (GET_CODE (insn) != INSN)
1702 if (GET_CODE (PATTERN (insn)) == SET)
1703 set = PATTERN (insn);
1704 else if (GET_CODE (PATTERN (insn)) == PARALLEL)
1706 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
1707 if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET)
1709 set = XVECEXP (PATTERN (insn), 0, i);
1717 if (! reg_overlap_mentioned_p (target, SET_DEST (set)))
1719 if (PREV_INSN (insn))
1720 NEXT_INSN (PREV_INSN (insn)) = next;
1725 PREV_INSN (next) = PREV_INSN (insn);
1731 prev = get_last_insn ();
1733 /* Now write the CLOBBER of the output, followed by the setting of each
1734 of the words, followed by the final copy. */
1735 if (target != op0 && target != op1)
1736 emit_insn (gen_rtx (CLOBBER, VOIDmode, target));
1738 for (insn = insns; insn; insn = next)
1740 next = NEXT_INSN (insn);
1743 if (op1 && GET_CODE (op1) == REG)
1744 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_NO_CONFLICT, op1,
1747 if (op0 && GET_CODE (op0) == REG)
1748 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_NO_CONFLICT, op0,
1752 last = emit_move_insn (target, target);
1754 REG_NOTES (last) = gen_rtx (EXPR_LIST, REG_EQUAL, equiv, REG_NOTES (last));
1757 first = get_insns ();
1759 first = NEXT_INSN (prev);
1761 /* Encapsulate the block so it gets manipulated as a unit. */
1762 REG_NOTES (first) = gen_rtx (INSN_LIST, REG_LIBCALL, last,
1764 REG_NOTES (last) = gen_rtx (INSN_LIST, REG_RETVAL, first, REG_NOTES (last));
1769 /* Emit code to make a call to a constant function or a library call.
1771 INSNS is a list containing all insns emitted in the call.
1772 These insns leave the result in RESULT. Our block is to copy RESULT
1773 to TARGET, which is logically equivalent to EQUIV.
1775 We first emit any insns that set a pseudo on the assumption that these are
1776 loading constants into registers; doing so allows them to be safely cse'ed
1777 between blocks. Then we emit all the other insns in the block, followed by
1778 an insn to move RESULT to TARGET. This last insn will have a REQ_EQUAL
1779 note with an operand of EQUIV.
1781 Moving assignments to pseudos outside of the block is done to improve
1782 the generated code, but is not required to generate correct code,
1783 hence being unable to move an assignment is not grounds for not making
1784 a libcall block. There are two reasons why it is safe to leave these
1785 insns inside the block: First, we know that these pseudos cannot be
1786 used in generated RTL outside the block since they are created for
1787 temporary purposes within the block. Second, CSE will not record the
1788 values of anything set inside a libcall block, so we know they must
1789 be dead at the end of the block.
1791 Except for the first group of insns (the ones setting pseudos), the
1792 block is delimited by REG_RETVAL and REG_LIBCALL notes. */
1795 emit_libcall_block (insns, target, result, equiv)
1801 rtx prev, next, first, last, insn;
1803 /* First emit all insns that set pseudos. Remove them from the list as
1804 we go. Avoid insns that set pseudo which were referenced in previous
1805 insns. These can be generated by move_by_pieces, for example,
1806 to update an address. */
1808 for (insn = insns; insn; insn = next)
1810 rtx set = single_set (insn);
1812 next = NEXT_INSN (insn);
1814 if (set != 0 && GET_CODE (SET_DEST (set)) == REG
1815 && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER
1817 || (! reg_mentioned_p (SET_DEST (set), PATTERN (insns))
1818 && ! reg_used_between_p (SET_DEST (set), insns, insn))))
1820 if (PREV_INSN (insn))
1821 NEXT_INSN (PREV_INSN (insn)) = next;
1826 PREV_INSN (next) = PREV_INSN (insn);
1832 prev = get_last_insn ();
1834 /* Write the remaining insns followed by the final copy. */
1836 for (insn = insns; insn; insn = next)
1838 next = NEXT_INSN (insn);
1843 last = emit_move_insn (target, result);
1844 REG_NOTES (last) = gen_rtx (EXPR_LIST, REG_EQUAL, equiv, REG_NOTES (last));
1847 first = get_insns ();
1849 first = NEXT_INSN (prev);
1851 /* Encapsulate the block so it gets manipulated as a unit. */
1852 REG_NOTES (first) = gen_rtx (INSN_LIST, REG_LIBCALL, last,
1854 REG_NOTES (last) = gen_rtx (INSN_LIST, REG_RETVAL, first, REG_NOTES (last));
1857 /* Generate code to store zero in X. */
1863 emit_move_insn (x, const0_rtx);
1866 /* Generate code to store 1 in X
1867 assuming it contains zero beforehand. */
1870 emit_0_to_1_insn (x)
1873 emit_move_insn (x, const1_rtx);
1876 /* Generate code to compare X with Y
1877 so that the condition codes are set.
1879 MODE is the mode of the inputs (in case they are const_int).
1880 UNSIGNEDP nonzero says that X and Y are unsigned;
1881 this matters if they need to be widened.
1883 If they have mode BLKmode, then SIZE specifies the size of both X and Y,
1884 and ALIGN specifies the known shared alignment of X and Y.
1886 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).
1887 It is ignored for fixed-point and block comparisons;
1888 it is used only for floating-point comparisons. */
1891 emit_cmp_insn (x, y, comparison, size, mode, unsignedp, align)
1893 enum rtx_code comparison;
1895 enum machine_mode mode;
1899 enum mode_class class;
1900 enum machine_mode wider_mode;
1902 class = GET_MODE_CLASS (mode);
1904 /* They could both be VOIDmode if both args are immediate constants,
1905 but we should fold that at an earlier stage.
1906 With no special code here, this will call abort,
1907 reminding the programmer to implement such folding. */
1909 if (mode != BLKmode && flag_force_mem)
1911 x = force_not_mem (x);
1912 y = force_not_mem (y);
1915 /* If we are inside an appropriately-short loop and one operand is an
1916 expensive constant, force it into a register. */
1917 if (CONSTANT_P (x) && preserve_subexpressions_p () && rtx_cost (x, COMPARE) > 2)
1918 x = force_reg (mode, x);
1920 if (CONSTANT_P (y) && preserve_subexpressions_p () && rtx_cost (y, COMPARE) > 2)
1921 y = force_reg (mode, y);
1923 /* Don't let both operands fail to indicate the mode. */
1924 if (GET_MODE (x) == VOIDmode && GET_MODE (y) == VOIDmode)
1925 x = force_reg (mode, x);
1927 /* Handle all BLKmode compares. */
1929 if (mode == BLKmode)
1932 x = protect_from_queue (x, 0);
1933 y = protect_from_queue (y, 0);
1937 #ifdef HAVE_cmpstrqi
1939 && GET_CODE (size) == CONST_INT
1940 && INTVAL (size) < (1 << GET_MODE_BITSIZE (QImode)))
1942 enum machine_mode result_mode
1943 = insn_operand_mode[(int) CODE_FOR_cmpstrqi][0];
1944 rtx result = gen_reg_rtx (result_mode);
1945 emit_insn (gen_cmpstrqi (result, x, y, size, GEN_INT (align)));
1946 emit_cmp_insn (result, const0_rtx, comparison, NULL_RTX,
1951 #ifdef HAVE_cmpstrhi
1953 && GET_CODE (size) == CONST_INT
1954 && INTVAL (size) < (1 << GET_MODE_BITSIZE (HImode)))
1956 enum machine_mode result_mode
1957 = insn_operand_mode[(int) CODE_FOR_cmpstrhi][0];
1958 rtx result = gen_reg_rtx (result_mode);
1959 emit_insn (gen_cmpstrhi (result, x, y, size, GEN_INT (align)));
1960 emit_cmp_insn (result, const0_rtx, comparison, NULL_RTX,
1965 #ifdef HAVE_cmpstrsi
1968 enum machine_mode result_mode
1969 = insn_operand_mode[(int) CODE_FOR_cmpstrsi][0];
1970 rtx result = gen_reg_rtx (result_mode);
1971 size = protect_from_queue (size, 0);
1972 emit_insn (gen_cmpstrsi (result, x, y,
1973 convert_to_mode (SImode, size, 1),
1975 emit_cmp_insn (result, const0_rtx, comparison, NULL_RTX,
1981 #ifdef TARGET_MEM_FUNCTIONS
1982 emit_library_call (memcmp_libfunc, 0,
1983 TYPE_MODE (integer_type_node), 3,
1984 XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
1987 emit_library_call (bcmp_libfunc, 0,
1988 TYPE_MODE (integer_type_node), 3,
1989 XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
1992 emit_cmp_insn (hard_libcall_value (TYPE_MODE (integer_type_node)),
1993 const0_rtx, comparison, NULL_RTX,
1994 TYPE_MODE (integer_type_node), 0, 0);
1999 /* Handle some compares against zero. */
2001 if (y == CONST0_RTX (mode)
2002 && tst_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2004 int icode = (int) tst_optab->handlers[(int) mode].insn_code;
2007 x = protect_from_queue (x, 0);
2008 y = protect_from_queue (y, 0);
2010 /* Now, if insn does accept these operands, put them into pseudos. */
2011 if (! (*insn_operand_predicate[icode][0])
2012 (x, insn_operand_mode[icode][0]))
2013 x = copy_to_mode_reg (insn_operand_mode[icode][0], x);
2015 emit_insn (GEN_FCN (icode) (x));
2019 /* Handle compares for which there is a directly suitable insn. */
2021 if (cmp_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2023 int icode = (int) cmp_optab->handlers[(int) mode].insn_code;
2026 x = protect_from_queue (x, 0);
2027 y = protect_from_queue (y, 0);
2029 /* Now, if insn doesn't accept these operands, put them into pseudos. */
2030 if (! (*insn_operand_predicate[icode][0])
2031 (x, insn_operand_mode[icode][0]))
2032 x = copy_to_mode_reg (insn_operand_mode[icode][0], x);
2034 if (! (*insn_operand_predicate[icode][1])
2035 (y, insn_operand_mode[icode][1]))
2036 y = copy_to_mode_reg (insn_operand_mode[icode][1], y);
2038 emit_insn (GEN_FCN (icode) (x, y));
2042 /* Try widening if we can find a direct insn that way. */
2044 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
2046 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2047 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2049 if (cmp_optab->handlers[(int) wider_mode].insn_code
2050 != CODE_FOR_nothing)
2052 x = protect_from_queue (x, 0);
2053 y = protect_from_queue (y, 0);
2054 x = convert_to_mode (wider_mode, x, unsignedp);
2055 y = convert_to_mode (wider_mode, y, unsignedp);
2056 emit_cmp_insn (x, y, comparison, NULL_RTX,
2057 wider_mode, unsignedp, align);
2063 /* Handle a lib call just for the mode we are using. */
2065 if (cmp_optab->handlers[(int) mode].libfunc
2066 && class != MODE_FLOAT)
2068 rtx libfunc = cmp_optab->handlers[(int) mode].libfunc;
2069 /* If we want unsigned, and this mode has a distinct unsigned
2070 comparison routine, use that. */
2071 if (unsignedp && ucmp_optab->handlers[(int) mode].libfunc)
2072 libfunc = ucmp_optab->handlers[(int) mode].libfunc;
2074 emit_library_call (libfunc, 1,
2075 SImode, 2, x, mode, y, mode);
2077 /* Integer comparison returns a result that must be compared against 1,
2078 so that even if we do an unsigned compare afterward,
2079 there is still a value that can represent the result "less than". */
2081 emit_cmp_insn (hard_libcall_value (SImode), const1_rtx,
2082 comparison, NULL_RTX, SImode, unsignedp, 0);
2086 if (class == MODE_FLOAT)
2087 emit_float_lib_cmp (x, y, comparison);
2093 /* Nonzero if a compare of mode MODE can be done straightforwardly
2094 (without splitting it into pieces). */
2097 can_compare_p (mode)
2098 enum machine_mode mode;
2102 if (cmp_optab->handlers[(int)mode].insn_code != CODE_FOR_nothing)
2104 mode = GET_MODE_WIDER_MODE (mode);
2105 } while (mode != VOIDmode);
2110 /* Emit a library call comparison between floating point X and Y.
2111 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */
2114 emit_float_lib_cmp (x, y, comparison)
2116 enum rtx_code comparison;
2118 enum machine_mode mode = GET_MODE (x);
2125 libfunc = eqsf2_libfunc;
2129 libfunc = nesf2_libfunc;
2133 libfunc = gtsf2_libfunc;
2137 libfunc = gesf2_libfunc;
2141 libfunc = ltsf2_libfunc;
2145 libfunc = lesf2_libfunc;
2148 else if (mode == DFmode)
2152 libfunc = eqdf2_libfunc;
2156 libfunc = nedf2_libfunc;
2160 libfunc = gtdf2_libfunc;
2164 libfunc = gedf2_libfunc;
2168 libfunc = ltdf2_libfunc;
2172 libfunc = ledf2_libfunc;
2175 else if (mode == XFmode)
2179 libfunc = eqxf2_libfunc;
2183 libfunc = nexf2_libfunc;
2187 libfunc = gtxf2_libfunc;
2191 libfunc = gexf2_libfunc;
2195 libfunc = ltxf2_libfunc;
2199 libfunc = lexf2_libfunc;
2202 else if (mode == TFmode)
2206 libfunc = eqtf2_libfunc;
2210 libfunc = netf2_libfunc;
2214 libfunc = gttf2_libfunc;
2218 libfunc = getf2_libfunc;
2222 libfunc = lttf2_libfunc;
2226 libfunc = letf2_libfunc;
2231 enum machine_mode wider_mode;
2233 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2234 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2236 if ((cmp_optab->handlers[(int) wider_mode].insn_code
2237 != CODE_FOR_nothing)
2238 || (cmp_optab->handlers[(int) wider_mode].libfunc != 0))
2240 x = protect_from_queue (x, 0);
2241 y = protect_from_queue (y, 0);
2242 x = convert_to_mode (wider_mode, x, 0);
2243 y = convert_to_mode (wider_mode, y, 0);
2244 emit_float_lib_cmp (x, y, comparison);
2251 emit_library_call (libfunc, 1,
2252 SImode, 2, x, mode, y, mode);
2254 emit_cmp_insn (hard_libcall_value (SImode), const0_rtx, comparison,
2255 NULL_RTX, SImode, 0, 0);
2258 /* Generate code to indirectly jump to a location given in the rtx LOC. */
2261 emit_indirect_jump (loc)
2264 if (! ((*insn_operand_predicate[(int)CODE_FOR_indirect_jump][0])
2266 loc = copy_to_mode_reg (insn_operand_mode[(int)CODE_FOR_indirect_jump][0],
2269 emit_jump_insn (gen_indirect_jump (loc));
2273 /* These three functions generate an insn body and return it
2274 rather than emitting the insn.
2276 They do not protect from queued increments,
2277 because they may be used 1) in protect_from_queue itself
2278 and 2) in other passes where there is no queue. */
2280 /* Generate and return an insn body to add Y to X. */
2283 gen_add2_insn (x, y)
2286 int icode = (int) add_optab->handlers[(int) GET_MODE (x)].insn_code;
2288 if (! (*insn_operand_predicate[icode][0]) (x, insn_operand_mode[icode][0])
2289 || ! (*insn_operand_predicate[icode][1]) (x, insn_operand_mode[icode][1])
2290 || ! (*insn_operand_predicate[icode][2]) (y, insn_operand_mode[icode][2]))
2293 return (GEN_FCN (icode) (x, x, y));
2297 have_add2_insn (mode)
2298 enum machine_mode mode;
2300 return add_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
2303 /* Generate and return an insn body to subtract Y from X. */
2306 gen_sub2_insn (x, y)
2309 int icode = (int) sub_optab->handlers[(int) GET_MODE (x)].insn_code;
2311 if (! (*insn_operand_predicate[icode][0]) (x, insn_operand_mode[icode][0])
2312 || ! (*insn_operand_predicate[icode][1]) (x, insn_operand_mode[icode][1])
2313 || ! (*insn_operand_predicate[icode][2]) (y, insn_operand_mode[icode][2]))
2316 return (GEN_FCN (icode) (x, x, y));
2320 have_sub2_insn (mode)
2321 enum machine_mode mode;
2323 return sub_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
2326 /* Generate the body of an instruction to copy Y into X. */
2329 gen_move_insn (x, y)
2332 register enum machine_mode mode = GET_MODE (x);
2333 enum insn_code insn_code;
2335 if (mode == VOIDmode)
2336 mode = GET_MODE (y);
2338 insn_code = mov_optab->handlers[(int) mode].insn_code;
2340 /* Handle MODE_CC modes: If we don't have a special move insn for this mode,
2341 find a mode to do it in. If we have a movcc, use it. Otherwise,
2342 find the MODE_INT mode of the same width. */
2344 if (insn_code == CODE_FOR_nothing)
2346 enum machine_mode tmode = VOIDmode;
2349 if (GET_MODE_CLASS (mode) == MODE_CC && mode != CCmode
2350 && mov_optab->handlers[(int) CCmode].insn_code != CODE_FOR_nothing)
2352 else if (GET_MODE_CLASS (mode) == MODE_CC)
2353 for (tmode = QImode; tmode != VOIDmode;
2354 tmode = GET_MODE_WIDER_MODE (tmode))
2355 if (GET_MODE_SIZE (tmode) == GET_MODE_SIZE (mode))
2358 if (tmode == VOIDmode)
2361 /* Get X and Y in TMODE. We can't use gen_lowpart here because it
2362 may call change_address which is not appropriate if we were
2363 called when a reload was in progress. We don't have to worry
2364 about changing the address since the size in bytes is supposed to
2365 be the same. Copy the MEM to change the mode and move any
2366 substitutions from the old MEM to the new one. */
2368 if (reload_in_progress)
2370 x = gen_lowpart_common (tmode, x1);
2371 if (x == 0 && GET_CODE (x1) == MEM)
2373 x = gen_rtx (MEM, tmode, XEXP (x1, 0));
2374 RTX_UNCHANGING_P (x) = RTX_UNCHANGING_P (x1);
2375 MEM_IN_STRUCT_P (x) = MEM_IN_STRUCT_P (x1);
2376 MEM_VOLATILE_P (x) = MEM_VOLATILE_P (x1);
2377 copy_replacements (x1, x);
2380 y = gen_lowpart_common (tmode, y1);
2381 if (y == 0 && GET_CODE (y1) == MEM)
2383 y = gen_rtx (MEM, tmode, XEXP (y1, 0));
2384 RTX_UNCHANGING_P (y) = RTX_UNCHANGING_P (y1);
2385 MEM_IN_STRUCT_P (y) = MEM_IN_STRUCT_P (y1);
2386 MEM_VOLATILE_P (y) = MEM_VOLATILE_P (y1);
2387 copy_replacements (y1, y);
2392 x = gen_lowpart (tmode, x);
2393 y = gen_lowpart (tmode, y);
2396 insn_code = mov_optab->handlers[(int) tmode].insn_code;
2399 return (GEN_FCN (insn_code) (x, y));
2402 /* Tables of patterns for extending one integer mode to another. */
2403 static enum insn_code extendtab[MAX_MACHINE_MODE][MAX_MACHINE_MODE][2];
2405 /* Return the insn code used to extend FROM_MODE to TO_MODE.
2406 UNSIGNEDP specifies zero-extension instead of sign-extension. If
2407 no such operation exists, CODE_FOR_nothing will be returned. */
2410 can_extend_p (to_mode, from_mode, unsignedp)
2411 enum machine_mode to_mode, from_mode;
2414 return extendtab[(int) to_mode][(int) from_mode][unsignedp];
2417 /* Generate the body of an insn to extend Y (with mode MFROM)
2418 into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */
2421 gen_extend_insn (x, y, mto, mfrom, unsignedp)
2423 enum machine_mode mto, mfrom;
2426 return (GEN_FCN (extendtab[(int) mto][(int) mfrom][unsignedp]) (x, y));
2434 for (p = extendtab[0][0];
2435 p < extendtab[0][0] + sizeof extendtab / sizeof extendtab[0][0][0];
2437 *p = CODE_FOR_nothing;
2439 #ifdef HAVE_extendditi2
2440 if (HAVE_extendditi2)
2441 extendtab[(int) TImode][(int) DImode][0] = CODE_FOR_extendditi2;
2443 #ifdef HAVE_extendsiti2
2444 if (HAVE_extendsiti2)
2445 extendtab[(int) TImode][(int) SImode][0] = CODE_FOR_extendsiti2;
2447 #ifdef HAVE_extendhiti2
2448 if (HAVE_extendhiti2)
2449 extendtab[(int) TImode][(int) HImode][0] = CODE_FOR_extendhiti2;
2451 #ifdef HAVE_extendqiti2
2452 if (HAVE_extendqiti2)
2453 extendtab[(int) TImode][(int) QImode][0] = CODE_FOR_extendqiti2;
2455 #ifdef HAVE_extendsidi2
2456 if (HAVE_extendsidi2)
2457 extendtab[(int) DImode][(int) SImode][0] = CODE_FOR_extendsidi2;
2459 #ifdef HAVE_extendhidi2
2460 if (HAVE_extendhidi2)
2461 extendtab[(int) DImode][(int) HImode][0] = CODE_FOR_extendhidi2;
2463 #ifdef HAVE_extendqidi2
2464 if (HAVE_extendqidi2)
2465 extendtab[(int) DImode][(int) QImode][0] = CODE_FOR_extendqidi2;
2467 #ifdef HAVE_extendhisi2
2468 if (HAVE_extendhisi2)
2469 extendtab[(int) SImode][(int) HImode][0] = CODE_FOR_extendhisi2;
2471 #ifdef HAVE_extendqisi2
2472 if (HAVE_extendqisi2)
2473 extendtab[(int) SImode][(int) QImode][0] = CODE_FOR_extendqisi2;
2475 #ifdef HAVE_extendqihi2
2476 if (HAVE_extendqihi2)
2477 extendtab[(int) HImode][(int) QImode][0] = CODE_FOR_extendqihi2;
2480 #ifdef HAVE_zero_extendditi2
2481 if (HAVE_zero_extendsiti2)
2482 extendtab[(int) TImode][(int) DImode][1] = CODE_FOR_zero_extendditi2;
2484 #ifdef HAVE_zero_extendsiti2
2485 if (HAVE_zero_extendsiti2)
2486 extendtab[(int) TImode][(int) SImode][1] = CODE_FOR_zero_extendsiti2;
2488 #ifdef HAVE_zero_extendhiti2
2489 if (HAVE_zero_extendhiti2)
2490 extendtab[(int) TImode][(int) HImode][1] = CODE_FOR_zero_extendhiti2;
2492 #ifdef HAVE_zero_extendqiti2
2493 if (HAVE_zero_extendqiti2)
2494 extendtab[(int) TImode][(int) QImode][1] = CODE_FOR_zero_extendqiti2;
2496 #ifdef HAVE_zero_extendsidi2
2497 if (HAVE_zero_extendsidi2)
2498 extendtab[(int) DImode][(int) SImode][1] = CODE_FOR_zero_extendsidi2;
2500 #ifdef HAVE_zero_extendhidi2
2501 if (HAVE_zero_extendhidi2)
2502 extendtab[(int) DImode][(int) HImode][1] = CODE_FOR_zero_extendhidi2;
2504 #ifdef HAVE_zero_extendqidi2
2505 if (HAVE_zero_extendqidi2)
2506 extendtab[(int) DImode][(int) QImode][1] = CODE_FOR_zero_extendqidi2;
2508 #ifdef HAVE_zero_extendhisi2
2509 if (HAVE_zero_extendhisi2)
2510 extendtab[(int) SImode][(int) HImode][1] = CODE_FOR_zero_extendhisi2;
2512 #ifdef HAVE_zero_extendqisi2
2513 if (HAVE_zero_extendqisi2)
2514 extendtab[(int) SImode][(int) QImode][1] = CODE_FOR_zero_extendqisi2;
2516 #ifdef HAVE_zero_extendqihi2
2517 if (HAVE_zero_extendqihi2)
2518 extendtab[(int) HImode][(int) QImode][1] = CODE_FOR_zero_extendqihi2;
2522 /* can_fix_p and can_float_p say whether the target machine
2523 can directly convert a given fixed point type to
2524 a given floating point type, or vice versa.
2525 The returned value is the CODE_FOR_... value to use,
2526 or CODE_FOR_nothing if these modes cannot be directly converted. */
2528 static enum insn_code fixtab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
2529 static enum insn_code fixtrunctab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
2530 static enum insn_code floattab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
2532 /* *TRUNCP_PTR is set to 1 if it is necessary to output
2533 an explicit FTRUNC insn before the fix insn; otherwise 0. */
2535 static enum insn_code
2536 can_fix_p (fixmode, fltmode, unsignedp, truncp_ptr)
2537 enum machine_mode fltmode, fixmode;
2542 if (fixtrunctab[(int) fltmode][(int) fixmode][unsignedp] != CODE_FOR_nothing)
2543 return fixtrunctab[(int) fltmode][(int) fixmode][unsignedp];
2545 if (ftrunc_optab->handlers[(int) fltmode].insn_code != CODE_FOR_nothing)
2548 return fixtab[(int) fltmode][(int) fixmode][unsignedp];
2550 return CODE_FOR_nothing;
2553 static enum insn_code
2554 can_float_p (fltmode, fixmode, unsignedp)
2555 enum machine_mode fixmode, fltmode;
2558 return floattab[(int) fltmode][(int) fixmode][unsignedp];
2565 for (p = fixtab[0][0];
2566 p < fixtab[0][0] + sizeof fixtab / sizeof (fixtab[0][0][0]);
2568 *p = CODE_FOR_nothing;
2569 for (p = fixtrunctab[0][0];
2570 p < fixtrunctab[0][0] + sizeof fixtrunctab / sizeof (fixtrunctab[0][0][0]);
2572 *p = CODE_FOR_nothing;
2574 #ifdef HAVE_fixsfqi2
2576 fixtab[(int) SFmode][(int) QImode][0] = CODE_FOR_fixsfqi2;
2578 #ifdef HAVE_fixsfhi2
2580 fixtab[(int) SFmode][(int) HImode][0] = CODE_FOR_fixsfhi2;
2582 #ifdef HAVE_fixsfsi2
2584 fixtab[(int) SFmode][(int) SImode][0] = CODE_FOR_fixsfsi2;
2586 #ifdef HAVE_fixsfdi2
2588 fixtab[(int) SFmode][(int) DImode][0] = CODE_FOR_fixsfdi2;
2591 #ifdef HAVE_fixdfqi2
2593 fixtab[(int) DFmode][(int) QImode][0] = CODE_FOR_fixdfqi2;
2595 #ifdef HAVE_fixdfhi2
2597 fixtab[(int) DFmode][(int) HImode][0] = CODE_FOR_fixdfhi2;
2599 #ifdef HAVE_fixdfsi2
2601 fixtab[(int) DFmode][(int) SImode][0] = CODE_FOR_fixdfsi2;
2603 #ifdef HAVE_fixdfdi2
2605 fixtab[(int) DFmode][(int) DImode][0] = CODE_FOR_fixdfdi2;
2607 #ifdef HAVE_fixdfti2
2609 fixtab[(int) DFmode][(int) TImode][0] = CODE_FOR_fixdfti2;
2612 #ifdef HAVE_fixxfqi2
2614 fixtab[(int) XFmode][(int) QImode][0] = CODE_FOR_fixxfqi2;
2616 #ifdef HAVE_fixxfhi2
2618 fixtab[(int) XFmode][(int) HImode][0] = CODE_FOR_fixxfhi2;
2620 #ifdef HAVE_fixxfsi2
2622 fixtab[(int) XFmode][(int) SImode][0] = CODE_FOR_fixxfsi2;
2624 #ifdef HAVE_fixxfdi2
2626 fixtab[(int) XFmode][(int) DImode][0] = CODE_FOR_fixxfdi2;
2628 #ifdef HAVE_fixxfti2
2630 fixtab[(int) XFmode][(int) TImode][0] = CODE_FOR_fixxfti2;
2633 #ifdef HAVE_fixtfqi2
2635 fixtab[(int) TFmode][(int) QImode][0] = CODE_FOR_fixtfqi2;
2637 #ifdef HAVE_fixtfhi2
2639 fixtab[(int) TFmode][(int) HImode][0] = CODE_FOR_fixtfhi2;
2641 #ifdef HAVE_fixtfsi2
2643 fixtab[(int) TFmode][(int) SImode][0] = CODE_FOR_fixtfsi2;
2645 #ifdef HAVE_fixtfdi2
2647 fixtab[(int) TFmode][(int) DImode][0] = CODE_FOR_fixtfdi2;
2649 #ifdef HAVE_fixtfti2
2651 fixtab[(int) TFmode][(int) TImode][0] = CODE_FOR_fixtfti2;
2654 #ifdef HAVE_fixunssfqi2
2655 if (HAVE_fixunssfqi2)
2656 fixtab[(int) SFmode][(int) QImode][1] = CODE_FOR_fixunssfqi2;
2658 #ifdef HAVE_fixunssfhi2
2659 if (HAVE_fixunssfhi2)
2660 fixtab[(int) SFmode][(int) HImode][1] = CODE_FOR_fixunssfhi2;
2662 #ifdef HAVE_fixunssfsi2
2663 if (HAVE_fixunssfsi2)
2664 fixtab[(int) SFmode][(int) SImode][1] = CODE_FOR_fixunssfsi2;
2666 #ifdef HAVE_fixunssfdi2
2667 if (HAVE_fixunssfdi2)
2668 fixtab[(int) SFmode][(int) DImode][1] = CODE_FOR_fixunssfdi2;
2671 #ifdef HAVE_fixunsdfqi2
2672 if (HAVE_fixunsdfqi2)
2673 fixtab[(int) DFmode][(int) QImode][1] = CODE_FOR_fixunsdfqi2;
2675 #ifdef HAVE_fixunsdfhi2
2676 if (HAVE_fixunsdfhi2)
2677 fixtab[(int) DFmode][(int) HImode][1] = CODE_FOR_fixunsdfhi2;
2679 #ifdef HAVE_fixunsdfsi2
2680 if (HAVE_fixunsdfsi2)
2681 fixtab[(int) DFmode][(int) SImode][1] = CODE_FOR_fixunsdfsi2;
2683 #ifdef HAVE_fixunsdfdi2
2684 if (HAVE_fixunsdfdi2)
2685 fixtab[(int) DFmode][(int) DImode][1] = CODE_FOR_fixunsdfdi2;
2687 #ifdef HAVE_fixunsdfti2
2688 if (HAVE_fixunsdfti2)
2689 fixtab[(int) DFmode][(int) TImode][1] = CODE_FOR_fixunsdfti2;
2692 #ifdef HAVE_fixunsxfqi2
2693 if (HAVE_fixunsxfqi2)
2694 fixtab[(int) XFmode][(int) QImode][1] = CODE_FOR_fixunsxfqi2;
2696 #ifdef HAVE_fixunsxfhi2
2697 if (HAVE_fixunsxfhi2)
2698 fixtab[(int) XFmode][(int) HImode][1] = CODE_FOR_fixunsxfhi2;
2700 #ifdef HAVE_fixunsxfsi2
2701 if (HAVE_fixunsxfsi2)
2702 fixtab[(int) XFmode][(int) SImode][1] = CODE_FOR_fixunsxfsi2;
2704 #ifdef HAVE_fixunsxfdi2
2705 if (HAVE_fixunsxfdi2)
2706 fixtab[(int) XFmode][(int) DImode][1] = CODE_FOR_fixunsxfdi2;
2708 #ifdef HAVE_fixunsxfti2
2709 if (HAVE_fixunsxfti2)
2710 fixtab[(int) XFmode][(int) TImode][1] = CODE_FOR_fixunsxfti2;
2713 #ifdef HAVE_fixunstfqi2
2714 if (HAVE_fixunstfqi2)
2715 fixtab[(int) TFmode][(int) QImode][1] = CODE_FOR_fixunstfqi2;
2717 #ifdef HAVE_fixunstfhi2
2718 if (HAVE_fixunstfhi2)
2719 fixtab[(int) TFmode][(int) HImode][1] = CODE_FOR_fixunstfhi2;
2721 #ifdef HAVE_fixunstfsi2
2722 if (HAVE_fixunstfsi2)
2723 fixtab[(int) TFmode][(int) SImode][1] = CODE_FOR_fixunstfsi2;
2725 #ifdef HAVE_fixunstfdi2
2726 if (HAVE_fixunstfdi2)
2727 fixtab[(int) TFmode][(int) DImode][1] = CODE_FOR_fixunstfdi2;
2729 #ifdef HAVE_fixunstfti2
2730 if (HAVE_fixunstfti2)
2731 fixtab[(int) TFmode][(int) TImode][1] = CODE_FOR_fixunstfti2;
2734 #ifdef HAVE_fix_truncsfqi2
2735 if (HAVE_fix_truncsfqi2)
2736 fixtrunctab[(int) SFmode][(int) QImode][0] = CODE_FOR_fix_truncsfqi2;
2738 #ifdef HAVE_fix_truncsfhi2
2739 if (HAVE_fix_truncsfhi2)
2740 fixtrunctab[(int) SFmode][(int) HImode][0] = CODE_FOR_fix_truncsfhi2;
2742 #ifdef HAVE_fix_truncsfsi2
2743 if (HAVE_fix_truncsfsi2)
2744 fixtrunctab[(int) SFmode][(int) SImode][0] = CODE_FOR_fix_truncsfsi2;
2746 #ifdef HAVE_fix_truncsfdi2
2747 if (HAVE_fix_truncsfdi2)
2748 fixtrunctab[(int) SFmode][(int) DImode][0] = CODE_FOR_fix_truncsfdi2;
2751 #ifdef HAVE_fix_truncdfqi2
2752 if (HAVE_fix_truncdfqi2)
2753 fixtrunctab[(int) DFmode][(int) QImode][0] = CODE_FOR_fix_truncdfqi2;
2755 #ifdef HAVE_fix_truncdfhi2
2756 if (HAVE_fix_truncdfhi2)
2757 fixtrunctab[(int) DFmode][(int) HImode][0] = CODE_FOR_fix_truncdfhi2;
2759 #ifdef HAVE_fix_truncdfsi2
2760 if (HAVE_fix_truncdfsi2)
2761 fixtrunctab[(int) DFmode][(int) SImode][0] = CODE_FOR_fix_truncdfsi2;
2763 #ifdef HAVE_fix_truncdfdi2
2764 if (HAVE_fix_truncdfdi2)
2765 fixtrunctab[(int) DFmode][(int) DImode][0] = CODE_FOR_fix_truncdfdi2;
2767 #ifdef HAVE_fix_truncdfti2
2768 if (HAVE_fix_truncdfti2)
2769 fixtrunctab[(int) DFmode][(int) TImode][0] = CODE_FOR_fix_truncdfti2;
2772 #ifdef HAVE_fix_truncxfqi2
2773 if (HAVE_fix_truncxfqi2)
2774 fixtrunctab[(int) XFmode][(int) QImode][0] = CODE_FOR_fix_truncxfqi2;
2776 #ifdef HAVE_fix_truncxfhi2
2777 if (HAVE_fix_truncxfhi2)
2778 fixtrunctab[(int) XFmode][(int) HImode][0] = CODE_FOR_fix_truncxfhi2;
2780 #ifdef HAVE_fix_truncxfsi2
2781 if (HAVE_fix_truncxfsi2)
2782 fixtrunctab[(int) XFmode][(int) SImode][0] = CODE_FOR_fix_truncxfsi2;
2784 #ifdef HAVE_fix_truncxfdi2
2785 if (HAVE_fix_truncxfdi2)
2786 fixtrunctab[(int) XFmode][(int) DImode][0] = CODE_FOR_fix_truncxfdi2;
2788 #ifdef HAVE_fix_truncxfti2
2789 if (HAVE_fix_truncxfti2)
2790 fixtrunctab[(int) XFmode][(int) TImode][0] = CODE_FOR_fix_truncxfti2;
2793 #ifdef HAVE_fix_trunctfqi2
2794 if (HAVE_fix_trunctfqi2)
2795 fixtrunctab[(int) TFmode][(int) QImode][0] = CODE_FOR_fix_trunctfqi2;
2797 #ifdef HAVE_fix_trunctfhi2
2798 if (HAVE_fix_trunctfhi2)
2799 fixtrunctab[(int) TFmode][(int) HImode][0] = CODE_FOR_fix_trunctfhi2;
2801 #ifdef HAVE_fix_trunctfsi2
2802 if (HAVE_fix_trunctfsi2)
2803 fixtrunctab[(int) TFmode][(int) SImode][0] = CODE_FOR_fix_trunctfsi2;
2805 #ifdef HAVE_fix_trunctfdi2
2806 if (HAVE_fix_trunctfdi2)
2807 fixtrunctab[(int) TFmode][(int) DImode][0] = CODE_FOR_fix_trunctfdi2;
2809 #ifdef HAVE_fix_trunctfti2
2810 if (HAVE_fix_trunctfti2)
2811 fixtrunctab[(int) TFmode][(int) TImode][0] = CODE_FOR_fix_trunctfti2;
2814 #ifdef HAVE_fixuns_truncsfqi2
2815 if (HAVE_fixuns_truncsfqi2)
2816 fixtrunctab[(int) SFmode][(int) QImode][1] = CODE_FOR_fixuns_truncsfqi2;
2818 #ifdef HAVE_fixuns_truncsfhi2
2819 if (HAVE_fixuns_truncsfhi2)
2820 fixtrunctab[(int) SFmode][(int) HImode][1] = CODE_FOR_fixuns_truncsfhi2;
2822 #ifdef HAVE_fixuns_truncsfsi2
2823 if (HAVE_fixuns_truncsfsi2)
2824 fixtrunctab[(int) SFmode][(int) SImode][1] = CODE_FOR_fixuns_truncsfsi2;
2826 #ifdef HAVE_fixuns_truncsfdi2
2827 if (HAVE_fixuns_truncsfdi2)
2828 fixtrunctab[(int) SFmode][(int) DImode][1] = CODE_FOR_fixuns_truncsfdi2;
2831 #ifdef HAVE_fixuns_truncdfqi2
2832 if (HAVE_fixuns_truncdfqi2)
2833 fixtrunctab[(int) DFmode][(int) QImode][1] = CODE_FOR_fixuns_truncdfqi2;
2835 #ifdef HAVE_fixuns_truncdfhi2
2836 if (HAVE_fixuns_truncdfhi2)
2837 fixtrunctab[(int) DFmode][(int) HImode][1] = CODE_FOR_fixuns_truncdfhi2;
2839 #ifdef HAVE_fixuns_truncdfsi2
2840 if (HAVE_fixuns_truncdfsi2)
2841 fixtrunctab[(int) DFmode][(int) SImode][1] = CODE_FOR_fixuns_truncdfsi2;
2843 #ifdef HAVE_fixuns_truncdfdi2
2844 if (HAVE_fixuns_truncdfdi2)
2845 fixtrunctab[(int) DFmode][(int) DImode][1] = CODE_FOR_fixuns_truncdfdi2;
2847 #ifdef HAVE_fixuns_truncdfti2
2848 if (HAVE_fixuns_truncdfti2)
2849 fixtrunctab[(int) DFmode][(int) TImode][1] = CODE_FOR_fixuns_truncdfti2;
2852 #ifdef HAVE_fixuns_truncxfqi2
2853 if (HAVE_fixuns_truncxfqi2)
2854 fixtrunctab[(int) XFmode][(int) QImode][1] = CODE_FOR_fixuns_truncxfqi2;
2856 #ifdef HAVE_fixuns_truncxfhi2
2857 if (HAVE_fixuns_truncxfhi2)
2858 fixtrunctab[(int) XFmode][(int) HImode][1] = CODE_FOR_fixuns_truncxfhi2;
2860 #ifdef HAVE_fixuns_truncxfsi2
2861 if (HAVE_fixuns_truncxfsi2)
2862 fixtrunctab[(int) XFmode][(int) SImode][1] = CODE_FOR_fixuns_truncxfsi2;
2864 #ifdef HAVE_fixuns_truncxfdi2
2865 if (HAVE_fixuns_truncxfdi2)
2866 fixtrunctab[(int) XFmode][(int) DImode][1] = CODE_FOR_fixuns_truncxfdi2;
2868 #ifdef HAVE_fixuns_truncxfti2
2869 if (HAVE_fixuns_truncxfti2)
2870 fixtrunctab[(int) XFmode][(int) TImode][1] = CODE_FOR_fixuns_truncxfti2;
2873 #ifdef HAVE_fixuns_trunctfqi2
2874 if (HAVE_fixuns_trunctfqi2)
2875 fixtrunctab[(int) TFmode][(int) QImode][1] = CODE_FOR_fixuns_trunctfqi2;
2877 #ifdef HAVE_fixuns_trunctfhi2
2878 if (HAVE_fixuns_trunctfhi2)
2879 fixtrunctab[(int) TFmode][(int) HImode][1] = CODE_FOR_fixuns_trunctfhi2;
2881 #ifdef HAVE_fixuns_trunctfsi2
2882 if (HAVE_fixuns_trunctfsi2)
2883 fixtrunctab[(int) TFmode][(int) SImode][1] = CODE_FOR_fixuns_trunctfsi2;
2885 #ifdef HAVE_fixuns_trunctfdi2
2886 if (HAVE_fixuns_trunctfdi2)
2887 fixtrunctab[(int) TFmode][(int) DImode][1] = CODE_FOR_fixuns_trunctfdi2;
2889 #ifdef HAVE_fixuns_trunctfti2
2890 if (HAVE_fixuns_trunctfti2)
2891 fixtrunctab[(int) TFmode][(int) TImode][1] = CODE_FOR_fixuns_trunctfti2;
2894 #ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC
2895 /* This flag says the same insns that convert to a signed fixnum
2896 also convert validly to an unsigned one. */
2900 for (i = 0; i < NUM_MACHINE_MODES; i++)
2901 for (j = 0; j < NUM_MACHINE_MODES; j++)
2902 fixtrunctab[i][j][1] = fixtrunctab[i][j][0];
2911 for (p = floattab[0][0];
2912 p < floattab[0][0] + sizeof floattab / sizeof (floattab[0][0][0]);
2914 *p = CODE_FOR_nothing;
2916 #ifdef HAVE_floatqisf2
2917 if (HAVE_floatqisf2)
2918 floattab[(int) SFmode][(int) QImode][0] = CODE_FOR_floatqisf2;
2920 #ifdef HAVE_floathisf2
2921 if (HAVE_floathisf2)
2922 floattab[(int) SFmode][(int) HImode][0] = CODE_FOR_floathisf2;
2924 #ifdef HAVE_floatsisf2
2925 if (HAVE_floatsisf2)
2926 floattab[(int) SFmode][(int) SImode][0] = CODE_FOR_floatsisf2;
2928 #ifdef HAVE_floatdisf2
2929 if (HAVE_floatdisf2)
2930 floattab[(int) SFmode][(int) DImode][0] = CODE_FOR_floatdisf2;
2932 #ifdef HAVE_floattisf2
2933 if (HAVE_floattisf2)
2934 floattab[(int) SFmode][(int) TImode][0] = CODE_FOR_floattisf2;
2937 #ifdef HAVE_floatqidf2
2938 if (HAVE_floatqidf2)
2939 floattab[(int) DFmode][(int) QImode][0] = CODE_FOR_floatqidf2;
2941 #ifdef HAVE_floathidf2
2942 if (HAVE_floathidf2)
2943 floattab[(int) DFmode][(int) HImode][0] = CODE_FOR_floathidf2;
2945 #ifdef HAVE_floatsidf2
2946 if (HAVE_floatsidf2)
2947 floattab[(int) DFmode][(int) SImode][0] = CODE_FOR_floatsidf2;
2949 #ifdef HAVE_floatdidf2
2950 if (HAVE_floatdidf2)
2951 floattab[(int) DFmode][(int) DImode][0] = CODE_FOR_floatdidf2;
2953 #ifdef HAVE_floattidf2
2954 if (HAVE_floattidf2)
2955 floattab[(int) DFmode][(int) TImode][0] = CODE_FOR_floattidf2;
2958 #ifdef HAVE_floatqixf2
2959 if (HAVE_floatqixf2)
2960 floattab[(int) XFmode][(int) QImode][0] = CODE_FOR_floatqixf2;
2962 #ifdef HAVE_floathixf2
2963 if (HAVE_floathixf2)
2964 floattab[(int) XFmode][(int) HImode][0] = CODE_FOR_floathixf2;
2966 #ifdef HAVE_floatsixf2
2967 if (HAVE_floatsixf2)
2968 floattab[(int) XFmode][(int) SImode][0] = CODE_FOR_floatsixf2;
2970 #ifdef HAVE_floatdixf2
2971 if (HAVE_floatdixf2)
2972 floattab[(int) XFmode][(int) DImode][0] = CODE_FOR_floatdixf2;
2974 #ifdef HAVE_floattixf2
2975 if (HAVE_floattixf2)
2976 floattab[(int) XFmode][(int) TImode][0] = CODE_FOR_floattixf2;
2979 #ifdef HAVE_floatqitf2
2980 if (HAVE_floatqitf2)
2981 floattab[(int) TFmode][(int) QImode][0] = CODE_FOR_floatqitf2;
2983 #ifdef HAVE_floathitf2
2984 if (HAVE_floathitf2)
2985 floattab[(int) TFmode][(int) HImode][0] = CODE_FOR_floathitf2;
2987 #ifdef HAVE_floatsitf2
2988 if (HAVE_floatsitf2)
2989 floattab[(int) TFmode][(int) SImode][0] = CODE_FOR_floatsitf2;
2991 #ifdef HAVE_floatditf2
2992 if (HAVE_floatditf2)
2993 floattab[(int) TFmode][(int) DImode][0] = CODE_FOR_floatditf2;
2995 #ifdef HAVE_floattitf2
2996 if (HAVE_floattitf2)
2997 floattab[(int) TFmode][(int) TImode][0] = CODE_FOR_floattitf2;
3000 #ifdef HAVE_floatunsqisf2
3001 if (HAVE_floatunsqisf2)
3002 floattab[(int) SFmode][(int) QImode][1] = CODE_FOR_floatunsqisf2;
3004 #ifdef HAVE_floatunshisf2
3005 if (HAVE_floatunshisf2)
3006 floattab[(int) SFmode][(int) HImode][1] = CODE_FOR_floatunshisf2;
3008 #ifdef HAVE_floatunssisf2
3009 if (HAVE_floatunssisf2)
3010 floattab[(int) SFmode][(int) SImode][1] = CODE_FOR_floatunssisf2;
3012 #ifdef HAVE_floatunsdisf2
3013 if (HAVE_floatunsdisf2)
3014 floattab[(int) SFmode][(int) DImode][1] = CODE_FOR_floatunsdisf2;
3016 #ifdef HAVE_floatunstisf2
3017 if (HAVE_floatunstisf2)
3018 floattab[(int) SFmode][(int) TImode][1] = CODE_FOR_floatunstisf2;
3021 #ifdef HAVE_floatunsqidf2
3022 if (HAVE_floatunsqidf2)
3023 floattab[(int) DFmode][(int) QImode][1] = CODE_FOR_floatunsqidf2;
3025 #ifdef HAVE_floatunshidf2
3026 if (HAVE_floatunshidf2)
3027 floattab[(int) DFmode][(int) HImode][1] = CODE_FOR_floatunshidf2;
3029 #ifdef HAVE_floatunssidf2
3030 if (HAVE_floatunssidf2)
3031 floattab[(int) DFmode][(int) SImode][1] = CODE_FOR_floatunssidf2;
3033 #ifdef HAVE_floatunsdidf2
3034 if (HAVE_floatunsdidf2)
3035 floattab[(int) DFmode][(int) DImode][1] = CODE_FOR_floatunsdidf2;
3037 #ifdef HAVE_floatunstidf2
3038 if (HAVE_floatunstidf2)
3039 floattab[(int) DFmode][(int) TImode][1] = CODE_FOR_floatunstidf2;
3042 #ifdef HAVE_floatunsqixf2
3043 if (HAVE_floatunsqixf2)
3044 floattab[(int) XFmode][(int) QImode][1] = CODE_FOR_floatunsqixf2;
3046 #ifdef HAVE_floatunshixf2
3047 if (HAVE_floatunshixf2)
3048 floattab[(int) XFmode][(int) HImode][1] = CODE_FOR_floatunshixf2;
3050 #ifdef HAVE_floatunssixf2
3051 if (HAVE_floatunssixf2)
3052 floattab[(int) XFmode][(int) SImode][1] = CODE_FOR_floatunssixf2;
3054 #ifdef HAVE_floatunsdixf2
3055 if (HAVE_floatunsdixf2)
3056 floattab[(int) XFmode][(int) DImode][1] = CODE_FOR_floatunsdixf2;
3058 #ifdef HAVE_floatunstixf2
3059 if (HAVE_floatunstixf2)
3060 floattab[(int) XFmode][(int) TImode][1] = CODE_FOR_floatunstixf2;
3063 #ifdef HAVE_floatunsqitf2
3064 if (HAVE_floatunsqitf2)
3065 floattab[(int) TFmode][(int) QImode][1] = CODE_FOR_floatunsqitf2;
3067 #ifdef HAVE_floatunshitf2
3068 if (HAVE_floatunshitf2)
3069 floattab[(int) TFmode][(int) HImode][1] = CODE_FOR_floatunshitf2;
3071 #ifdef HAVE_floatunssitf2
3072 if (HAVE_floatunssitf2)
3073 floattab[(int) TFmode][(int) SImode][1] = CODE_FOR_floatunssitf2;
3075 #ifdef HAVE_floatunsditf2
3076 if (HAVE_floatunsditf2)
3077 floattab[(int) TFmode][(int) DImode][1] = CODE_FOR_floatunsditf2;
3079 #ifdef HAVE_floatunstitf2
3080 if (HAVE_floatunstitf2)
3081 floattab[(int) TFmode][(int) TImode][1] = CODE_FOR_floatunstitf2;
3085 /* Generate code to convert FROM to floating point
3086 and store in TO. FROM must be fixed point and not VOIDmode.
3087 UNSIGNEDP nonzero means regard FROM as unsigned.
3088 Normally this is done by correcting the final value
3089 if it is negative. */
3092 expand_float (to, from, unsignedp)
3096 enum insn_code icode;
3097 register rtx target = to;
3098 enum machine_mode fmode, imode;
3100 /* Crash now, because we won't be able to decide which mode to use. */
3101 if (GET_MODE (from) == VOIDmode)
3104 /* Look for an insn to do the conversion. Do it in the specified
3105 modes if possible; otherwise convert either input, output or both to
3106 wider mode. If the integer mode is wider than the mode of FROM,
3107 we can do the conversion signed even if the input is unsigned. */
3109 for (imode = GET_MODE (from); imode != VOIDmode;
3110 imode = GET_MODE_WIDER_MODE (imode))
3111 for (fmode = GET_MODE (to); fmode != VOIDmode;
3112 fmode = GET_MODE_WIDER_MODE (fmode))
3114 int doing_unsigned = unsignedp;
3116 icode = can_float_p (fmode, imode, unsignedp);
3117 if (icode == CODE_FOR_nothing && imode != GET_MODE (from) && unsignedp)
3118 icode = can_float_p (fmode, imode, 0), doing_unsigned = 0;
3120 if (icode != CODE_FOR_nothing)
3122 to = protect_from_queue (to, 1);
3123 from = protect_from_queue (from, 0);
3125 if (imode != GET_MODE (from))
3126 from = convert_to_mode (imode, from, unsignedp);
3128 if (fmode != GET_MODE (to))
3129 target = gen_reg_rtx (fmode);
3131 emit_unop_insn (icode, target, from,
3132 doing_unsigned ? UNSIGNED_FLOAT : FLOAT);
3135 convert_move (to, target, 0);
3140 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
3142 /* Unsigned integer, and no way to convert directly.
3143 Convert as signed, then conditionally adjust the result. */
3146 rtx label = gen_label_rtx ();
3148 REAL_VALUE_TYPE offset;
3152 to = protect_from_queue (to, 1);
3153 from = protect_from_queue (from, 0);
3156 from = force_not_mem (from);
3158 /* If we are about to do some arithmetic to correct for an
3159 unsigned operand, do it in a pseudo-register. */
3161 if (GET_CODE (to) != REG || REGNO (to) <= LAST_VIRTUAL_REGISTER)
3162 target = gen_reg_rtx (GET_MODE (to));
3164 /* Convert as signed integer to floating. */
3165 expand_float (target, from, 0);
3167 /* If FROM is negative (and therefore TO is negative),
3168 correct its value by 2**bitwidth. */
3170 do_pending_stack_adjust ();
3171 emit_cmp_insn (from, const0_rtx, GE, NULL_RTX, GET_MODE (from), 0, 0);
3172 emit_jump_insn (gen_bge (label));
3173 /* On SCO 3.2.1, ldexp rejects values outside [0.5, 1).
3174 Rather than setting up a dconst_dot_5, let's hope SCO
3176 offset = REAL_VALUE_LDEXP (dconst1, GET_MODE_BITSIZE (GET_MODE (from)));
3177 temp = expand_binop (GET_MODE (to), add_optab, target,
3178 immed_real_const_1 (offset, GET_MODE (to)),
3179 target, 0, OPTAB_LIB_WIDEN);
3181 emit_move_insn (target, temp);
3182 do_pending_stack_adjust ();
3188 /* No hardware instruction available; call a library rotine to convert from
3189 SImode, DImode, or TImode into SFmode, DFmode, XFmode, or TFmode. */
3194 to = protect_from_queue (to, 1);
3195 from = protect_from_queue (from, 0);
3197 if (GET_MODE_SIZE (GET_MODE (from)) < GET_MODE_SIZE (SImode))
3198 from = convert_to_mode (SImode, from, unsignedp);
3201 from = force_not_mem (from);
3203 if (GET_MODE (to) == SFmode)
3205 if (GET_MODE (from) == SImode)
3206 libfcn = floatsisf_libfunc;
3207 else if (GET_MODE (from) == DImode)
3208 libfcn = floatdisf_libfunc;
3209 else if (GET_MODE (from) == TImode)
3210 libfcn = floattisf_libfunc;
3214 else if (GET_MODE (to) == DFmode)
3216 if (GET_MODE (from) == SImode)
3217 libfcn = floatsidf_libfunc;
3218 else if (GET_MODE (from) == DImode)
3219 libfcn = floatdidf_libfunc;
3220 else if (GET_MODE (from) == TImode)
3221 libfcn = floattidf_libfunc;
3225 else if (GET_MODE (to) == XFmode)
3227 if (GET_MODE (from) == SImode)
3228 libfcn = floatsixf_libfunc;
3229 else if (GET_MODE (from) == DImode)
3230 libfcn = floatdixf_libfunc;
3231 else if (GET_MODE (from) == TImode)
3232 libfcn = floattixf_libfunc;
3236 else if (GET_MODE (to) == TFmode)
3238 if (GET_MODE (from) == SImode)
3239 libfcn = floatsitf_libfunc;
3240 else if (GET_MODE (from) == DImode)
3241 libfcn = floatditf_libfunc;
3242 else if (GET_MODE (from) == TImode)
3243 libfcn = floattitf_libfunc;
3252 emit_library_call (libfcn, 1, GET_MODE (to), 1, from, GET_MODE (from));
3253 insns = get_insns ();
3256 emit_libcall_block (insns, target, hard_libcall_value (GET_MODE (to)),
3257 gen_rtx (FLOAT, GET_MODE (to), from));
3260 /* Copy result to requested destination
3261 if we have been computing in a temp location. */
3265 if (GET_MODE (target) == GET_MODE (to))
3266 emit_move_insn (to, target);
3268 convert_move (to, target, 0);
3272 /* expand_fix: generate code to convert FROM to fixed point
3273 and store in TO. FROM must be floating point. */
3279 rtx temp = gen_reg_rtx (GET_MODE (x));
3280 return expand_unop (GET_MODE (x), ftrunc_optab, x, temp, 0);
3284 expand_fix (to, from, unsignedp)
3285 register rtx to, from;
3288 enum insn_code icode;
3289 register rtx target = to;
3290 enum machine_mode fmode, imode;
3294 /* We first try to find a pair of modes, one real and one integer, at
3295 least as wide as FROM and TO, respectively, in which we can open-code
3296 this conversion. If the integer mode is wider than the mode of TO,
3297 we can do the conversion either signed or unsigned. */
3299 for (imode = GET_MODE (to); imode != VOIDmode;
3300 imode = GET_MODE_WIDER_MODE (imode))
3301 for (fmode = GET_MODE (from); fmode != VOIDmode;
3302 fmode = GET_MODE_WIDER_MODE (fmode))
3304 int doing_unsigned = unsignedp;
3306 icode = can_fix_p (imode, fmode, unsignedp, &must_trunc);
3307 if (icode == CODE_FOR_nothing && imode != GET_MODE (to) && unsignedp)
3308 icode = can_fix_p (imode, fmode, 0, &must_trunc), doing_unsigned = 0;
3310 if (icode != CODE_FOR_nothing)
3312 to = protect_from_queue (to, 1);
3313 from = protect_from_queue (from, 0);
3315 if (fmode != GET_MODE (from))
3316 from = convert_to_mode (fmode, from, 0);
3319 from = ftruncify (from);
3321 if (imode != GET_MODE (to))
3322 target = gen_reg_rtx (imode);
3324 emit_unop_insn (icode, target, from,
3325 doing_unsigned ? UNSIGNED_FIX : FIX);
3327 convert_move (to, target, unsignedp);
3332 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
3333 /* For an unsigned conversion, there is one more way to do it.
3334 If we have a signed conversion, we generate code that compares
3335 the real value to the largest representable positive number. If if
3336 is smaller, the conversion is done normally. Otherwise, subtract
3337 one plus the highest signed number, convert, and add it back.
3339 We only need to check all real modes, since we know we didn't find
3340 anything with a wider integer mode. */
3342 if (unsignedp && GET_MODE_BITSIZE (GET_MODE (to)) <= HOST_BITS_PER_WIDE_INT)
3343 for (fmode = GET_MODE (from); fmode != VOIDmode;
3344 fmode = GET_MODE_WIDER_MODE (fmode))
3345 /* Make sure we won't lose significant bits doing this. */
3346 if (GET_MODE_BITSIZE (fmode) > GET_MODE_BITSIZE (GET_MODE (to))
3347 && CODE_FOR_nothing != can_fix_p (GET_MODE (to), fmode, 0,
3350 int bitsize = GET_MODE_BITSIZE (GET_MODE (to));
3351 REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (dconst1, bitsize - 1);
3352 rtx limit = immed_real_const_1 (offset, fmode);
3353 rtx lab1 = gen_label_rtx ();
3354 rtx lab2 = gen_label_rtx ();
3358 to = protect_from_queue (to, 1);
3359 from = protect_from_queue (from, 0);
3362 from = force_not_mem (from);
3364 if (fmode != GET_MODE (from))
3365 from = convert_to_mode (fmode, from, 0);
3367 /* See if we need to do the subtraction. */
3368 do_pending_stack_adjust ();
3369 emit_cmp_insn (from, limit, GE, NULL_RTX, GET_MODE (from), 0, 0);
3370 emit_jump_insn (gen_bge (lab1));
3372 /* If not, do the signed "fix" and branch around fixup code. */
3373 expand_fix (to, from, 0);
3374 emit_jump_insn (gen_jump (lab2));
3377 /* Otherwise, subtract 2**(N-1), convert to signed number,
3378 then add 2**(N-1). Do the addition using XOR since this
3379 will often generate better code. */
3381 target = expand_binop (GET_MODE (from), sub_optab, from, limit,
3382 NULL_RTX, 0, OPTAB_LIB_WIDEN);
3383 expand_fix (to, target, 0);
3384 target = expand_binop (GET_MODE (to), xor_optab, to,
3385 GEN_INT ((HOST_WIDE_INT) 1 << (bitsize - 1)),
3386 to, 1, OPTAB_LIB_WIDEN);
3389 emit_move_insn (to, target);
3393 /* Make a place for a REG_NOTE and add it. */
3394 insn = emit_move_insn (to, to);
3395 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL,
3396 gen_rtx (UNSIGNED_FIX, GET_MODE (to),
3397 from), REG_NOTES (insn));
3403 /* We can't do it with an insn, so use a library call. But first ensure
3404 that the mode of TO is at least as wide as SImode, since those are the
3405 only library calls we know about. */
3407 if (GET_MODE_SIZE (GET_MODE (to)) < GET_MODE_SIZE (SImode))
3409 target = gen_reg_rtx (SImode);
3411 expand_fix (target, from, unsignedp);
3413 else if (GET_MODE (from) == SFmode)
3415 if (GET_MODE (to) == SImode)
3416 libfcn = unsignedp ? fixunssfsi_libfunc : fixsfsi_libfunc;
3417 else if (GET_MODE (to) == DImode)
3418 libfcn = unsignedp ? fixunssfdi_libfunc : fixsfdi_libfunc;
3419 else if (GET_MODE (to) == TImode)
3420 libfcn = unsignedp ? fixunssfti_libfunc : fixsfti_libfunc;
3424 else if (GET_MODE (from) == DFmode)
3426 if (GET_MODE (to) == SImode)
3427 libfcn = unsignedp ? fixunsdfsi_libfunc : fixdfsi_libfunc;
3428 else if (GET_MODE (to) == DImode)
3429 libfcn = unsignedp ? fixunsdfdi_libfunc : fixdfdi_libfunc;
3430 else if (GET_MODE (to) == TImode)
3431 libfcn = unsignedp ? fixunsdfti_libfunc : fixdfti_libfunc;
3435 else if (GET_MODE (from) == XFmode)
3437 if (GET_MODE (to) == SImode)
3438 libfcn = unsignedp ? fixunsxfsi_libfunc : fixxfsi_libfunc;
3439 else if (GET_MODE (to) == DImode)
3440 libfcn = unsignedp ? fixunsxfdi_libfunc : fixxfdi_libfunc;
3441 else if (GET_MODE (to) == TImode)
3442 libfcn = unsignedp ? fixunsxfti_libfunc : fixxfti_libfunc;
3446 else if (GET_MODE (from) == TFmode)
3448 if (GET_MODE (to) == SImode)
3449 libfcn = unsignedp ? fixunstfsi_libfunc : fixtfsi_libfunc;
3450 else if (GET_MODE (to) == DImode)
3451 libfcn = unsignedp ? fixunstfdi_libfunc : fixtfdi_libfunc;
3452 else if (GET_MODE (to) == TImode)
3453 libfcn = unsignedp ? fixunstfti_libfunc : fixtfti_libfunc;
3464 to = protect_from_queue (to, 1);
3465 from = protect_from_queue (from, 0);
3468 from = force_not_mem (from);
3472 emit_library_call (libfcn, 1, GET_MODE (to), 1, from, GET_MODE (from));
3473 insns = get_insns ();
3476 emit_libcall_block (insns, target, hard_libcall_value (GET_MODE (to)),
3477 gen_rtx (unsignedp ? FIX : UNSIGNED_FIX,
3478 GET_MODE (to), from));
3481 if (GET_MODE (to) == GET_MODE (target))
3482 emit_move_insn (to, target);
3484 convert_move (to, target, 0);
3492 optab op = (optab) xmalloc (sizeof (struct optab));
3494 for (i = 0; i < NUM_MACHINE_MODES; i++)
3496 op->handlers[i].insn_code = CODE_FOR_nothing;
3497 op->handlers[i].libfunc = 0;
3502 /* Initialize the libfunc fields of an entire group of entries in some
3503 optab. Each entry is set equal to a string consisting of a leading
3504 pair of underscores followed by a generic operation name followed by
3505 a mode name (downshifted to lower case) followed by a single character
3506 representing the number of operands for the given operation (which is
3507 usually one of the characters '2', '3', or '4').
3509 OPTABLE is the table in which libfunc fields are to be initialized.
3510 FIRST_MODE is the first machine mode index in the given optab to
3512 LAST_MODE is the last machine mode index in the given optab to
3514 OPNAME is the generic (string) name of the operation.
3515 SUFFIX is the character which specifies the number of operands for
3516 the given generic operation.
3520 init_libfuncs (optable, first_mode, last_mode, opname, suffix)
3521 register optab optable;
3522 register char *opname;
3523 register enum machine_mode first_mode;
3524 register enum machine_mode last_mode;
3525 register char suffix;
3527 register enum machine_mode mode;
3528 register unsigned opname_len = strlen (opname);
3530 for (mode = first_mode; mode <= last_mode; mode++)
3532 register char *mname = mode_name[(int) mode];
3533 register unsigned mname_len = strlen (mname);
3534 register char *libfunc_name
3535 = (char *) xmalloc (2 + opname_len + mname_len + 1 + 1);
3542 for (q = opname; *q; )
3544 for (q = mname; *q; q++)
3545 *p++ = tolower (*q);
3548 optable->handlers[(int) mode].libfunc
3549 = gen_rtx (SYMBOL_REF, Pmode, libfunc_name);
3553 /* Initialize the libfunc fields of an entire group of entries in some
3554 optab which correspond to all integer mode operations. The parameters
3555 have the same meaning as similarly named ones for the `init_libfuncs'
3556 routine. (See above). */
3559 init_integral_libfuncs (optable, opname, suffix)
3560 register optab optable;
3561 register char *opname;
3562 register char suffix;
3564 init_libfuncs (optable, SImode, TImode, opname, suffix);
3567 /* Initialize the libfunc fields of an entire group of entries in some
3568 optab which correspond to all real mode operations. The parameters
3569 have the same meaning as similarly named ones for the `init_libfuncs'
3570 routine. (See above). */
3573 init_floating_libfuncs (optable, opname, suffix)
3574 register optab optable;
3575 register char *opname;
3576 register char suffix;
3578 init_libfuncs (optable, SFmode, TFmode, opname, suffix);
3581 /* Call this once to initialize the contents of the optabs
3582 appropriately for the current target machine. */
3593 add_optab = init_optab (PLUS);
3594 sub_optab = init_optab (MINUS);
3595 smul_optab = init_optab (MULT);
3596 smul_widen_optab = init_optab (UNKNOWN);
3597 umul_widen_optab = init_optab (UNKNOWN);
3598 sdiv_optab = init_optab (DIV);
3599 sdivmod_optab = init_optab (UNKNOWN);
3600 udiv_optab = init_optab (UDIV);
3601 udivmod_optab = init_optab (UNKNOWN);
3602 smod_optab = init_optab (MOD);
3603 umod_optab = init_optab (UMOD);
3604 flodiv_optab = init_optab (DIV);
3605 ftrunc_optab = init_optab (UNKNOWN);
3606 and_optab = init_optab (AND);
3607 ior_optab = init_optab (IOR);
3608 xor_optab = init_optab (XOR);
3609 ashl_optab = init_optab (ASHIFT);
3610 ashr_optab = init_optab (ASHIFTRT);
3611 lshl_optab = init_optab (LSHIFT);
3612 lshr_optab = init_optab (LSHIFTRT);
3613 rotl_optab = init_optab (ROTATE);
3614 rotr_optab = init_optab (ROTATERT);
3615 smin_optab = init_optab (SMIN);
3616 smax_optab = init_optab (SMAX);
3617 umin_optab = init_optab (UMIN);
3618 umax_optab = init_optab (UMAX);
3619 mov_optab = init_optab (UNKNOWN);
3620 movstrict_optab = init_optab (UNKNOWN);
3621 cmp_optab = init_optab (UNKNOWN);
3622 ucmp_optab = init_optab (UNKNOWN);
3623 tst_optab = init_optab (UNKNOWN);
3624 neg_optab = init_optab (NEG);
3625 abs_optab = init_optab (ABS);
3626 one_cmpl_optab = init_optab (NOT);
3627 ffs_optab = init_optab (FFS);
3628 sqrt_optab = init_optab (SQRT);
3629 sin_optab = init_optab (UNKNOWN);
3630 cos_optab = init_optab (UNKNOWN);
3631 strlen_optab = init_optab (UNKNOWN);
3635 add_optab->handlers[(int) QImode].insn_code = CODE_FOR_addqi3;
3639 add_optab->handlers[(int) HImode].insn_code = CODE_FOR_addhi3;
3643 add_optab->handlers[(int) PSImode].insn_code = CODE_FOR_addpsi3;
3647 add_optab->handlers[(int) SImode].insn_code = CODE_FOR_addsi3;
3651 add_optab->handlers[(int) DImode].insn_code = CODE_FOR_adddi3;
3655 add_optab->handlers[(int) TImode].insn_code = CODE_FOR_addti3;
3659 add_optab->handlers[(int) SFmode].insn_code = CODE_FOR_addsf3;
3663 add_optab->handlers[(int) DFmode].insn_code = CODE_FOR_adddf3;
3667 add_optab->handlers[(int) XFmode].insn_code = CODE_FOR_addxf3;
3671 add_optab->handlers[(int) TFmode].insn_code = CODE_FOR_addtf3;
3673 init_integral_libfuncs (add_optab, "add", '3');
3674 init_floating_libfuncs (add_optab, "add", '3');
3678 sub_optab->handlers[(int) QImode].insn_code = CODE_FOR_subqi3;
3682 sub_optab->handlers[(int) HImode].insn_code = CODE_FOR_subhi3;
3686 sub_optab->handlers[(int) PSImode].insn_code = CODE_FOR_subpsi3;
3690 sub_optab->handlers[(int) SImode].insn_code = CODE_FOR_subsi3;
3694 sub_optab->handlers[(int) DImode].insn_code = CODE_FOR_subdi3;
3698 sub_optab->handlers[(int) TImode].insn_code = CODE_FOR_subti3;
3702 sub_optab->handlers[(int) SFmode].insn_code = CODE_FOR_subsf3;
3706 sub_optab->handlers[(int) DFmode].insn_code = CODE_FOR_subdf3;
3710 sub_optab->handlers[(int) XFmode].insn_code = CODE_FOR_subxf3;
3714 sub_optab->handlers[(int) TFmode].insn_code = CODE_FOR_subtf3;
3716 init_integral_libfuncs (sub_optab, "sub", '3');
3717 init_floating_libfuncs (sub_optab, "sub", '3');
3721 smul_optab->handlers[(int) QImode].insn_code = CODE_FOR_mulqi3;
3725 smul_optab->handlers[(int) HImode].insn_code = CODE_FOR_mulhi3;
3729 smul_optab->handlers[(int) PSImode].insn_code = CODE_FOR_mulpsi3;
3733 smul_optab->handlers[(int) SImode].insn_code = CODE_FOR_mulsi3;
3737 smul_optab->handlers[(int) DImode].insn_code = CODE_FOR_muldi3;
3741 smul_optab->handlers[(int) TImode].insn_code = CODE_FOR_multi3;
3745 smul_optab->handlers[(int) SFmode].insn_code = CODE_FOR_mulsf3;
3749 smul_optab->handlers[(int) DFmode].insn_code = CODE_FOR_muldf3;
3753 smul_optab->handlers[(int) XFmode].insn_code = CODE_FOR_mulxf3;
3757 smul_optab->handlers[(int) TFmode].insn_code = CODE_FOR_multf3;
3759 init_integral_libfuncs (smul_optab, "mul", '3');
3760 init_floating_libfuncs (smul_optab, "mul", '3');
3762 #ifdef MULSI3_LIBCALL
3763 smul_optab->handlers[(int) SImode].libfunc
3764 = gen_rtx (SYMBOL_REF, Pmode, MULSI3_LIBCALL);
3766 #ifdef MULDI3_LIBCALL
3767 smul_optab->handlers[(int) DImode].libfunc
3768 = gen_rtx (SYMBOL_REF, Pmode, MULDI3_LIBCALL);
3770 #ifdef MULTI3_LIBCALL
3771 smul_optab->handlers[(int) TImode].libfunc
3772 = gen_rtx (SYMBOL_REF, Pmode, MULTI3_LIBCALL);
3775 #ifdef HAVE_mulqihi3
3777 smul_widen_optab->handlers[(int) HImode].insn_code = CODE_FOR_mulqihi3;
3779 #ifdef HAVE_mulhisi3
3781 smul_widen_optab->handlers[(int) SImode].insn_code = CODE_FOR_mulhisi3;
3783 #ifdef HAVE_mulsidi3
3785 smul_widen_optab->handlers[(int) DImode].insn_code = CODE_FOR_mulsidi3;
3787 #ifdef HAVE_mulditi3
3789 smul_widen_optab->handlers[(int) TImode].insn_code = CODE_FOR_mulditi3;
3792 #ifdef HAVE_umulqihi3
3794 umul_widen_optab->handlers[(int) HImode].insn_code = CODE_FOR_umulqihi3;
3796 #ifdef HAVE_umulhisi3
3798 umul_widen_optab->handlers[(int) SImode].insn_code = CODE_FOR_umulhisi3;
3800 #ifdef HAVE_umulsidi3
3802 umul_widen_optab->handlers[(int) DImode].insn_code = CODE_FOR_umulsidi3;
3804 #ifdef HAVE_umulditi3
3806 umul_widen_optab->handlers[(int) TImode].insn_code = CODE_FOR_umulditi3;
3811 sdiv_optab->handlers[(int) QImode].insn_code = CODE_FOR_divqi3;
3815 sdiv_optab->handlers[(int) HImode].insn_code = CODE_FOR_divhi3;
3819 sdiv_optab->handlers[(int) PSImode].insn_code = CODE_FOR_divpsi3;
3823 sdiv_optab->handlers[(int) SImode].insn_code = CODE_FOR_divsi3;
3827 sdiv_optab->handlers[(int) DImode].insn_code = CODE_FOR_divdi3;
3831 sdiv_optab->handlers[(int) TImode].insn_code = CODE_FOR_divti3;
3833 init_integral_libfuncs (sdiv_optab, "div", '3');
3835 #ifdef DIVSI3_LIBCALL
3836 sdiv_optab->handlers[(int) SImode].libfunc
3837 = gen_rtx (SYMBOL_REF, Pmode, DIVSI3_LIBCALL);
3839 #ifdef DIVDI3_LIBCALL
3840 sdiv_optab->handlers[(int) DImode].libfunc
3841 = gen_rtx (SYMBOL_REF, Pmode, DIVDI3_LIBCALL);
3843 #ifdef DIVTI3_LIBCALL
3844 sdiv_optab->handlers[(int) TImode].libfunc
3845 = gen_rtx (SYMBOL_REF, Pmode, DIVTI3_LIBCALL);
3850 udiv_optab->handlers[(int) QImode].insn_code = CODE_FOR_udivqi3;
3854 udiv_optab->handlers[(int) HImode].insn_code = CODE_FOR_udivhi3;
3856 #ifdef HAVE_udivpsi3
3858 udiv_optab->handlers[(int) PSImode].insn_code = CODE_FOR_udivpsi3;
3862 udiv_optab->handlers[(int) SImode].insn_code = CODE_FOR_udivsi3;
3866 udiv_optab->handlers[(int) DImode].insn_code = CODE_FOR_udivdi3;
3870 udiv_optab->handlers[(int) TImode].insn_code = CODE_FOR_udivti3;
3872 init_integral_libfuncs (udiv_optab, "udiv", '3');
3874 #ifdef UDIVSI3_LIBCALL
3875 udiv_optab->handlers[(int) SImode].libfunc
3876 = gen_rtx (SYMBOL_REF, Pmode, UDIVSI3_LIBCALL);
3878 #ifdef UDIVDI3_LIBCALL
3879 udiv_optab->handlers[(int) DImode].libfunc
3880 = gen_rtx (SYMBOL_REF, Pmode, UDIVDI3_LIBCALL);
3882 #ifdef UDIVTI3_LIBCALL
3883 udiv_optab->handlers[(int) TImode].libfunc
3884 = gen_rtx (SYMBOL_REF, Pmode, UDIVTI3_LIBCALL);
3887 #ifdef HAVE_divmodqi4
3889 sdivmod_optab->handlers[(int) QImode].insn_code = CODE_FOR_divmodqi4;
3891 #ifdef HAVE_divmodhi4
3893 sdivmod_optab->handlers[(int) HImode].insn_code = CODE_FOR_divmodhi4;
3895 #ifdef HAVE_divmodsi4
3897 sdivmod_optab->handlers[(int) SImode].insn_code = CODE_FOR_divmodsi4;
3899 #ifdef HAVE_divmoddi4
3901 sdivmod_optab->handlers[(int) DImode].insn_code = CODE_FOR_divmoddi4;
3903 #ifdef HAVE_divmodti4
3905 sdivmod_optab->handlers[(int) TImode].insn_code = CODE_FOR_divmodti4;
3907 init_integral_libfuncs (sdivmod_optab, "divmod", '4');
3909 #ifdef HAVE_udivmodqi4
3910 if (HAVE_udivmodqi4)
3911 udivmod_optab->handlers[(int) QImode].insn_code = CODE_FOR_udivmodqi4;
3913 #ifdef HAVE_udivmodhi4
3914 if (HAVE_udivmodhi4)
3915 udivmod_optab->handlers[(int) HImode].insn_code = CODE_FOR_udivmodhi4;
3917 #ifdef HAVE_udivmodsi4
3918 if (HAVE_udivmodsi4)
3919 udivmod_optab->handlers[(int) SImode].insn_code = CODE_FOR_udivmodsi4;
3921 #ifdef HAVE_udivmoddi4
3922 if (HAVE_udivmoddi4)
3923 udivmod_optab->handlers[(int) DImode].insn_code = CODE_FOR_udivmoddi4;
3925 #ifdef HAVE_udivmodti4
3926 if (HAVE_udivmodti4)
3927 udivmod_optab->handlers[(int) TImode].insn_code = CODE_FOR_udivmodti4;
3929 init_integral_libfuncs (udivmod_optab, "udivmod", '4');
3933 smod_optab->handlers[(int) QImode].insn_code = CODE_FOR_modqi3;
3937 smod_optab->handlers[(int) HImode].insn_code = CODE_FOR_modhi3;
3941 smod_optab->handlers[(int) PSImode].insn_code = CODE_FOR_modpsi3;
3945 smod_optab->handlers[(int) SImode].insn_code = CODE_FOR_modsi3;
3949 smod_optab->handlers[(int) DImode].insn_code = CODE_FOR_moddi3;
3953 smod_optab->handlers[(int) TImode].insn_code = CODE_FOR_modti3;
3955 init_integral_libfuncs (smod_optab, "mod", '3');
3957 #ifdef MODSI3_LIBCALL
3958 smod_optab->handlers[(int) SImode].libfunc
3959 = gen_rtx (SYMBOL_REF, Pmode, MODSI3_LIBCALL);
3961 #ifdef MODDI3_LIBCALL
3962 smod_optab->handlers[(int) DImode].libfunc
3963 = gen_rtx (SYMBOL_REF, Pmode, MODDI3_LIBCALL);
3965 #ifdef MODTI3_LIBCALL
3966 smod_optab->handlers[(int) TImode].libfunc
3967 = gen_rtx (SYMBOL_REF, Pmode, MODTI3_LIBCALL);
3972 umod_optab->handlers[(int) QImode].insn_code = CODE_FOR_umodqi3;
3976 umod_optab->handlers[(int) HImode].insn_code = CODE_FOR_umodhi3;
3978 #ifdef HAVE_umodpsi3
3980 umod_optab->handlers[(int) PSImode].insn_code = CODE_FOR_umodpsi3;
3984 umod_optab->handlers[(int) SImode].insn_code = CODE_FOR_umodsi3;
3988 umod_optab->handlers[(int) DImode].insn_code = CODE_FOR_umoddi3;
3992 umod_optab->handlers[(int) TImode].insn_code = CODE_FOR_umodti3;
3994 init_integral_libfuncs (umod_optab, "umod", '3');
3996 #ifdef UMODSI3_LIBCALL
3997 umod_optab->handlers[(int) SImode].libfunc
3998 = gen_rtx (SYMBOL_REF, Pmode, UMODSI3_LIBCALL);
4000 #ifdef UMODDI3_LIBCALL
4001 umod_optab->handlers[(int) DImode].libfunc
4002 = gen_rtx (SYMBOL_REF, Pmode, UMODDI3_LIBCALL);
4004 #ifdef UMODTI3_LIBCALL
4005 umod_optab->handlers[(int) TImode].libfunc
4006 = gen_rtx (SYMBOL_REF, Pmode, UMODTI3_LIBCALL);
4011 flodiv_optab->handlers[(int) SFmode].insn_code = CODE_FOR_divsf3;
4015 flodiv_optab->handlers[(int) DFmode].insn_code = CODE_FOR_divdf3;
4019 flodiv_optab->handlers[(int) XFmode].insn_code = CODE_FOR_divxf3;
4023 flodiv_optab->handlers[(int) TFmode].insn_code = CODE_FOR_divtf3;
4025 init_floating_libfuncs (flodiv_optab, "div", '3');
4027 #ifdef HAVE_ftruncsf2
4029 ftrunc_optab->handlers[(int) SFmode].insn_code = CODE_FOR_ftruncsf2;
4031 #ifdef HAVE_ftruncdf2
4033 ftrunc_optab->handlers[(int) DFmode].insn_code = CODE_FOR_ftruncdf2;
4035 #ifdef HAVE_ftruncxf2
4037 ftrunc_optab->handlers[(int) XFmode].insn_code = CODE_FOR_ftruncxf2;
4039 #ifdef HAVE_ftrunctf2
4041 ftrunc_optab->handlers[(int) TFmode].insn_code = CODE_FOR_ftrunctf2;
4043 init_floating_libfuncs (ftrunc_optab, "ftrunc", '2');
4047 and_optab->handlers[(int) QImode].insn_code = CODE_FOR_andqi3;
4051 and_optab->handlers[(int) HImode].insn_code = CODE_FOR_andhi3;
4055 and_optab->handlers[(int) PSImode].insn_code = CODE_FOR_andpsi3;
4059 and_optab->handlers[(int) SImode].insn_code = CODE_FOR_andsi3;
4063 and_optab->handlers[(int) DImode].insn_code = CODE_FOR_anddi3;
4067 and_optab->handlers[(int) TImode].insn_code = CODE_FOR_andti3;
4069 init_integral_libfuncs (and_optab, "and", '3');
4073 ior_optab->handlers[(int) QImode].insn_code = CODE_FOR_iorqi3;
4077 ior_optab->handlers[(int) HImode].insn_code = CODE_FOR_iorhi3;
4081 ior_optab->handlers[(int) PSImode].insn_code = CODE_FOR_iorpsi3;
4085 ior_optab->handlers[(int) SImode].insn_code = CODE_FOR_iorsi3;
4089 ior_optab->handlers[(int) DImode].insn_code = CODE_FOR_iordi3;
4093 ior_optab->handlers[(int) TImode].insn_code = CODE_FOR_iorti3;
4095 init_integral_libfuncs (ior_optab, "ior", '3');
4099 xor_optab->handlers[(int) QImode].insn_code = CODE_FOR_xorqi3;
4103 xor_optab->handlers[(int) HImode].insn_code = CODE_FOR_xorhi3;
4107 xor_optab->handlers[(int) PSImode].insn_code = CODE_FOR_xorpsi3;
4111 xor_optab->handlers[(int) SImode].insn_code = CODE_FOR_xorsi3;
4115 xor_optab->handlers[(int) DImode].insn_code = CODE_FOR_xordi3;
4119 xor_optab->handlers[(int) TImode].insn_code = CODE_FOR_xorti3;
4121 init_integral_libfuncs (xor_optab, "xor", '3');
4125 ashl_optab->handlers[(int) QImode].insn_code = CODE_FOR_ashlqi3;
4129 ashl_optab->handlers[(int) HImode].insn_code = CODE_FOR_ashlhi3;
4131 #ifdef HAVE_ashlpsi3
4133 ashl_optab->handlers[(int) PSImode].insn_code = CODE_FOR_ashlpsi3;
4137 ashl_optab->handlers[(int) SImode].insn_code = CODE_FOR_ashlsi3;
4141 ashl_optab->handlers[(int) DImode].insn_code = CODE_FOR_ashldi3;
4145 ashl_optab->handlers[(int) TImode].insn_code = CODE_FOR_ashlti3;
4147 init_integral_libfuncs (ashl_optab, "ashl", '3');
4151 ashr_optab->handlers[(int) QImode].insn_code = CODE_FOR_ashrqi3;
4155 ashr_optab->handlers[(int) HImode].insn_code = CODE_FOR_ashrhi3;
4157 #ifdef HAVE_ashrpsi3
4159 ashr_optab->handlers[(int) PSImode].insn_code = CODE_FOR_ashrpsi3;
4163 ashr_optab->handlers[(int) SImode].insn_code = CODE_FOR_ashrsi3;
4167 ashr_optab->handlers[(int) DImode].insn_code = CODE_FOR_ashrdi3;
4171 ashr_optab->handlers[(int) TImode].insn_code = CODE_FOR_ashrti3;
4173 init_integral_libfuncs (ashr_optab, "ashr", '3');
4177 lshl_optab->handlers[(int) QImode].insn_code = CODE_FOR_lshlqi3;
4181 lshl_optab->handlers[(int) HImode].insn_code = CODE_FOR_lshlhi3;
4183 #ifdef HAVE_lshlpsi3
4185 lshl_optab->handlers[(int) PSImode].insn_code = CODE_FOR_lshlpsi3;
4189 lshl_optab->handlers[(int) SImode].insn_code = CODE_FOR_lshlsi3;
4193 lshl_optab->handlers[(int) DImode].insn_code = CODE_FOR_lshldi3;
4197 lshl_optab->handlers[(int) TImode].insn_code = CODE_FOR_lshlti3;
4199 init_integral_libfuncs (lshl_optab, "lshl", '3');
4203 lshr_optab->handlers[(int) QImode].insn_code = CODE_FOR_lshrqi3;
4207 lshr_optab->handlers[(int) HImode].insn_code = CODE_FOR_lshrhi3;
4209 #ifdef HAVE_lshrpsi3
4211 lshr_optab->handlers[(int) PSImode].insn_code = CODE_FOR_lshrpsi3;
4215 lshr_optab->handlers[(int) SImode].insn_code = CODE_FOR_lshrsi3;
4219 lshr_optab->handlers[(int) DImode].insn_code = CODE_FOR_lshrdi3;
4223 lshr_optab->handlers[(int) TImode].insn_code = CODE_FOR_lshrti3;
4225 init_integral_libfuncs (lshr_optab, "lshr", '3');
4229 rotl_optab->handlers[(int) QImode].insn_code = CODE_FOR_rotlqi3;
4233 rotl_optab->handlers[(int) HImode].insn_code = CODE_FOR_rotlhi3;
4235 #ifdef HAVE_rotlpsi3
4237 rotl_optab->handlers[(int) PSImode].insn_code = CODE_FOR_rotlpsi3;
4241 rotl_optab->handlers[(int) SImode].insn_code = CODE_FOR_rotlsi3;
4245 rotl_optab->handlers[(int) DImode].insn_code = CODE_FOR_rotldi3;
4249 rotl_optab->handlers[(int) TImode].insn_code = CODE_FOR_rotlti3;
4251 init_integral_libfuncs (rotl_optab, "rotl", '3');
4255 rotr_optab->handlers[(int) QImode].insn_code = CODE_FOR_rotrqi3;
4259 rotr_optab->handlers[(int) HImode].insn_code = CODE_FOR_rotrhi3;
4261 #ifdef HAVE_rotrpsi3
4263 rotr_optab->handlers[(int) PSImode].insn_code = CODE_FOR_rotrpsi3;
4267 rotr_optab->handlers[(int) SImode].insn_code = CODE_FOR_rotrsi3;
4271 rotr_optab->handlers[(int) DImode].insn_code = CODE_FOR_rotrdi3;
4275 rotr_optab->handlers[(int) TImode].insn_code = CODE_FOR_rotrti3;
4277 init_integral_libfuncs (rotr_optab, "rotr", '3');
4281 smin_optab->handlers[(int) QImode].insn_code = CODE_FOR_sminqi3;
4285 smin_optab->handlers[(int) HImode].insn_code = CODE_FOR_sminhi3;
4289 smin_optab->handlers[(int) SImode].insn_code = CODE_FOR_sminsi3;
4293 smin_optab->handlers[(int) DImode].insn_code = CODE_FOR_smindi3;
4297 smin_optab->handlers[(int) TImode].insn_code = CODE_FOR_sminti3;
4301 smin_optab->handlers[(int) SFmode].insn_code = CODE_FOR_minsf3;
4305 smin_optab->handlers[(int) DFmode].insn_code = CODE_FOR_mindf3;
4309 smin_optab->handlers[(int) XFmode].insn_code = CODE_FOR_minxf3;
4313 smin_optab->handlers[(int) TFmode].insn_code = CODE_FOR_mintf3;
4315 init_integral_libfuncs (smin_optab, "min", '3');
4316 init_floating_libfuncs (smin_optab, "min", '3');
4320 smax_optab->handlers[(int) QImode].insn_code = CODE_FOR_smaxqi3;
4324 smax_optab->handlers[(int) HImode].insn_code = CODE_FOR_smaxhi3;
4328 smax_optab->handlers[(int) SImode].insn_code = CODE_FOR_smaxsi3;
4332 smax_optab->handlers[(int) DImode].insn_code = CODE_FOR_smaxdi3;
4336 smax_optab->handlers[(int) TImode].insn_code = CODE_FOR_smaxti3;
4340 smax_optab->handlers[(int) SFmode].insn_code = CODE_FOR_maxsf3;
4344 smax_optab->handlers[(int) DFmode].insn_code = CODE_FOR_maxdf3;
4348 smax_optab->handlers[(int) XFmode].insn_code = CODE_FOR_maxxf3;
4352 smax_optab->handlers[(int) TFmode].insn_code = CODE_FOR_maxtf3;
4354 init_integral_libfuncs (smax_optab, "max", '3');
4355 init_floating_libfuncs (smax_optab, "max", '3');
4359 umin_optab->handlers[(int) QImode].insn_code = CODE_FOR_uminqi3;
4363 umin_optab->handlers[(int) HImode].insn_code = CODE_FOR_uminhi3;
4367 umin_optab->handlers[(int) SImode].insn_code = CODE_FOR_uminsi3;
4371 umin_optab->handlers[(int) DImode].insn_code = CODE_FOR_umindi3;
4375 umin_optab->handlers[(int) TImode].insn_code = CODE_FOR_uminti3;
4377 init_integral_libfuncs (umin_optab, "umin", '3');
4381 umax_optab->handlers[(int) QImode].insn_code = CODE_FOR_umaxqi3;
4385 umax_optab->handlers[(int) HImode].insn_code = CODE_FOR_umaxhi3;
4389 umax_optab->handlers[(int) SImode].insn_code = CODE_FOR_umaxsi3;
4393 umax_optab->handlers[(int) DImode].insn_code = CODE_FOR_umaxdi3;
4397 umax_optab->handlers[(int) TImode].insn_code = CODE_FOR_umaxti3;
4399 init_integral_libfuncs (umax_optab, "umax", '3');
4403 neg_optab->handlers[(int) QImode].insn_code = CODE_FOR_negqi2;
4407 neg_optab->handlers[(int) HImode].insn_code = CODE_FOR_neghi2;
4411 neg_optab->handlers[(int) PSImode].insn_code = CODE_FOR_negpsi2;
4415 neg_optab->handlers[(int) SImode].insn_code = CODE_FOR_negsi2;
4419 neg_optab->handlers[(int) DImode].insn_code = CODE_FOR_negdi2;
4423 neg_optab->handlers[(int) TImode].insn_code = CODE_FOR_negti2;
4427 neg_optab->handlers[(int) SFmode].insn_code = CODE_FOR_negsf2;
4431 neg_optab->handlers[(int) DFmode].insn_code = CODE_FOR_negdf2;
4435 neg_optab->handlers[(int) XFmode].insn_code = CODE_FOR_negxf2;
4439 neg_optab->handlers[(int) TFmode].insn_code = CODE_FOR_negtf2;
4441 init_integral_libfuncs (neg_optab, "neg", '2');
4442 init_floating_libfuncs (neg_optab, "neg", '2');
4446 abs_optab->handlers[(int) QImode].insn_code = CODE_FOR_absqi2;
4450 abs_optab->handlers[(int) HImode].insn_code = CODE_FOR_abshi2;
4454 abs_optab->handlers[(int) PSImode].insn_code = CODE_FOR_abspsi2;
4458 abs_optab->handlers[(int) SImode].insn_code = CODE_FOR_abssi2;
4462 abs_optab->handlers[(int) DImode].insn_code = CODE_FOR_absdi2;
4466 abs_optab->handlers[(int) TImode].insn_code = CODE_FOR_absti2;
4470 abs_optab->handlers[(int) SFmode].insn_code = CODE_FOR_abssf2;
4474 abs_optab->handlers[(int) DFmode].insn_code = CODE_FOR_absdf2;
4478 abs_optab->handlers[(int) XFmode].insn_code = CODE_FOR_absxf2;
4482 abs_optab->handlers[(int) TFmode].insn_code = CODE_FOR_abstf2;
4484 /* No library calls here! If there is no abs instruction,
4485 expand_expr will generate a conditional negation. */
4489 sqrt_optab->handlers[(int) QImode].insn_code = CODE_FOR_sqrtqi2;
4493 sqrt_optab->handlers[(int) HImode].insn_code = CODE_FOR_sqrthi2;
4495 #ifdef HAVE_sqrtpsi2
4497 sqrt_optab->handlers[(int) PSImode].insn_code = CODE_FOR_sqrtpsi2;
4501 sqrt_optab->handlers[(int) SImode].insn_code = CODE_FOR_sqrtsi2;
4505 sqrt_optab->handlers[(int) DImode].insn_code = CODE_FOR_sqrtdi2;
4509 sqrt_optab->handlers[(int) TImode].insn_code = CODE_FOR_sqrtti2;
4513 sqrt_optab->handlers[(int) SFmode].insn_code = CODE_FOR_sqrtsf2;
4517 sqrt_optab->handlers[(int) DFmode].insn_code = CODE_FOR_sqrtdf2;
4521 sqrt_optab->handlers[(int) TFmode].insn_code = CODE_FOR_sqrttf2;
4523 /* No library calls here! If there is no sqrt instruction expand_builtin
4524 should force the library call. */
4528 sin_optab->handlers[(int) SFmode].insn_code = CODE_FOR_sinsf2;
4532 sin_optab->handlers[(int) DFmode].insn_code = CODE_FOR_sindf2;
4536 sin_optab->handlers[(int) TFmode].insn_code = CODE_FOR_sintf2;
4538 /* No library calls here! If there is no sin instruction expand_builtin
4539 should force the library call. */
4543 cos_optab->handlers[(int) SFmode].insn_code = CODE_FOR_cossf2;
4547 cos_optab->handlers[(int) DFmode].insn_code = CODE_FOR_cosdf2;
4551 cos_optab->handlers[(int) TFmode].insn_code = CODE_FOR_costf2;
4553 /* No library calls here! If there is no cos instruction expand_builtin
4554 should force the library call. */
4556 #ifdef HAVE_strlenqi
4558 strlen_optab->handlers[(int) QImode].insn_code = CODE_FOR_strlenqi;
4560 #ifdef HAVE_strlenhi
4562 strlen_optab->handlers[(int) HImode].insn_code = CODE_FOR_strlenhi;
4564 #ifdef HAVE_strlenpsi
4566 strlen_optab->handlers[(int) PSImode].insn_code = CODE_FOR_strlenpsi;
4568 #ifdef HAVE_strlensi
4570 strlen_optab->handlers[(int) SImode].insn_code = CODE_FOR_strlensi;
4572 #ifdef HAVE_strlendi
4574 strlen_optab->handlers[(int) DImode].insn_code = CODE_FOR_strlendi;
4576 #ifdef HAVE_strlenti
4578 strlen_optab->handlers[(int) TImode].insn_code = CODE_FOR_strlenti;
4580 /* No library calls here! If there is no strlen instruction expand_builtin
4581 should force the library call. */
4583 #ifdef HAVE_one_cmplqi2
4584 if (HAVE_one_cmplqi2)
4585 one_cmpl_optab->handlers[(int) QImode].insn_code = CODE_FOR_one_cmplqi2;
4587 #ifdef HAVE_one_cmplhi2
4588 if (HAVE_one_cmplhi2)
4589 one_cmpl_optab->handlers[(int) HImode].insn_code = CODE_FOR_one_cmplhi2;
4591 #ifdef HAVE_one_cmplpsi2
4592 if (HAVE_one_cmplpsi2)
4593 one_cmpl_optab->handlers[(int) PSImode].insn_code = CODE_FOR_one_cmplpsi2;
4595 #ifdef HAVE_one_cmplsi2
4596 if (HAVE_one_cmplsi2)
4597 one_cmpl_optab->handlers[(int) SImode].insn_code = CODE_FOR_one_cmplsi2;
4599 #ifdef HAVE_one_cmpldi2
4600 if (HAVE_one_cmpldi2)
4601 one_cmpl_optab->handlers[(int) DImode].insn_code = CODE_FOR_one_cmpldi2;
4603 #ifdef HAVE_one_cmplti2
4604 if (HAVE_one_cmplti2)
4605 one_cmpl_optab->handlers[(int) TImode].insn_code = CODE_FOR_one_cmplti2;
4607 init_integral_libfuncs (one_cmpl_optab, "one_cmpl", '2');
4611 ffs_optab->handlers[(int) QImode].insn_code = CODE_FOR_ffsqi2;
4615 ffs_optab->handlers[(int) HImode].insn_code = CODE_FOR_ffshi2;
4619 ffs_optab->handlers[(int) PSImode].insn_code = CODE_FOR_ffspsi2;
4623 ffs_optab->handlers[(int) SImode].insn_code = CODE_FOR_ffssi2;
4627 ffs_optab->handlers[(int) DImode].insn_code = CODE_FOR_ffsdi2;
4631 ffs_optab->handlers[(int) TImode].insn_code = CODE_FOR_ffsti2;
4633 init_integral_libfuncs (ffs_optab, "ffs", '2');
4637 mov_optab->handlers[(int) QImode].insn_code = CODE_FOR_movqi;
4641 mov_optab->handlers[(int) HImode].insn_code = CODE_FOR_movhi;
4645 mov_optab->handlers[(int) PSImode].insn_code = CODE_FOR_movpsi;
4649 mov_optab->handlers[(int) SImode].insn_code = CODE_FOR_movsi;
4653 mov_optab->handlers[(int) DImode].insn_code = CODE_FOR_movdi;
4657 mov_optab->handlers[(int) TImode].insn_code = CODE_FOR_movti;
4661 mov_optab->handlers[(int) SFmode].insn_code = CODE_FOR_movsf;
4665 mov_optab->handlers[(int) DFmode].insn_code = CODE_FOR_movdf;
4669 mov_optab->handlers[(int) XFmode].insn_code = CODE_FOR_movxf;
4673 mov_optab->handlers[(int) TFmode].insn_code = CODE_FOR_movtf;
4677 mov_optab->handlers[(int) CCmode].insn_code = CODE_FOR_movcc;
4680 #ifdef EXTRA_CC_MODES
4684 #ifdef HAVE_movstrictqi
4685 if (HAVE_movstrictqi)
4686 movstrict_optab->handlers[(int) QImode].insn_code = CODE_FOR_movstrictqi;
4688 #ifdef HAVE_movstricthi
4689 if (HAVE_movstricthi)
4690 movstrict_optab->handlers[(int) HImode].insn_code = CODE_FOR_movstricthi;
4692 #ifdef HAVE_movstrictpsi
4693 if (HAVE_movstrictpsi)
4694 movstrict_optab->handlers[(int) PSImode].insn_code = CODE_FOR_movstrictpsi;
4696 #ifdef HAVE_movstrictsi
4697 if (HAVE_movstrictsi)
4698 movstrict_optab->handlers[(int) SImode].insn_code = CODE_FOR_movstrictsi;
4700 #ifdef HAVE_movstrictdi
4701 if (HAVE_movstrictdi)
4702 movstrict_optab->handlers[(int) DImode].insn_code = CODE_FOR_movstrictdi;
4704 #ifdef HAVE_movstrictti
4705 if (HAVE_movstrictti)
4706 movstrict_optab->handlers[(int) TImode].insn_code = CODE_FOR_movstrictti;
4711 cmp_optab->handlers[(int) QImode].insn_code = CODE_FOR_cmpqi;
4715 cmp_optab->handlers[(int) HImode].insn_code = CODE_FOR_cmphi;
4719 cmp_optab->handlers[(int) PSImode].insn_code = CODE_FOR_cmppsi;
4723 cmp_optab->handlers[(int) SImode].insn_code = CODE_FOR_cmpsi;
4727 cmp_optab->handlers[(int) DImode].insn_code = CODE_FOR_cmpdi;
4731 cmp_optab->handlers[(int) TImode].insn_code = CODE_FOR_cmpti;
4735 cmp_optab->handlers[(int) SFmode].insn_code = CODE_FOR_cmpsf;
4739 cmp_optab->handlers[(int) DFmode].insn_code = CODE_FOR_cmpdf;
4743 cmp_optab->handlers[(int) XFmode].insn_code = CODE_FOR_cmpxf;
4747 cmp_optab->handlers[(int) TFmode].insn_code = CODE_FOR_cmptf;
4749 /* Comparison libcalls for integers MUST come in pairs, signed/unsigned. */
4750 init_integral_libfuncs (cmp_optab, "cmp", '2');
4751 init_integral_libfuncs (ucmp_optab, "ucmp", '2');
4752 init_floating_libfuncs (cmp_optab, "cmp", '2');
4756 tst_optab->handlers[(int) QImode].insn_code = CODE_FOR_tstqi;
4760 tst_optab->handlers[(int) HImode].insn_code = CODE_FOR_tsthi;
4764 tst_optab->handlers[(int) PSImode].insn_code = CODE_FOR_tstpsi;
4768 tst_optab->handlers[(int) SImode].insn_code = CODE_FOR_tstsi;
4772 tst_optab->handlers[(int) DImode].insn_code = CODE_FOR_tstdi;
4776 tst_optab->handlers[(int) TImode].insn_code = CODE_FOR_tstti;
4780 tst_optab->handlers[(int) SFmode].insn_code = CODE_FOR_tstsf;
4784 tst_optab->handlers[(int) DFmode].insn_code = CODE_FOR_tstdf;
4788 tst_optab->handlers[(int) XFmode].insn_code = CODE_FOR_tstxf;
4792 tst_optab->handlers[(int) TFmode].insn_code = CODE_FOR_tsttf;
4797 bcc_gen_fctn[(int) EQ] = gen_beq;
4801 bcc_gen_fctn[(int) NE] = gen_bne;
4805 bcc_gen_fctn[(int) GT] = gen_bgt;
4809 bcc_gen_fctn[(int) GE] = gen_bge;
4813 bcc_gen_fctn[(int) GTU] = gen_bgtu;
4817 bcc_gen_fctn[(int) GEU] = gen_bgeu;
4821 bcc_gen_fctn[(int) LT] = gen_blt;
4825 bcc_gen_fctn[(int) LE] = gen_ble;
4829 bcc_gen_fctn[(int) LTU] = gen_bltu;
4833 bcc_gen_fctn[(int) LEU] = gen_bleu;
4836 for (i = 0; i < NUM_RTX_CODE; i++)
4837 setcc_gen_code[i] = CODE_FOR_nothing;
4841 setcc_gen_code[(int) EQ] = CODE_FOR_seq;
4845 setcc_gen_code[(int) NE] = CODE_FOR_sne;
4849 setcc_gen_code[(int) GT] = CODE_FOR_sgt;
4853 setcc_gen_code[(int) GE] = CODE_FOR_sge;
4857 setcc_gen_code[(int) GTU] = CODE_FOR_sgtu;
4861 setcc_gen_code[(int) GEU] = CODE_FOR_sgeu;
4865 setcc_gen_code[(int) LT] = CODE_FOR_slt;
4869 setcc_gen_code[(int) LE] = CODE_FOR_sle;
4873 setcc_gen_code[(int) LTU] = CODE_FOR_sltu;
4877 setcc_gen_code[(int) LEU] = CODE_FOR_sleu;
4880 extendsfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extendsfdf2");
4881 extendsfxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extendsfxf2");
4882 extendsftf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extendsftf2");
4883 extenddfxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extenddfxf2");
4884 extenddftf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extenddftf2");
4886 truncdfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__truncdfsf2");
4887 truncxfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__truncxfsf2");
4888 trunctfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__trunctfsf2");
4889 truncxfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__truncxfdf2");
4890 trunctfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__trunctfdf2");
4892 memcpy_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memcpy");
4893 bcopy_libfunc = gen_rtx (SYMBOL_REF, Pmode, "bcopy");
4894 memcmp_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memcmp");
4895 bcmp_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gcc_bcmp");
4896 memset_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memset");
4897 bzero_libfunc = gen_rtx (SYMBOL_REF, Pmode, "bzero");
4899 eqsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqsf2");
4900 nesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nesf2");
4901 gtsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtsf2");
4902 gesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gesf2");
4903 ltsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltsf2");
4904 lesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lesf2");
4906 eqdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqdf2");
4907 nedf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nedf2");
4908 gtdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtdf2");
4909 gedf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gedf2");
4910 ltdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltdf2");
4911 ledf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ledf2");
4913 eqxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqxf2");
4914 nexf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nexf2");
4915 gtxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtxf2");
4916 gexf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gexf2");
4917 ltxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltxf2");
4918 lexf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lexf2");
4920 eqtf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqtf2");
4921 netf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__netf2");
4922 gttf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gttf2");
4923 getf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__getf2");
4924 lttf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lttf2");
4925 letf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__letf2");
4927 floatsisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsisf");
4928 floatdisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatdisf");
4929 floattisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattisf");
4931 floatsidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsidf");
4932 floatdidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatdidf");
4933 floattidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattidf");
4935 floatsixf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsixf");
4936 floatdixf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatdixf");
4937 floattixf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattixf");
4939 floatsitf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsitf");
4940 floatditf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatditf");
4941 floattitf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattitf");
4943 fixsfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixsfsi");
4944 fixsfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixsfdi");
4945 fixsfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixsfti");
4947 fixdfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixdfsi");
4948 fixdfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixdfdi");
4949 fixdfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixdfti");
4951 fixxfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixxfsi");
4952 fixxfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixxfdi");
4953 fixxfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixxfti");
4955 fixtfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixtfsi");
4956 fixtfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixtfdi");
4957 fixtfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixtfti");
4959 fixunssfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunssfsi");
4960 fixunssfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunssfdi");
4961 fixunssfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunssfti");
4963 fixunsdfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsdfsi");
4964 fixunsdfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsdfdi");
4965 fixunsdfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsdfti");
4967 fixunsxfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsxfsi");
4968 fixunsxfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsxfdi");
4969 fixunsxfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsxfti");
4971 fixunstfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunstfsi");
4972 fixunstfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunstfdi");
4973 fixunstfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunstfti");
4978 /* SCO 3.2 apparently has a broken ldexp. */
4991 #endif /* BROKEN_LDEXP */