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;
183 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
184 gives the gen_function to make a branch to test that condition. */
186 rtxfun bcc_gen_fctn[NUM_RTX_CODE];
188 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
189 gives the insn code to make a store-condition insn
190 to test that condition. */
192 enum insn_code setcc_gen_code[NUM_RTX_CODE];
194 static void emit_float_lib_cmp ();
196 /* Add a REG_EQUAL note to the last insn in SEQ. TARGET is being set to
197 the result of operation CODE applied to OP0 (and OP1 if it is a binary
200 If the last insn does not set TARGET, don't do anything, but return 1.
202 If a previous insn sets TARGET and TARGET is one of OP0 or OP1,
203 don't add the REG_EQUAL note but return 0. Our caller can then try
204 again, ensuring that TARGET is not one of the operands. */
207 add_equal_note (seq, target, code, op0, op1)
217 if ((GET_RTX_CLASS (code) != '1' && GET_RTX_CLASS (code) != '2'
218 && GET_RTX_CLASS (code) != 'c' && GET_RTX_CLASS (code) != '<')
219 || GET_CODE (seq) != SEQUENCE
220 || (set = single_set (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1))) == 0
221 || GET_CODE (target) == ZERO_EXTRACT
222 || (! rtx_equal_p (SET_DEST (set), target)
223 /* For a STRICT_LOW_PART, the REG_NOTE applies to what is inside the
225 && (GET_CODE (SET_DEST (set)) != STRICT_LOW_PART
226 || ! rtx_equal_p (SUBREG_REG (XEXP (SET_DEST (set), 0)),
230 /* If TARGET is in OP0 or OP1, check if anything in SEQ sets TARGET
231 besides the last insn. */
232 if (reg_overlap_mentioned_p (target, op0)
233 || (op1 && reg_overlap_mentioned_p (target, op1)))
234 for (i = XVECLEN (seq, 0) - 2; i >= 0; i--)
235 if (reg_set_p (target, XVECEXP (seq, 0, i)))
238 if (GET_RTX_CLASS (code) == '1')
239 note = gen_rtx (code, GET_MODE (target), op0);
241 note = gen_rtx (code, GET_MODE (target), op0, op1);
243 REG_NOTES (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1))
244 = gen_rtx (EXPR_LIST, REG_EQUAL, note,
245 REG_NOTES (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1)));
250 /* Generate code to perform an operation specified by BINOPTAB
251 on operands OP0 and OP1, with result having machine-mode MODE.
253 UNSIGNEDP is for the case where we have to widen the operands
254 to perform the operation. It says to use zero-extension.
256 If TARGET is nonzero, the value
257 is generated there, if it is convenient to do so.
258 In all cases an rtx is returned for the locus of the value;
259 this may or may not be TARGET. */
262 expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods)
263 enum machine_mode mode;
268 enum optab_methods methods;
270 enum mode_class class;
271 enum machine_mode wider_mode;
273 int commutative_op = 0;
274 int shift_op = (binoptab->code == ASHIFT
275 || binoptab->code == ASHIFTRT
276 || binoptab->code == LSHIFT
277 || binoptab->code == LSHIFTRT
278 || binoptab->code == ROTATE
279 || binoptab->code == ROTATERT);
282 class = GET_MODE_CLASS (mode);
284 op0 = protect_from_queue (op0, 0);
285 op1 = protect_from_queue (op1, 0);
287 target = protect_from_queue (target, 1);
291 op0 = force_not_mem (op0);
292 op1 = force_not_mem (op1);
295 /* If we are inside an appropriately-short loop and one operand is an
296 expensive constant, force it into a register. */
297 if (CONSTANT_P (op0) && preserve_subexpressions_p ()
298 && rtx_cost (op0, binoptab->code) > 2)
299 op0 = force_reg (mode, op0);
301 if (CONSTANT_P (op1) && preserve_subexpressions_p ()
302 && rtx_cost (op1, binoptab->code) > 2)
303 op1 = force_reg (shift_op ? word_mode : mode, op1);
305 #if 0 /* Turned off because it seems to be a kludgy method. */
306 /* If subtracting integer from pointer, and the pointer has a special mode,
307 then change it to an add. We use the add insn of Pmode for combining
308 integers with pointers, and the sub insn to subtract two pointers. */
310 if (binoptab == sub_optab
311 && GET_MODE (op0) == Pmode && GET_MODE (op1) != Pmode)
313 op1 = negate_rtx (GET_MODE(op1), op1);
314 binoptab = add_optab;
318 /* Record where to delete back to if we backtrack. */
319 last = get_last_insn ();
321 /* If operation is commutative,
322 try to make the first operand a register.
323 Even better, try to make it the same as the target.
324 Also try to make the last operand a constant. */
325 if (GET_RTX_CLASS (binoptab->code) == 'c'
326 || binoptab == smul_widen_optab
327 || binoptab == umul_widen_optab)
331 if (((target == 0 || GET_CODE (target) == REG)
332 ? ((GET_CODE (op1) == REG
333 && GET_CODE (op0) != REG)
335 : rtx_equal_p (op1, target))
336 || GET_CODE (op0) == CONST_INT)
344 /* If we can do it with a three-operand insn, do so. */
346 if (methods != OPTAB_MUST_WIDEN
347 && binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
349 int icode = (int) binoptab->handlers[(int) mode].insn_code;
350 enum machine_mode mode0 = insn_operand_mode[icode][1];
351 enum machine_mode mode1 = insn_operand_mode[icode][2];
353 rtx xop0 = op0, xop1 = op1;
358 temp = gen_reg_rtx (mode);
360 /* If it is a commutative operator and the modes would match
361 if we would swap the operands, we can save the conversions. */
364 if (GET_MODE (op0) != mode0 && GET_MODE (op1) != mode1
365 && GET_MODE (op0) == mode1 && GET_MODE (op1) == mode0)
369 tmp = op0; op0 = op1; op1 = tmp;
370 tmp = xop0; xop0 = xop1; xop1 = tmp;
374 /* In case the insn wants input operands in modes different from
375 the result, convert the operands. */
377 if (GET_MODE (op0) != VOIDmode
378 && GET_MODE (op0) != mode0)
379 xop0 = convert_to_mode (mode0, xop0, unsignedp);
381 if (GET_MODE (xop1) != VOIDmode
382 && GET_MODE (xop1) != mode1)
383 xop1 = convert_to_mode (mode1, xop1, unsignedp);
385 /* Now, if insn's predicates don't allow our operands, put them into
388 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
389 xop0 = copy_to_mode_reg (mode0, xop0);
391 if (! (*insn_operand_predicate[icode][2]) (xop1, mode1))
392 xop1 = copy_to_mode_reg (mode1, xop1);
394 if (! (*insn_operand_predicate[icode][0]) (temp, mode))
395 temp = gen_reg_rtx (mode);
397 pat = GEN_FCN (icode) (temp, xop0, xop1);
400 /* If PAT is a multi-insn sequence, try to add an appropriate
401 REG_EQUAL note to it. If we can't because TEMP conflicts with an
402 operand, call ourselves again, this time without a target. */
403 if (GET_CODE (pat) == SEQUENCE
404 && ! add_equal_note (pat, temp, binoptab->code, xop0, xop1))
406 delete_insns_since (last);
407 return expand_binop (mode, binoptab, op0, op1, NULL_RTX,
415 delete_insns_since (last);
418 /* If this is a multiply, see if we can do a widening operation that
419 takes operands of this mode and makes a wider mode. */
421 if (binoptab == smul_optab && GET_MODE_WIDER_MODE (mode) != VOIDmode
422 && (((unsignedp ? umul_widen_optab : smul_widen_optab)
423 ->handlers[(int) GET_MODE_WIDER_MODE (mode)].insn_code)
424 != CODE_FOR_nothing))
426 temp = expand_binop (GET_MODE_WIDER_MODE (mode),
427 unsignedp ? umul_widen_optab : smul_widen_optab,
428 op0, op1, 0, unsignedp, OPTAB_DIRECT);
430 if (GET_MODE_CLASS (mode) == MODE_INT)
431 return gen_lowpart (mode, temp);
433 return convert_to_mode (mode, temp, unsignedp);
436 /* Look for a wider mode of the same class for which we think we
437 can open-code the operation. Check for a widening multiply at the
438 wider mode as well. */
440 if ((class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
441 && mode != OPTAB_DIRECT && mode != OPTAB_LIB)
442 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
443 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
445 if (binoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing
446 || (binoptab == smul_optab
447 && GET_MODE_WIDER_MODE (wider_mode) != VOIDmode
448 && (((unsignedp ? umul_widen_optab : smul_widen_optab)
449 ->handlers[(int) GET_MODE_WIDER_MODE (wider_mode)].insn_code)
450 != CODE_FOR_nothing)))
452 rtx xop0 = op0, xop1 = op1;
455 /* For certain integer operations, we need not actually extend
456 the narrow operands, as long as we will truncate
457 the results to the same narrowness. Don't do this when
458 WIDER_MODE is wider than a word since a paradoxical SUBREG
459 isn't valid for such modes. */
461 if ((binoptab == ior_optab || binoptab == and_optab
462 || binoptab == xor_optab
463 || binoptab == add_optab || binoptab == sub_optab
464 || binoptab == smul_optab
465 || binoptab == ashl_optab || binoptab == lshl_optab)
467 && GET_MODE_SIZE (wider_mode) <= UNITS_PER_WORD)
470 /* If an operand is a constant integer, we might as well
471 convert it since that is more efficient than using a SUBREG,
472 unlike the case for other operands. */
474 if (no_extend && GET_MODE (xop0) != VOIDmode)
475 xop0 = gen_rtx (SUBREG, wider_mode,
476 force_reg (GET_MODE (xop0), xop0), 0);
478 xop0 = convert_to_mode (wider_mode, xop0, unsignedp);
480 if (no_extend && GET_MODE (xop1) != VOIDmode)
481 xop1 = gen_rtx (SUBREG, wider_mode,
482 force_reg (GET_MODE (xop1), xop1), 0);
484 xop1 = convert_to_mode (wider_mode, xop1, unsignedp);
486 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
487 unsignedp, OPTAB_DIRECT);
490 if (class != MODE_INT)
493 target = gen_reg_rtx (mode);
494 convert_move (target, temp, 0);
498 return gen_lowpart (mode, temp);
501 delete_insns_since (last);
505 /* These can be done a word at a time. */
506 if ((binoptab == and_optab || binoptab == ior_optab || binoptab == xor_optab)
508 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
509 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
515 /* If TARGET is the same as one of the operands, the REG_EQUAL note
516 won't be accurate, so use a new target. */
517 if (target == 0 || target == op0 || target == op1)
518 target = gen_reg_rtx (mode);
522 /* Do the actual arithmetic. */
523 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
525 rtx target_piece = operand_subword (target, i, 1, mode);
526 rtx x = expand_binop (word_mode, binoptab,
527 operand_subword_force (op0, i, mode),
528 operand_subword_force (op1, i, mode),
529 target_piece, unsignedp, methods);
530 if (target_piece != x)
531 emit_move_insn (target_piece, x);
534 insns = get_insns ();
537 if (binoptab->code != UNKNOWN)
538 equiv_value = gen_rtx (binoptab->code, mode, op0, op1);
542 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
546 /* These can be done a word at a time by propagating carries. */
547 if ((binoptab == add_optab || binoptab == sub_optab)
549 && GET_MODE_SIZE (mode) >= 2 * UNITS_PER_WORD
550 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
553 rtx carry_tmp = gen_reg_rtx (word_mode);
554 optab otheroptab = binoptab == add_optab ? sub_optab : add_optab;
555 int nwords = GET_MODE_BITSIZE (mode) / BITS_PER_WORD;
556 rtx carry_in, carry_out;
558 /* We can handle either a 1 or -1 value for the carry. If STORE_FLAG
559 value is one of those, use it. Otherwise, use 1 since it is the
560 one easiest to get. */
561 #if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
562 int normalizep = STORE_FLAG_VALUE;
567 /* Prepare the operands. */
568 op0 = force_reg (mode, op0);
569 op1 = force_reg (mode, op1);
571 if (target == 0 || GET_CODE (target) != REG
572 || target == op0 || target == op1)
573 target = gen_reg_rtx (mode);
575 /* Do the actual arithmetic. */
576 for (i = 0; i < nwords; i++)
578 int index = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i);
579 rtx target_piece = operand_subword (target, index, 1, mode);
580 rtx op0_piece = operand_subword_force (op0, index, mode);
581 rtx op1_piece = operand_subword_force (op1, index, mode);
584 /* Main add/subtract of the input operands. */
585 x = expand_binop (word_mode, binoptab,
586 op0_piece, op1_piece,
587 target_piece, unsignedp, methods);
593 /* Store carry from main add/subtract. */
594 carry_out = gen_reg_rtx (word_mode);
595 carry_out = emit_store_flag (carry_out,
596 binoptab == add_optab ? LTU : GTU,
598 word_mode, 1, normalizep);
605 /* Add/subtract previous carry to main result. */
606 x = expand_binop (word_mode,
607 normalizep == 1 ? binoptab : otheroptab,
609 target_piece, 1, methods);
610 if (target_piece != x)
611 emit_move_insn (target_piece, x);
615 /* THIS CODE HAS NOT BEEN TESTED. */
616 /* Get out carry from adding/subtracting carry in. */
617 carry_tmp = emit_store_flag (carry_tmp,
618 binoptab == add_optab
621 word_mode, 1, normalizep);
622 /* Logical-ior the two poss. carry together. */
623 carry_out = expand_binop (word_mode, ior_optab,
624 carry_out, carry_tmp,
625 carry_out, 0, methods);
631 carry_in = carry_out;
634 if (i == GET_MODE_BITSIZE (mode) / BITS_PER_WORD)
638 temp = emit_move_insn (target, target);
639 REG_NOTES (temp) = gen_rtx (EXPR_LIST, REG_EQUAL,
640 gen_rtx (binoptab->code, mode, op0, op1),
645 delete_insns_since (last);
648 /* If we want to multiply two two-word values and have normal and widening
649 multiplies of single-word values, we can do this with three smaller
650 multiplications. Note that we do not make a REG_NO_CONFLICT block here
651 because we are not operating on one word at a time.
653 The multiplication proceeds as follows:
654 _______________________
655 [__op0_high_|__op0_low__]
656 _______________________
657 * [__op1_high_|__op1_low__]
658 _______________________________________________
659 _______________________
660 (1) [__op0_low__*__op1_low__]
661 _______________________
662 (2a) [__op0_low__*__op1_high_]
663 _______________________
664 (2b) [__op0_high_*__op1_low__]
665 _______________________
666 (3) [__op0_high_*__op1_high_]
669 This gives a 4-word result. Since we are only interested in the
670 lower 2 words, partial result (3) and the upper words of (2a) and
671 (2b) don't need to be calculated. Hence (2a) and (2b) can be
672 calculated using non-widening multiplication.
674 (1), however, needs to be calculated with an unsigned widening
675 multiplication. If this operation is not directly supported we
676 try using a signed widening multiplication and adjust the result.
677 This adjustment works as follows:
679 If both operands are positive then no adjustment is needed.
681 If the operands have different signs, for example op0_low < 0 and
682 op1_low >= 0, the instruction treats the most significant bit of
683 op0_low as a sign bit instead of a bit with significance
684 2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low
685 with 2**BITS_PER_WORD - op0_low, and two's complements the
686 result. Conclusion: We need to add op1_low * 2**BITS_PER_WORD to
689 Similarly, if both operands are negative, we need to add
690 (op0_low + op1_low) * 2**BITS_PER_WORD.
692 We use a trick to adjust quickly. We logically shift op0_low right
693 (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to
694 op0_high (op1_high) before it is used to calculate 2b (2a). If no
695 logical shift exists, we do an arithmetic right shift and subtract
698 if (binoptab == smul_optab
700 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
701 && smul_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
702 && add_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
703 && ((umul_widen_optab->handlers[(int) mode].insn_code
705 || (smul_widen_optab->handlers[(int) mode].insn_code
706 != CODE_FOR_nothing)))
708 int low = (WORDS_BIG_ENDIAN ? 1 : 0);
709 int high = (WORDS_BIG_ENDIAN ? 0 : 1);
710 rtx op0_high = operand_subword_force (op0, high, mode);
711 rtx op0_low = operand_subword_force (op0, low, mode);
712 rtx op1_high = operand_subword_force (op1, high, mode);
713 rtx op1_low = operand_subword_force (op1, low, mode);
718 /* If the target is the same as one of the inputs, don't use it. This
719 prevents problems with the REG_EQUAL note. */
720 if (target == op0 || target == op1)
723 /* Multiply the two lower words to get a double-word product.
724 If unsigned widening multiplication is available, use that;
725 otherwise use the signed form and compensate. */
727 if (umul_widen_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
729 product = expand_binop (mode, umul_widen_optab, op0_low, op1_low,
730 target, 1, OPTAB_DIRECT);
732 /* If we didn't succeed, delete everything we did so far. */
734 delete_insns_since (last);
736 op0_xhigh = op0_high, op1_xhigh = op1_high;
740 && smul_widen_optab->handlers[(int) mode].insn_code
743 rtx wordm1 = GEN_INT (BITS_PER_WORD - 1);
744 product = expand_binop (mode, smul_widen_optab, op0_low, op1_low,
745 target, 1, OPTAB_DIRECT);
746 op0_xhigh = expand_binop (word_mode, lshr_optab, op0_low, wordm1,
747 NULL_RTX, 1, OPTAB_DIRECT);
749 op0_xhigh = expand_binop (word_mode, add_optab, op0_high,
750 op0_xhigh, op0_xhigh, 0, OPTAB_DIRECT);
753 op0_xhigh = expand_binop (word_mode, ashr_optab, op0_low, wordm1,
754 NULL_RTX, 0, OPTAB_DIRECT);
756 op0_xhigh = expand_binop (word_mode, sub_optab, op0_high,
757 op0_xhigh, op0_xhigh, 0,
761 op1_xhigh = expand_binop (word_mode, lshr_optab, op1_low, wordm1,
762 NULL_RTX, 1, OPTAB_DIRECT);
764 op1_xhigh = expand_binop (word_mode, add_optab, op1_high,
765 op1_xhigh, op1_xhigh, 0, OPTAB_DIRECT);
768 op1_xhigh = expand_binop (word_mode, ashr_optab, op1_low, wordm1,
769 NULL_RTX, 0, OPTAB_DIRECT);
771 op1_xhigh = expand_binop (word_mode, sub_optab, op1_high,
772 op1_xhigh, op1_xhigh, 0,
777 /* If we have been able to directly compute the product of the
778 low-order words of the operands and perform any required adjustments
779 of the operands, we proceed by trying two more multiplications
780 and then computing the appropriate sum.
782 We have checked above that the required addition is provided.
783 Full-word addition will normally always succeed, especially if
784 it is provided at all, so we don't worry about its failure. The
785 multiplication may well fail, however, so we do handle that. */
787 if (product && op0_xhigh && op1_xhigh)
790 rtx product_high = operand_subword (product, high, 1, mode);
791 rtx temp = expand_binop (word_mode, binoptab, op0_low, op1_xhigh,
792 NULL_RTX, 0, OPTAB_DIRECT);
796 product_piece = expand_binop (word_mode, add_optab, temp,
797 product_high, product_high,
799 if (product_piece != product_high)
800 emit_move_insn (product_high, product_piece);
802 temp = expand_binop (word_mode, binoptab, op1_low, op0_xhigh,
803 NULL_RTX, 0, OPTAB_DIRECT);
805 product_piece = expand_binop (word_mode, add_optab, temp,
806 product_high, product_high,
808 if (product_piece != product_high)
809 emit_move_insn (product_high, product_piece);
811 temp = emit_move_insn (product, product);
812 REG_NOTES (temp) = gen_rtx (EXPR_LIST, REG_EQUAL,
813 gen_rtx (MULT, mode, op0, op1),
820 /* If we get here, we couldn't do it for some reason even though we
821 originally thought we could. Delete anything we've emitted in
824 delete_insns_since (last);
827 /* It can't be open-coded in this mode.
828 Use a library call if one is available and caller says that's ok. */
830 if (binoptab->handlers[(int) mode].libfunc
831 && (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN))
834 rtx funexp = binoptab->handlers[(int) mode].libfunc;
838 /* Pass 1 for NO_QUEUE so we don't lose any increments
839 if the libcall is cse'd or moved. */
840 emit_library_call (binoptab->handlers[(int) mode].libfunc,
841 1, mode, 2, op0, mode, op1,
842 (shift_op ? word_mode : mode));
844 insns = get_insns ();
847 target = gen_reg_rtx (mode);
848 emit_libcall_block (insns, target, hard_libcall_value (mode),
849 gen_rtx (binoptab->code, mode, op0, op1));
854 delete_insns_since (last);
856 /* It can't be done in this mode. Can we do it in a wider mode? */
858 if (! (methods == OPTAB_WIDEN || methods == OPTAB_LIB_WIDEN
859 || methods == OPTAB_MUST_WIDEN))
860 return 0; /* Caller says, don't even try. */
862 /* Compute the value of METHODS to pass to recursive calls.
863 Don't allow widening to be tried recursively. */
865 methods = (methods == OPTAB_LIB_WIDEN ? OPTAB_LIB : OPTAB_DIRECT);
867 /* Look for a wider mode of the same class for which it appears we can do
870 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
872 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
873 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
875 if ((binoptab->handlers[(int) wider_mode].insn_code
877 || (methods == OPTAB_LIB
878 && binoptab->handlers[(int) wider_mode].libfunc))
880 rtx xop0 = op0, xop1 = op1;
883 /* For certain integer operations, we need not actually extend
884 the narrow operands, as long as we will truncate
885 the results to the same narrowness. Don't do this when
886 WIDER_MODE is wider than a word since a paradoxical SUBREG
887 isn't valid for such modes. */
889 if ((binoptab == ior_optab || binoptab == and_optab
890 || binoptab == xor_optab
891 || binoptab == add_optab || binoptab == sub_optab
892 || binoptab == smul_optab
893 || binoptab == ashl_optab || binoptab == lshl_optab)
895 && GET_MODE_SIZE (wider_mode) <= UNITS_PER_WORD)
898 /* If an operand is a constant integer, we might as well
899 convert it since that is more efficient than using a SUBREG,
900 unlike the case for other operands. */
902 if (no_extend && GET_MODE (xop0) != VOIDmode)
903 xop0 = gen_rtx (SUBREG, wider_mode,
904 force_reg (GET_MODE (xop0), xop0), 0);
906 xop0 = convert_to_mode (wider_mode, xop0, unsignedp);
908 if (no_extend && GET_MODE (xop1) != VOIDmode)
909 xop1 = gen_rtx (SUBREG, wider_mode,
910 force_reg (GET_MODE (xop1), xop1), 0);
912 xop1 = convert_to_mode (wider_mode, xop1, unsignedp);
914 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
918 if (class != MODE_INT)
921 target = gen_reg_rtx (mode);
922 convert_move (target, temp, 0);
926 return gen_lowpart (mode, temp);
929 delete_insns_since (last);
937 /* Expand a binary operator which has both signed and unsigned forms.
938 UOPTAB is the optab for unsigned operations, and SOPTAB is for
941 If we widen unsigned operands, we may use a signed wider operation instead
942 of an unsigned wider operation, since the result would be the same. */
945 sign_expand_binop (mode, uoptab, soptab, op0, op1, target, unsignedp, methods)
946 enum machine_mode mode;
947 optab uoptab, soptab;
948 rtx op0, op1, target;
950 enum optab_methods methods;
953 optab direct_optab = unsignedp ? uoptab : soptab;
954 struct optab wide_soptab;
956 /* Do it without widening, if possible. */
957 temp = expand_binop (mode, direct_optab, op0, op1, target,
958 unsignedp, OPTAB_DIRECT);
959 if (temp || methods == OPTAB_DIRECT)
962 /* Try widening to a signed int. Make a fake signed optab that
963 hides any signed insn for direct use. */
964 wide_soptab = *soptab;
965 wide_soptab.handlers[(int) mode].insn_code = CODE_FOR_nothing;
966 wide_soptab.handlers[(int) mode].libfunc = 0;
968 temp = expand_binop (mode, &wide_soptab, op0, op1, target,
969 unsignedp, OPTAB_WIDEN);
971 /* For unsigned operands, try widening to an unsigned int. */
972 if (temp == 0 && unsignedp)
973 temp = expand_binop (mode, uoptab, op0, op1, target,
974 unsignedp, OPTAB_WIDEN);
975 if (temp || methods == OPTAB_WIDEN)
978 /* Use the right width lib call if that exists. */
979 temp = expand_binop (mode, direct_optab, op0, op1, target, unsignedp, OPTAB_LIB);
980 if (temp || methods == OPTAB_LIB)
983 /* Must widen and use a lib call, use either signed or unsigned. */
984 temp = expand_binop (mode, &wide_soptab, op0, op1, target,
989 return expand_binop (mode, uoptab, op0, op1, target,
994 /* Generate code to perform an operation specified by BINOPTAB
995 on operands OP0 and OP1, with two results to TARG1 and TARG2.
996 We assume that the order of the operands for the instruction
997 is TARG0, OP0, OP1, TARG1, which would fit a pattern like
998 [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
1000 Either TARG0 or TARG1 may be zero, but what that means is that
1001 that result is not actually wanted. We will generate it into
1002 a dummy pseudo-reg and discard it. They may not both be zero.
1004 Returns 1 if this operation can be performed; 0 if not. */
1007 expand_twoval_binop (binoptab, op0, op1, targ0, targ1, unsignedp)
1013 enum machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
1014 enum mode_class class;
1015 enum machine_mode wider_mode;
1018 class = GET_MODE_CLASS (mode);
1020 op0 = protect_from_queue (op0, 0);
1021 op1 = protect_from_queue (op1, 0);
1025 op0 = force_not_mem (op0);
1026 op1 = force_not_mem (op1);
1029 /* If we are inside an appropriately-short loop and one operand is an
1030 expensive constant, force it into a register. */
1031 if (CONSTANT_P (op0) && preserve_subexpressions_p ()
1032 && rtx_cost (op0, binoptab->code) > 2)
1033 op0 = force_reg (mode, op0);
1035 if (CONSTANT_P (op1) && preserve_subexpressions_p ()
1036 && rtx_cost (op1, binoptab->code) > 2)
1037 op1 = force_reg (mode, op1);
1040 targ0 = protect_from_queue (targ0, 1);
1042 targ0 = gen_reg_rtx (mode);
1044 targ1 = protect_from_queue (targ1, 1);
1046 targ1 = gen_reg_rtx (mode);
1048 /* Record where to go back to if we fail. */
1049 last = get_last_insn ();
1051 if (binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1053 int icode = (int) binoptab->handlers[(int) mode].insn_code;
1054 enum machine_mode mode0 = insn_operand_mode[icode][1];
1055 enum machine_mode mode1 = insn_operand_mode[icode][2];
1057 rtx xop0 = op0, xop1 = op1;
1059 /* In case this insn wants input operands in modes different from the
1060 result, convert the operands. */
1061 if (GET_MODE (op0) != VOIDmode && GET_MODE (op0) != mode0)
1062 xop0 = convert_to_mode (mode0, xop0, unsignedp);
1064 if (GET_MODE (op1) != VOIDmode && GET_MODE (op1) != mode1)
1065 xop1 = convert_to_mode (mode1, xop1, unsignedp);
1067 /* Now, if insn doesn't accept these operands, put them into pseudos. */
1068 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
1069 xop0 = copy_to_mode_reg (mode0, xop0);
1071 if (! (*insn_operand_predicate[icode][2]) (xop1, mode1))
1072 xop1 = copy_to_mode_reg (mode1, xop1);
1074 /* We could handle this, but we should always be called with a pseudo
1075 for our targets and all insns should take them as outputs. */
1076 if (! (*insn_operand_predicate[icode][0]) (targ0, mode)
1077 || ! (*insn_operand_predicate[icode][3]) (targ1, mode))
1080 pat = GEN_FCN (icode) (targ0, xop0, xop1, targ1);
1087 delete_insns_since (last);
1090 /* It can't be done in this mode. Can we do it in a wider mode? */
1092 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1094 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1095 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1097 if (binoptab->handlers[(int) wider_mode].insn_code
1098 != CODE_FOR_nothing)
1100 register rtx t0 = gen_reg_rtx (wider_mode);
1101 register rtx t1 = gen_reg_rtx (wider_mode);
1103 if (expand_twoval_binop (binoptab,
1104 convert_to_mode (wider_mode, op0,
1106 convert_to_mode (wider_mode, op1,
1110 convert_move (targ0, t0, unsignedp);
1111 convert_move (targ1, t1, unsignedp);
1115 delete_insns_since (last);
1123 /* Generate code to perform an operation specified by UNOPTAB
1124 on operand OP0, with result having machine-mode MODE.
1126 UNSIGNEDP is for the case where we have to widen the operands
1127 to perform the operation. It says to use zero-extension.
1129 If TARGET is nonzero, the value
1130 is generated there, if it is convenient to do so.
1131 In all cases an rtx is returned for the locus of the value;
1132 this may or may not be TARGET. */
1135 expand_unop (mode, unoptab, op0, target, unsignedp)
1136 enum machine_mode mode;
1142 enum mode_class class;
1143 enum machine_mode wider_mode;
1145 rtx last = get_last_insn ();
1148 class = GET_MODE_CLASS (mode);
1150 op0 = protect_from_queue (op0, 0);
1154 op0 = force_not_mem (op0);
1158 target = protect_from_queue (target, 1);
1160 if (unoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1162 int icode = (int) unoptab->handlers[(int) mode].insn_code;
1163 enum machine_mode mode0 = insn_operand_mode[icode][1];
1169 temp = gen_reg_rtx (mode);
1171 if (GET_MODE (xop0) != VOIDmode
1172 && GET_MODE (xop0) != mode0)
1173 xop0 = convert_to_mode (mode0, xop0, unsignedp);
1175 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
1177 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
1178 xop0 = copy_to_mode_reg (mode0, xop0);
1180 if (! (*insn_operand_predicate[icode][0]) (temp, mode))
1181 temp = gen_reg_rtx (mode);
1183 pat = GEN_FCN (icode) (temp, xop0);
1186 if (GET_CODE (pat) == SEQUENCE
1187 && ! add_equal_note (pat, temp, unoptab->code, xop0, NULL_RTX))
1189 delete_insns_since (last);
1190 return expand_unop (mode, unoptab, op0, NULL_RTX, unsignedp);
1198 delete_insns_since (last);
1201 /* It can't be done in this mode. Can we open-code it in a wider mode? */
1203 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1204 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1205 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1207 if (unoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing)
1211 /* For certain operations, we need not actually extend
1212 the narrow operand, as long as we will truncate the
1213 results to the same narrowness. */
1215 if ((unoptab == neg_optab || unoptab == one_cmpl_optab)
1216 && GET_MODE_SIZE (wider_mode) <= UNITS_PER_WORD
1217 && class == MODE_INT)
1218 xop0 = gen_rtx (SUBREG, wider_mode, force_reg (mode, xop0), 0);
1220 xop0 = convert_to_mode (wider_mode, xop0, unsignedp);
1222 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
1227 if (class != MODE_INT)
1230 target = gen_reg_rtx (mode);
1231 convert_move (target, temp, 0);
1235 return gen_lowpart (mode, temp);
1238 delete_insns_since (last);
1242 /* These can be done a word at a time. */
1243 if (unoptab == one_cmpl_optab
1244 && class == MODE_INT
1245 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
1246 && unoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
1251 if (target == 0 || target == op0)
1252 target = gen_reg_rtx (mode);
1256 /* Do the actual arithmetic. */
1257 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
1259 rtx target_piece = operand_subword (target, i, 1, mode);
1260 rtx x = expand_unop (word_mode, unoptab,
1261 operand_subword_force (op0, i, mode),
1262 target_piece, unsignedp);
1263 if (target_piece != x)
1264 emit_move_insn (target_piece, x);
1267 insns = get_insns ();
1270 emit_no_conflict_block (insns, target, op0, NULL_RTX,
1271 gen_rtx (unoptab->code, mode, op0));
1275 if (unoptab->handlers[(int) mode].libfunc)
1278 rtx funexp = unoptab->handlers[(int) mode].libfunc;
1282 /* Pass 1 for NO_QUEUE so we don't lose any increments
1283 if the libcall is cse'd or moved. */
1284 emit_library_call (unoptab->handlers[(int) mode].libfunc,
1285 1, mode, 1, op0, mode);
1286 insns = get_insns ();
1289 target = gen_reg_rtx (mode);
1290 emit_libcall_block (insns, target, hard_libcall_value (mode),
1291 gen_rtx (unoptab->code, mode, op0));
1296 /* It can't be done in this mode. Can we do it in a wider mode? */
1298 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1300 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1301 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1303 if ((unoptab->handlers[(int) wider_mode].insn_code
1304 != CODE_FOR_nothing)
1305 || unoptab->handlers[(int) wider_mode].libfunc)
1309 /* For certain operations, we need not actually extend
1310 the narrow operand, as long as we will truncate the
1311 results to the same narrowness. */
1313 if ((unoptab == neg_optab || unoptab == one_cmpl_optab)
1314 && GET_MODE_SIZE (wider_mode) <= UNITS_PER_WORD
1315 && class == MODE_INT)
1316 xop0 = gen_rtx (SUBREG, wider_mode, force_reg (mode, xop0), 0);
1318 xop0 = convert_to_mode (wider_mode, xop0, unsignedp);
1320 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
1325 if (class != MODE_INT)
1328 target = gen_reg_rtx (mode);
1329 convert_move (target, temp, 0);
1333 return gen_lowpart (mode, temp);
1336 delete_insns_since (last);
1344 /* Generate an instruction whose insn-code is INSN_CODE,
1345 with two operands: an output TARGET and an input OP0.
1346 TARGET *must* be nonzero, and the output is always stored there.
1347 CODE is an rtx code such that (CODE OP0) is an rtx that describes
1348 the value that is stored into TARGET. */
1351 emit_unop_insn (icode, target, op0, code)
1358 enum machine_mode mode0 = insn_operand_mode[icode][1];
1361 temp = target = protect_from_queue (target, 1);
1363 op0 = protect_from_queue (op0, 0);
1366 op0 = force_not_mem (op0);
1368 /* Now, if insn does not accept our operands, put them into pseudos. */
1370 if (! (*insn_operand_predicate[icode][1]) (op0, mode0))
1371 op0 = copy_to_mode_reg (mode0, op0);
1373 if (! (*insn_operand_predicate[icode][0]) (temp, GET_MODE (temp))
1374 || (flag_force_mem && GET_CODE (temp) == MEM))
1375 temp = gen_reg_rtx (GET_MODE (temp));
1377 pat = GEN_FCN (icode) (temp, op0);
1379 if (GET_CODE (pat) == SEQUENCE && code != UNKNOWN)
1380 add_equal_note (pat, temp, code, op0, NULL_RTX);
1385 emit_move_insn (target, temp);
1388 /* Emit code to perform a series of operations on a multi-word quantity, one
1391 Such a block is preceded by a CLOBBER of the output, consists of multiple
1392 insns, each setting one word of the output, and followed by a SET copying
1393 the output to itself.
1395 Each of the insns setting words of the output receives a REG_NO_CONFLICT
1396 note indicating that it doesn't conflict with the (also multi-word)
1397 inputs. The entire block is surrounded by REG_LIBCALL and REG_RETVAL
1400 INSNS is a block of code generated to perform the operation, not including
1401 the CLOBBER and final copy. All insns that compute intermediate values
1402 are first emitted, followed by the block as described above. Only
1403 INSNs are allowed in the block; no library calls or jumps may be
1406 TARGET, OP0, and OP1 are the output and inputs of the operations,
1407 respectively. OP1 may be zero for a unary operation.
1409 EQUIV, if non-zero, is an expression to be placed into a REG_EQUAL note
1412 If TARGET is not a register, INSNS is simply emitted with no special
1415 The final insn emitted is returned. */
1418 emit_no_conflict_block (insns, target, op0, op1, equiv)
1424 rtx prev, next, first, last, insn;
1426 if (GET_CODE (target) != REG || reload_in_progress)
1427 return emit_insns (insns);
1429 /* First emit all insns that do not store into words of the output and remove
1430 these from the list. */
1431 for (insn = insns; insn; insn = next)
1436 next = NEXT_INSN (insn);
1438 if (GET_CODE (insn) != INSN)
1441 if (GET_CODE (PATTERN (insn)) == SET)
1442 set = PATTERN (insn);
1443 else if (GET_CODE (PATTERN (insn)) == PARALLEL)
1445 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
1446 if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET)
1448 set = XVECEXP (PATTERN (insn), 0, i);
1456 if (! reg_overlap_mentioned_p (target, SET_DEST (set)))
1458 if (PREV_INSN (insn))
1459 NEXT_INSN (PREV_INSN (insn)) = next;
1464 PREV_INSN (next) = PREV_INSN (insn);
1470 prev = get_last_insn ();
1472 /* Now write the CLOBBER of the output, followed by the setting of each
1473 of the words, followed by the final copy. */
1474 if (target != op0 && target != op1)
1475 emit_insn (gen_rtx (CLOBBER, VOIDmode, target));
1477 for (insn = insns; insn; insn = next)
1479 next = NEXT_INSN (insn);
1482 if (op1 && GET_CODE (op1) == REG)
1483 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_NO_CONFLICT, op1,
1486 if (op0 && GET_CODE (op0) == REG)
1487 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_NO_CONFLICT, op0,
1491 last = emit_move_insn (target, target);
1493 REG_NOTES (last) = gen_rtx (EXPR_LIST, REG_EQUAL, equiv, REG_NOTES (last));
1496 first = get_insns ();
1498 first = NEXT_INSN (prev);
1500 /* Encapsulate the block so it gets manipulated as a unit. */
1501 REG_NOTES (first) = gen_rtx (INSN_LIST, REG_LIBCALL, last,
1503 REG_NOTES (last) = gen_rtx (INSN_LIST, REG_RETVAL, first, REG_NOTES (last));
1508 /* Emit code to make a call to a constant function or a library call.
1510 INSNS is a list containing all insns emitted in the call.
1511 These insns leave the result in RESULT. Our block is to copy RESULT
1512 to TARGET, which is logically equivalent to EQUIV.
1514 We first emit any insns that set a pseudo on the assumption that these are
1515 loading constants into registers; doing so allows them to be safely cse'ed
1516 between blocks. Then we emit all the other insns in the block, followed by
1517 an insn to move RESULT to TARGET. This last insn will have a REQ_EQUAL
1518 note with an operand of EQUIV.
1520 Moving assignments to pseudos outside of the block is done to improve
1521 the generated code, but is not required to generate correct code,
1522 hence being unable to move an assignment is not grounds for not making
1523 a libcall block. There are two reasons why it is safe to leave these
1524 insns inside the block: First, we know that these pseudos cannot be
1525 used in generated RTL outside the block since they are created for
1526 temporary purposes within the block. Second, CSE will not record the
1527 values of anything set inside a libcall block, so we know they must
1528 be dead at the end of the block.
1530 Except for the first group of insns (the ones setting pseudos), the
1531 block is delimited by REG_RETVAL and REG_LIBCALL notes. */
1534 emit_libcall_block (insns, target, result, equiv)
1540 rtx prev, next, first, last, insn;
1542 /* First emit all insns that set pseudos. Remove them from the list as
1543 we go. Avoid insns that set pseudo which were referenced in previous
1544 insns. These can be generated by move_by_pieces, for example,
1545 to update an address. */
1547 for (insn = insns; insn; insn = next)
1549 rtx set = single_set (insn);
1551 next = NEXT_INSN (insn);
1553 if (set != 0 && GET_CODE (SET_DEST (set)) == REG
1554 && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER
1556 || (! reg_mentioned_p (SET_DEST (set), PATTERN (insns))
1557 && ! reg_used_between_p (SET_DEST (set), insns, insn))))
1559 if (PREV_INSN (insn))
1560 NEXT_INSN (PREV_INSN (insn)) = next;
1565 PREV_INSN (next) = PREV_INSN (insn);
1571 prev = get_last_insn ();
1573 /* Write the remaining insns followed by the final copy. */
1575 for (insn = insns; insn; insn = next)
1577 next = NEXT_INSN (insn);
1582 last = emit_move_insn (target, result);
1583 REG_NOTES (last) = gen_rtx (EXPR_LIST, REG_EQUAL, equiv, REG_NOTES (last));
1586 first = get_insns ();
1588 first = NEXT_INSN (prev);
1590 /* Encapsulate the block so it gets manipulated as a unit. */
1591 REG_NOTES (first) = gen_rtx (INSN_LIST, REG_LIBCALL, last,
1593 REG_NOTES (last) = gen_rtx (INSN_LIST, REG_RETVAL, first, REG_NOTES (last));
1596 /* Generate code to store zero in X. */
1602 emit_move_insn (x, const0_rtx);
1605 /* Generate code to store 1 in X
1606 assuming it contains zero beforehand. */
1609 emit_0_to_1_insn (x)
1612 emit_move_insn (x, const1_rtx);
1615 /* Generate code to compare X with Y
1616 so that the condition codes are set.
1618 MODE is the mode of the inputs (in case they are const_int).
1619 UNSIGNEDP nonzero says that X and Y are unsigned;
1620 this matters if they need to be widened.
1622 If they have mode BLKmode, then SIZE specifies the size of both X and Y,
1623 and ALIGN specifies the known shared alignment of X and Y.
1625 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).
1626 It is ignored for fixed-point and block comparisons;
1627 it is used only for floating-point comparisons. */
1630 emit_cmp_insn (x, y, comparison, size, mode, unsignedp, align)
1632 enum rtx_code comparison;
1634 enum machine_mode mode;
1638 enum mode_class class;
1639 enum machine_mode wider_mode;
1641 class = GET_MODE_CLASS (mode);
1643 /* They could both be VOIDmode if both args are immediate constants,
1644 but we should fold that at an earlier stage.
1645 With no special code here, this will call abort,
1646 reminding the programmer to implement such folding. */
1648 if (mode != BLKmode && flag_force_mem)
1650 x = force_not_mem (x);
1651 y = force_not_mem (y);
1654 /* If we are inside an appropriately-short loop and one operand is an
1655 expensive constant, force it into a register. */
1656 if (CONSTANT_P (x) && preserve_subexpressions_p () && rtx_cost (x, COMPARE) > 2)
1657 x = force_reg (mode, x);
1659 if (CONSTANT_P (y) && preserve_subexpressions_p () && rtx_cost (y, COMPARE) > 2)
1660 y = force_reg (mode, y);
1662 /* Don't let both operands fail to indicate the mode. */
1663 if (GET_MODE (x) == VOIDmode && GET_MODE (y) == VOIDmode)
1664 x = force_reg (mode, x);
1666 /* Handle all BLKmode compares. */
1668 if (mode == BLKmode)
1671 x = protect_from_queue (x, 0);
1672 y = protect_from_queue (y, 0);
1676 #ifdef HAVE_cmpstrqi
1678 && GET_CODE (size) == CONST_INT
1679 && INTVAL (size) < (1 << GET_MODE_BITSIZE (QImode)))
1681 enum machine_mode result_mode
1682 = insn_operand_mode[(int) CODE_FOR_cmpstrqi][0];
1683 rtx result = gen_reg_rtx (result_mode);
1684 emit_insn (gen_cmpstrqi (result, x, y, size, GEN_INT (align)));
1685 emit_cmp_insn (result, const0_rtx, comparison, NULL_RTX,
1690 #ifdef HAVE_cmpstrhi
1692 && GET_CODE (size) == CONST_INT
1693 && INTVAL (size) < (1 << GET_MODE_BITSIZE (HImode)))
1695 enum machine_mode result_mode
1696 = insn_operand_mode[(int) CODE_FOR_cmpstrhi][0];
1697 rtx result = gen_reg_rtx (result_mode);
1698 emit_insn (gen_cmpstrhi (result, x, y, size, GEN_INT (align)));
1699 emit_cmp_insn (result, const0_rtx, comparison, NULL_RTX,
1704 #ifdef HAVE_cmpstrsi
1707 enum machine_mode result_mode
1708 = insn_operand_mode[(int) CODE_FOR_cmpstrsi][0];
1709 rtx result = gen_reg_rtx (result_mode);
1710 size = protect_from_queue (size, 0);
1711 emit_insn (gen_cmpstrsi (result, x, y,
1712 convert_to_mode (SImode, size, 1),
1714 emit_cmp_insn (result, const0_rtx, comparison, NULL_RTX,
1720 #ifdef TARGET_MEM_FUNCTIONS
1721 emit_library_call (memcmp_libfunc, 0,
1722 TYPE_MODE (integer_type_node), 3,
1723 XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
1726 emit_library_call (bcmp_libfunc, 0,
1727 TYPE_MODE (integer_type_node), 3,
1728 XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
1731 emit_cmp_insn (hard_libcall_value (TYPE_MODE (integer_type_node)),
1732 const0_rtx, comparison, NULL_RTX,
1733 TYPE_MODE (integer_type_node), 0, 0);
1738 /* Handle some compares against zero. */
1740 if (y == CONST0_RTX (mode)
1741 && tst_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1743 int icode = (int) tst_optab->handlers[(int) mode].insn_code;
1746 x = protect_from_queue (x, 0);
1747 y = protect_from_queue (y, 0);
1749 /* Now, if insn does accept these operands, put them into pseudos. */
1750 if (! (*insn_operand_predicate[icode][0])
1751 (x, insn_operand_mode[icode][0]))
1752 x = copy_to_mode_reg (insn_operand_mode[icode][0], x);
1754 emit_insn (GEN_FCN (icode) (x));
1758 /* Handle compares for which there is a directly suitable insn. */
1760 if (cmp_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1762 int icode = (int) cmp_optab->handlers[(int) mode].insn_code;
1765 x = protect_from_queue (x, 0);
1766 y = protect_from_queue (y, 0);
1768 /* Now, if insn doesn't accept these operands, put them into pseudos. */
1769 if (! (*insn_operand_predicate[icode][0])
1770 (x, insn_operand_mode[icode][0]))
1771 x = copy_to_mode_reg (insn_operand_mode[icode][0], x);
1773 if (! (*insn_operand_predicate[icode][1])
1774 (y, insn_operand_mode[icode][1]))
1775 y = copy_to_mode_reg (insn_operand_mode[icode][1], y);
1777 emit_insn (GEN_FCN (icode) (x, y));
1781 /* Try widening if we can find a direct insn that way. */
1783 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1785 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1786 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1788 if (cmp_optab->handlers[(int) wider_mode].insn_code
1789 != CODE_FOR_nothing)
1791 x = protect_from_queue (x, 0);
1792 y = protect_from_queue (y, 0);
1793 x = convert_to_mode (wider_mode, x, unsignedp);
1794 y = convert_to_mode (wider_mode, y, unsignedp);
1795 emit_cmp_insn (x, y, comparison, NULL_RTX,
1796 wider_mode, unsignedp, align);
1802 /* Handle a lib call just for the mode we are using. */
1804 if (cmp_optab->handlers[(int) mode].libfunc
1805 && class != MODE_FLOAT)
1807 rtx libfunc = cmp_optab->handlers[(int) mode].libfunc;
1808 /* If we want unsigned, and this mode has a distinct unsigned
1809 comparison routine, use that. */
1810 if (unsignedp && ucmp_optab->handlers[(int) mode].libfunc)
1811 libfunc = ucmp_optab->handlers[(int) mode].libfunc;
1813 emit_library_call (libfunc, 1,
1814 SImode, 2, x, mode, y, mode);
1816 /* Integer comparison returns a result that must be compared against 1,
1817 so that even if we do an unsigned compare afterward,
1818 there is still a value that can represent the result "less than". */
1820 emit_cmp_insn (hard_libcall_value (SImode), const1_rtx,
1821 comparison, NULL_RTX, SImode, unsignedp, 0);
1825 if (class == MODE_FLOAT)
1826 emit_float_lib_cmp (x, y, comparison);
1832 /* Nonzero if a compare of mode MODE can be done straightforwardly
1833 (without splitting it into pieces). */
1836 can_compare_p (mode)
1837 enum machine_mode mode;
1841 if (cmp_optab->handlers[(int)mode].insn_code != CODE_FOR_nothing)
1843 mode = GET_MODE_WIDER_MODE (mode);
1844 } while (mode != VOIDmode);
1849 /* Emit a library call comparison between floating point X and Y.
1850 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */
1853 emit_float_lib_cmp (x, y, comparison)
1855 enum rtx_code comparison;
1857 enum machine_mode mode = GET_MODE (x);
1864 libfunc = eqsf2_libfunc;
1868 libfunc = nesf2_libfunc;
1872 libfunc = gtsf2_libfunc;
1876 libfunc = gesf2_libfunc;
1880 libfunc = ltsf2_libfunc;
1884 libfunc = lesf2_libfunc;
1887 else if (mode == DFmode)
1891 libfunc = eqdf2_libfunc;
1895 libfunc = nedf2_libfunc;
1899 libfunc = gtdf2_libfunc;
1903 libfunc = gedf2_libfunc;
1907 libfunc = ltdf2_libfunc;
1911 libfunc = ledf2_libfunc;
1914 else if (mode == XFmode)
1918 libfunc = eqxf2_libfunc;
1922 libfunc = nexf2_libfunc;
1926 libfunc = gtxf2_libfunc;
1930 libfunc = gexf2_libfunc;
1934 libfunc = ltxf2_libfunc;
1938 libfunc = lexf2_libfunc;
1941 else if (mode == TFmode)
1945 libfunc = eqtf2_libfunc;
1949 libfunc = netf2_libfunc;
1953 libfunc = gttf2_libfunc;
1957 libfunc = getf2_libfunc;
1961 libfunc = lttf2_libfunc;
1965 libfunc = letf2_libfunc;
1970 enum machine_mode wider_mode;
1972 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1973 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1975 if ((cmp_optab->handlers[(int) wider_mode].insn_code
1976 != CODE_FOR_nothing)
1977 || (cmp_optab->handlers[(int) wider_mode].libfunc != 0))
1979 x = protect_from_queue (x, 0);
1980 y = protect_from_queue (y, 0);
1981 x = convert_to_mode (wider_mode, x, 0);
1982 y = convert_to_mode (wider_mode, y, 0);
1983 emit_float_lib_cmp (x, y, comparison);
1990 emit_library_call (libfunc, 1,
1991 SImode, 2, x, mode, y, mode);
1993 emit_cmp_insn (hard_libcall_value (SImode), const0_rtx, comparison,
1994 NULL_RTX, SImode, 0, 0);
1997 /* Generate code to indirectly jump to a location given in the rtx LOC. */
2000 emit_indirect_jump (loc)
2003 if (! ((*insn_operand_predicate[(int)CODE_FOR_indirect_jump][0])
2005 loc = copy_to_mode_reg (insn_operand_mode[(int)CODE_FOR_indirect_jump][0],
2008 emit_jump_insn (gen_indirect_jump (loc));
2012 /* These three functions generate an insn body and return it
2013 rather than emitting the insn.
2015 They do not protect from queued increments,
2016 because they may be used 1) in protect_from_queue itself
2017 and 2) in other passes where there is no queue. */
2019 /* Generate and return an insn body to add Y to X. */
2022 gen_add2_insn (x, y)
2025 int icode = (int) add_optab->handlers[(int) GET_MODE (x)].insn_code;
2027 if (! (*insn_operand_predicate[icode][0]) (x, insn_operand_mode[icode][0])
2028 || ! (*insn_operand_predicate[icode][1]) (x, insn_operand_mode[icode][1])
2029 || ! (*insn_operand_predicate[icode][2]) (y, insn_operand_mode[icode][2]))
2032 return (GEN_FCN (icode) (x, x, y));
2036 have_add2_insn (mode)
2037 enum machine_mode mode;
2039 return add_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
2042 /* Generate and return an insn body to subtract Y from X. */
2045 gen_sub2_insn (x, y)
2048 int icode = (int) sub_optab->handlers[(int) GET_MODE (x)].insn_code;
2050 if (! (*insn_operand_predicate[icode][0]) (x, insn_operand_mode[icode][0])
2051 || ! (*insn_operand_predicate[icode][1]) (x, insn_operand_mode[icode][1])
2052 || ! (*insn_operand_predicate[icode][2]) (y, insn_operand_mode[icode][2]))
2055 return (GEN_FCN (icode) (x, x, y));
2059 have_sub2_insn (mode)
2060 enum machine_mode mode;
2062 return sub_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
2065 /* Generate the body of an instruction to copy Y into X. */
2068 gen_move_insn (x, y)
2071 register enum machine_mode mode = GET_MODE (x);
2072 enum insn_code insn_code;
2074 if (mode == VOIDmode)
2075 mode = GET_MODE (y);
2077 insn_code = mov_optab->handlers[(int) mode].insn_code;
2079 /* Handle MODE_CC modes: If we don't have a special move insn for this mode,
2080 find a mode to do it in. If we have a movcc, use it. Otherwise,
2081 find the MODE_INT mode of the same width. */
2083 if (insn_code == CODE_FOR_nothing)
2085 enum machine_mode tmode = VOIDmode;
2088 if (GET_MODE_CLASS (mode) == MODE_CC && mode != CCmode
2089 && mov_optab->handlers[(int) CCmode].insn_code != CODE_FOR_nothing)
2091 else if (GET_MODE_CLASS (mode) == MODE_CC)
2092 for (tmode = QImode; tmode != VOIDmode;
2093 tmode = GET_MODE_WIDER_MODE (tmode))
2094 if (GET_MODE_SIZE (tmode) == GET_MODE_SIZE (mode))
2097 if (tmode == VOIDmode)
2100 /* Get X and Y in TMODE. We can't use gen_lowpart here because it
2101 may call change_address which is not appropriate if we were
2102 called when a reload was in progress. We don't have to worry
2103 about changing the address since the size in bytes is supposed to
2104 be the same. Copy the MEM to change the mode and move any
2105 substitutions from the old MEM to the new one. */
2107 if (reload_in_progress)
2109 x = gen_lowpart_common (tmode, x1);
2110 if (x == 0 && GET_CODE (x1) == MEM)
2112 x = gen_rtx (MEM, tmode, XEXP (x1, 0));
2113 RTX_UNCHANGING_P (x) = RTX_UNCHANGING_P (x1);
2114 MEM_IN_STRUCT_P (x) = MEM_IN_STRUCT_P (x1);
2115 MEM_VOLATILE_P (x) = MEM_VOLATILE_P (x1);
2116 copy_replacements (x1, x);
2119 y = gen_lowpart_common (tmode, y1);
2120 if (y == 0 && GET_CODE (y1) == MEM)
2122 y = gen_rtx (MEM, tmode, XEXP (y1, 0));
2123 RTX_UNCHANGING_P (y) = RTX_UNCHANGING_P (y1);
2124 MEM_IN_STRUCT_P (y) = MEM_IN_STRUCT_P (y1);
2125 MEM_VOLATILE_P (y) = MEM_VOLATILE_P (y1);
2126 copy_replacements (y1, y);
2131 x = gen_lowpart (tmode, x);
2132 y = gen_lowpart (tmode, y);
2135 insn_code = mov_optab->handlers[(int) tmode].insn_code;
2138 return (GEN_FCN (insn_code) (x, y));
2141 /* Tables of patterns for extending one integer mode to another. */
2142 static enum insn_code extendtab[MAX_MACHINE_MODE][MAX_MACHINE_MODE][2];
2144 /* Return the insn code used to extend FROM_MODE to TO_MODE.
2145 UNSIGNEDP specifies zero-extension instead of sign-extension. If
2146 no such operation exists, CODE_FOR_nothing will be returned. */
2149 can_extend_p (to_mode, from_mode, unsignedp)
2150 enum machine_mode to_mode, from_mode;
2153 return extendtab[(int) to_mode][(int) from_mode][unsignedp];
2156 /* Generate the body of an insn to extend Y (with mode MFROM)
2157 into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */
2160 gen_extend_insn (x, y, mto, mfrom, unsignedp)
2162 enum machine_mode mto, mfrom;
2165 return (GEN_FCN (extendtab[(int) mto][(int) mfrom][unsignedp]) (x, y));
2173 for (p = extendtab[0][0];
2174 p < extendtab[0][0] + sizeof extendtab / sizeof extendtab[0][0][0];
2176 *p = CODE_FOR_nothing;
2178 #ifdef HAVE_extendditi2
2179 if (HAVE_extendditi2)
2180 extendtab[(int) TImode][(int) DImode][0] = CODE_FOR_extendditi2;
2182 #ifdef HAVE_extendsiti2
2183 if (HAVE_extendsiti2)
2184 extendtab[(int) TImode][(int) SImode][0] = CODE_FOR_extendsiti2;
2186 #ifdef HAVE_extendhiti2
2187 if (HAVE_extendhiti2)
2188 extendtab[(int) TImode][(int) HImode][0] = CODE_FOR_extendhiti2;
2190 #ifdef HAVE_extendqiti2
2191 if (HAVE_extendqiti2)
2192 extendtab[(int) TImode][(int) QImode][0] = CODE_FOR_extendqiti2;
2194 #ifdef HAVE_extendsidi2
2195 if (HAVE_extendsidi2)
2196 extendtab[(int) DImode][(int) SImode][0] = CODE_FOR_extendsidi2;
2198 #ifdef HAVE_extendhidi2
2199 if (HAVE_extendhidi2)
2200 extendtab[(int) DImode][(int) HImode][0] = CODE_FOR_extendhidi2;
2202 #ifdef HAVE_extendqidi2
2203 if (HAVE_extendqidi2)
2204 extendtab[(int) DImode][(int) QImode][0] = CODE_FOR_extendqidi2;
2206 #ifdef HAVE_extendhisi2
2207 if (HAVE_extendhisi2)
2208 extendtab[(int) SImode][(int) HImode][0] = CODE_FOR_extendhisi2;
2210 #ifdef HAVE_extendqisi2
2211 if (HAVE_extendqisi2)
2212 extendtab[(int) SImode][(int) QImode][0] = CODE_FOR_extendqisi2;
2214 #ifdef HAVE_extendqihi2
2215 if (HAVE_extendqihi2)
2216 extendtab[(int) HImode][(int) QImode][0] = CODE_FOR_extendqihi2;
2219 #ifdef HAVE_zero_extendditi2
2220 if (HAVE_zero_extendsiti2)
2221 extendtab[(int) TImode][(int) DImode][1] = CODE_FOR_zero_extendditi2;
2223 #ifdef HAVE_zero_extendsiti2
2224 if (HAVE_zero_extendsiti2)
2225 extendtab[(int) TImode][(int) SImode][1] = CODE_FOR_zero_extendsiti2;
2227 #ifdef HAVE_zero_extendhiti2
2228 if (HAVE_zero_extendhiti2)
2229 extendtab[(int) TImode][(int) HImode][1] = CODE_FOR_zero_extendhiti2;
2231 #ifdef HAVE_zero_extendqiti2
2232 if (HAVE_zero_extendqiti2)
2233 extendtab[(int) TImode][(int) QImode][1] = CODE_FOR_zero_extendqiti2;
2235 #ifdef HAVE_zero_extendsidi2
2236 if (HAVE_zero_extendsidi2)
2237 extendtab[(int) DImode][(int) SImode][1] = CODE_FOR_zero_extendsidi2;
2239 #ifdef HAVE_zero_extendhidi2
2240 if (HAVE_zero_extendhidi2)
2241 extendtab[(int) DImode][(int) HImode][1] = CODE_FOR_zero_extendhidi2;
2243 #ifdef HAVE_zero_extendqidi2
2244 if (HAVE_zero_extendqidi2)
2245 extendtab[(int) DImode][(int) QImode][1] = CODE_FOR_zero_extendqidi2;
2247 #ifdef HAVE_zero_extendhisi2
2248 if (HAVE_zero_extendhisi2)
2249 extendtab[(int) SImode][(int) HImode][1] = CODE_FOR_zero_extendhisi2;
2251 #ifdef HAVE_zero_extendqisi2
2252 if (HAVE_zero_extendqisi2)
2253 extendtab[(int) SImode][(int) QImode][1] = CODE_FOR_zero_extendqisi2;
2255 #ifdef HAVE_zero_extendqihi2
2256 if (HAVE_zero_extendqihi2)
2257 extendtab[(int) HImode][(int) QImode][1] = CODE_FOR_zero_extendqihi2;
2261 /* can_fix_p and can_float_p say whether the target machine
2262 can directly convert a given fixed point type to
2263 a given floating point type, or vice versa.
2264 The returned value is the CODE_FOR_... value to use,
2265 or CODE_FOR_nothing if these modes cannot be directly converted. */
2267 static enum insn_code fixtab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
2268 static enum insn_code fixtrunctab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
2269 static enum insn_code floattab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
2271 /* *TRUNCP_PTR is set to 1 if it is necessary to output
2272 an explicit FTRUNC insn before the fix insn; otherwise 0. */
2274 static enum insn_code
2275 can_fix_p (fixmode, fltmode, unsignedp, truncp_ptr)
2276 enum machine_mode fltmode, fixmode;
2281 if (fixtrunctab[(int) fltmode][(int) fixmode][unsignedp] != CODE_FOR_nothing)
2282 return fixtrunctab[(int) fltmode][(int) fixmode][unsignedp];
2284 if (ftrunc_optab->handlers[(int) fltmode].insn_code != CODE_FOR_nothing)
2287 return fixtab[(int) fltmode][(int) fixmode][unsignedp];
2289 return CODE_FOR_nothing;
2292 static enum insn_code
2293 can_float_p (fltmode, fixmode, unsignedp)
2294 enum machine_mode fixmode, fltmode;
2297 return floattab[(int) fltmode][(int) fixmode][unsignedp];
2304 for (p = fixtab[0][0];
2305 p < fixtab[0][0] + sizeof fixtab / sizeof (fixtab[0][0][0]);
2307 *p = CODE_FOR_nothing;
2308 for (p = fixtrunctab[0][0];
2309 p < fixtrunctab[0][0] + sizeof fixtrunctab / sizeof (fixtrunctab[0][0][0]);
2311 *p = CODE_FOR_nothing;
2313 #ifdef HAVE_fixsfqi2
2315 fixtab[(int) SFmode][(int) QImode][0] = CODE_FOR_fixsfqi2;
2317 #ifdef HAVE_fixsfhi2
2319 fixtab[(int) SFmode][(int) HImode][0] = CODE_FOR_fixsfhi2;
2321 #ifdef HAVE_fixsfsi2
2323 fixtab[(int) SFmode][(int) SImode][0] = CODE_FOR_fixsfsi2;
2325 #ifdef HAVE_fixsfdi2
2327 fixtab[(int) SFmode][(int) DImode][0] = CODE_FOR_fixsfdi2;
2330 #ifdef HAVE_fixdfqi2
2332 fixtab[(int) DFmode][(int) QImode][0] = CODE_FOR_fixdfqi2;
2334 #ifdef HAVE_fixdfhi2
2336 fixtab[(int) DFmode][(int) HImode][0] = CODE_FOR_fixdfhi2;
2338 #ifdef HAVE_fixdfsi2
2340 fixtab[(int) DFmode][(int) SImode][0] = CODE_FOR_fixdfsi2;
2342 #ifdef HAVE_fixdfdi2
2344 fixtab[(int) DFmode][(int) DImode][0] = CODE_FOR_fixdfdi2;
2346 #ifdef HAVE_fixdfti2
2348 fixtab[(int) DFmode][(int) TImode][0] = CODE_FOR_fixdfti2;
2351 #ifdef HAVE_fixxfqi2
2353 fixtab[(int) XFmode][(int) QImode][0] = CODE_FOR_fixxfqi2;
2355 #ifdef HAVE_fixxfhi2
2357 fixtab[(int) XFmode][(int) HImode][0] = CODE_FOR_fixxfhi2;
2359 #ifdef HAVE_fixxfsi2
2361 fixtab[(int) XFmode][(int) SImode][0] = CODE_FOR_fixxfsi2;
2363 #ifdef HAVE_fixxfdi2
2365 fixtab[(int) XFmode][(int) DImode][0] = CODE_FOR_fixxfdi2;
2367 #ifdef HAVE_fixxfti2
2369 fixtab[(int) XFmode][(int) TImode][0] = CODE_FOR_fixxfti2;
2372 #ifdef HAVE_fixtfqi2
2374 fixtab[(int) TFmode][(int) QImode][0] = CODE_FOR_fixtfqi2;
2376 #ifdef HAVE_fixtfhi2
2378 fixtab[(int) TFmode][(int) HImode][0] = CODE_FOR_fixtfhi2;
2380 #ifdef HAVE_fixtfsi2
2382 fixtab[(int) TFmode][(int) SImode][0] = CODE_FOR_fixtfsi2;
2384 #ifdef HAVE_fixtfdi2
2386 fixtab[(int) TFmode][(int) DImode][0] = CODE_FOR_fixtfdi2;
2388 #ifdef HAVE_fixtfti2
2390 fixtab[(int) TFmode][(int) TImode][0] = CODE_FOR_fixtfti2;
2393 #ifdef HAVE_fixunssfqi2
2394 if (HAVE_fixunssfqi2)
2395 fixtab[(int) SFmode][(int) QImode][1] = CODE_FOR_fixunssfqi2;
2397 #ifdef HAVE_fixunssfhi2
2398 if (HAVE_fixunssfhi2)
2399 fixtab[(int) SFmode][(int) HImode][1] = CODE_FOR_fixunssfhi2;
2401 #ifdef HAVE_fixunssfsi2
2402 if (HAVE_fixunssfsi2)
2403 fixtab[(int) SFmode][(int) SImode][1] = CODE_FOR_fixunssfsi2;
2405 #ifdef HAVE_fixunssfdi2
2406 if (HAVE_fixunssfdi2)
2407 fixtab[(int) SFmode][(int) DImode][1] = CODE_FOR_fixunssfdi2;
2410 #ifdef HAVE_fixunsdfqi2
2411 if (HAVE_fixunsdfqi2)
2412 fixtab[(int) DFmode][(int) QImode][1] = CODE_FOR_fixunsdfqi2;
2414 #ifdef HAVE_fixunsdfhi2
2415 if (HAVE_fixunsdfhi2)
2416 fixtab[(int) DFmode][(int) HImode][1] = CODE_FOR_fixunsdfhi2;
2418 #ifdef HAVE_fixunsdfsi2
2419 if (HAVE_fixunsdfsi2)
2420 fixtab[(int) DFmode][(int) SImode][1] = CODE_FOR_fixunsdfsi2;
2422 #ifdef HAVE_fixunsdfdi2
2423 if (HAVE_fixunsdfdi2)
2424 fixtab[(int) DFmode][(int) DImode][1] = CODE_FOR_fixunsdfdi2;
2426 #ifdef HAVE_fixunsdfti2
2427 if (HAVE_fixunsdfti2)
2428 fixtab[(int) DFmode][(int) TImode][1] = CODE_FOR_fixunsdfti2;
2431 #ifdef HAVE_fixunsxfqi2
2432 if (HAVE_fixunsxfqi2)
2433 fixtab[(int) XFmode][(int) QImode][1] = CODE_FOR_fixunsxfqi2;
2435 #ifdef HAVE_fixunsxfhi2
2436 if (HAVE_fixunsxfhi2)
2437 fixtab[(int) XFmode][(int) HImode][1] = CODE_FOR_fixunsxfhi2;
2439 #ifdef HAVE_fixunsxfsi2
2440 if (HAVE_fixunsxfsi2)
2441 fixtab[(int) XFmode][(int) SImode][1] = CODE_FOR_fixunsxfsi2;
2443 #ifdef HAVE_fixunsxfdi2
2444 if (HAVE_fixunsxfdi2)
2445 fixtab[(int) XFmode][(int) DImode][1] = CODE_FOR_fixunsxfdi2;
2447 #ifdef HAVE_fixunsxfti2
2448 if (HAVE_fixunsxfti2)
2449 fixtab[(int) XFmode][(int) TImode][1] = CODE_FOR_fixunsxfti2;
2452 #ifdef HAVE_fixunstfqi2
2453 if (HAVE_fixunstfqi2)
2454 fixtab[(int) TFmode][(int) QImode][1] = CODE_FOR_fixunstfqi2;
2456 #ifdef HAVE_fixunstfhi2
2457 if (HAVE_fixunstfhi2)
2458 fixtab[(int) TFmode][(int) HImode][1] = CODE_FOR_fixunstfhi2;
2460 #ifdef HAVE_fixunstfsi2
2461 if (HAVE_fixunstfsi2)
2462 fixtab[(int) TFmode][(int) SImode][1] = CODE_FOR_fixunstfsi2;
2464 #ifdef HAVE_fixunstfdi2
2465 if (HAVE_fixunstfdi2)
2466 fixtab[(int) TFmode][(int) DImode][1] = CODE_FOR_fixunstfdi2;
2468 #ifdef HAVE_fixunstfti2
2469 if (HAVE_fixunstfti2)
2470 fixtab[(int) TFmode][(int) TImode][1] = CODE_FOR_fixunstfti2;
2473 #ifdef HAVE_fix_truncsfqi2
2474 if (HAVE_fix_truncsfqi2)
2475 fixtrunctab[(int) SFmode][(int) QImode][0] = CODE_FOR_fix_truncsfqi2;
2477 #ifdef HAVE_fix_truncsfhi2
2478 if (HAVE_fix_truncsfhi2)
2479 fixtrunctab[(int) SFmode][(int) HImode][0] = CODE_FOR_fix_truncsfhi2;
2481 #ifdef HAVE_fix_truncsfsi2
2482 if (HAVE_fix_truncsfsi2)
2483 fixtrunctab[(int) SFmode][(int) SImode][0] = CODE_FOR_fix_truncsfsi2;
2485 #ifdef HAVE_fix_truncsfdi2
2486 if (HAVE_fix_truncsfdi2)
2487 fixtrunctab[(int) SFmode][(int) DImode][0] = CODE_FOR_fix_truncsfdi2;
2490 #ifdef HAVE_fix_truncdfqi2
2491 if (HAVE_fix_truncdfsi2)
2492 fixtrunctab[(int) DFmode][(int) QImode][0] = CODE_FOR_fix_truncdfqi2;
2494 #ifdef HAVE_fix_truncdfhi2
2495 if (HAVE_fix_truncdfhi2)
2496 fixtrunctab[(int) DFmode][(int) HImode][0] = CODE_FOR_fix_truncdfhi2;
2498 #ifdef HAVE_fix_truncdfsi2
2499 if (HAVE_fix_truncdfsi2)
2500 fixtrunctab[(int) DFmode][(int) SImode][0] = CODE_FOR_fix_truncdfsi2;
2502 #ifdef HAVE_fix_truncdfdi2
2503 if (HAVE_fix_truncdfdi2)
2504 fixtrunctab[(int) DFmode][(int) DImode][0] = CODE_FOR_fix_truncdfdi2;
2506 #ifdef HAVE_fix_truncdfti2
2507 if (HAVE_fix_truncdfti2)
2508 fixtrunctab[(int) DFmode][(int) TImode][0] = CODE_FOR_fix_truncdfti2;
2511 #ifdef HAVE_fix_truncxfqi2
2512 if (HAVE_fix_truncxfqi2)
2513 fixtrunctab[(int) XFmode][(int) QImode][0] = CODE_FOR_fix_truncxfqi2;
2515 #ifdef HAVE_fix_truncxfhi2
2516 if (HAVE_fix_truncxfhi2)
2517 fixtrunctab[(int) XFmode][(int) HImode][0] = CODE_FOR_fix_truncxfhi2;
2519 #ifdef HAVE_fix_truncxfsi2
2520 if (HAVE_fix_truncxfsi2)
2521 fixtrunctab[(int) XFmode][(int) SImode][0] = CODE_FOR_fix_truncxfsi2;
2523 #ifdef HAVE_fix_truncxfdi2
2524 if (HAVE_fix_truncxfdi2)
2525 fixtrunctab[(int) XFmode][(int) DImode][0] = CODE_FOR_fix_truncxfdi2;
2527 #ifdef HAVE_fix_truncxfti2
2528 if (HAVE_fix_truncxfti2)
2529 fixtrunctab[(int) XFmode][(int) TImode][0] = CODE_FOR_fix_truncxfti2;
2532 #ifdef HAVE_fix_trunctfqi2
2533 if (HAVE_fix_trunctfqi2)
2534 fixtrunctab[(int) TFmode][(int) QImode][0] = CODE_FOR_fix_trunctfqi2;
2536 #ifdef HAVE_fix_trunctfhi2
2537 if (HAVE_fix_trunctfhi2)
2538 fixtrunctab[(int) TFmode][(int) HImode][0] = CODE_FOR_fix_trunctfhi2;
2540 #ifdef HAVE_fix_trunctfsi2
2541 if (HAVE_fix_trunctfsi2)
2542 fixtrunctab[(int) TFmode][(int) SImode][0] = CODE_FOR_fix_trunctfsi2;
2544 #ifdef HAVE_fix_trunctfdi2
2545 if (HAVE_fix_trunctfdi2)
2546 fixtrunctab[(int) TFmode][(int) DImode][0] = CODE_FOR_fix_trunctfdi2;
2548 #ifdef HAVE_fix_trunctfti2
2549 if (HAVE_fix_trunctfti2)
2550 fixtrunctab[(int) TFmode][(int) TImode][0] = CODE_FOR_fix_trunctfti2;
2553 #ifdef HAVE_fixuns_truncsfqi2
2554 if (HAVE_fixuns_truncsfqi2)
2555 fixtrunctab[(int) SFmode][(int) QImode][1] = CODE_FOR_fixuns_truncsfqi2;
2557 #ifdef HAVE_fixuns_truncsfhi2
2558 if (HAVE_fixuns_truncsfhi2)
2559 fixtrunctab[(int) SFmode][(int) HImode][1] = CODE_FOR_fixuns_truncsfhi2;
2561 #ifdef HAVE_fixuns_truncsfsi2
2562 if (HAVE_fixuns_truncsfsi2)
2563 fixtrunctab[(int) SFmode][(int) SImode][1] = CODE_FOR_fixuns_truncsfsi2;
2565 #ifdef HAVE_fixuns_truncsfdi2
2566 if (HAVE_fixuns_truncsfdi2)
2567 fixtrunctab[(int) SFmode][(int) DImode][1] = CODE_FOR_fixuns_truncsfdi2;
2570 #ifdef HAVE_fixuns_truncdfqi2
2571 if (HAVE_fixuns_truncdfqi2)
2572 fixtrunctab[(int) DFmode][(int) QImode][1] = CODE_FOR_fixuns_truncdfqi2;
2574 #ifdef HAVE_fixuns_truncdfhi2
2575 if (HAVE_fixuns_truncdfhi2)
2576 fixtrunctab[(int) DFmode][(int) HImode][1] = CODE_FOR_fixuns_truncdfhi2;
2578 #ifdef HAVE_fixuns_truncdfsi2
2579 if (HAVE_fixuns_truncdfsi2)
2580 fixtrunctab[(int) DFmode][(int) SImode][1] = CODE_FOR_fixuns_truncdfsi2;
2582 #ifdef HAVE_fixuns_truncdfdi2
2583 if (HAVE_fixuns_truncdfdi2)
2584 fixtrunctab[(int) DFmode][(int) DImode][1] = CODE_FOR_fixuns_truncdfdi2;
2586 #ifdef HAVE_fixuns_truncdfti2
2587 if (HAVE_fixuns_truncdfti2)
2588 fixtrunctab[(int) DFmode][(int) TImode][1] = CODE_FOR_fixuns_truncdfti2;
2591 #ifdef HAVE_fixuns_truncxfqi2
2592 if (HAVE_fixuns_truncxfqi2)
2593 fixtrunctab[(int) XFmode][(int) QImode][1] = CODE_FOR_fixuns_truncxfqi2;
2595 #ifdef HAVE_fixuns_truncxfhi2
2596 if (HAVE_fixuns_truncxfhi2)
2597 fixtrunctab[(int) XFmode][(int) HImode][1] = CODE_FOR_fixuns_truncxfhi2;
2599 #ifdef HAVE_fixuns_truncxfsi2
2600 if (HAVE_fixuns_truncxfsi2)
2601 fixtrunctab[(int) XFmode][(int) SImode][1] = CODE_FOR_fixuns_truncxfsi2;
2603 #ifdef HAVE_fixuns_truncxfdi2
2604 if (HAVE_fixuns_truncxfdi2)
2605 fixtrunctab[(int) XFmode][(int) DImode][1] = CODE_FOR_fixuns_truncxfdi2;
2607 #ifdef HAVE_fixuns_truncxfti2
2608 if (HAVE_fixuns_truncxfti2)
2609 fixtrunctab[(int) XFmode][(int) TImode][1] = CODE_FOR_fixuns_truncxfti2;
2612 #ifdef HAVE_fixuns_trunctfqi2
2613 if (HAVE_fixuns_trunctfqi2)
2614 fixtrunctab[(int) TFmode][(int) QImode][1] = CODE_FOR_fixuns_trunctfqi2;
2616 #ifdef HAVE_fixuns_trunctfhi2
2617 if (HAVE_fixuns_trunctfhi2)
2618 fixtrunctab[(int) TFmode][(int) HImode][1] = CODE_FOR_fixuns_trunctfhi2;
2620 #ifdef HAVE_fixuns_trunctfsi2
2621 if (HAVE_fixuns_trunctfsi2)
2622 fixtrunctab[(int) TFmode][(int) SImode][1] = CODE_FOR_fixuns_trunctfsi2;
2624 #ifdef HAVE_fixuns_trunctfdi2
2625 if (HAVE_fixuns_trunctfdi2)
2626 fixtrunctab[(int) TFmode][(int) DImode][1] = CODE_FOR_fixuns_trunctfdi2;
2628 #ifdef HAVE_fixuns_trunctfti2
2629 if (HAVE_fixuns_trunctfti2)
2630 fixtrunctab[(int) TFmode][(int) TImode][1] = CODE_FOR_fixuns_trunctfti2;
2633 #ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC
2634 /* This flag says the same insns that convert to a signed fixnum
2635 also convert validly to an unsigned one. */
2639 for (i = 0; i < NUM_MACHINE_MODES; i++)
2640 for (j = 0; j < NUM_MACHINE_MODES; j++)
2641 fixtrunctab[i][j][1] = fixtrunctab[i][j][0];
2650 for (p = floattab[0][0];
2651 p < floattab[0][0] + sizeof floattab / sizeof (floattab[0][0][0]);
2653 *p = CODE_FOR_nothing;
2655 #ifdef HAVE_floatqisf2
2656 if (HAVE_floatqisf2)
2657 floattab[(int) SFmode][(int) QImode][0] = CODE_FOR_floatqisf2;
2659 #ifdef HAVE_floathisf2
2660 if (HAVE_floathisf2)
2661 floattab[(int) SFmode][(int) HImode][0] = CODE_FOR_floathisf2;
2663 #ifdef HAVE_floatsisf2
2664 if (HAVE_floatsisf2)
2665 floattab[(int) SFmode][(int) SImode][0] = CODE_FOR_floatsisf2;
2667 #ifdef HAVE_floatdisf2
2668 if (HAVE_floatdisf2)
2669 floattab[(int) SFmode][(int) DImode][0] = CODE_FOR_floatdisf2;
2671 #ifdef HAVE_floattisf2
2672 if (HAVE_floattisf2)
2673 floattab[(int) SFmode][(int) TImode][0] = CODE_FOR_floattisf2;
2676 #ifdef HAVE_floatqidf2
2677 if (HAVE_floatqidf2)
2678 floattab[(int) DFmode][(int) QImode][0] = CODE_FOR_floatqidf2;
2680 #ifdef HAVE_floathidf2
2681 if (HAVE_floathidf2)
2682 floattab[(int) DFmode][(int) HImode][0] = CODE_FOR_floathidf2;
2684 #ifdef HAVE_floatsidf2
2685 if (HAVE_floatsidf2)
2686 floattab[(int) DFmode][(int) SImode][0] = CODE_FOR_floatsidf2;
2688 #ifdef HAVE_floatdidf2
2689 if (HAVE_floatdidf2)
2690 floattab[(int) DFmode][(int) DImode][0] = CODE_FOR_floatdidf2;
2692 #ifdef HAVE_floattidf2
2693 if (HAVE_floattidf2)
2694 floattab[(int) DFmode][(int) TImode][0] = CODE_FOR_floattidf2;
2697 #ifdef HAVE_floatqixf2
2698 if (HAVE_floatqixf2)
2699 floattab[(int) XFmode][(int) QImode][0] = CODE_FOR_floatqixf2;
2701 #ifdef HAVE_floathixf2
2702 if (HAVE_floathixf2)
2703 floattab[(int) XFmode][(int) HImode][0] = CODE_FOR_floathixf2;
2705 #ifdef HAVE_floatsixf2
2706 if (HAVE_floatsixf2)
2707 floattab[(int) XFmode][(int) SImode][0] = CODE_FOR_floatsixf2;
2709 #ifdef HAVE_floatdixf2
2710 if (HAVE_floatdixf2)
2711 floattab[(int) XFmode][(int) DImode][0] = CODE_FOR_floatdixf2;
2713 #ifdef HAVE_floattixf2
2714 if (HAVE_floattixf2)
2715 floattab[(int) XFmode][(int) TImode][0] = CODE_FOR_floattixf2;
2718 #ifdef HAVE_floatqitf2
2719 if (HAVE_floatqitf2)
2720 floattab[(int) TFmode][(int) QImode][0] = CODE_FOR_floatqitf2;
2722 #ifdef HAVE_floathitf2
2723 if (HAVE_floathitf2)
2724 floattab[(int) TFmode][(int) HImode][0] = CODE_FOR_floathitf2;
2726 #ifdef HAVE_floatsitf2
2727 if (HAVE_floatsitf2)
2728 floattab[(int) TFmode][(int) SImode][0] = CODE_FOR_floatsitf2;
2730 #ifdef HAVE_floatditf2
2731 if (HAVE_floatditf2)
2732 floattab[(int) TFmode][(int) DImode][0] = CODE_FOR_floatditf2;
2734 #ifdef HAVE_floattitf2
2735 if (HAVE_floattitf2)
2736 floattab[(int) TFmode][(int) TImode][0] = CODE_FOR_floattitf2;
2739 #ifdef HAVE_floatunsqisf2
2740 if (HAVE_floatunsqisf2)
2741 floattab[(int) SFmode][(int) QImode][1] = CODE_FOR_floatunsqisf2;
2743 #ifdef HAVE_floatunshisf2
2744 if (HAVE_floatunshisf2)
2745 floattab[(int) SFmode][(int) HImode][1] = CODE_FOR_floatunshisf2;
2747 #ifdef HAVE_floatunssisf2
2748 if (HAVE_floatunssisf2)
2749 floattab[(int) SFmode][(int) SImode][1] = CODE_FOR_floatunssisf2;
2751 #ifdef HAVE_floatunsdisf2
2752 if (HAVE_floatunsdisf2)
2753 floattab[(int) SFmode][(int) DImode][1] = CODE_FOR_floatunsdisf2;
2755 #ifdef HAVE_floatunstisf2
2756 if (HAVE_floatunstisf2)
2757 floattab[(int) SFmode][(int) TImode][1] = CODE_FOR_floatunstisf2;
2760 #ifdef HAVE_floatunsqidf2
2761 if (HAVE_floatunsqidf2)
2762 floattab[(int) DFmode][(int) QImode][1] = CODE_FOR_floatunsqidf2;
2764 #ifdef HAVE_floatunshidf2
2765 if (HAVE_floatunshidf2)
2766 floattab[(int) DFmode][(int) HImode][1] = CODE_FOR_floatunshidf2;
2768 #ifdef HAVE_floatunssidf2
2769 if (HAVE_floatunssidf2)
2770 floattab[(int) DFmode][(int) SImode][1] = CODE_FOR_floatunssidf2;
2772 #ifdef HAVE_floatunsdidf2
2773 if (HAVE_floatunsdidf2)
2774 floattab[(int) DFmode][(int) DImode][1] = CODE_FOR_floatunsdidf2;
2776 #ifdef HAVE_floatunstidf2
2777 if (HAVE_floatunstidf2)
2778 floattab[(int) DFmode][(int) TImode][1] = CODE_FOR_floatunstidf2;
2781 #ifdef HAVE_floatunsqixf2
2782 if (HAVE_floatunsqixf2)
2783 floattab[(int) XFmode][(int) QImode][1] = CODE_FOR_floatunsqixf2;
2785 #ifdef HAVE_floatunshixf2
2786 if (HAVE_floatunshixf2)
2787 floattab[(int) XFmode][(int) HImode][1] = CODE_FOR_floatunshixf2;
2789 #ifdef HAVE_floatunssixf2
2790 if (HAVE_floatunssixf2)
2791 floattab[(int) XFmode][(int) SImode][1] = CODE_FOR_floatunssixf2;
2793 #ifdef HAVE_floatunsdixf2
2794 if (HAVE_floatunsdixf2)
2795 floattab[(int) XFmode][(int) DImode][1] = CODE_FOR_floatunsdixf2;
2797 #ifdef HAVE_floatunstixf2
2798 if (HAVE_floatunstixf2)
2799 floattab[(int) XFmode][(int) TImode][1] = CODE_FOR_floatunstixf2;
2802 #ifdef HAVE_floatunsqitf2
2803 if (HAVE_floatunsqitf2)
2804 floattab[(int) TFmode][(int) QImode][1] = CODE_FOR_floatunsqitf2;
2806 #ifdef HAVE_floatunshitf2
2807 if (HAVE_floatunshitf2)
2808 floattab[(int) TFmode][(int) HImode][1] = CODE_FOR_floatunshitf2;
2810 #ifdef HAVE_floatunssitf2
2811 if (HAVE_floatunssitf2)
2812 floattab[(int) TFmode][(int) SImode][1] = CODE_FOR_floatunssitf2;
2814 #ifdef HAVE_floatunsditf2
2815 if (HAVE_floatunsditf2)
2816 floattab[(int) TFmode][(int) DImode][1] = CODE_FOR_floatunsditf2;
2818 #ifdef HAVE_floatunstitf2
2819 if (HAVE_floatunstitf2)
2820 floattab[(int) TFmode][(int) TImode][1] = CODE_FOR_floatunstitf2;
2824 /* Generate code to convert FROM to floating point
2825 and store in TO. FROM must be fixed point and not VOIDmode.
2826 UNSIGNEDP nonzero means regard FROM as unsigned.
2827 Normally this is done by correcting the final value
2828 if it is negative. */
2831 expand_float (to, from, unsignedp)
2835 enum insn_code icode;
2836 register rtx target = to;
2837 enum machine_mode fmode, imode;
2839 /* Crash now, because we won't be able to decide which mode to use. */
2840 if (GET_MODE (from) == VOIDmode)
2843 /* Look for an insn to do the conversion. Do it in the specified
2844 modes if possible; otherwise convert either input, output or both to
2845 wider mode. If the integer mode is wider than the mode of FROM,
2846 we can do the conversion signed even if the input is unsigned. */
2848 for (imode = GET_MODE (from); imode != VOIDmode;
2849 imode = GET_MODE_WIDER_MODE (imode))
2850 for (fmode = GET_MODE (to); fmode != VOIDmode;
2851 fmode = GET_MODE_WIDER_MODE (fmode))
2853 int doing_unsigned = unsignedp;
2855 icode = can_float_p (fmode, imode, unsignedp);
2856 if (icode == CODE_FOR_nothing && imode != GET_MODE (from) && unsignedp)
2857 icode = can_float_p (fmode, imode, 0), doing_unsigned = 0;
2859 if (icode != CODE_FOR_nothing)
2861 to = protect_from_queue (to, 1);
2862 from = protect_from_queue (from, 0);
2864 if (imode != GET_MODE (from))
2865 from = convert_to_mode (imode, from, unsignedp);
2867 if (fmode != GET_MODE (to))
2868 target = gen_reg_rtx (fmode);
2870 emit_unop_insn (icode, target, from,
2871 doing_unsigned ? UNSIGNED_FLOAT : FLOAT);
2874 convert_move (to, target, 0);
2879 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
2881 /* Unsigned integer, and no way to convert directly.
2882 Convert as signed, then conditionally adjust the result. */
2885 rtx label = gen_label_rtx ();
2887 REAL_VALUE_TYPE offset;
2891 to = protect_from_queue (to, 1);
2892 from = protect_from_queue (from, 0);
2895 from = force_not_mem (from);
2897 /* If we are about to do some arithmetic to correct for an
2898 unsigned operand, do it in a pseudo-register. */
2900 if (GET_CODE (to) != REG || REGNO (to) <= LAST_VIRTUAL_REGISTER)
2901 target = gen_reg_rtx (GET_MODE (to));
2903 /* Convert as signed integer to floating. */
2904 expand_float (target, from, 0);
2906 /* If FROM is negative (and therefore TO is negative),
2907 correct its value by 2**bitwidth. */
2909 do_pending_stack_adjust ();
2910 emit_cmp_insn (from, const0_rtx, GE, NULL_RTX, GET_MODE (from), 0, 0);
2911 emit_jump_insn (gen_bge (label));
2912 /* On SCO 3.2.1, ldexp rejects values outside [0.5, 1).
2913 Rather than setting up a dconst_dot_5, let's hope SCO
2915 offset = REAL_VALUE_LDEXP (dconst1, GET_MODE_BITSIZE (GET_MODE (from)));
2916 temp = expand_binop (GET_MODE (to), add_optab, target,
2917 immed_real_const_1 (offset, GET_MODE (to)),
2918 target, 0, OPTAB_LIB_WIDEN);
2920 emit_move_insn (target, temp);
2921 do_pending_stack_adjust ();
2927 /* No hardware instruction available; call a library rotine to convert from
2928 SImode, DImode, or TImode into SFmode, DFmode, XFmode, or TFmode. */
2933 to = protect_from_queue (to, 1);
2934 from = protect_from_queue (from, 0);
2936 if (GET_MODE_SIZE (GET_MODE (from)) < GET_MODE_SIZE (SImode))
2937 from = convert_to_mode (SImode, from, unsignedp);
2940 from = force_not_mem (from);
2942 if (GET_MODE (to) == SFmode)
2944 if (GET_MODE (from) == SImode)
2945 libfcn = floatsisf_libfunc;
2946 else if (GET_MODE (from) == DImode)
2947 libfcn = floatdisf_libfunc;
2948 else if (GET_MODE (from) == TImode)
2949 libfcn = floattisf_libfunc;
2953 else if (GET_MODE (to) == DFmode)
2955 if (GET_MODE (from) == SImode)
2956 libfcn = floatsidf_libfunc;
2957 else if (GET_MODE (from) == DImode)
2958 libfcn = floatdidf_libfunc;
2959 else if (GET_MODE (from) == TImode)
2960 libfcn = floattidf_libfunc;
2964 else if (GET_MODE (to) == XFmode)
2966 if (GET_MODE (from) == SImode)
2967 libfcn = floatsixf_libfunc;
2968 else if (GET_MODE (from) == DImode)
2969 libfcn = floatdixf_libfunc;
2970 else if (GET_MODE (from) == TImode)
2971 libfcn = floattixf_libfunc;
2975 else if (GET_MODE (to) == TFmode)
2977 if (GET_MODE (from) == SImode)
2978 libfcn = floatsitf_libfunc;
2979 else if (GET_MODE (from) == DImode)
2980 libfcn = floatditf_libfunc;
2981 else if (GET_MODE (from) == TImode)
2982 libfcn = floattitf_libfunc;
2991 emit_library_call (libfcn, 1, GET_MODE (to), 1, from, GET_MODE (from));
2992 insns = get_insns ();
2995 emit_libcall_block (insns, target, hard_libcall_value (GET_MODE (to)),
2996 gen_rtx (FLOAT, GET_MODE (to), from));
2999 /* Copy result to requested destination
3000 if we have been computing in a temp location. */
3004 if (GET_MODE (target) == GET_MODE (to))
3005 emit_move_insn (to, target);
3007 convert_move (to, target, 0);
3011 /* expand_fix: generate code to convert FROM to fixed point
3012 and store in TO. FROM must be floating point. */
3018 rtx temp = gen_reg_rtx (GET_MODE (x));
3019 return expand_unop (GET_MODE (x), ftrunc_optab, x, temp, 0);
3023 expand_fix (to, from, unsignedp)
3024 register rtx to, from;
3027 enum insn_code icode;
3028 register rtx target = to;
3029 enum machine_mode fmode, imode;
3033 /* We first try to find a pair of modes, one real and one integer, at
3034 least as wide as FROM and TO, respectively, in which we can open-code
3035 this conversion. If the integer mode is wider than the mode of TO,
3036 we can do the conversion either signed or unsigned. */
3038 for (imode = GET_MODE (to); imode != VOIDmode;
3039 imode = GET_MODE_WIDER_MODE (imode))
3040 for (fmode = GET_MODE (from); fmode != VOIDmode;
3041 fmode = GET_MODE_WIDER_MODE (fmode))
3043 int doing_unsigned = unsignedp;
3045 icode = can_fix_p (imode, fmode, unsignedp, &must_trunc);
3046 if (icode == CODE_FOR_nothing && imode != GET_MODE (to) && unsignedp)
3047 icode = can_fix_p (imode, fmode, 0, &must_trunc), doing_unsigned = 0;
3049 if (icode != CODE_FOR_nothing)
3051 to = protect_from_queue (to, 1);
3052 from = protect_from_queue (from, 0);
3054 if (fmode != GET_MODE (from))
3055 from = convert_to_mode (fmode, from, 0);
3058 from = ftruncify (from);
3060 if (imode != GET_MODE (to))
3061 target = gen_reg_rtx (imode);
3063 emit_unop_insn (icode, target, from,
3064 doing_unsigned ? UNSIGNED_FIX : FIX);
3066 convert_move (to, target, unsignedp);
3071 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
3072 /* For an unsigned conversion, there is one more way to do it.
3073 If we have a signed conversion, we generate code that compares
3074 the real value to the largest representable positive number. If if
3075 is smaller, the conversion is done normally. Otherwise, subtract
3076 one plus the highest signed number, convert, and add it back.
3078 We only need to check all real modes, since we know we didn't find
3079 anything with a wider integer mode. */
3081 if (unsignedp && GET_MODE_BITSIZE (GET_MODE (to)) <= HOST_BITS_PER_WIDE_INT)
3082 for (fmode = GET_MODE (from); fmode != VOIDmode;
3083 fmode = GET_MODE_WIDER_MODE (fmode))
3084 /* Make sure we won't lose significant bits doing this. */
3085 if (GET_MODE_BITSIZE (fmode) > GET_MODE_BITSIZE (GET_MODE (to))
3086 && CODE_FOR_nothing != can_fix_p (GET_MODE (to), fmode, 0,
3089 int bitsize = GET_MODE_BITSIZE (GET_MODE (to));
3090 REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (dconst1, bitsize - 1);
3091 rtx limit = immed_real_const_1 (offset, fmode);
3092 rtx lab1 = gen_label_rtx ();
3093 rtx lab2 = gen_label_rtx ();
3097 to = protect_from_queue (to, 1);
3098 from = protect_from_queue (from, 0);
3101 from = force_not_mem (from);
3103 if (fmode != GET_MODE (from))
3104 from = convert_to_mode (fmode, from, 0);
3106 /* See if we need to do the subtraction. */
3107 do_pending_stack_adjust ();
3108 emit_cmp_insn (from, limit, GE, NULL_RTX, GET_MODE (from), 0, 0);
3109 emit_jump_insn (gen_bge (lab1));
3111 /* If not, do the signed "fix" and branch around fixup code. */
3112 expand_fix (to, from, 0);
3113 emit_jump_insn (gen_jump (lab2));
3116 /* Otherwise, subtract 2**(N-1), convert to signed number,
3117 then add 2**(N-1). Do the addition using XOR since this
3118 will often generate better code. */
3120 target = expand_binop (GET_MODE (from), sub_optab, from, limit,
3121 NULL_RTX, 0, OPTAB_LIB_WIDEN);
3122 expand_fix (to, target, 0);
3123 target = expand_binop (GET_MODE (to), xor_optab, to,
3124 GEN_INT ((HOST_WIDE_INT) 1 << (bitsize - 1)),
3125 to, 1, OPTAB_LIB_WIDEN);
3128 emit_move_insn (to, target);
3132 /* Make a place for a REG_NOTE and add it. */
3133 insn = emit_move_insn (to, to);
3134 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL,
3135 gen_rtx (UNSIGNED_FIX, GET_MODE (to),
3136 from), REG_NOTES (insn));
3142 /* We can't do it with an insn, so use a library call. But first ensure
3143 that the mode of TO is at least as wide as SImode, since those are the
3144 only library calls we know about. */
3146 if (GET_MODE_SIZE (GET_MODE (to)) < GET_MODE_SIZE (SImode))
3148 target = gen_reg_rtx (SImode);
3150 expand_fix (target, from, unsignedp);
3152 else if (GET_MODE (from) == SFmode)
3154 if (GET_MODE (to) == SImode)
3155 libfcn = unsignedp ? fixunssfsi_libfunc : fixsfsi_libfunc;
3156 else if (GET_MODE (to) == DImode)
3157 libfcn = unsignedp ? fixunssfdi_libfunc : fixsfdi_libfunc;
3158 else if (GET_MODE (to) == TImode)
3159 libfcn = unsignedp ? fixunssfti_libfunc : fixsfti_libfunc;
3163 else if (GET_MODE (from) == DFmode)
3165 if (GET_MODE (to) == SImode)
3166 libfcn = unsignedp ? fixunsdfsi_libfunc : fixdfsi_libfunc;
3167 else if (GET_MODE (to) == DImode)
3168 libfcn = unsignedp ? fixunsdfdi_libfunc : fixdfdi_libfunc;
3169 else if (GET_MODE (to) == TImode)
3170 libfcn = unsignedp ? fixunsdfti_libfunc : fixdfti_libfunc;
3174 else if (GET_MODE (from) == XFmode)
3176 if (GET_MODE (to) == SImode)
3177 libfcn = unsignedp ? fixunsxfsi_libfunc : fixxfsi_libfunc;
3178 else if (GET_MODE (to) == DImode)
3179 libfcn = unsignedp ? fixunsxfdi_libfunc : fixxfdi_libfunc;
3180 else if (GET_MODE (to) == TImode)
3181 libfcn = unsignedp ? fixunsxfti_libfunc : fixxfti_libfunc;
3185 else if (GET_MODE (from) == TFmode)
3187 if (GET_MODE (to) == SImode)
3188 libfcn = unsignedp ? fixunstfsi_libfunc : fixtfsi_libfunc;
3189 else if (GET_MODE (to) == DImode)
3190 libfcn = unsignedp ? fixunstfdi_libfunc : fixtfdi_libfunc;
3191 else if (GET_MODE (to) == TImode)
3192 libfcn = unsignedp ? fixunstfti_libfunc : fixtfti_libfunc;
3203 to = protect_from_queue (to, 1);
3204 from = protect_from_queue (from, 0);
3207 from = force_not_mem (from);
3211 emit_library_call (libfcn, 1, GET_MODE (to), 1, from, GET_MODE (from));
3212 insns = get_insns ();
3215 emit_libcall_block (insns, target, hard_libcall_value (GET_MODE (to)),
3216 gen_rtx (unsignedp ? FIX : UNSIGNED_FIX,
3217 GET_MODE (to), from));
3220 if (GET_MODE (to) == GET_MODE (target))
3221 emit_move_insn (to, target);
3223 convert_move (to, target, 0);
3231 optab op = (optab) xmalloc (sizeof (struct optab));
3233 for (i = 0; i < NUM_MACHINE_MODES; i++)
3235 op->handlers[i].insn_code = CODE_FOR_nothing;
3236 op->handlers[i].libfunc = 0;
3241 /* Initialize the libfunc fields of an entire group of entries in some
3242 optab. Each entry is set equal to a string consisting of a leading
3243 pair of underscores followed by a generic operation name followed by
3244 a mode name (downshifted to lower case) followed by a single character
3245 representing the number of operands for the given operation (which is
3246 usually one of the characters '2', '3', or '4').
3248 OPTABLE is the table in which libfunc fields are to be initialized.
3249 FIRST_MODE is the first machine mode index in the given optab to
3251 LAST_MODE is the last machine mode index in the given optab to
3253 OPNAME is the generic (string) name of the operation.
3254 SUFFIX is the character which specifies the number of operands for
3255 the given generic operation.
3259 init_libfuncs (optable, first_mode, last_mode, opname, suffix)
3260 register optab optable;
3261 register char *opname;
3262 register enum machine_mode first_mode;
3263 register enum machine_mode last_mode;
3264 register char suffix;
3266 register enum machine_mode mode;
3267 register unsigned opname_len = strlen (opname);
3269 for (mode = first_mode; mode <= last_mode; mode++)
3271 register char *mname = mode_name[(int) mode];
3272 register unsigned mname_len = strlen (mname);
3273 register char *libfunc_name
3274 = (char *) xmalloc (2 + opname_len + mname_len + 1 + 1);
3281 for (q = opname; *q; )
3283 for (q = mname; *q; q++)
3284 *p++ = tolower (*q);
3287 optable->handlers[(int) mode].libfunc
3288 = gen_rtx (SYMBOL_REF, Pmode, libfunc_name);
3292 /* Initialize the libfunc fields of an entire group of entries in some
3293 optab which correspond to all integer mode operations. The parameters
3294 have the same meaning as similarly named ones for the `init_libfuncs'
3295 routine. (See above). */
3298 init_integral_libfuncs (optable, opname, suffix)
3299 register optab optable;
3300 register char *opname;
3301 register char suffix;
3303 init_libfuncs (optable, SImode, TImode, opname, suffix);
3306 /* Initialize the libfunc fields of an entire group of entries in some
3307 optab which correspond to all real mode operations. The parameters
3308 have the same meaning as similarly named ones for the `init_libfuncs'
3309 routine. (See above). */
3312 init_floating_libfuncs (optable, opname, suffix)
3313 register optab optable;
3314 register char *opname;
3315 register char suffix;
3317 init_libfuncs (optable, SFmode, TFmode, opname, suffix);
3320 /* Call this once to initialize the contents of the optabs
3321 appropriately for the current target machine. */
3332 add_optab = init_optab (PLUS);
3333 sub_optab = init_optab (MINUS);
3334 smul_optab = init_optab (MULT);
3335 smul_widen_optab = init_optab (UNKNOWN);
3336 umul_widen_optab = init_optab (UNKNOWN);
3337 sdiv_optab = init_optab (DIV);
3338 sdivmod_optab = init_optab (UNKNOWN);
3339 udiv_optab = init_optab (UDIV);
3340 udivmod_optab = init_optab (UNKNOWN);
3341 smod_optab = init_optab (MOD);
3342 umod_optab = init_optab (UMOD);
3343 flodiv_optab = init_optab (DIV);
3344 ftrunc_optab = init_optab (UNKNOWN);
3345 and_optab = init_optab (AND);
3346 ior_optab = init_optab (IOR);
3347 xor_optab = init_optab (XOR);
3348 ashl_optab = init_optab (ASHIFT);
3349 ashr_optab = init_optab (ASHIFTRT);
3350 lshl_optab = init_optab (LSHIFT);
3351 lshr_optab = init_optab (LSHIFTRT);
3352 rotl_optab = init_optab (ROTATE);
3353 rotr_optab = init_optab (ROTATERT);
3354 smin_optab = init_optab (SMIN);
3355 smax_optab = init_optab (SMAX);
3356 umin_optab = init_optab (UMIN);
3357 umax_optab = init_optab (UMAX);
3358 mov_optab = init_optab (UNKNOWN);
3359 movstrict_optab = init_optab (UNKNOWN);
3360 cmp_optab = init_optab (UNKNOWN);
3361 ucmp_optab = init_optab (UNKNOWN);
3362 tst_optab = init_optab (UNKNOWN);
3363 neg_optab = init_optab (NEG);
3364 abs_optab = init_optab (ABS);
3365 one_cmpl_optab = init_optab (NOT);
3366 ffs_optab = init_optab (FFS);
3367 sqrt_optab = init_optab (SQRT);
3368 sin_optab = init_optab (UNKNOWN);
3369 cos_optab = init_optab (UNKNOWN);
3370 strlen_optab = init_optab (UNKNOWN);
3374 add_optab->handlers[(int) QImode].insn_code = CODE_FOR_addqi3;
3378 add_optab->handlers[(int) HImode].insn_code = CODE_FOR_addhi3;
3382 add_optab->handlers[(int) PSImode].insn_code = CODE_FOR_addpsi3;
3386 add_optab->handlers[(int) SImode].insn_code = CODE_FOR_addsi3;
3390 add_optab->handlers[(int) DImode].insn_code = CODE_FOR_adddi3;
3394 add_optab->handlers[(int) TImode].insn_code = CODE_FOR_addti3;
3398 add_optab->handlers[(int) SFmode].insn_code = CODE_FOR_addsf3;
3402 add_optab->handlers[(int) DFmode].insn_code = CODE_FOR_adddf3;
3406 add_optab->handlers[(int) XFmode].insn_code = CODE_FOR_addxf3;
3410 add_optab->handlers[(int) TFmode].insn_code = CODE_FOR_addtf3;
3412 init_integral_libfuncs (add_optab, "add", '3');
3413 init_floating_libfuncs (add_optab, "add", '3');
3417 sub_optab->handlers[(int) QImode].insn_code = CODE_FOR_subqi3;
3421 sub_optab->handlers[(int) HImode].insn_code = CODE_FOR_subhi3;
3425 sub_optab->handlers[(int) PSImode].insn_code = CODE_FOR_subpsi3;
3429 sub_optab->handlers[(int) SImode].insn_code = CODE_FOR_subsi3;
3433 sub_optab->handlers[(int) DImode].insn_code = CODE_FOR_subdi3;
3437 sub_optab->handlers[(int) TImode].insn_code = CODE_FOR_subti3;
3441 sub_optab->handlers[(int) SFmode].insn_code = CODE_FOR_subsf3;
3445 sub_optab->handlers[(int) DFmode].insn_code = CODE_FOR_subdf3;
3449 sub_optab->handlers[(int) XFmode].insn_code = CODE_FOR_subxf3;
3453 sub_optab->handlers[(int) TFmode].insn_code = CODE_FOR_subtf3;
3455 init_integral_libfuncs (sub_optab, "sub", '3');
3456 init_floating_libfuncs (sub_optab, "sub", '3');
3460 smul_optab->handlers[(int) QImode].insn_code = CODE_FOR_mulqi3;
3464 smul_optab->handlers[(int) HImode].insn_code = CODE_FOR_mulhi3;
3468 smul_optab->handlers[(int) PSImode].insn_code = CODE_FOR_mulpsi3;
3472 smul_optab->handlers[(int) SImode].insn_code = CODE_FOR_mulsi3;
3476 smul_optab->handlers[(int) DImode].insn_code = CODE_FOR_muldi3;
3480 smul_optab->handlers[(int) TImode].insn_code = CODE_FOR_multi3;
3484 smul_optab->handlers[(int) SFmode].insn_code = CODE_FOR_mulsf3;
3488 smul_optab->handlers[(int) DFmode].insn_code = CODE_FOR_muldf3;
3492 smul_optab->handlers[(int) XFmode].insn_code = CODE_FOR_mulxf3;
3496 smul_optab->handlers[(int) TFmode].insn_code = CODE_FOR_multf3;
3498 init_integral_libfuncs (smul_optab, "mul", '3');
3499 init_floating_libfuncs (smul_optab, "mul", '3');
3501 #ifdef MULSI3_LIBCALL
3502 smul_optab->handlers[(int) SImode].libfunc
3503 = gen_rtx (SYMBOL_REF, Pmode, MULSI3_LIBCALL);
3505 #ifdef MULDI3_LIBCALL
3506 smul_optab->handlers[(int) DImode].libfunc
3507 = gen_rtx (SYMBOL_REF, Pmode, MULDI3_LIBCALL);
3509 #ifdef MULTI3_LIBCALL
3510 smul_optab->handlers[(int) TImode].libfunc
3511 = gen_rtx (SYMBOL_REF, Pmode, MULTI3_LIBCALL);
3514 #ifdef HAVE_mulqihi3
3516 smul_widen_optab->handlers[(int) HImode].insn_code = CODE_FOR_mulqihi3;
3518 #ifdef HAVE_mulhisi3
3520 smul_widen_optab->handlers[(int) SImode].insn_code = CODE_FOR_mulhisi3;
3522 #ifdef HAVE_mulsidi3
3524 smul_widen_optab->handlers[(int) DImode].insn_code = CODE_FOR_mulsidi3;
3526 #ifdef HAVE_mulditi3
3528 smul_widen_optab->handlers[(int) TImode].insn_code = CODE_FOR_mulditi3;
3531 #ifdef HAVE_umulqihi3
3533 umul_widen_optab->handlers[(int) HImode].insn_code = CODE_FOR_umulqihi3;
3535 #ifdef HAVE_umulhisi3
3537 umul_widen_optab->handlers[(int) SImode].insn_code = CODE_FOR_umulhisi3;
3539 #ifdef HAVE_umulsidi3
3541 umul_widen_optab->handlers[(int) DImode].insn_code = CODE_FOR_umulsidi3;
3543 #ifdef HAVE_umulditi3
3545 umul_widen_optab->handlers[(int) TImode].insn_code = CODE_FOR_umulditi3;
3550 sdiv_optab->handlers[(int) QImode].insn_code = CODE_FOR_divqi3;
3554 sdiv_optab->handlers[(int) HImode].insn_code = CODE_FOR_divhi3;
3558 sdiv_optab->handlers[(int) PSImode].insn_code = CODE_FOR_divpsi3;
3562 sdiv_optab->handlers[(int) SImode].insn_code = CODE_FOR_divsi3;
3566 sdiv_optab->handlers[(int) DImode].insn_code = CODE_FOR_divdi3;
3570 sdiv_optab->handlers[(int) TImode].insn_code = CODE_FOR_divti3;
3572 init_integral_libfuncs (sdiv_optab, "div", '3');
3574 #ifdef DIVSI3_LIBCALL
3575 sdiv_optab->handlers[(int) SImode].libfunc
3576 = gen_rtx (SYMBOL_REF, Pmode, DIVSI3_LIBCALL);
3578 #ifdef DIVDI3_LIBCALL
3579 sdiv_optab->handlers[(int) DImode].libfunc
3580 = gen_rtx (SYMBOL_REF, Pmode, DIVDI3_LIBCALL);
3582 #ifdef DIVTI3_LIBCALL
3583 sdiv_optab->handlers[(int) TImode].libfunc
3584 = gen_rtx (SYMBOL_REF, Pmode, DIVTI3_LIBCALL);
3589 udiv_optab->handlers[(int) QImode].insn_code = CODE_FOR_udivqi3;
3593 udiv_optab->handlers[(int) HImode].insn_code = CODE_FOR_udivhi3;
3595 #ifdef HAVE_udivpsi3
3597 udiv_optab->handlers[(int) PSImode].insn_code = CODE_FOR_udivpsi3;
3601 udiv_optab->handlers[(int) SImode].insn_code = CODE_FOR_udivsi3;
3605 udiv_optab->handlers[(int) DImode].insn_code = CODE_FOR_udivdi3;
3609 udiv_optab->handlers[(int) TImode].insn_code = CODE_FOR_udivti3;
3611 init_integral_libfuncs (udiv_optab, "udiv", '3');
3613 #ifdef UDIVSI3_LIBCALL
3614 udiv_optab->handlers[(int) SImode].libfunc
3615 = gen_rtx (SYMBOL_REF, Pmode, UDIVSI3_LIBCALL);
3617 #ifdef UDIVDI3_LIBCALL
3618 udiv_optab->handlers[(int) DImode].libfunc
3619 = gen_rtx (SYMBOL_REF, Pmode, UDIVDI3_LIBCALL);
3621 #ifdef UDIVTI3_LIBCALL
3622 udiv_optab->handlers[(int) TImode].libfunc
3623 = gen_rtx (SYMBOL_REF, Pmode, UDIVTI3_LIBCALL);
3626 #ifdef HAVE_divmodqi4
3628 sdivmod_optab->handlers[(int) QImode].insn_code = CODE_FOR_divmodqi4;
3630 #ifdef HAVE_divmodhi4
3632 sdivmod_optab->handlers[(int) HImode].insn_code = CODE_FOR_divmodhi4;
3634 #ifdef HAVE_divmodsi4
3636 sdivmod_optab->handlers[(int) SImode].insn_code = CODE_FOR_divmodsi4;
3638 #ifdef HAVE_divmoddi4
3640 sdivmod_optab->handlers[(int) DImode].insn_code = CODE_FOR_divmoddi4;
3642 #ifdef HAVE_divmodti4
3644 sdivmod_optab->handlers[(int) TImode].insn_code = CODE_FOR_divmodti4;
3646 init_integral_libfuncs (sdivmod_optab, "divmod", '4');
3648 #ifdef HAVE_udivmodqi4
3649 if (HAVE_udivmodqi4)
3650 udivmod_optab->handlers[(int) QImode].insn_code = CODE_FOR_udivmodqi4;
3652 #ifdef HAVE_udivmodhi4
3653 if (HAVE_udivmodhi4)
3654 udivmod_optab->handlers[(int) HImode].insn_code = CODE_FOR_udivmodhi4;
3656 #ifdef HAVE_udivmodsi4
3657 if (HAVE_udivmodsi4)
3658 udivmod_optab->handlers[(int) SImode].insn_code = CODE_FOR_udivmodsi4;
3660 #ifdef HAVE_udivmoddi4
3661 if (HAVE_udivmoddi4)
3662 udivmod_optab->handlers[(int) DImode].insn_code = CODE_FOR_udivmoddi4;
3664 #ifdef HAVE_udivmodti4
3665 if (HAVE_udivmodti4)
3666 udivmod_optab->handlers[(int) TImode].insn_code = CODE_FOR_udivmodti4;
3668 init_integral_libfuncs (udivmod_optab, "udivmod", '4');
3672 smod_optab->handlers[(int) QImode].insn_code = CODE_FOR_modqi3;
3676 smod_optab->handlers[(int) HImode].insn_code = CODE_FOR_modhi3;
3680 smod_optab->handlers[(int) PSImode].insn_code = CODE_FOR_modpsi3;
3684 smod_optab->handlers[(int) SImode].insn_code = CODE_FOR_modsi3;
3688 smod_optab->handlers[(int) DImode].insn_code = CODE_FOR_moddi3;
3692 smod_optab->handlers[(int) TImode].insn_code = CODE_FOR_modti3;
3694 init_integral_libfuncs (smod_optab, "mod", '3');
3696 #ifdef MODSI3_LIBCALL
3697 smod_optab->handlers[(int) SImode].libfunc
3698 = gen_rtx (SYMBOL_REF, Pmode, MODSI3_LIBCALL);
3700 #ifdef MODDI3_LIBCALL
3701 smod_optab->handlers[(int) DImode].libfunc
3702 = gen_rtx (SYMBOL_REF, Pmode, MODDI3_LIBCALL);
3704 #ifdef MODTI3_LIBCALL
3705 smod_optab->handlers[(int) TImode].libfunc
3706 = gen_rtx (SYMBOL_REF, Pmode, MODTI3_LIBCALL);
3711 umod_optab->handlers[(int) QImode].insn_code = CODE_FOR_umodqi3;
3715 umod_optab->handlers[(int) HImode].insn_code = CODE_FOR_umodhi3;
3717 #ifdef HAVE_umodpsi3
3719 umod_optab->handlers[(int) PSImode].insn_code = CODE_FOR_umodpsi3;
3723 umod_optab->handlers[(int) SImode].insn_code = CODE_FOR_umodsi3;
3727 umod_optab->handlers[(int) DImode].insn_code = CODE_FOR_umoddi3;
3731 umod_optab->handlers[(int) TImode].insn_code = CODE_FOR_umodti3;
3733 init_integral_libfuncs (umod_optab, "umod", '3');
3735 #ifdef UMODSI3_LIBCALL
3736 umod_optab->handlers[(int) SImode].libfunc
3737 = gen_rtx (SYMBOL_REF, Pmode, UMODSI3_LIBCALL);
3739 #ifdef UMODDI3_LIBCALL
3740 umod_optab->handlers[(int) DImode].libfunc
3741 = gen_rtx (SYMBOL_REF, Pmode, UMODDI3_LIBCALL);
3743 #ifdef UMODTI3_LIBCALL
3744 umod_optab->handlers[(int) TImode].libfunc
3745 = gen_rtx (SYMBOL_REF, Pmode, UMODTI3_LIBCALL);
3750 flodiv_optab->handlers[(int) SFmode].insn_code = CODE_FOR_divsf3;
3754 flodiv_optab->handlers[(int) DFmode].insn_code = CODE_FOR_divdf3;
3758 flodiv_optab->handlers[(int) XFmode].insn_code = CODE_FOR_divxf3;
3762 flodiv_optab->handlers[(int) TFmode].insn_code = CODE_FOR_divtf3;
3764 init_floating_libfuncs (flodiv_optab, "div", '3');
3766 #ifdef HAVE_ftruncsf2
3768 ftrunc_optab->handlers[(int) SFmode].insn_code = CODE_FOR_ftruncsf2;
3770 #ifdef HAVE_ftruncdf2
3772 ftrunc_optab->handlers[(int) DFmode].insn_code = CODE_FOR_ftruncdf2;
3774 #ifdef HAVE_ftruncxf2
3776 ftrunc_optab->handlers[(int) XFmode].insn_code = CODE_FOR_ftruncxf2;
3778 #ifdef HAVE_ftrunctf2
3780 ftrunc_optab->handlers[(int) TFmode].insn_code = CODE_FOR_ftrunctf2;
3782 init_floating_libfuncs (ftrunc_optab, "ftrunc", '2');
3786 and_optab->handlers[(int) QImode].insn_code = CODE_FOR_andqi3;
3790 and_optab->handlers[(int) HImode].insn_code = CODE_FOR_andhi3;
3794 and_optab->handlers[(int) PSImode].insn_code = CODE_FOR_andpsi3;
3798 and_optab->handlers[(int) SImode].insn_code = CODE_FOR_andsi3;
3802 and_optab->handlers[(int) DImode].insn_code = CODE_FOR_anddi3;
3806 and_optab->handlers[(int) TImode].insn_code = CODE_FOR_andti3;
3808 init_integral_libfuncs (and_optab, "and", '3');
3812 ior_optab->handlers[(int) QImode].insn_code = CODE_FOR_iorqi3;
3816 ior_optab->handlers[(int) HImode].insn_code = CODE_FOR_iorhi3;
3820 ior_optab->handlers[(int) PSImode].insn_code = CODE_FOR_iorpsi3;
3824 ior_optab->handlers[(int) SImode].insn_code = CODE_FOR_iorsi3;
3828 ior_optab->handlers[(int) DImode].insn_code = CODE_FOR_iordi3;
3832 ior_optab->handlers[(int) TImode].insn_code = CODE_FOR_iorti3;
3834 init_integral_libfuncs (ior_optab, "ior", '3');
3838 xor_optab->handlers[(int) QImode].insn_code = CODE_FOR_xorqi3;
3842 xor_optab->handlers[(int) HImode].insn_code = CODE_FOR_xorhi3;
3846 xor_optab->handlers[(int) PSImode].insn_code = CODE_FOR_xorpsi3;
3850 xor_optab->handlers[(int) SImode].insn_code = CODE_FOR_xorsi3;
3854 xor_optab->handlers[(int) DImode].insn_code = CODE_FOR_xordi3;
3858 xor_optab->handlers[(int) TImode].insn_code = CODE_FOR_xorti3;
3860 init_integral_libfuncs (xor_optab, "xor", '3');
3864 ashl_optab->handlers[(int) QImode].insn_code = CODE_FOR_ashlqi3;
3868 ashl_optab->handlers[(int) HImode].insn_code = CODE_FOR_ashlhi3;
3870 #ifdef HAVE_ashlpsi3
3872 ashl_optab->handlers[(int) PSImode].insn_code = CODE_FOR_ashlpsi3;
3876 ashl_optab->handlers[(int) SImode].insn_code = CODE_FOR_ashlsi3;
3880 ashl_optab->handlers[(int) DImode].insn_code = CODE_FOR_ashldi3;
3884 ashl_optab->handlers[(int) TImode].insn_code = CODE_FOR_ashlti3;
3886 init_integral_libfuncs (ashl_optab, "ashl", '3');
3890 ashr_optab->handlers[(int) QImode].insn_code = CODE_FOR_ashrqi3;
3894 ashr_optab->handlers[(int) HImode].insn_code = CODE_FOR_ashrhi3;
3896 #ifdef HAVE_ashrpsi3
3898 ashr_optab->handlers[(int) PSImode].insn_code = CODE_FOR_ashrpsi3;
3902 ashr_optab->handlers[(int) SImode].insn_code = CODE_FOR_ashrsi3;
3906 ashr_optab->handlers[(int) DImode].insn_code = CODE_FOR_ashrdi3;
3910 ashr_optab->handlers[(int) TImode].insn_code = CODE_FOR_ashrti3;
3912 init_integral_libfuncs (ashr_optab, "ashr", '3');
3916 lshl_optab->handlers[(int) QImode].insn_code = CODE_FOR_lshlqi3;
3920 lshl_optab->handlers[(int) HImode].insn_code = CODE_FOR_lshlhi3;
3922 #ifdef HAVE_lshlpsi3
3924 lshl_optab->handlers[(int) PSImode].insn_code = CODE_FOR_lshlpsi3;
3928 lshl_optab->handlers[(int) SImode].insn_code = CODE_FOR_lshlsi3;
3932 lshl_optab->handlers[(int) DImode].insn_code = CODE_FOR_lshldi3;
3936 lshl_optab->handlers[(int) TImode].insn_code = CODE_FOR_lshlti3;
3938 init_integral_libfuncs (lshl_optab, "lshl", '3');
3942 lshr_optab->handlers[(int) QImode].insn_code = CODE_FOR_lshrqi3;
3946 lshr_optab->handlers[(int) HImode].insn_code = CODE_FOR_lshrhi3;
3948 #ifdef HAVE_lshrpsi3
3950 lshr_optab->handlers[(int) PSImode].insn_code = CODE_FOR_lshrpsi3;
3954 lshr_optab->handlers[(int) SImode].insn_code = CODE_FOR_lshrsi3;
3958 lshr_optab->handlers[(int) DImode].insn_code = CODE_FOR_lshrdi3;
3962 lshr_optab->handlers[(int) TImode].insn_code = CODE_FOR_lshrti3;
3964 init_integral_libfuncs (lshr_optab, "lshr", '3');
3968 rotl_optab->handlers[(int) QImode].insn_code = CODE_FOR_rotlqi3;
3972 rotl_optab->handlers[(int) HImode].insn_code = CODE_FOR_rotlhi3;
3974 #ifdef HAVE_rotlpsi3
3976 rotl_optab->handlers[(int) PSImode].insn_code = CODE_FOR_rotlpsi3;
3980 rotl_optab->handlers[(int) SImode].insn_code = CODE_FOR_rotlsi3;
3984 rotl_optab->handlers[(int) DImode].insn_code = CODE_FOR_rotldi3;
3988 rotl_optab->handlers[(int) TImode].insn_code = CODE_FOR_rotlti3;
3990 init_integral_libfuncs (rotl_optab, "rotl", '3');
3994 rotr_optab->handlers[(int) QImode].insn_code = CODE_FOR_rotrqi3;
3998 rotr_optab->handlers[(int) HImode].insn_code = CODE_FOR_rotrhi3;
4000 #ifdef HAVE_rotrpsi3
4002 rotr_optab->handlers[(int) PSImode].insn_code = CODE_FOR_rotrpsi3;
4006 rotr_optab->handlers[(int) SImode].insn_code = CODE_FOR_rotrsi3;
4010 rotr_optab->handlers[(int) DImode].insn_code = CODE_FOR_rotrdi3;
4014 rotr_optab->handlers[(int) TImode].insn_code = CODE_FOR_rotrti3;
4016 init_integral_libfuncs (rotr_optab, "rotr", '3');
4020 smin_optab->handlers[(int) QImode].insn_code = CODE_FOR_sminqi3;
4024 smin_optab->handlers[(int) HImode].insn_code = CODE_FOR_sminhi3;
4028 smin_optab->handlers[(int) SImode].insn_code = CODE_FOR_sminsi3;
4032 smin_optab->handlers[(int) DImode].insn_code = CODE_FOR_smindi3;
4036 smin_optab->handlers[(int) TImode].insn_code = CODE_FOR_sminti3;
4040 smin_optab->handlers[(int) SFmode].insn_code = CODE_FOR_minsf3;
4044 smin_optab->handlers[(int) DFmode].insn_code = CODE_FOR_mindf3;
4048 smin_optab->handlers[(int) XFmode].insn_code = CODE_FOR_minxf3;
4052 smin_optab->handlers[(int) TFmode].insn_code = CODE_FOR_mintf3;
4054 init_integral_libfuncs (smin_optab, "min", '3');
4055 init_floating_libfuncs (smin_optab, "min", '3');
4059 smax_optab->handlers[(int) QImode].insn_code = CODE_FOR_smaxqi3;
4063 smax_optab->handlers[(int) HImode].insn_code = CODE_FOR_smaxhi3;
4067 smax_optab->handlers[(int) SImode].insn_code = CODE_FOR_smaxsi3;
4071 smax_optab->handlers[(int) DImode].insn_code = CODE_FOR_smaxdi3;
4075 smax_optab->handlers[(int) TImode].insn_code = CODE_FOR_smaxti3;
4079 smax_optab->handlers[(int) SFmode].insn_code = CODE_FOR_maxsf3;
4083 smax_optab->handlers[(int) DFmode].insn_code = CODE_FOR_maxdf3;
4087 smax_optab->handlers[(int) XFmode].insn_code = CODE_FOR_maxxf3;
4091 smax_optab->handlers[(int) TFmode].insn_code = CODE_FOR_maxtf3;
4093 init_integral_libfuncs (smax_optab, "max", '3');
4094 init_floating_libfuncs (smax_optab, "max", '3');
4098 umin_optab->handlers[(int) QImode].insn_code = CODE_FOR_uminqi3;
4102 umin_optab->handlers[(int) HImode].insn_code = CODE_FOR_uminhi3;
4106 umin_optab->handlers[(int) SImode].insn_code = CODE_FOR_uminsi3;
4110 umin_optab->handlers[(int) DImode].insn_code = CODE_FOR_umindi3;
4114 umin_optab->handlers[(int) TImode].insn_code = CODE_FOR_uminti3;
4116 init_integral_libfuncs (umin_optab, "umin", '3');
4120 umax_optab->handlers[(int) QImode].insn_code = CODE_FOR_umaxqi3;
4124 umax_optab->handlers[(int) HImode].insn_code = CODE_FOR_umaxhi3;
4128 umax_optab->handlers[(int) SImode].insn_code = CODE_FOR_umaxsi3;
4132 umax_optab->handlers[(int) DImode].insn_code = CODE_FOR_umaxdi3;
4136 umax_optab->handlers[(int) TImode].insn_code = CODE_FOR_umaxti3;
4138 init_integral_libfuncs (umax_optab, "umax", '3');
4142 neg_optab->handlers[(int) QImode].insn_code = CODE_FOR_negqi2;
4146 neg_optab->handlers[(int) HImode].insn_code = CODE_FOR_neghi2;
4150 neg_optab->handlers[(int) PSImode].insn_code = CODE_FOR_negpsi2;
4154 neg_optab->handlers[(int) SImode].insn_code = CODE_FOR_negsi2;
4158 neg_optab->handlers[(int) DImode].insn_code = CODE_FOR_negdi2;
4162 neg_optab->handlers[(int) TImode].insn_code = CODE_FOR_negti2;
4166 neg_optab->handlers[(int) SFmode].insn_code = CODE_FOR_negsf2;
4170 neg_optab->handlers[(int) DFmode].insn_code = CODE_FOR_negdf2;
4174 neg_optab->handlers[(int) XFmode].insn_code = CODE_FOR_negxf2;
4178 neg_optab->handlers[(int) TFmode].insn_code = CODE_FOR_negtf2;
4180 init_integral_libfuncs (neg_optab, "neg", '2');
4181 init_floating_libfuncs (neg_optab, "neg", '2');
4185 abs_optab->handlers[(int) QImode].insn_code = CODE_FOR_absqi2;
4189 abs_optab->handlers[(int) HImode].insn_code = CODE_FOR_abshi2;
4193 abs_optab->handlers[(int) PSImode].insn_code = CODE_FOR_abspsi2;
4197 abs_optab->handlers[(int) SImode].insn_code = CODE_FOR_abssi2;
4201 abs_optab->handlers[(int) DImode].insn_code = CODE_FOR_absdi2;
4205 abs_optab->handlers[(int) TImode].insn_code = CODE_FOR_absti2;
4209 abs_optab->handlers[(int) SFmode].insn_code = CODE_FOR_abssf2;
4213 abs_optab->handlers[(int) DFmode].insn_code = CODE_FOR_absdf2;
4217 abs_optab->handlers[(int) XFmode].insn_code = CODE_FOR_absxf2;
4221 abs_optab->handlers[(int) TFmode].insn_code = CODE_FOR_abstf2;
4223 /* No library calls here! If there is no abs instruction,
4224 expand_expr will generate a conditional negation. */
4228 sqrt_optab->handlers[(int) QImode].insn_code = CODE_FOR_sqrtqi2;
4232 sqrt_optab->handlers[(int) HImode].insn_code = CODE_FOR_sqrthi2;
4234 #ifdef HAVE_sqrtpsi2
4236 sqrt_optab->handlers[(int) PSImode].insn_code = CODE_FOR_sqrtpsi2;
4240 sqrt_optab->handlers[(int) SImode].insn_code = CODE_FOR_sqrtsi2;
4244 sqrt_optab->handlers[(int) DImode].insn_code = CODE_FOR_sqrtdi2;
4248 sqrt_optab->handlers[(int) TImode].insn_code = CODE_FOR_sqrtti2;
4252 sqrt_optab->handlers[(int) SFmode].insn_code = CODE_FOR_sqrtsf2;
4256 sqrt_optab->handlers[(int) DFmode].insn_code = CODE_FOR_sqrtdf2;
4260 sqrt_optab->handlers[(int) TFmode].insn_code = CODE_FOR_sqrttf2;
4262 /* No library calls here! If there is no sqrt instruction expand_builtin
4263 should force the library call. */
4267 sin_optab->handlers[(int) SFmode].insn_code = CODE_FOR_sinsf2;
4271 sin_optab->handlers[(int) DFmode].insn_code = CODE_FOR_sindf2;
4275 sin_optab->handlers[(int) TFmode].insn_code = CODE_FOR_sintf2;
4277 /* No library calls here! If there is no sin instruction expand_builtin
4278 should force the library call. */
4282 cos_optab->handlers[(int) SFmode].insn_code = CODE_FOR_cossf2;
4286 cos_optab->handlers[(int) DFmode].insn_code = CODE_FOR_cosdf2;
4290 cos_optab->handlers[(int) TFmode].insn_code = CODE_FOR_costf2;
4292 /* No library calls here! If there is no cos instruction expand_builtin
4293 should force the library call. */
4295 #ifdef HAVE_strlenqi
4297 strlen_optab->handlers[(int) QImode].insn_code = CODE_FOR_strlenqi;
4299 #ifdef HAVE_strlenhi
4301 strlen_optab->handlers[(int) HImode].insn_code = CODE_FOR_strlenhi;
4303 #ifdef HAVE_strlenpsi
4305 strlen_optab->handlers[(int) PSImode].insn_code = CODE_FOR_strlenpsi;
4307 #ifdef HAVE_strlensi
4309 strlen_optab->handlers[(int) SImode].insn_code = CODE_FOR_strlensi;
4311 #ifdef HAVE_strlendi
4313 strlen_optab->handlers[(int) DImode].insn_code = CODE_FOR_strlendi;
4315 #ifdef HAVE_strlenti
4317 strlen_optab->handlers[(int) TImode].insn_code = CODE_FOR_strlenti;
4319 /* No library calls here! If there is no strlen instruction expand_builtin
4320 should force the library call. */
4322 #ifdef HAVE_one_cmplqi2
4323 if (HAVE_one_cmplqi2)
4324 one_cmpl_optab->handlers[(int) QImode].insn_code = CODE_FOR_one_cmplqi2;
4326 #ifdef HAVE_one_cmplhi2
4327 if (HAVE_one_cmplhi2)
4328 one_cmpl_optab->handlers[(int) HImode].insn_code = CODE_FOR_one_cmplhi2;
4330 #ifdef HAVE_one_cmplpsi2
4331 if (HAVE_one_cmplpsi2)
4332 one_cmpl_optab->handlers[(int) PSImode].insn_code = CODE_FOR_one_cmplpsi2;
4334 #ifdef HAVE_one_cmplsi2
4335 if (HAVE_one_cmplsi2)
4336 one_cmpl_optab->handlers[(int) SImode].insn_code = CODE_FOR_one_cmplsi2;
4338 #ifdef HAVE_one_cmpldi2
4339 if (HAVE_one_cmpldi2)
4340 one_cmpl_optab->handlers[(int) DImode].insn_code = CODE_FOR_one_cmpldi2;
4342 #ifdef HAVE_one_cmplti2
4343 if (HAVE_one_cmplti2)
4344 one_cmpl_optab->handlers[(int) TImode].insn_code = CODE_FOR_one_cmplti2;
4346 init_integral_libfuncs (one_cmpl_optab, "one_cmpl", '2');
4350 ffs_optab->handlers[(int) QImode].insn_code = CODE_FOR_ffsqi2;
4354 ffs_optab->handlers[(int) HImode].insn_code = CODE_FOR_ffshi2;
4358 ffs_optab->handlers[(int) PSImode].insn_code = CODE_FOR_ffspsi2;
4362 ffs_optab->handlers[(int) SImode].insn_code = CODE_FOR_ffssi2;
4366 ffs_optab->handlers[(int) DImode].insn_code = CODE_FOR_ffsdi2;
4370 ffs_optab->handlers[(int) TImode].insn_code = CODE_FOR_ffsti2;
4372 init_integral_libfuncs (ffs_optab, "ffs", '2');
4376 mov_optab->handlers[(int) QImode].insn_code = CODE_FOR_movqi;
4380 mov_optab->handlers[(int) HImode].insn_code = CODE_FOR_movhi;
4384 mov_optab->handlers[(int) PSImode].insn_code = CODE_FOR_movpsi;
4388 mov_optab->handlers[(int) SImode].insn_code = CODE_FOR_movsi;
4392 mov_optab->handlers[(int) DImode].insn_code = CODE_FOR_movdi;
4396 mov_optab->handlers[(int) TImode].insn_code = CODE_FOR_movti;
4400 mov_optab->handlers[(int) SFmode].insn_code = CODE_FOR_movsf;
4404 mov_optab->handlers[(int) DFmode].insn_code = CODE_FOR_movdf;
4408 mov_optab->handlers[(int) XFmode].insn_code = CODE_FOR_movxf;
4412 mov_optab->handlers[(int) TFmode].insn_code = CODE_FOR_movtf;
4416 mov_optab->handlers[(int) CCmode].insn_code = CODE_FOR_movcc;
4419 #ifdef EXTRA_CC_MODES
4423 #ifdef HAVE_movstrictqi
4424 if (HAVE_movstrictqi)
4425 movstrict_optab->handlers[(int) QImode].insn_code = CODE_FOR_movstrictqi;
4427 #ifdef HAVE_movstricthi
4428 if (HAVE_movstricthi)
4429 movstrict_optab->handlers[(int) HImode].insn_code = CODE_FOR_movstricthi;
4431 #ifdef HAVE_movstrictpsi
4432 if (HAVE_movstrictpsi)
4433 movstrict_optab->handlers[(int) PSImode].insn_code = CODE_FOR_movstrictpsi;
4435 #ifdef HAVE_movstrictsi
4436 if (HAVE_movstrictsi)
4437 movstrict_optab->handlers[(int) SImode].insn_code = CODE_FOR_movstrictsi;
4439 #ifdef HAVE_movstrictdi
4440 if (HAVE_movstrictdi)
4441 movstrict_optab->handlers[(int) DImode].insn_code = CODE_FOR_movstrictdi;
4443 #ifdef HAVE_movstrictti
4444 if (HAVE_movstrictti)
4445 movstrict_optab->handlers[(int) TImode].insn_code = CODE_FOR_movstrictti;
4450 cmp_optab->handlers[(int) QImode].insn_code = CODE_FOR_cmpqi;
4454 cmp_optab->handlers[(int) HImode].insn_code = CODE_FOR_cmphi;
4458 cmp_optab->handlers[(int) PSImode].insn_code = CODE_FOR_cmppsi;
4462 cmp_optab->handlers[(int) SImode].insn_code = CODE_FOR_cmpsi;
4466 cmp_optab->handlers[(int) DImode].insn_code = CODE_FOR_cmpdi;
4470 cmp_optab->handlers[(int) TImode].insn_code = CODE_FOR_cmpti;
4474 cmp_optab->handlers[(int) SFmode].insn_code = CODE_FOR_cmpsf;
4478 cmp_optab->handlers[(int) DFmode].insn_code = CODE_FOR_cmpdf;
4482 cmp_optab->handlers[(int) XFmode].insn_code = CODE_FOR_cmpxf;
4486 cmp_optab->handlers[(int) TFmode].insn_code = CODE_FOR_cmptf;
4488 /* Comparison libcalls for integers MUST come in pairs, signed/unsigned. */
4489 init_integral_libfuncs (cmp_optab, "cmp", '2');
4490 init_integral_libfuncs (ucmp_optab, "ucmp", '2');
4491 init_floating_libfuncs (cmp_optab, "cmp", '2');
4495 tst_optab->handlers[(int) QImode].insn_code = CODE_FOR_tstqi;
4499 tst_optab->handlers[(int) HImode].insn_code = CODE_FOR_tsthi;
4503 tst_optab->handlers[(int) PSImode].insn_code = CODE_FOR_tstpsi;
4507 tst_optab->handlers[(int) SImode].insn_code = CODE_FOR_tstsi;
4511 tst_optab->handlers[(int) DImode].insn_code = CODE_FOR_tstdi;
4515 tst_optab->handlers[(int) TImode].insn_code = CODE_FOR_tstti;
4519 tst_optab->handlers[(int) SFmode].insn_code = CODE_FOR_tstsf;
4523 tst_optab->handlers[(int) DFmode].insn_code = CODE_FOR_tstdf;
4527 tst_optab->handlers[(int) XFmode].insn_code = CODE_FOR_tstxf;
4531 tst_optab->handlers[(int) TFmode].insn_code = CODE_FOR_tsttf;
4536 bcc_gen_fctn[(int) EQ] = gen_beq;
4540 bcc_gen_fctn[(int) NE] = gen_bne;
4544 bcc_gen_fctn[(int) GT] = gen_bgt;
4548 bcc_gen_fctn[(int) GE] = gen_bge;
4552 bcc_gen_fctn[(int) GTU] = gen_bgtu;
4556 bcc_gen_fctn[(int) GEU] = gen_bgeu;
4560 bcc_gen_fctn[(int) LT] = gen_blt;
4564 bcc_gen_fctn[(int) LE] = gen_ble;
4568 bcc_gen_fctn[(int) LTU] = gen_bltu;
4572 bcc_gen_fctn[(int) LEU] = gen_bleu;
4575 for (i = 0; i < NUM_RTX_CODE; i++)
4576 setcc_gen_code[i] = CODE_FOR_nothing;
4580 setcc_gen_code[(int) EQ] = CODE_FOR_seq;
4584 setcc_gen_code[(int) NE] = CODE_FOR_sne;
4588 setcc_gen_code[(int) GT] = CODE_FOR_sgt;
4592 setcc_gen_code[(int) GE] = CODE_FOR_sge;
4596 setcc_gen_code[(int) GTU] = CODE_FOR_sgtu;
4600 setcc_gen_code[(int) GEU] = CODE_FOR_sgeu;
4604 setcc_gen_code[(int) LT] = CODE_FOR_slt;
4608 setcc_gen_code[(int) LE] = CODE_FOR_sle;
4612 setcc_gen_code[(int) LTU] = CODE_FOR_sltu;
4616 setcc_gen_code[(int) LEU] = CODE_FOR_sleu;
4619 extendsfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extendsfdf2");
4620 extendsfxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extendsfxf2");
4621 extendsftf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extendsftf2");
4622 extenddfxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extenddfxf2");
4623 extenddftf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extenddftf2");
4625 truncdfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__truncdfsf2");
4626 truncxfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__truncxfsf2");
4627 trunctfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__trunctfsf2");
4628 truncxfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__truncxfdf2");
4629 trunctfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__trunctfdf2");
4631 memcpy_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memcpy");
4632 bcopy_libfunc = gen_rtx (SYMBOL_REF, Pmode, "bcopy");
4633 memcmp_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memcmp");
4634 bcmp_libfunc = gen_rtx (SYMBOL_REF, Pmode, "bcmp");
4635 memset_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memset");
4636 bzero_libfunc = gen_rtx (SYMBOL_REF, Pmode, "bzero");
4638 eqsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqsf2");
4639 nesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nesf2");
4640 gtsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtsf2");
4641 gesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gesf2");
4642 ltsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltsf2");
4643 lesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lesf2");
4645 eqdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqdf2");
4646 nedf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nedf2");
4647 gtdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtdf2");
4648 gedf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gedf2");
4649 ltdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltdf2");
4650 ledf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ledf2");
4652 eqxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqxf2");
4653 nexf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nexf2");
4654 gtxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtxf2");
4655 gexf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gexf2");
4656 ltxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltxf2");
4657 lexf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lexf2");
4659 eqtf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqtf2");
4660 netf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__netf2");
4661 gttf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gttf2");
4662 getf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__getf2");
4663 lttf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lttf2");
4664 letf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__letf2");
4666 floatsisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsisf");
4667 floatdisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatdisf");
4668 floattisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattisf");
4670 floatsidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsidf");
4671 floatdidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatdidf");
4672 floattidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattidf");
4674 floatsixf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsixf");
4675 floatdixf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatdixf");
4676 floattixf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattixf");
4678 floatsitf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsitf");
4679 floatditf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatditf");
4680 floattitf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattitf");
4682 fixsfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixsfsi");
4683 fixsfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixsfdi");
4684 fixsfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixsfti");
4686 fixdfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixdfsi");
4687 fixdfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixdfdi");
4688 fixdfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixdfti");
4690 fixxfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixxfsi");
4691 fixxfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixxfdi");
4692 fixxfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixxfti");
4694 fixtfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixtfsi");
4695 fixtfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixtfdi");
4696 fixtfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixtfti");
4698 fixunssfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunssfsi");
4699 fixunssfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunssfdi");
4700 fixunssfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunssfti");
4702 fixunsdfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsdfsi");
4703 fixunsdfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsdfdi");
4704 fixunsdfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsdfti");
4706 fixunsxfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsxfsi");
4707 fixunsxfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsxfdi");
4708 fixunsxfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsxfti");
4710 fixunstfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunstfsi");
4711 fixunstfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunstfdi");
4712 fixunstfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunstfti");
4717 /* SCO 3.2 apparently has a broken ldexp. */
4730 #endif /* BROKEN_LDEXP */