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 /* from emit-rtl.c */
184 extern rtx gen_highpart ();
186 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
187 gives the gen_function to make a branch to test that condition. */
189 rtxfun bcc_gen_fctn[NUM_RTX_CODE];
191 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
192 gives the insn code to make a store-condition insn
193 to test that condition. */
195 enum insn_code setcc_gen_code[NUM_RTX_CODE];
197 static void emit_float_lib_cmp ();
199 /* Add a REG_EQUAL note to the last insn in SEQ. TARGET is being set to
200 the result of operation CODE applied to OP0 (and OP1 if it is a binary
203 If the last insn does not set TARGET, don't do anything, but return 1.
205 If a previous insn sets TARGET and TARGET is one of OP0 or OP1,
206 don't add the REG_EQUAL note but return 0. Our caller can then try
207 again, ensuring that TARGET is not one of the operands. */
210 add_equal_note (seq, target, code, op0, op1)
220 if ((GET_RTX_CLASS (code) != '1' && GET_RTX_CLASS (code) != '2'
221 && GET_RTX_CLASS (code) != 'c' && GET_RTX_CLASS (code) != '<')
222 || GET_CODE (seq) != SEQUENCE
223 || (set = single_set (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1))) == 0
224 || GET_CODE (target) == ZERO_EXTRACT
225 || (! rtx_equal_p (SET_DEST (set), target)
226 /* For a STRICT_LOW_PART, the REG_NOTE applies to what is inside the
228 && (GET_CODE (SET_DEST (set)) != STRICT_LOW_PART
229 || ! rtx_equal_p (SUBREG_REG (XEXP (SET_DEST (set), 0)),
233 /* If TARGET is in OP0 or OP1, check if anything in SEQ sets TARGET
234 besides the last insn. */
235 if (reg_overlap_mentioned_p (target, op0)
236 || (op1 && reg_overlap_mentioned_p (target, op1)))
237 for (i = XVECLEN (seq, 0) - 2; i >= 0; i--)
238 if (reg_set_p (target, XVECEXP (seq, 0, i)))
241 if (GET_RTX_CLASS (code) == '1')
242 note = gen_rtx (code, GET_MODE (target), op0);
244 note = gen_rtx (code, GET_MODE (target), op0, op1);
246 REG_NOTES (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1))
247 = gen_rtx (EXPR_LIST, REG_EQUAL, note,
248 REG_NOTES (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1)));
253 /* Generate code to perform an operation specified by BINOPTAB
254 on operands OP0 and OP1, with result having machine-mode MODE.
256 UNSIGNEDP is for the case where we have to widen the operands
257 to perform the operation. It says to use zero-extension.
259 If TARGET is nonzero, the value
260 is generated there, if it is convenient to do so.
261 In all cases an rtx is returned for the locus of the value;
262 this may or may not be TARGET. */
265 expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods)
266 enum machine_mode mode;
271 enum optab_methods methods;
273 enum mode_class class;
274 enum machine_mode wider_mode;
276 int commutative_op = 0;
277 int shift_op = (binoptab->code == ASHIFT
278 || binoptab->code == ASHIFTRT
279 || binoptab->code == LSHIFT
280 || binoptab->code == LSHIFTRT
281 || binoptab->code == ROTATE
282 || binoptab->code == ROTATERT);
283 rtx entry_last = get_last_insn ();
286 class = GET_MODE_CLASS (mode);
288 op0 = protect_from_queue (op0, 0);
289 op1 = protect_from_queue (op1, 0);
291 target = protect_from_queue (target, 1);
295 op0 = force_not_mem (op0);
296 op1 = force_not_mem (op1);
299 /* If subtracting an integer constant, convert this into an addition of
300 the negated constant. */
302 if (binoptab == sub_optab && GET_CODE (op1) == CONST_INT)
304 op1 = negate_rtx (mode, op1);
305 binoptab = add_optab;
308 /* If we are inside an appropriately-short loop and one operand is an
309 expensive constant, force it into a register. */
310 if (CONSTANT_P (op0) && preserve_subexpressions_p ()
311 && rtx_cost (op0, binoptab->code) > 2)
312 op0 = force_reg (mode, op0);
314 if (CONSTANT_P (op1) && preserve_subexpressions_p ()
315 && rtx_cost (op1, binoptab->code) > 2)
316 op1 = force_reg (shift_op ? word_mode : mode, op1);
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 && methods != OPTAB_DIRECT && methods != 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. Similarly for
473 SUBREGs that were made due to promoted objects. */
475 if (no_extend && GET_MODE (xop0) != VOIDmode
476 && ! (GET_CODE (xop0) == SUBREG
477 && SUBREG_PROMOTED_VAR_P (xop0)))
478 xop0 = gen_rtx (SUBREG, wider_mode,
479 force_reg (GET_MODE (xop0), xop0), 0);
481 xop0 = convert_to_mode (wider_mode, xop0, unsignedp);
483 if (no_extend && GET_MODE (xop1) != VOIDmode
484 && ! (GET_CODE (xop1) == SUBREG
485 && SUBREG_PROMOTED_VAR_P (xop1)))
486 xop1 = gen_rtx (SUBREG, wider_mode,
487 force_reg (GET_MODE (xop1), xop1), 0);
489 xop1 = convert_to_mode (wider_mode, xop1, unsignedp);
491 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
492 unsignedp, OPTAB_DIRECT);
495 if (class != MODE_INT)
498 target = gen_reg_rtx (mode);
499 convert_move (target, temp, 0);
503 return gen_lowpart (mode, temp);
506 delete_insns_since (last);
510 /* These can be done a word at a time. */
511 if ((binoptab == and_optab || binoptab == ior_optab || binoptab == xor_optab)
513 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
514 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
520 /* If TARGET is the same as one of the operands, the REG_EQUAL note
521 won't be accurate, so use a new target. */
522 if (target == 0 || target == op0 || target == op1)
523 target = gen_reg_rtx (mode);
527 /* Do the actual arithmetic. */
528 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
530 rtx target_piece = operand_subword (target, i, 1, mode);
531 rtx x = expand_binop (word_mode, binoptab,
532 operand_subword_force (op0, i, mode),
533 operand_subword_force (op1, i, mode),
534 target_piece, unsignedp, methods);
535 if (target_piece != x)
536 emit_move_insn (target_piece, x);
539 insns = get_insns ();
542 if (binoptab->code != UNKNOWN)
543 equiv_value = gen_rtx (binoptab->code, mode, op0, op1);
547 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
551 /* These can be done a word at a time by propagating carries. */
552 if ((binoptab == add_optab || binoptab == sub_optab)
554 && GET_MODE_SIZE (mode) >= 2 * UNITS_PER_WORD
555 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
558 rtx carry_tmp = gen_reg_rtx (word_mode);
559 optab otheroptab = binoptab == add_optab ? sub_optab : add_optab;
560 int nwords = GET_MODE_BITSIZE (mode) / BITS_PER_WORD;
561 rtx carry_in, carry_out;
564 /* We can handle either a 1 or -1 value for the carry. If STORE_FLAG
565 value is one of those, use it. Otherwise, use 1 since it is the
566 one easiest to get. */
567 #if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
568 int normalizep = STORE_FLAG_VALUE;
573 /* Prepare the operands. */
574 xop0 = force_reg (mode, op0);
575 xop1 = force_reg (mode, op1);
577 if (target == 0 || GET_CODE (target) != REG
578 || target == xop0 || target == xop1)
579 target = gen_reg_rtx (mode);
581 /* Do the actual arithmetic. */
582 for (i = 0; i < nwords; i++)
584 int index = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i);
585 rtx target_piece = operand_subword (target, index, 1, mode);
586 rtx op0_piece = operand_subword_force (xop0, index, mode);
587 rtx op1_piece = operand_subword_force (xop1, index, mode);
590 /* Main add/subtract of the input operands. */
591 x = expand_binop (word_mode, binoptab,
592 op0_piece, op1_piece,
593 target_piece, unsignedp, methods);
599 /* Store carry from main add/subtract. */
600 carry_out = gen_reg_rtx (word_mode);
601 carry_out = emit_store_flag (carry_out,
602 binoptab == add_optab ? LTU : GTU,
604 word_mode, 1, normalizep);
611 /* Add/subtract previous carry to main result. */
612 x = expand_binop (word_mode,
613 normalizep == 1 ? binoptab : otheroptab,
615 target_piece, 1, methods);
616 if (target_piece != x)
617 emit_move_insn (target_piece, x);
621 /* THIS CODE HAS NOT BEEN TESTED. */
622 /* Get out carry from adding/subtracting carry in. */
623 carry_tmp = emit_store_flag (carry_tmp,
624 binoptab == add_optab
627 word_mode, 1, normalizep);
628 /* Logical-ior the two poss. carry together. */
629 carry_out = expand_binop (word_mode, ior_optab,
630 carry_out, carry_tmp,
631 carry_out, 0, methods);
637 carry_in = carry_out;
640 if (i == GET_MODE_BITSIZE (mode) / BITS_PER_WORD)
644 temp = emit_move_insn (target, target);
645 REG_NOTES (temp) = gen_rtx (EXPR_LIST, REG_EQUAL,
646 gen_rtx (binoptab->code, mode, xop0, xop1),
651 delete_insns_since (last);
654 /* If we want to multiply two two-word values and have normal and widening
655 multiplies of single-word values, we can do this with three smaller
656 multiplications. Note that we do not make a REG_NO_CONFLICT block here
657 because we are not operating on one word at a time.
659 The multiplication proceeds as follows:
660 _______________________
661 [__op0_high_|__op0_low__]
662 _______________________
663 * [__op1_high_|__op1_low__]
664 _______________________________________________
665 _______________________
666 (1) [__op0_low__*__op1_low__]
667 _______________________
668 (2a) [__op0_low__*__op1_high_]
669 _______________________
670 (2b) [__op0_high_*__op1_low__]
671 _______________________
672 (3) [__op0_high_*__op1_high_]
675 This gives a 4-word result. Since we are only interested in the
676 lower 2 words, partial result (3) and the upper words of (2a) and
677 (2b) don't need to be calculated. Hence (2a) and (2b) can be
678 calculated using non-widening multiplication.
680 (1), however, needs to be calculated with an unsigned widening
681 multiplication. If this operation is not directly supported we
682 try using a signed widening multiplication and adjust the result.
683 This adjustment works as follows:
685 If both operands are positive then no adjustment is needed.
687 If the operands have different signs, for example op0_low < 0 and
688 op1_low >= 0, the instruction treats the most significant bit of
689 op0_low as a sign bit instead of a bit with significance
690 2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low
691 with 2**BITS_PER_WORD - op0_low, and two's complements the
692 result. Conclusion: We need to add op1_low * 2**BITS_PER_WORD to
695 Similarly, if both operands are negative, we need to add
696 (op0_low + op1_low) * 2**BITS_PER_WORD.
698 We use a trick to adjust quickly. We logically shift op0_low right
699 (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to
700 op0_high (op1_high) before it is used to calculate 2b (2a). If no
701 logical shift exists, we do an arithmetic right shift and subtract
704 if (binoptab == smul_optab
706 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
707 && smul_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
708 && add_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
709 && ((umul_widen_optab->handlers[(int) mode].insn_code
711 || (smul_widen_optab->handlers[(int) mode].insn_code
712 != CODE_FOR_nothing)))
714 int low = (WORDS_BIG_ENDIAN ? 1 : 0);
715 int high = (WORDS_BIG_ENDIAN ? 0 : 1);
716 rtx op0_high = operand_subword_force (op0, high, mode);
717 rtx op0_low = operand_subword_force (op0, low, mode);
718 rtx op1_high = operand_subword_force (op1, high, mode);
719 rtx op1_low = operand_subword_force (op1, low, mode);
724 /* If the target is the same as one of the inputs, don't use it. This
725 prevents problems with the REG_EQUAL note. */
726 if (target == op0 || target == op1)
729 /* Multiply the two lower words to get a double-word product.
730 If unsigned widening multiplication is available, use that;
731 otherwise use the signed form and compensate. */
733 if (umul_widen_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
735 product = expand_binop (mode, umul_widen_optab, op0_low, op1_low,
736 target, 1, OPTAB_DIRECT);
738 /* If we didn't succeed, delete everything we did so far. */
740 delete_insns_since (last);
742 op0_xhigh = op0_high, op1_xhigh = op1_high;
746 && smul_widen_optab->handlers[(int) mode].insn_code
749 rtx wordm1 = GEN_INT (BITS_PER_WORD - 1);
750 product = expand_binop (mode, smul_widen_optab, op0_low, op1_low,
751 target, 1, OPTAB_DIRECT);
752 op0_xhigh = expand_binop (word_mode, lshr_optab, op0_low, wordm1,
753 NULL_RTX, 1, OPTAB_DIRECT);
755 op0_xhigh = expand_binop (word_mode, add_optab, op0_high,
756 op0_xhigh, op0_xhigh, 0, OPTAB_DIRECT);
759 op0_xhigh = expand_binop (word_mode, ashr_optab, op0_low, wordm1,
760 NULL_RTX, 0, OPTAB_DIRECT);
762 op0_xhigh = expand_binop (word_mode, sub_optab, op0_high,
763 op0_xhigh, op0_xhigh, 0,
767 op1_xhigh = expand_binop (word_mode, lshr_optab, op1_low, wordm1,
768 NULL_RTX, 1, OPTAB_DIRECT);
770 op1_xhigh = expand_binop (word_mode, add_optab, op1_high,
771 op1_xhigh, op1_xhigh, 0, OPTAB_DIRECT);
774 op1_xhigh = expand_binop (word_mode, ashr_optab, op1_low, wordm1,
775 NULL_RTX, 0, OPTAB_DIRECT);
777 op1_xhigh = expand_binop (word_mode, sub_optab, op1_high,
778 op1_xhigh, op1_xhigh, 0,
783 /* If we have been able to directly compute the product of the
784 low-order words of the operands and perform any required adjustments
785 of the operands, we proceed by trying two more multiplications
786 and then computing the appropriate sum.
788 We have checked above that the required addition is provided.
789 Full-word addition will normally always succeed, especially if
790 it is provided at all, so we don't worry about its failure. The
791 multiplication may well fail, however, so we do handle that. */
793 if (product && op0_xhigh && op1_xhigh)
796 rtx product_high = operand_subword (product, high, 1, mode);
797 rtx temp = expand_binop (word_mode, binoptab, op0_low, op1_xhigh,
798 NULL_RTX, 0, OPTAB_DIRECT);
802 product_piece = expand_binop (word_mode, add_optab, temp,
803 product_high, product_high,
805 if (product_piece != product_high)
806 emit_move_insn (product_high, product_piece);
808 temp = expand_binop (word_mode, binoptab, op1_low, op0_xhigh,
809 NULL_RTX, 0, OPTAB_DIRECT);
811 product_piece = expand_binop (word_mode, add_optab, temp,
812 product_high, product_high,
814 if (product_piece != product_high)
815 emit_move_insn (product_high, product_piece);
817 temp = emit_move_insn (product, product);
818 REG_NOTES (temp) = gen_rtx (EXPR_LIST, REG_EQUAL,
819 gen_rtx (MULT, mode, op0, op1),
826 /* If we get here, we couldn't do it for some reason even though we
827 originally thought we could. Delete anything we've emitted in
830 delete_insns_since (last);
833 /* We need to open-code the complex type operations: '+, -, * and /' */
835 /* At this point we allow operations between two similar complex
836 numbers, and also if one of the operands is not a complex number
837 but rather of MODE_FLOAT or MODE_INT. However, the caller
838 must make sure that the MODE of the non-complex operand matches
839 the SUBMODE of the complex operand. */
841 if (class == MODE_COMPLEX_FLOAT || class == MODE_COMPLEX_INT)
853 /* Find the correct mode for the real and imaginary parts */
854 enum machine_mode submode
855 = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
856 class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
859 if (submode == BLKmode)
863 target = gen_reg_rtx (mode);
867 realr = gen_realpart (submode, target);
868 imagr = gen_imagpart (submode, target);
870 if (GET_MODE (op0) == mode)
872 real0 = gen_realpart (submode, op0);
873 imag0 = gen_imagpart (submode, op0);
878 if (GET_MODE (op1) == mode)
880 real1 = gen_realpart (submode, op1);
881 imag1 = gen_imagpart (submode, op1);
886 if (! real0 || ! real1 || ! (imag0 || imag1))
889 switch (binoptab->code)
892 /* (a+ib) + (c+id) = (a+c) + i(b+d) */
894 /* (a+ib) - (c+id) = (a-c) + i(b-d) */
895 res = expand_binop (submode, binoptab, real0, real1,
896 realr, unsignedp, methods);
898 emit_move_insn (realr, res);
901 res = expand_binop (submode, binoptab, imag0, imag1,
902 imagr, unsignedp, methods);
905 else if (binoptab->code == MINUS)
906 res = expand_unop (submode, neg_optab, imag1, imagr, unsignedp);
911 emit_move_insn (imagr, res);
915 /* (a+ib) * (c+id) = (ac-bd) + i(ad+cb) */
920 expand_binop (submode, sub_optab,
921 expand_binop (submode, binoptab, real0,
922 real1, 0, unsignedp, methods),
923 expand_binop (submode, binoptab, imag0,
924 imag1, 0, unsignedp, methods),
925 realr, unsignedp, methods);
928 emit_move_insn (realr, temp);
930 res = expand_binop (submode, add_optab,
931 expand_binop (submode, binoptab,
933 0, unsignedp, methods),
934 expand_binop (submode, binoptab,
936 0, unsignedp, methods),
937 imagr, unsignedp, methods);
939 emit_move_insn (imagr, res);
943 res = expand_binop (submode, binoptab, real0, real1,
944 realr, unsignedp, methods);
946 emit_move_insn (realr, res);
949 res = expand_binop (submode, binoptab,
950 real1, imag0, imagr, unsignedp, methods);
952 res = expand_binop (submode, binoptab,
953 real0, imag1, imagr, unsignedp, methods);
955 emit_move_insn (imagr, res);
960 /* (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd)) */
963 { /* (a+ib) / (c+i0) = (a/c) + i(b/c) */
964 /* Simply divide the real and imaginary parts by `c' */
965 res = expand_binop (submode, binoptab, real0, real1,
966 realr, unsignedp, methods);
968 emit_move_insn (realr, res);
970 res = expand_binop (submode, binoptab, imag0, real1,
971 imagr, unsignedp, methods);
973 emit_move_insn (imagr, res);
975 else /* Divisor is of complex type */
982 optab mulopt = unsignedp ? umul_widen_optab : smul_optab;
984 /* Divisor: c*c + d*d */
985 divisor = expand_binop (submode, add_optab,
986 expand_binop (submode, mulopt,
988 0, unsignedp, methods),
989 expand_binop (submode, mulopt,
991 0, unsignedp, methods),
992 0, unsignedp, methods);
994 if (! imag0) /* ((a)(c-id))/divisor */
995 { /* (a+i0) / (c+id) = (ac/(cc+dd)) + i(-ad/(cc+dd)) */
996 /* Calculate the dividend */
997 real_t = expand_binop (submode, mulopt, real0, real1,
998 0, unsignedp, methods);
1001 = expand_unop (submode, neg_optab,
1002 expand_binop (submode, mulopt, real0, imag1,
1003 0, unsignedp, methods),
1006 else /* ((a+ib)(c-id))/divider */
1008 /* Calculate the dividend */
1009 real_t = expand_binop (submode, add_optab,
1010 expand_binop (submode, mulopt,
1012 0, unsignedp, methods),
1013 expand_binop (submode, mulopt,
1015 0, unsignedp, methods),
1016 0, unsignedp, methods);
1018 imag_t = expand_binop (submode, sub_optab,
1019 expand_binop (submode, mulopt,
1021 0, unsignedp, methods),
1022 expand_binop (submode, mulopt,
1024 0, unsignedp, methods),
1025 0, unsignedp, methods);
1029 res = expand_binop (submode, binoptab, real_t, divisor,
1030 realr, unsignedp, methods);
1032 emit_move_insn (realr, res);
1034 res = expand_binop (submode, binoptab, imag_t, divisor,
1035 imagr, unsignedp, methods);
1037 emit_move_insn (imagr, res);
1048 if (binoptab->code != UNKNOWN)
1049 equiv_value = gen_rtx (binoptab->code, mode, op0, op1);
1053 emit_no_conflict_block (seq, target, op0, op1, equiv_value);
1058 /* It can't be open-coded in this mode.
1059 Use a library call if one is available and caller says that's ok. */
1061 if (binoptab->handlers[(int) mode].libfunc
1062 && (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN))
1065 rtx funexp = binoptab->handlers[(int) mode].libfunc;
1067 enum machine_mode op1_mode = mode;
1073 op1_mode = word_mode;
1074 /* Specify unsigned here,
1075 since negative shift counts are meaningless. */
1076 op1x = convert_to_mode (word_mode, op1, 1);
1079 /* Pass 1 for NO_QUEUE so we don't lose any increments
1080 if the libcall is cse'd or moved. */
1081 emit_library_call (binoptab->handlers[(int) mode].libfunc,
1082 1, mode, 2, op0, mode, op1x, op1_mode);
1084 insns = get_insns ();
1087 target = gen_reg_rtx (mode);
1088 emit_libcall_block (insns, target, hard_libcall_value (mode),
1089 gen_rtx (binoptab->code, mode, op0, op1));
1094 delete_insns_since (last);
1096 /* It can't be done in this mode. Can we do it in a wider mode? */
1098 if (! (methods == OPTAB_WIDEN || methods == OPTAB_LIB_WIDEN
1099 || methods == OPTAB_MUST_WIDEN))
1101 /* Caller says, don't even try. */
1102 delete_insns_since (entry_last);
1106 /* Compute the value of METHODS to pass to recursive calls.
1107 Don't allow widening to be tried recursively. */
1109 methods = (methods == OPTAB_LIB_WIDEN ? OPTAB_LIB : OPTAB_DIRECT);
1111 /* Look for a wider mode of the same class for which it appears we can do
1114 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1116 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1117 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1119 if ((binoptab->handlers[(int) wider_mode].insn_code
1120 != CODE_FOR_nothing)
1121 || (methods == OPTAB_LIB
1122 && binoptab->handlers[(int) wider_mode].libfunc))
1124 rtx xop0 = op0, xop1 = op1;
1127 /* For certain integer operations, we need not actually extend
1128 the narrow operands, as long as we will truncate
1129 the results to the same narrowness. Don't do this when
1130 WIDER_MODE is wider than a word since a paradoxical SUBREG
1131 isn't valid for such modes. */
1133 if ((binoptab == ior_optab || binoptab == and_optab
1134 || binoptab == xor_optab
1135 || binoptab == add_optab || binoptab == sub_optab
1136 || binoptab == smul_optab
1137 || binoptab == ashl_optab || binoptab == lshl_optab)
1138 && class == MODE_INT
1139 && GET_MODE_SIZE (wider_mode) <= UNITS_PER_WORD)
1142 /* If an operand is a constant integer, we might as well
1143 convert it since that is more efficient than using a SUBREG,
1144 unlike the case for other operands. Similarly for
1145 SUBREGs that were made due to promoted objects.*/
1147 if (no_extend && GET_MODE (xop0) != VOIDmode
1148 && ! (GET_CODE (xop0) == SUBREG
1149 && SUBREG_PROMOTED_VAR_P (xop0)))
1150 xop0 = gen_rtx (SUBREG, wider_mode,
1151 force_reg (GET_MODE (xop0), xop0), 0);
1153 xop0 = convert_to_mode (wider_mode, xop0, unsignedp);
1155 if (no_extend && GET_MODE (xop1) != VOIDmode
1156 && ! (GET_CODE (xop1) == SUBREG
1157 && SUBREG_PROMOTED_VAR_P (xop1)))
1158 xop1 = gen_rtx (SUBREG, wider_mode,
1159 force_reg (GET_MODE (xop1), xop1), 0);
1161 xop1 = convert_to_mode (wider_mode, xop1, unsignedp);
1163 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
1164 unsignedp, methods);
1167 if (class != MODE_INT)
1170 target = gen_reg_rtx (mode);
1171 convert_move (target, temp, 0);
1175 return gen_lowpart (mode, temp);
1178 delete_insns_since (last);
1183 delete_insns_since (entry_last);
1187 /* Expand a binary operator which has both signed and unsigned forms.
1188 UOPTAB is the optab for unsigned operations, and SOPTAB is for
1191 If we widen unsigned operands, we may use a signed wider operation instead
1192 of an unsigned wider operation, since the result would be the same. */
1195 sign_expand_binop (mode, uoptab, soptab, op0, op1, target, unsignedp, methods)
1196 enum machine_mode mode;
1197 optab uoptab, soptab;
1198 rtx op0, op1, target;
1200 enum optab_methods methods;
1203 optab direct_optab = unsignedp ? uoptab : soptab;
1204 struct optab wide_soptab;
1206 /* Do it without widening, if possible. */
1207 temp = expand_binop (mode, direct_optab, op0, op1, target,
1208 unsignedp, OPTAB_DIRECT);
1209 if (temp || methods == OPTAB_DIRECT)
1212 /* Try widening to a signed int. Make a fake signed optab that
1213 hides any signed insn for direct use. */
1214 wide_soptab = *soptab;
1215 wide_soptab.handlers[(int) mode].insn_code = CODE_FOR_nothing;
1216 wide_soptab.handlers[(int) mode].libfunc = 0;
1218 temp = expand_binop (mode, &wide_soptab, op0, op1, target,
1219 unsignedp, OPTAB_WIDEN);
1221 /* For unsigned operands, try widening to an unsigned int. */
1222 if (temp == 0 && unsignedp)
1223 temp = expand_binop (mode, uoptab, op0, op1, target,
1224 unsignedp, OPTAB_WIDEN);
1225 if (temp || methods == OPTAB_WIDEN)
1228 /* Use the right width lib call if that exists. */
1229 temp = expand_binop (mode, direct_optab, op0, op1, target, unsignedp, OPTAB_LIB);
1230 if (temp || methods == OPTAB_LIB)
1233 /* Must widen and use a lib call, use either signed or unsigned. */
1234 temp = expand_binop (mode, &wide_soptab, op0, op1, target,
1235 unsignedp, methods);
1239 return expand_binop (mode, uoptab, op0, op1, target,
1240 unsignedp, methods);
1244 /* Generate code to perform an operation specified by BINOPTAB
1245 on operands OP0 and OP1, with two results to TARG1 and TARG2.
1246 We assume that the order of the operands for the instruction
1247 is TARG0, OP0, OP1, TARG1, which would fit a pattern like
1248 [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
1250 Either TARG0 or TARG1 may be zero, but what that means is that
1251 that result is not actually wanted. We will generate it into
1252 a dummy pseudo-reg and discard it. They may not both be zero.
1254 Returns 1 if this operation can be performed; 0 if not. */
1257 expand_twoval_binop (binoptab, op0, op1, targ0, targ1, unsignedp)
1263 enum machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
1264 enum mode_class class;
1265 enum machine_mode wider_mode;
1266 rtx entry_last = get_last_insn ();
1269 class = GET_MODE_CLASS (mode);
1271 op0 = protect_from_queue (op0, 0);
1272 op1 = protect_from_queue (op1, 0);
1276 op0 = force_not_mem (op0);
1277 op1 = force_not_mem (op1);
1280 /* If we are inside an appropriately-short loop and one operand is an
1281 expensive constant, force it into a register. */
1282 if (CONSTANT_P (op0) && preserve_subexpressions_p ()
1283 && rtx_cost (op0, binoptab->code) > 2)
1284 op0 = force_reg (mode, op0);
1286 if (CONSTANT_P (op1) && preserve_subexpressions_p ()
1287 && rtx_cost (op1, binoptab->code) > 2)
1288 op1 = force_reg (mode, op1);
1291 targ0 = protect_from_queue (targ0, 1);
1293 targ0 = gen_reg_rtx (mode);
1295 targ1 = protect_from_queue (targ1, 1);
1297 targ1 = gen_reg_rtx (mode);
1299 /* Record where to go back to if we fail. */
1300 last = get_last_insn ();
1302 if (binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1304 int icode = (int) binoptab->handlers[(int) mode].insn_code;
1305 enum machine_mode mode0 = insn_operand_mode[icode][1];
1306 enum machine_mode mode1 = insn_operand_mode[icode][2];
1308 rtx xop0 = op0, xop1 = op1;
1310 /* In case this insn wants input operands in modes different from the
1311 result, convert the operands. */
1312 if (GET_MODE (op0) != VOIDmode && GET_MODE (op0) != mode0)
1313 xop0 = convert_to_mode (mode0, xop0, unsignedp);
1315 if (GET_MODE (op1) != VOIDmode && GET_MODE (op1) != mode1)
1316 xop1 = convert_to_mode (mode1, xop1, unsignedp);
1318 /* Now, if insn doesn't accept these operands, put them into pseudos. */
1319 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
1320 xop0 = copy_to_mode_reg (mode0, xop0);
1322 if (! (*insn_operand_predicate[icode][2]) (xop1, mode1))
1323 xop1 = copy_to_mode_reg (mode1, xop1);
1325 /* We could handle this, but we should always be called with a pseudo
1326 for our targets and all insns should take them as outputs. */
1327 if (! (*insn_operand_predicate[icode][0]) (targ0, mode)
1328 || ! (*insn_operand_predicate[icode][3]) (targ1, mode))
1331 pat = GEN_FCN (icode) (targ0, xop0, xop1, targ1);
1338 delete_insns_since (last);
1341 /* It can't be done in this mode. Can we do it in a wider mode? */
1343 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1345 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1346 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1348 if (binoptab->handlers[(int) wider_mode].insn_code
1349 != CODE_FOR_nothing)
1351 register rtx t0 = gen_reg_rtx (wider_mode);
1352 register rtx t1 = gen_reg_rtx (wider_mode);
1354 if (expand_twoval_binop (binoptab,
1355 convert_to_mode (wider_mode, op0,
1357 convert_to_mode (wider_mode, op1,
1361 convert_move (targ0, t0, unsignedp);
1362 convert_move (targ1, t1, unsignedp);
1366 delete_insns_since (last);
1371 delete_insns_since (entry_last);
1375 /* Generate code to perform an operation specified by UNOPTAB
1376 on operand OP0, with result having machine-mode MODE.
1378 UNSIGNEDP is for the case where we have to widen the operands
1379 to perform the operation. It says to use zero-extension.
1381 If TARGET is nonzero, the value
1382 is generated there, if it is convenient to do so.
1383 In all cases an rtx is returned for the locus of the value;
1384 this may or may not be TARGET. */
1387 expand_unop (mode, unoptab, op0, target, unsignedp)
1388 enum machine_mode mode;
1394 enum mode_class class;
1395 enum machine_mode wider_mode;
1397 rtx last = get_last_insn ();
1400 class = GET_MODE_CLASS (mode);
1402 op0 = protect_from_queue (op0, 0);
1406 op0 = force_not_mem (op0);
1410 target = protect_from_queue (target, 1);
1412 if (unoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1414 int icode = (int) unoptab->handlers[(int) mode].insn_code;
1415 enum machine_mode mode0 = insn_operand_mode[icode][1];
1421 temp = gen_reg_rtx (mode);
1423 if (GET_MODE (xop0) != VOIDmode
1424 && GET_MODE (xop0) != mode0)
1425 xop0 = convert_to_mode (mode0, xop0, unsignedp);
1427 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
1429 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
1430 xop0 = copy_to_mode_reg (mode0, xop0);
1432 if (! (*insn_operand_predicate[icode][0]) (temp, mode))
1433 temp = gen_reg_rtx (mode);
1435 pat = GEN_FCN (icode) (temp, xop0);
1438 if (GET_CODE (pat) == SEQUENCE
1439 && ! add_equal_note (pat, temp, unoptab->code, xop0, NULL_RTX))
1441 delete_insns_since (last);
1442 return expand_unop (mode, unoptab, op0, NULL_RTX, unsignedp);
1450 delete_insns_since (last);
1453 /* It can't be done in this mode. Can we open-code it in a wider mode? */
1455 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1456 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1457 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1459 if (unoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing)
1463 /* For certain operations, we need not actually extend
1464 the narrow operand, as long as we will truncate the
1465 results to the same narrowness. But it is faster to
1466 convert a SUBREG due to mode promotion. */
1468 if ((unoptab == neg_optab || unoptab == one_cmpl_optab)
1469 && GET_MODE_SIZE (wider_mode) <= UNITS_PER_WORD
1470 && class == MODE_INT
1471 && ! (GET_CODE (xop0) == SUBREG
1472 && SUBREG_PROMOTED_VAR_P (xop0)))
1473 xop0 = gen_rtx (SUBREG, wider_mode, force_reg (mode, xop0), 0);
1475 xop0 = convert_to_mode (wider_mode, xop0, unsignedp);
1477 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
1482 if (class != MODE_INT)
1485 target = gen_reg_rtx (mode);
1486 convert_move (target, temp, 0);
1490 return gen_lowpart (mode, temp);
1493 delete_insns_since (last);
1497 /* These can be done a word at a time. */
1498 if (unoptab == one_cmpl_optab
1499 && class == MODE_INT
1500 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
1501 && unoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
1506 if (target == 0 || target == op0)
1507 target = gen_reg_rtx (mode);
1511 /* Do the actual arithmetic. */
1512 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
1514 rtx target_piece = operand_subword (target, i, 1, mode);
1515 rtx x = expand_unop (word_mode, unoptab,
1516 operand_subword_force (op0, i, mode),
1517 target_piece, unsignedp);
1518 if (target_piece != x)
1519 emit_move_insn (target_piece, x);
1522 insns = get_insns ();
1525 emit_no_conflict_block (insns, target, op0, NULL_RTX,
1526 gen_rtx (unoptab->code, mode, op0));
1530 /* Open-code the complex negation operation. */
1531 else if (unoptab == neg_optab
1532 && (class == MODE_COMPLEX_FLOAT || class == MODE_COMPLEX_INT))
1538 /* Find the correct mode for the real and imaginary parts */
1539 enum machine_mode submode
1540 = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
1541 class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
1544 if (submode == BLKmode)
1548 target = gen_reg_rtx (mode);
1552 target_piece = gen_imagpart (submode, target);
1553 x = expand_unop (submode, unoptab,
1554 gen_imagpart (submode, op0),
1555 target_piece, unsignedp);
1556 if (target_piece != x)
1557 emit_move_insn (target_piece, x);
1559 target_piece = gen_realpart (submode, target);
1560 x = expand_unop (submode, unoptab,
1561 gen_realpart (submode, op0),
1562 target_piece, unsignedp);
1563 if (target_piece != x)
1564 emit_move_insn (target_piece, x);
1569 emit_no_conflict_block (seq, target, op0, 0,
1570 gen_rtx (unoptab->code, mode, op0));
1574 /* Now try a library call in this mode. */
1575 if (unoptab->handlers[(int) mode].libfunc)
1578 rtx funexp = unoptab->handlers[(int) mode].libfunc;
1582 /* Pass 1 for NO_QUEUE so we don't lose any increments
1583 if the libcall is cse'd or moved. */
1584 emit_library_call (unoptab->handlers[(int) mode].libfunc,
1585 1, mode, 1, op0, mode);
1586 insns = get_insns ();
1589 target = gen_reg_rtx (mode);
1590 emit_libcall_block (insns, target, hard_libcall_value (mode),
1591 gen_rtx (unoptab->code, mode, op0));
1596 /* It can't be done in this mode. Can we do it in a wider mode? */
1598 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1600 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1601 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1603 if ((unoptab->handlers[(int) wider_mode].insn_code
1604 != CODE_FOR_nothing)
1605 || unoptab->handlers[(int) wider_mode].libfunc)
1609 /* For certain operations, we need not actually extend
1610 the narrow operand, as long as we will truncate the
1611 results to the same narrowness. */
1613 if ((unoptab == neg_optab || unoptab == one_cmpl_optab)
1614 && GET_MODE_SIZE (wider_mode) <= UNITS_PER_WORD
1615 && class == MODE_INT
1616 && ! (GET_CODE (xop0) == SUBREG
1617 && SUBREG_PROMOTED_VAR_P (xop0)))
1618 xop0 = gen_rtx (SUBREG, wider_mode, force_reg (mode, xop0), 0);
1620 xop0 = convert_to_mode (wider_mode, xop0, unsignedp);
1622 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
1627 if (class != MODE_INT)
1630 target = gen_reg_rtx (mode);
1631 convert_move (target, temp, 0);
1635 return gen_lowpart (mode, temp);
1638 delete_insns_since (last);
1646 /* Emit code to compute the absolute value of OP0, with result to
1647 TARGET if convenient. (TARGET may be 0.) The return value says
1648 where the result actually is to be found.
1650 MODE is the mode of the operand; the mode of the result is
1651 different but can be deduced from MODE.
1653 UNSIGNEDP is relevant for complex integer modes. */
1656 expand_complex_abs (mode, op0, target, unsignedp)
1657 enum machine_mode mode;
1662 enum mode_class class = GET_MODE_CLASS (mode);
1663 enum machine_mode wider_mode;
1665 rtx entry_last = get_last_insn ();
1669 /* Find the correct mode for the real and imaginary parts. */
1670 enum machine_mode submode
1671 = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
1672 class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
1675 if (submode == BLKmode)
1678 op0 = protect_from_queue (op0, 0);
1682 op0 = force_not_mem (op0);
1685 last = get_last_insn ();
1688 target = protect_from_queue (target, 1);
1690 if (abs_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1692 int icode = (int) abs_optab->handlers[(int) mode].insn_code;
1693 enum machine_mode mode0 = insn_operand_mode[icode][1];
1699 temp = gen_reg_rtx (submode);
1701 if (GET_MODE (xop0) != VOIDmode
1702 && GET_MODE (xop0) != mode0)
1703 xop0 = convert_to_mode (mode0, xop0, unsignedp);
1705 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
1707 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
1708 xop0 = copy_to_mode_reg (mode0, xop0);
1710 if (! (*insn_operand_predicate[icode][0]) (temp, submode))
1711 temp = gen_reg_rtx (submode);
1713 pat = GEN_FCN (icode) (temp, xop0);
1716 if (GET_CODE (pat) == SEQUENCE
1717 && ! add_equal_note (pat, temp, abs_optab->code, xop0, NULL_RTX))
1719 delete_insns_since (last);
1720 return expand_unop (mode, abs_optab, op0, NULL_RTX, unsignedp);
1728 delete_insns_since (last);
1731 /* It can't be done in this mode. Can we open-code it in a wider mode? */
1733 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1734 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1736 if (abs_optab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing)
1740 xop0 = convert_to_mode (wider_mode, xop0, unsignedp);
1741 temp = expand_complex_abs (wider_mode, xop0, NULL_RTX, unsignedp);
1745 if (class != MODE_COMPLEX_INT)
1748 target = gen_reg_rtx (submode);
1749 convert_move (target, temp, 0);
1753 return gen_lowpart (submode, temp);
1756 delete_insns_since (last);
1760 /* Open-code the complex absolute-value operation
1761 if we can open-code sqrt. Otherwise it's not worth while. */
1762 if (sqrt_optab->handlers[(int) submode].insn_code != CODE_FOR_nothing)
1764 rtx real, imag, total;
1766 real = gen_realpart (submode, op0);
1767 imag = gen_imagpart (submode, op0);
1768 /* Square both parts. */
1769 real = expand_mult (mode, real, real, NULL_RTX, 0);
1770 imag = expand_mult (mode, imag, imag, NULL_RTX, 0);
1771 /* Sum the parts. */
1772 total = expand_binop (submode, add_optab, real, imag, 0,
1773 0, OPTAB_LIB_WIDEN);
1774 /* Get sqrt in TARGET. Set TARGET to where the result is. */
1775 target = expand_unop (submode, sqrt_optab, total, target, 0);
1777 delete_insns_since (last);
1782 /* Now try a library call in this mode. */
1783 if (abs_optab->handlers[(int) mode].libfunc)
1786 rtx funexp = abs_optab->handlers[(int) mode].libfunc;
1790 /* Pass 1 for NO_QUEUE so we don't lose any increments
1791 if the libcall is cse'd or moved. */
1792 emit_library_call (abs_optab->handlers[(int) mode].libfunc,
1793 1, mode, 1, op0, mode);
1794 insns = get_insns ();
1797 target = gen_reg_rtx (submode);
1798 emit_libcall_block (insns, target, hard_libcall_value (submode),
1799 gen_rtx (abs_optab->code, mode, op0));
1804 /* It can't be done in this mode. Can we do it in a wider mode? */
1806 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1807 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1809 if ((abs_optab->handlers[(int) wider_mode].insn_code
1810 != CODE_FOR_nothing)
1811 || abs_optab->handlers[(int) wider_mode].libfunc)
1815 xop0 = convert_to_mode (wider_mode, xop0, unsignedp);
1817 temp = expand_complex_abs (wider_mode, xop0, NULL_RTX, unsignedp);
1821 if (class != MODE_COMPLEX_INT)
1824 target = gen_reg_rtx (submode);
1825 convert_move (target, temp, 0);
1829 return gen_lowpart (submode, temp);
1832 delete_insns_since (last);
1836 delete_insns_since (entry_last);
1840 /* Generate an instruction whose insn-code is INSN_CODE,
1841 with two operands: an output TARGET and an input OP0.
1842 TARGET *must* be nonzero, and the output is always stored there.
1843 CODE is an rtx code such that (CODE OP0) is an rtx that describes
1844 the value that is stored into TARGET. */
1847 emit_unop_insn (icode, target, op0, code)
1854 enum machine_mode mode0 = insn_operand_mode[icode][1];
1857 temp = target = protect_from_queue (target, 1);
1859 op0 = protect_from_queue (op0, 0);
1862 op0 = force_not_mem (op0);
1864 /* Now, if insn does not accept our operands, put them into pseudos. */
1866 if (! (*insn_operand_predicate[icode][1]) (op0, mode0))
1867 op0 = copy_to_mode_reg (mode0, op0);
1869 if (! (*insn_operand_predicate[icode][0]) (temp, GET_MODE (temp))
1870 || (flag_force_mem && GET_CODE (temp) == MEM))
1871 temp = gen_reg_rtx (GET_MODE (temp));
1873 pat = GEN_FCN (icode) (temp, op0);
1875 if (GET_CODE (pat) == SEQUENCE && code != UNKNOWN)
1876 add_equal_note (pat, temp, code, op0, NULL_RTX);
1881 emit_move_insn (target, temp);
1884 /* Emit code to perform a series of operations on a multi-word quantity, one
1887 Such a block is preceded by a CLOBBER of the output, consists of multiple
1888 insns, each setting one word of the output, and followed by a SET copying
1889 the output to itself.
1891 Each of the insns setting words of the output receives a REG_NO_CONFLICT
1892 note indicating that it doesn't conflict with the (also multi-word)
1893 inputs. The entire block is surrounded by REG_LIBCALL and REG_RETVAL
1896 INSNS is a block of code generated to perform the operation, not including
1897 the CLOBBER and final copy. All insns that compute intermediate values
1898 are first emitted, followed by the block as described above. Only
1899 INSNs are allowed in the block; no library calls or jumps may be
1902 TARGET, OP0, and OP1 are the output and inputs of the operations,
1903 respectively. OP1 may be zero for a unary operation.
1905 EQUIV, if non-zero, is an expression to be placed into a REG_EQUAL note
1908 If TARGET is not a register, INSNS is simply emitted with no special
1911 The final insn emitted is returned. */
1914 emit_no_conflict_block (insns, target, op0, op1, equiv)
1920 rtx prev, next, first, last, insn;
1922 if (GET_CODE (target) != REG || reload_in_progress)
1923 return emit_insns (insns);
1925 /* First emit all insns that do not store into words of the output and remove
1926 these from the list. */
1927 for (insn = insns; insn; insn = next)
1932 next = NEXT_INSN (insn);
1934 if (GET_CODE (insn) != INSN)
1937 if (GET_CODE (PATTERN (insn)) == SET)
1938 set = PATTERN (insn);
1939 else if (GET_CODE (PATTERN (insn)) == PARALLEL)
1941 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
1942 if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET)
1944 set = XVECEXP (PATTERN (insn), 0, i);
1952 if (! reg_overlap_mentioned_p (target, SET_DEST (set)))
1954 if (PREV_INSN (insn))
1955 NEXT_INSN (PREV_INSN (insn)) = next;
1960 PREV_INSN (next) = PREV_INSN (insn);
1966 prev = get_last_insn ();
1968 /* Now write the CLOBBER of the output, followed by the setting of each
1969 of the words, followed by the final copy. */
1970 if (target != op0 && target != op1)
1971 emit_insn (gen_rtx (CLOBBER, VOIDmode, target));
1973 for (insn = insns; insn; insn = next)
1975 next = NEXT_INSN (insn);
1978 if (op1 && GET_CODE (op1) == REG)
1979 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_NO_CONFLICT, op1,
1982 if (op0 && GET_CODE (op0) == REG)
1983 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_NO_CONFLICT, op0,
1987 last = emit_move_insn (target, target);
1989 REG_NOTES (last) = gen_rtx (EXPR_LIST, REG_EQUAL, equiv, REG_NOTES (last));
1992 first = get_insns ();
1994 first = NEXT_INSN (prev);
1996 /* Encapsulate the block so it gets manipulated as a unit. */
1997 REG_NOTES (first) = gen_rtx (INSN_LIST, REG_LIBCALL, last,
1999 REG_NOTES (last) = gen_rtx (INSN_LIST, REG_RETVAL, first, REG_NOTES (last));
2004 /* Emit code to make a call to a constant function or a library call.
2006 INSNS is a list containing all insns emitted in the call.
2007 These insns leave the result in RESULT. Our block is to copy RESULT
2008 to TARGET, which is logically equivalent to EQUIV.
2010 We first emit any insns that set a pseudo on the assumption that these are
2011 loading constants into registers; doing so allows them to be safely cse'ed
2012 between blocks. Then we emit all the other insns in the block, followed by
2013 an insn to move RESULT to TARGET. This last insn will have a REQ_EQUAL
2014 note with an operand of EQUIV.
2016 Moving assignments to pseudos outside of the block is done to improve
2017 the generated code, but is not required to generate correct code,
2018 hence being unable to move an assignment is not grounds for not making
2019 a libcall block. There are two reasons why it is safe to leave these
2020 insns inside the block: First, we know that these pseudos cannot be
2021 used in generated RTL outside the block since they are created for
2022 temporary purposes within the block. Second, CSE will not record the
2023 values of anything set inside a libcall block, so we know they must
2024 be dead at the end of the block.
2026 Except for the first group of insns (the ones setting pseudos), the
2027 block is delimited by REG_RETVAL and REG_LIBCALL notes. */
2030 emit_libcall_block (insns, target, result, equiv)
2036 rtx prev, next, first, last, insn;
2038 /* First emit all insns that set pseudos. Remove them from the list as
2039 we go. Avoid insns that set pseudo which were referenced in previous
2040 insns. These can be generated by move_by_pieces, for example,
2041 to update an address. */
2043 for (insn = insns; insn; insn = next)
2045 rtx set = single_set (insn);
2047 next = NEXT_INSN (insn);
2049 if (set != 0 && GET_CODE (SET_DEST (set)) == REG
2050 && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER
2052 || (! reg_mentioned_p (SET_DEST (set), PATTERN (insns))
2053 && ! reg_used_between_p (SET_DEST (set), insns, insn))))
2055 if (PREV_INSN (insn))
2056 NEXT_INSN (PREV_INSN (insn)) = next;
2061 PREV_INSN (next) = PREV_INSN (insn);
2067 prev = get_last_insn ();
2069 /* Write the remaining insns followed by the final copy. */
2071 for (insn = insns; insn; insn = next)
2073 next = NEXT_INSN (insn);
2078 last = emit_move_insn (target, result);
2079 REG_NOTES (last) = gen_rtx (EXPR_LIST, REG_EQUAL, equiv, REG_NOTES (last));
2082 first = get_insns ();
2084 first = NEXT_INSN (prev);
2086 /* Encapsulate the block so it gets manipulated as a unit. */
2087 REG_NOTES (first) = gen_rtx (INSN_LIST, REG_LIBCALL, last,
2089 REG_NOTES (last) = gen_rtx (INSN_LIST, REG_RETVAL, first, REG_NOTES (last));
2092 /* Generate code to store zero in X. */
2098 emit_move_insn (x, const0_rtx);
2101 /* Generate code to store 1 in X
2102 assuming it contains zero beforehand. */
2105 emit_0_to_1_insn (x)
2108 emit_move_insn (x, const1_rtx);
2111 /* Generate code to compare X with Y
2112 so that the condition codes are set.
2114 MODE is the mode of the inputs (in case they are const_int).
2115 UNSIGNEDP nonzero says that X and Y are unsigned;
2116 this matters if they need to be widened.
2118 If they have mode BLKmode, then SIZE specifies the size of both X and Y,
2119 and ALIGN specifies the known shared alignment of X and Y.
2121 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).
2122 It is ignored for fixed-point and block comparisons;
2123 it is used only for floating-point comparisons. */
2126 emit_cmp_insn (x, y, comparison, size, mode, unsignedp, align)
2128 enum rtx_code comparison;
2130 enum machine_mode mode;
2134 enum mode_class class;
2135 enum machine_mode wider_mode;
2137 class = GET_MODE_CLASS (mode);
2139 /* They could both be VOIDmode if both args are immediate constants,
2140 but we should fold that at an earlier stage.
2141 With no special code here, this will call abort,
2142 reminding the programmer to implement such folding. */
2144 if (mode != BLKmode && flag_force_mem)
2146 x = force_not_mem (x);
2147 y = force_not_mem (y);
2150 /* If we are inside an appropriately-short loop and one operand is an
2151 expensive constant, force it into a register. */
2152 if (CONSTANT_P (x) && preserve_subexpressions_p () && rtx_cost (x, COMPARE) > 2)
2153 x = force_reg (mode, x);
2155 if (CONSTANT_P (y) && preserve_subexpressions_p () && rtx_cost (y, COMPARE) > 2)
2156 y = force_reg (mode, y);
2158 /* Don't let both operands fail to indicate the mode. */
2159 if (GET_MODE (x) == VOIDmode && GET_MODE (y) == VOIDmode)
2160 x = force_reg (mode, x);
2162 /* Handle all BLKmode compares. */
2164 if (mode == BLKmode)
2167 x = protect_from_queue (x, 0);
2168 y = protect_from_queue (y, 0);
2172 #ifdef HAVE_cmpstrqi
2174 && GET_CODE (size) == CONST_INT
2175 && INTVAL (size) < (1 << GET_MODE_BITSIZE (QImode)))
2177 enum machine_mode result_mode
2178 = insn_operand_mode[(int) CODE_FOR_cmpstrqi][0];
2179 rtx result = gen_reg_rtx (result_mode);
2180 emit_insn (gen_cmpstrqi (result, x, y, size, GEN_INT (align)));
2181 emit_cmp_insn (result, const0_rtx, comparison, NULL_RTX,
2186 #ifdef HAVE_cmpstrhi
2188 && GET_CODE (size) == CONST_INT
2189 && INTVAL (size) < (1 << GET_MODE_BITSIZE (HImode)))
2191 enum machine_mode result_mode
2192 = insn_operand_mode[(int) CODE_FOR_cmpstrhi][0];
2193 rtx result = gen_reg_rtx (result_mode);
2194 emit_insn (gen_cmpstrhi (result, x, y, size, GEN_INT (align)));
2195 emit_cmp_insn (result, const0_rtx, comparison, NULL_RTX,
2200 #ifdef HAVE_cmpstrsi
2203 enum machine_mode result_mode
2204 = insn_operand_mode[(int) CODE_FOR_cmpstrsi][0];
2205 rtx result = gen_reg_rtx (result_mode);
2206 size = protect_from_queue (size, 0);
2207 emit_insn (gen_cmpstrsi (result, x, y,
2208 convert_to_mode (SImode, size, 1),
2210 emit_cmp_insn (result, const0_rtx, comparison, NULL_RTX,
2216 #ifdef TARGET_MEM_FUNCTIONS
2217 emit_library_call (memcmp_libfunc, 0,
2218 TYPE_MODE (integer_type_node), 3,
2219 XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
2222 emit_library_call (bcmp_libfunc, 0,
2223 TYPE_MODE (integer_type_node), 3,
2224 XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
2227 emit_cmp_insn (hard_libcall_value (TYPE_MODE (integer_type_node)),
2228 const0_rtx, comparison, NULL_RTX,
2229 TYPE_MODE (integer_type_node), 0, 0);
2234 /* Handle some compares against zero. */
2236 if (y == CONST0_RTX (mode)
2237 && tst_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2239 int icode = (int) tst_optab->handlers[(int) mode].insn_code;
2242 x = protect_from_queue (x, 0);
2243 y = protect_from_queue (y, 0);
2245 /* Now, if insn does accept these operands, put them into pseudos. */
2246 if (! (*insn_operand_predicate[icode][0])
2247 (x, insn_operand_mode[icode][0]))
2248 x = copy_to_mode_reg (insn_operand_mode[icode][0], x);
2250 emit_insn (GEN_FCN (icode) (x));
2254 /* Handle compares for which there is a directly suitable insn. */
2256 if (cmp_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2258 int icode = (int) cmp_optab->handlers[(int) mode].insn_code;
2261 x = protect_from_queue (x, 0);
2262 y = protect_from_queue (y, 0);
2264 /* Now, if insn doesn't accept these operands, put them into pseudos. */
2265 if (! (*insn_operand_predicate[icode][0])
2266 (x, insn_operand_mode[icode][0]))
2267 x = copy_to_mode_reg (insn_operand_mode[icode][0], x);
2269 if (! (*insn_operand_predicate[icode][1])
2270 (y, insn_operand_mode[icode][1]))
2271 y = copy_to_mode_reg (insn_operand_mode[icode][1], y);
2273 emit_insn (GEN_FCN (icode) (x, y));
2277 /* Try widening if we can find a direct insn that way. */
2279 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
2281 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2282 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2284 if (cmp_optab->handlers[(int) wider_mode].insn_code
2285 != CODE_FOR_nothing)
2287 x = protect_from_queue (x, 0);
2288 y = protect_from_queue (y, 0);
2289 x = convert_to_mode (wider_mode, x, unsignedp);
2290 y = convert_to_mode (wider_mode, y, unsignedp);
2291 emit_cmp_insn (x, y, comparison, NULL_RTX,
2292 wider_mode, unsignedp, align);
2298 /* Handle a lib call just for the mode we are using. */
2300 if (cmp_optab->handlers[(int) mode].libfunc
2301 && class != MODE_FLOAT)
2303 rtx libfunc = cmp_optab->handlers[(int) mode].libfunc;
2304 /* If we want unsigned, and this mode has a distinct unsigned
2305 comparison routine, use that. */
2306 if (unsignedp && ucmp_optab->handlers[(int) mode].libfunc)
2307 libfunc = ucmp_optab->handlers[(int) mode].libfunc;
2309 emit_library_call (libfunc, 1,
2310 SImode, 2, x, mode, y, mode);
2312 /* Integer comparison returns a result that must be compared against 1,
2313 so that even if we do an unsigned compare afterward,
2314 there is still a value that can represent the result "less than". */
2316 emit_cmp_insn (hard_libcall_value (SImode), const1_rtx,
2317 comparison, NULL_RTX, SImode, unsignedp, 0);
2321 if (class == MODE_FLOAT)
2322 emit_float_lib_cmp (x, y, comparison);
2328 /* Nonzero if a compare of mode MODE can be done straightforwardly
2329 (without splitting it into pieces). */
2332 can_compare_p (mode)
2333 enum machine_mode mode;
2337 if (cmp_optab->handlers[(int)mode].insn_code != CODE_FOR_nothing)
2339 mode = GET_MODE_WIDER_MODE (mode);
2340 } while (mode != VOIDmode);
2345 /* Emit a library call comparison between floating point X and Y.
2346 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */
2349 emit_float_lib_cmp (x, y, comparison)
2351 enum rtx_code comparison;
2353 enum machine_mode mode = GET_MODE (x);
2360 libfunc = eqsf2_libfunc;
2364 libfunc = nesf2_libfunc;
2368 libfunc = gtsf2_libfunc;
2372 libfunc = gesf2_libfunc;
2376 libfunc = ltsf2_libfunc;
2380 libfunc = lesf2_libfunc;
2383 else if (mode == DFmode)
2387 libfunc = eqdf2_libfunc;
2391 libfunc = nedf2_libfunc;
2395 libfunc = gtdf2_libfunc;
2399 libfunc = gedf2_libfunc;
2403 libfunc = ltdf2_libfunc;
2407 libfunc = ledf2_libfunc;
2410 else if (mode == XFmode)
2414 libfunc = eqxf2_libfunc;
2418 libfunc = nexf2_libfunc;
2422 libfunc = gtxf2_libfunc;
2426 libfunc = gexf2_libfunc;
2430 libfunc = ltxf2_libfunc;
2434 libfunc = lexf2_libfunc;
2437 else if (mode == TFmode)
2441 libfunc = eqtf2_libfunc;
2445 libfunc = netf2_libfunc;
2449 libfunc = gttf2_libfunc;
2453 libfunc = getf2_libfunc;
2457 libfunc = lttf2_libfunc;
2461 libfunc = letf2_libfunc;
2466 enum machine_mode wider_mode;
2468 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2469 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2471 if ((cmp_optab->handlers[(int) wider_mode].insn_code
2472 != CODE_FOR_nothing)
2473 || (cmp_optab->handlers[(int) wider_mode].libfunc != 0))
2475 x = protect_from_queue (x, 0);
2476 y = protect_from_queue (y, 0);
2477 x = convert_to_mode (wider_mode, x, 0);
2478 y = convert_to_mode (wider_mode, y, 0);
2479 emit_float_lib_cmp (x, y, comparison);
2486 emit_library_call (libfunc, 1,
2487 SImode, 2, x, mode, y, mode);
2489 emit_cmp_insn (hard_libcall_value (SImode), const0_rtx, comparison,
2490 NULL_RTX, SImode, 0, 0);
2493 /* Generate code to indirectly jump to a location given in the rtx LOC. */
2496 emit_indirect_jump (loc)
2499 if (! ((*insn_operand_predicate[(int)CODE_FOR_indirect_jump][0])
2501 loc = copy_to_mode_reg (insn_operand_mode[(int)CODE_FOR_indirect_jump][0],
2504 emit_jump_insn (gen_indirect_jump (loc));
2508 /* These three functions generate an insn body and return it
2509 rather than emitting the insn.
2511 They do not protect from queued increments,
2512 because they may be used 1) in protect_from_queue itself
2513 and 2) in other passes where there is no queue. */
2515 /* Generate and return an insn body to add Y to X. */
2518 gen_add2_insn (x, y)
2521 int icode = (int) add_optab->handlers[(int) GET_MODE (x)].insn_code;
2523 if (! (*insn_operand_predicate[icode][0]) (x, insn_operand_mode[icode][0])
2524 || ! (*insn_operand_predicate[icode][1]) (x, insn_operand_mode[icode][1])
2525 || ! (*insn_operand_predicate[icode][2]) (y, insn_operand_mode[icode][2]))
2528 return (GEN_FCN (icode) (x, x, y));
2532 have_add2_insn (mode)
2533 enum machine_mode mode;
2535 return add_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
2538 /* Generate and return an insn body to subtract Y from X. */
2541 gen_sub2_insn (x, y)
2544 int icode = (int) sub_optab->handlers[(int) GET_MODE (x)].insn_code;
2546 if (! (*insn_operand_predicate[icode][0]) (x, insn_operand_mode[icode][0])
2547 || ! (*insn_operand_predicate[icode][1]) (x, insn_operand_mode[icode][1])
2548 || ! (*insn_operand_predicate[icode][2]) (y, insn_operand_mode[icode][2]))
2551 return (GEN_FCN (icode) (x, x, y));
2555 have_sub2_insn (mode)
2556 enum machine_mode mode;
2558 return sub_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
2561 /* Generate the body of an instruction to copy Y into X. */
2564 gen_move_insn (x, y)
2567 register enum machine_mode mode = GET_MODE (x);
2568 enum insn_code insn_code;
2570 if (mode == VOIDmode)
2571 mode = GET_MODE (y);
2573 insn_code = mov_optab->handlers[(int) mode].insn_code;
2575 /* Handle MODE_CC modes: If we don't have a special move insn for this mode,
2576 find a mode to do it in. If we have a movcc, use it. Otherwise,
2577 find the MODE_INT mode of the same width. */
2579 if (insn_code == CODE_FOR_nothing)
2581 enum machine_mode tmode = VOIDmode;
2584 if (GET_MODE_CLASS (mode) == MODE_CC && mode != CCmode
2585 && mov_optab->handlers[(int) CCmode].insn_code != CODE_FOR_nothing)
2587 else if (GET_MODE_CLASS (mode) == MODE_CC)
2588 for (tmode = QImode; tmode != VOIDmode;
2589 tmode = GET_MODE_WIDER_MODE (tmode))
2590 if (GET_MODE_SIZE (tmode) == GET_MODE_SIZE (mode))
2593 if (tmode == VOIDmode)
2596 /* Get X and Y in TMODE. We can't use gen_lowpart here because it
2597 may call change_address which is not appropriate if we were
2598 called when a reload was in progress. We don't have to worry
2599 about changing the address since the size in bytes is supposed to
2600 be the same. Copy the MEM to change the mode and move any
2601 substitutions from the old MEM to the new one. */
2603 if (reload_in_progress)
2605 x = gen_lowpart_common (tmode, x1);
2606 if (x == 0 && GET_CODE (x1) == MEM)
2608 x = gen_rtx (MEM, tmode, XEXP (x1, 0));
2609 RTX_UNCHANGING_P (x) = RTX_UNCHANGING_P (x1);
2610 MEM_IN_STRUCT_P (x) = MEM_IN_STRUCT_P (x1);
2611 MEM_VOLATILE_P (x) = MEM_VOLATILE_P (x1);
2612 copy_replacements (x1, x);
2615 y = gen_lowpart_common (tmode, y1);
2616 if (y == 0 && GET_CODE (y1) == MEM)
2618 y = gen_rtx (MEM, tmode, XEXP (y1, 0));
2619 RTX_UNCHANGING_P (y) = RTX_UNCHANGING_P (y1);
2620 MEM_IN_STRUCT_P (y) = MEM_IN_STRUCT_P (y1);
2621 MEM_VOLATILE_P (y) = MEM_VOLATILE_P (y1);
2622 copy_replacements (y1, y);
2627 x = gen_lowpart (tmode, x);
2628 y = gen_lowpart (tmode, y);
2631 insn_code = mov_optab->handlers[(int) tmode].insn_code;
2634 return (GEN_FCN (insn_code) (x, y));
2637 /* Tables of patterns for extending one integer mode to another. */
2638 static enum insn_code extendtab[MAX_MACHINE_MODE][MAX_MACHINE_MODE][2];
2640 /* Return the insn code used to extend FROM_MODE to TO_MODE.
2641 UNSIGNEDP specifies zero-extension instead of sign-extension. If
2642 no such operation exists, CODE_FOR_nothing will be returned. */
2645 can_extend_p (to_mode, from_mode, unsignedp)
2646 enum machine_mode to_mode, from_mode;
2649 return extendtab[(int) to_mode][(int) from_mode][unsignedp];
2652 /* Generate the body of an insn to extend Y (with mode MFROM)
2653 into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */
2656 gen_extend_insn (x, y, mto, mfrom, unsignedp)
2658 enum machine_mode mto, mfrom;
2661 return (GEN_FCN (extendtab[(int) mto][(int) mfrom][unsignedp]) (x, y));
2669 for (p = extendtab[0][0];
2670 p < extendtab[0][0] + sizeof extendtab / sizeof extendtab[0][0][0];
2672 *p = CODE_FOR_nothing;
2674 #ifdef HAVE_extendditi2
2675 if (HAVE_extendditi2)
2676 extendtab[(int) TImode][(int) DImode][0] = CODE_FOR_extendditi2;
2678 #ifdef HAVE_extendsiti2
2679 if (HAVE_extendsiti2)
2680 extendtab[(int) TImode][(int) SImode][0] = CODE_FOR_extendsiti2;
2682 #ifdef HAVE_extendhiti2
2683 if (HAVE_extendhiti2)
2684 extendtab[(int) TImode][(int) HImode][0] = CODE_FOR_extendhiti2;
2686 #ifdef HAVE_extendqiti2
2687 if (HAVE_extendqiti2)
2688 extendtab[(int) TImode][(int) QImode][0] = CODE_FOR_extendqiti2;
2690 #ifdef HAVE_extendsidi2
2691 if (HAVE_extendsidi2)
2692 extendtab[(int) DImode][(int) SImode][0] = CODE_FOR_extendsidi2;
2694 #ifdef HAVE_extendhidi2
2695 if (HAVE_extendhidi2)
2696 extendtab[(int) DImode][(int) HImode][0] = CODE_FOR_extendhidi2;
2698 #ifdef HAVE_extendqidi2
2699 if (HAVE_extendqidi2)
2700 extendtab[(int) DImode][(int) QImode][0] = CODE_FOR_extendqidi2;
2702 #ifdef HAVE_extendhisi2
2703 if (HAVE_extendhisi2)
2704 extendtab[(int) SImode][(int) HImode][0] = CODE_FOR_extendhisi2;
2706 #ifdef HAVE_extendqisi2
2707 if (HAVE_extendqisi2)
2708 extendtab[(int) SImode][(int) QImode][0] = CODE_FOR_extendqisi2;
2710 #ifdef HAVE_extendqihi2
2711 if (HAVE_extendqihi2)
2712 extendtab[(int) HImode][(int) QImode][0] = CODE_FOR_extendqihi2;
2715 #ifdef HAVE_zero_extendditi2
2716 if (HAVE_zero_extendsiti2)
2717 extendtab[(int) TImode][(int) DImode][1] = CODE_FOR_zero_extendditi2;
2719 #ifdef HAVE_zero_extendsiti2
2720 if (HAVE_zero_extendsiti2)
2721 extendtab[(int) TImode][(int) SImode][1] = CODE_FOR_zero_extendsiti2;
2723 #ifdef HAVE_zero_extendhiti2
2724 if (HAVE_zero_extendhiti2)
2725 extendtab[(int) TImode][(int) HImode][1] = CODE_FOR_zero_extendhiti2;
2727 #ifdef HAVE_zero_extendqiti2
2728 if (HAVE_zero_extendqiti2)
2729 extendtab[(int) TImode][(int) QImode][1] = CODE_FOR_zero_extendqiti2;
2731 #ifdef HAVE_zero_extendsidi2
2732 if (HAVE_zero_extendsidi2)
2733 extendtab[(int) DImode][(int) SImode][1] = CODE_FOR_zero_extendsidi2;
2735 #ifdef HAVE_zero_extendhidi2
2736 if (HAVE_zero_extendhidi2)
2737 extendtab[(int) DImode][(int) HImode][1] = CODE_FOR_zero_extendhidi2;
2739 #ifdef HAVE_zero_extendqidi2
2740 if (HAVE_zero_extendqidi2)
2741 extendtab[(int) DImode][(int) QImode][1] = CODE_FOR_zero_extendqidi2;
2743 #ifdef HAVE_zero_extendhisi2
2744 if (HAVE_zero_extendhisi2)
2745 extendtab[(int) SImode][(int) HImode][1] = CODE_FOR_zero_extendhisi2;
2747 #ifdef HAVE_zero_extendqisi2
2748 if (HAVE_zero_extendqisi2)
2749 extendtab[(int) SImode][(int) QImode][1] = CODE_FOR_zero_extendqisi2;
2751 #ifdef HAVE_zero_extendqihi2
2752 if (HAVE_zero_extendqihi2)
2753 extendtab[(int) HImode][(int) QImode][1] = CODE_FOR_zero_extendqihi2;
2757 /* can_fix_p and can_float_p say whether the target machine
2758 can directly convert a given fixed point type to
2759 a given floating point type, or vice versa.
2760 The returned value is the CODE_FOR_... value to use,
2761 or CODE_FOR_nothing if these modes cannot be directly converted. */
2763 static enum insn_code fixtab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
2764 static enum insn_code fixtrunctab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
2765 static enum insn_code floattab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
2767 /* *TRUNCP_PTR is set to 1 if it is necessary to output
2768 an explicit FTRUNC insn before the fix insn; otherwise 0. */
2770 static enum insn_code
2771 can_fix_p (fixmode, fltmode, unsignedp, truncp_ptr)
2772 enum machine_mode fltmode, fixmode;
2777 if (fixtrunctab[(int) fltmode][(int) fixmode][unsignedp] != CODE_FOR_nothing)
2778 return fixtrunctab[(int) fltmode][(int) fixmode][unsignedp];
2780 if (ftrunc_optab->handlers[(int) fltmode].insn_code != CODE_FOR_nothing)
2783 return fixtab[(int) fltmode][(int) fixmode][unsignedp];
2785 return CODE_FOR_nothing;
2788 static enum insn_code
2789 can_float_p (fltmode, fixmode, unsignedp)
2790 enum machine_mode fixmode, fltmode;
2793 return floattab[(int) fltmode][(int) fixmode][unsignedp];
2800 for (p = fixtab[0][0];
2801 p < fixtab[0][0] + sizeof fixtab / sizeof (fixtab[0][0][0]);
2803 *p = CODE_FOR_nothing;
2804 for (p = fixtrunctab[0][0];
2805 p < fixtrunctab[0][0] + sizeof fixtrunctab / sizeof (fixtrunctab[0][0][0]);
2807 *p = CODE_FOR_nothing;
2809 #ifdef HAVE_fixqfqi2
2811 fixtab[(int) QFmode][(int) QImode][0] = CODE_FOR_fixqfqi2;
2813 #ifdef HAVE_fixhfqi2
2815 fixtab[(int) HFmode][(int) QImode][0] = CODE_FOR_fixhfqi2;
2817 #ifdef HAVE_fixhfhi2
2819 fixtab[(int) HFmode][(int) QImode][0] = CODE_FOR_fixhfhi2;
2821 #ifdef HAVE_fixsfqi2
2823 fixtab[(int) SFmode][(int) QImode][0] = CODE_FOR_fixsfqi2;
2825 #ifdef HAVE_fixsfhi2
2827 fixtab[(int) SFmode][(int) HImode][0] = CODE_FOR_fixsfhi2;
2829 #ifdef HAVE_fixsfsi2
2831 fixtab[(int) SFmode][(int) SImode][0] = CODE_FOR_fixsfsi2;
2833 #ifdef HAVE_fixsfdi2
2835 fixtab[(int) SFmode][(int) DImode][0] = CODE_FOR_fixsfdi2;
2838 #ifdef HAVE_fixdfqi2
2840 fixtab[(int) DFmode][(int) QImode][0] = CODE_FOR_fixdfqi2;
2842 #ifdef HAVE_fixdfhi2
2844 fixtab[(int) DFmode][(int) HImode][0] = CODE_FOR_fixdfhi2;
2846 #ifdef HAVE_fixdfsi2
2848 fixtab[(int) DFmode][(int) SImode][0] = CODE_FOR_fixdfsi2;
2850 #ifdef HAVE_fixdfdi2
2852 fixtab[(int) DFmode][(int) DImode][0] = CODE_FOR_fixdfdi2;
2854 #ifdef HAVE_fixdfti2
2856 fixtab[(int) DFmode][(int) TImode][0] = CODE_FOR_fixdfti2;
2859 #ifdef HAVE_fixxfqi2
2861 fixtab[(int) XFmode][(int) QImode][0] = CODE_FOR_fixxfqi2;
2863 #ifdef HAVE_fixxfhi2
2865 fixtab[(int) XFmode][(int) HImode][0] = CODE_FOR_fixxfhi2;
2867 #ifdef HAVE_fixxfsi2
2869 fixtab[(int) XFmode][(int) SImode][0] = CODE_FOR_fixxfsi2;
2871 #ifdef HAVE_fixxfdi2
2873 fixtab[(int) XFmode][(int) DImode][0] = CODE_FOR_fixxfdi2;
2875 #ifdef HAVE_fixxfti2
2877 fixtab[(int) XFmode][(int) TImode][0] = CODE_FOR_fixxfti2;
2880 #ifdef HAVE_fixtfqi2
2882 fixtab[(int) TFmode][(int) QImode][0] = CODE_FOR_fixtfqi2;
2884 #ifdef HAVE_fixtfhi2
2886 fixtab[(int) TFmode][(int) HImode][0] = CODE_FOR_fixtfhi2;
2888 #ifdef HAVE_fixtfsi2
2890 fixtab[(int) TFmode][(int) SImode][0] = CODE_FOR_fixtfsi2;
2892 #ifdef HAVE_fixtfdi2
2894 fixtab[(int) TFmode][(int) DImode][0] = CODE_FOR_fixtfdi2;
2896 #ifdef HAVE_fixtfti2
2898 fixtab[(int) TFmode][(int) TImode][0] = CODE_FOR_fixtfti2;
2901 #ifdef HAVE_fixunsqfqi2
2902 if (HAVE_fixunsqfqi2)
2903 fixtab[(int) QFmode][(int) QImode][0] = CODE_FOR_fixunsqfqi2;
2905 #ifdef HAVE_fixunshfqi2
2906 if (HAVE_fixunshfqi2)
2907 fixtab[(int) HFmode][(int) QImode][0] = CODE_FOR_fixunshfqi2;
2909 #ifdef HAVE_fixunshfhi2
2910 if (HAVE_fixunshfhi2)
2911 fixtab[(int) HFmode][(int) QImode][0] = CODE_FOR_fixunshfhi2;
2914 #ifdef HAVE_fixunssfqi2
2915 if (HAVE_fixunssfqi2)
2916 fixtab[(int) SFmode][(int) QImode][1] = CODE_FOR_fixunssfqi2;
2918 #ifdef HAVE_fixunssfhi2
2919 if (HAVE_fixunssfhi2)
2920 fixtab[(int) SFmode][(int) HImode][1] = CODE_FOR_fixunssfhi2;
2922 #ifdef HAVE_fixunssfsi2
2923 if (HAVE_fixunssfsi2)
2924 fixtab[(int) SFmode][(int) SImode][1] = CODE_FOR_fixunssfsi2;
2926 #ifdef HAVE_fixunssfdi2
2927 if (HAVE_fixunssfdi2)
2928 fixtab[(int) SFmode][(int) DImode][1] = CODE_FOR_fixunssfdi2;
2931 #ifdef HAVE_fixunsdfqi2
2932 if (HAVE_fixunsdfqi2)
2933 fixtab[(int) DFmode][(int) QImode][1] = CODE_FOR_fixunsdfqi2;
2935 #ifdef HAVE_fixunsdfhi2
2936 if (HAVE_fixunsdfhi2)
2937 fixtab[(int) DFmode][(int) HImode][1] = CODE_FOR_fixunsdfhi2;
2939 #ifdef HAVE_fixunsdfsi2
2940 if (HAVE_fixunsdfsi2)
2941 fixtab[(int) DFmode][(int) SImode][1] = CODE_FOR_fixunsdfsi2;
2943 #ifdef HAVE_fixunsdfdi2
2944 if (HAVE_fixunsdfdi2)
2945 fixtab[(int) DFmode][(int) DImode][1] = CODE_FOR_fixunsdfdi2;
2947 #ifdef HAVE_fixunsdfti2
2948 if (HAVE_fixunsdfti2)
2949 fixtab[(int) DFmode][(int) TImode][1] = CODE_FOR_fixunsdfti2;
2952 #ifdef HAVE_fixunsxfqi2
2953 if (HAVE_fixunsxfqi2)
2954 fixtab[(int) XFmode][(int) QImode][1] = CODE_FOR_fixunsxfqi2;
2956 #ifdef HAVE_fixunsxfhi2
2957 if (HAVE_fixunsxfhi2)
2958 fixtab[(int) XFmode][(int) HImode][1] = CODE_FOR_fixunsxfhi2;
2960 #ifdef HAVE_fixunsxfsi2
2961 if (HAVE_fixunsxfsi2)
2962 fixtab[(int) XFmode][(int) SImode][1] = CODE_FOR_fixunsxfsi2;
2964 #ifdef HAVE_fixunsxfdi2
2965 if (HAVE_fixunsxfdi2)
2966 fixtab[(int) XFmode][(int) DImode][1] = CODE_FOR_fixunsxfdi2;
2968 #ifdef HAVE_fixunsxfti2
2969 if (HAVE_fixunsxfti2)
2970 fixtab[(int) XFmode][(int) TImode][1] = CODE_FOR_fixunsxfti2;
2973 #ifdef HAVE_fixunstfqi2
2974 if (HAVE_fixunstfqi2)
2975 fixtab[(int) TFmode][(int) QImode][1] = CODE_FOR_fixunstfqi2;
2977 #ifdef HAVE_fixunstfhi2
2978 if (HAVE_fixunstfhi2)
2979 fixtab[(int) TFmode][(int) HImode][1] = CODE_FOR_fixunstfhi2;
2981 #ifdef HAVE_fixunstfsi2
2982 if (HAVE_fixunstfsi2)
2983 fixtab[(int) TFmode][(int) SImode][1] = CODE_FOR_fixunstfsi2;
2985 #ifdef HAVE_fixunstfdi2
2986 if (HAVE_fixunstfdi2)
2987 fixtab[(int) TFmode][(int) DImode][1] = CODE_FOR_fixunstfdi2;
2989 #ifdef HAVE_fixunstfti2
2990 if (HAVE_fixunstfti2)
2991 fixtab[(int) TFmode][(int) TImode][1] = CODE_FOR_fixunstfti2;
2994 #ifdef HAVE_fix_truncqfqi2
2995 if (HAVE_fix_truncqfqi2)
2996 fixtab[(int) QFmode][(int) QImode][0] = CODE_FOR_fix_truncqfqi2;
2998 #ifdef HAVE_fix_trunchfqi2
2999 if (HAVE_fix_trunchfqi2)
3000 fixtab[(int) HFmode][(int) QImode][0] = CODE_FOR_fix_trunchfqi2;
3002 #ifdef HAVE_fixhfhi2
3004 fixtab[(int) HFmode][(int) QImode][0] = CODE_FOR_fixhfhi2;
3006 #ifdef HAVE_fix_truncsfqi2
3007 if (HAVE_fix_truncsfqi2)
3008 fixtrunctab[(int) SFmode][(int) QImode][0] = CODE_FOR_fix_truncsfqi2;
3010 #ifdef HAVE_fix_truncsfhi2
3011 if (HAVE_fix_truncsfhi2)
3012 fixtrunctab[(int) SFmode][(int) HImode][0] = CODE_FOR_fix_truncsfhi2;
3014 #ifdef HAVE_fix_truncsfsi2
3015 if (HAVE_fix_truncsfsi2)
3016 fixtrunctab[(int) SFmode][(int) SImode][0] = CODE_FOR_fix_truncsfsi2;
3018 #ifdef HAVE_fix_truncsfdi2
3019 if (HAVE_fix_truncsfdi2)
3020 fixtrunctab[(int) SFmode][(int) DImode][0] = CODE_FOR_fix_truncsfdi2;
3023 #ifdef HAVE_fix_truncdfqi2
3024 if (HAVE_fix_truncdfqi2)
3025 fixtrunctab[(int) DFmode][(int) QImode][0] = CODE_FOR_fix_truncdfqi2;
3027 #ifdef HAVE_fix_truncdfhi2
3028 if (HAVE_fix_truncdfhi2)
3029 fixtrunctab[(int) DFmode][(int) HImode][0] = CODE_FOR_fix_truncdfhi2;
3031 #ifdef HAVE_fix_truncdfsi2
3032 if (HAVE_fix_truncdfsi2)
3033 fixtrunctab[(int) DFmode][(int) SImode][0] = CODE_FOR_fix_truncdfsi2;
3035 #ifdef HAVE_fix_truncdfdi2
3036 if (HAVE_fix_truncdfdi2)
3037 fixtrunctab[(int) DFmode][(int) DImode][0] = CODE_FOR_fix_truncdfdi2;
3039 #ifdef HAVE_fix_truncdfti2
3040 if (HAVE_fix_truncdfti2)
3041 fixtrunctab[(int) DFmode][(int) TImode][0] = CODE_FOR_fix_truncdfti2;
3044 #ifdef HAVE_fix_truncxfqi2
3045 if (HAVE_fix_truncxfqi2)
3046 fixtrunctab[(int) XFmode][(int) QImode][0] = CODE_FOR_fix_truncxfqi2;
3048 #ifdef HAVE_fix_truncxfhi2
3049 if (HAVE_fix_truncxfhi2)
3050 fixtrunctab[(int) XFmode][(int) HImode][0] = CODE_FOR_fix_truncxfhi2;
3052 #ifdef HAVE_fix_truncxfsi2
3053 if (HAVE_fix_truncxfsi2)
3054 fixtrunctab[(int) XFmode][(int) SImode][0] = CODE_FOR_fix_truncxfsi2;
3056 #ifdef HAVE_fix_truncxfdi2
3057 if (HAVE_fix_truncxfdi2)
3058 fixtrunctab[(int) XFmode][(int) DImode][0] = CODE_FOR_fix_truncxfdi2;
3060 #ifdef HAVE_fix_truncxfti2
3061 if (HAVE_fix_truncxfti2)
3062 fixtrunctab[(int) XFmode][(int) TImode][0] = CODE_FOR_fix_truncxfti2;
3065 #ifdef HAVE_fix_trunctfqi2
3066 if (HAVE_fix_trunctfqi2)
3067 fixtrunctab[(int) TFmode][(int) QImode][0] = CODE_FOR_fix_trunctfqi2;
3069 #ifdef HAVE_fix_trunctfhi2
3070 if (HAVE_fix_trunctfhi2)
3071 fixtrunctab[(int) TFmode][(int) HImode][0] = CODE_FOR_fix_trunctfhi2;
3073 #ifdef HAVE_fix_trunctfsi2
3074 if (HAVE_fix_trunctfsi2)
3075 fixtrunctab[(int) TFmode][(int) SImode][0] = CODE_FOR_fix_trunctfsi2;
3077 #ifdef HAVE_fix_trunctfdi2
3078 if (HAVE_fix_trunctfdi2)
3079 fixtrunctab[(int) TFmode][(int) DImode][0] = CODE_FOR_fix_trunctfdi2;
3081 #ifdef HAVE_fix_trunctfti2
3082 if (HAVE_fix_trunctfti2)
3083 fixtrunctab[(int) TFmode][(int) TImode][0] = CODE_FOR_fix_trunctfti2;
3086 #ifdef HAVE_fixuns_truncqfqi2
3087 if (HAVE_fixuns_truncqfqi2)
3088 fixtab[(int) QFmode][(int) QImode][0] = CODE_FOR_fixuns_truncqfqi2;
3090 #ifdef HAVE_fixuns_trunchfqi2
3091 if (HAVE_fixuns_trunchfqi2)
3092 fixtab[(int) HFmode][(int) QImode][0] = CODE_FOR_fixuns_trunchfqi2;
3094 #ifdef HAVE_fixhfhi2
3096 fixtab[(int) HFmode][(int) QImode][0] = CODE_FOR_fixhfhi2;
3098 #ifdef HAVE_fixuns_truncsfqi2
3099 if (HAVE_fixuns_truncsfqi2)
3100 fixtrunctab[(int) SFmode][(int) QImode][1] = CODE_FOR_fixuns_truncsfqi2;
3102 #ifdef HAVE_fixuns_truncsfhi2
3103 if (HAVE_fixuns_truncsfhi2)
3104 fixtrunctab[(int) SFmode][(int) HImode][1] = CODE_FOR_fixuns_truncsfhi2;
3106 #ifdef HAVE_fixuns_truncsfsi2
3107 if (HAVE_fixuns_truncsfsi2)
3108 fixtrunctab[(int) SFmode][(int) SImode][1] = CODE_FOR_fixuns_truncsfsi2;
3110 #ifdef HAVE_fixuns_truncsfdi2
3111 if (HAVE_fixuns_truncsfdi2)
3112 fixtrunctab[(int) SFmode][(int) DImode][1] = CODE_FOR_fixuns_truncsfdi2;
3115 #ifdef HAVE_fixuns_truncdfqi2
3116 if (HAVE_fixuns_truncdfqi2)
3117 fixtrunctab[(int) DFmode][(int) QImode][1] = CODE_FOR_fixuns_truncdfqi2;
3119 #ifdef HAVE_fixuns_truncdfhi2
3120 if (HAVE_fixuns_truncdfhi2)
3121 fixtrunctab[(int) DFmode][(int) HImode][1] = CODE_FOR_fixuns_truncdfhi2;
3123 #ifdef HAVE_fixuns_truncdfsi2
3124 if (HAVE_fixuns_truncdfsi2)
3125 fixtrunctab[(int) DFmode][(int) SImode][1] = CODE_FOR_fixuns_truncdfsi2;
3127 #ifdef HAVE_fixuns_truncdfdi2
3128 if (HAVE_fixuns_truncdfdi2)
3129 fixtrunctab[(int) DFmode][(int) DImode][1] = CODE_FOR_fixuns_truncdfdi2;
3131 #ifdef HAVE_fixuns_truncdfti2
3132 if (HAVE_fixuns_truncdfti2)
3133 fixtrunctab[(int) DFmode][(int) TImode][1] = CODE_FOR_fixuns_truncdfti2;
3136 #ifdef HAVE_fixuns_truncxfqi2
3137 if (HAVE_fixuns_truncxfqi2)
3138 fixtrunctab[(int) XFmode][(int) QImode][1] = CODE_FOR_fixuns_truncxfqi2;
3140 #ifdef HAVE_fixuns_truncxfhi2
3141 if (HAVE_fixuns_truncxfhi2)
3142 fixtrunctab[(int) XFmode][(int) HImode][1] = CODE_FOR_fixuns_truncxfhi2;
3144 #ifdef HAVE_fixuns_truncxfsi2
3145 if (HAVE_fixuns_truncxfsi2)
3146 fixtrunctab[(int) XFmode][(int) SImode][1] = CODE_FOR_fixuns_truncxfsi2;
3148 #ifdef HAVE_fixuns_truncxfdi2
3149 if (HAVE_fixuns_truncxfdi2)
3150 fixtrunctab[(int) XFmode][(int) DImode][1] = CODE_FOR_fixuns_truncxfdi2;
3152 #ifdef HAVE_fixuns_truncxfti2
3153 if (HAVE_fixuns_truncxfti2)
3154 fixtrunctab[(int) XFmode][(int) TImode][1] = CODE_FOR_fixuns_truncxfti2;
3157 #ifdef HAVE_fixuns_trunctfqi2
3158 if (HAVE_fixuns_trunctfqi2)
3159 fixtrunctab[(int) TFmode][(int) QImode][1] = CODE_FOR_fixuns_trunctfqi2;
3161 #ifdef HAVE_fixuns_trunctfhi2
3162 if (HAVE_fixuns_trunctfhi2)
3163 fixtrunctab[(int) TFmode][(int) HImode][1] = CODE_FOR_fixuns_trunctfhi2;
3165 #ifdef HAVE_fixuns_trunctfsi2
3166 if (HAVE_fixuns_trunctfsi2)
3167 fixtrunctab[(int) TFmode][(int) SImode][1] = CODE_FOR_fixuns_trunctfsi2;
3169 #ifdef HAVE_fixuns_trunctfdi2
3170 if (HAVE_fixuns_trunctfdi2)
3171 fixtrunctab[(int) TFmode][(int) DImode][1] = CODE_FOR_fixuns_trunctfdi2;
3173 #ifdef HAVE_fixuns_trunctfti2
3174 if (HAVE_fixuns_trunctfti2)
3175 fixtrunctab[(int) TFmode][(int) TImode][1] = CODE_FOR_fixuns_trunctfti2;
3178 #ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC
3179 /* This flag says the same insns that convert to a signed fixnum
3180 also convert validly to an unsigned one. */
3184 for (i = 0; i < NUM_MACHINE_MODES; i++)
3185 for (j = 0; j < NUM_MACHINE_MODES; j++)
3186 fixtrunctab[i][j][1] = fixtrunctab[i][j][0];
3195 for (p = floattab[0][0];
3196 p < floattab[0][0] + sizeof floattab / sizeof (floattab[0][0][0]);
3198 *p = CODE_FOR_nothing;
3200 #ifdef HAVE_floatqiqf2
3201 if (HAVE_floatqiqf2)
3202 floattab[(int) QFmode][(int) QImode][0] = CODE_FOR_floatqiqf2;
3204 #ifdef HAVE_floathiqf2
3205 if (HAVE_floathiqf2)
3206 floattab[(int) QFmode][(int) HImode][0] = CODE_FOR_floathiqf2;
3208 #ifdef HAVE_floatsiqf2
3209 if (HAVE_floatsiqf2)
3210 floattab[(int) QFmode][(int) SImode][0] = CODE_FOR_floatsiqf2;
3212 #ifdef HAVE_floatdiqf2
3213 if (HAVE_floatdiqf2)
3214 floattab[(int) QFmode][(int) DImode][0] = CODE_FOR_floatdiqf2;
3216 #ifdef HAVE_floattiqf2
3217 if (HAVE_floattiqf2)
3218 floattab[(int) QFmode][(int) TImode][0] = CODE_FOR_floattiqf2;
3221 #ifdef HAVE_floatqihf2
3222 if (HAVE_floatqihf2)
3223 floattab[(int) HFmode][(int) QImode][0] = CODE_FOR_floatqihf2;
3225 #ifdef HAVE_floathihf2
3226 if (HAVE_floathihf2)
3227 floattab[(int) HFmode][(int) HImode][0] = CODE_FOR_floathihf2;
3229 #ifdef HAVE_floatsihf2
3230 if (HAVE_floatsihf2)
3231 floattab[(int) HFmode][(int) SImode][0] = CODE_FOR_floatsihf2;
3233 #ifdef HAVE_floatdihf2
3234 if (HAVE_floatdihf2)
3235 floattab[(int) HFmode][(int) DImode][0] = CODE_FOR_floatdihf2;
3237 #ifdef HAVE_floattihf2
3238 if (HAVE_floattihf2)
3239 floattab[(int) HFmode][(int) TImode][0] = CODE_FOR_floattihf2;
3242 #ifdef HAVE_floatqisf2
3243 if (HAVE_floatqisf2)
3244 floattab[(int) SFmode][(int) QImode][0] = CODE_FOR_floatqisf2;
3246 #ifdef HAVE_floathisf2
3247 if (HAVE_floathisf2)
3248 floattab[(int) SFmode][(int) HImode][0] = CODE_FOR_floathisf2;
3250 #ifdef HAVE_floatsisf2
3251 if (HAVE_floatsisf2)
3252 floattab[(int) SFmode][(int) SImode][0] = CODE_FOR_floatsisf2;
3254 #ifdef HAVE_floatdisf2
3255 if (HAVE_floatdisf2)
3256 floattab[(int) SFmode][(int) DImode][0] = CODE_FOR_floatdisf2;
3258 #ifdef HAVE_floattisf2
3259 if (HAVE_floattisf2)
3260 floattab[(int) SFmode][(int) TImode][0] = CODE_FOR_floattisf2;
3263 #ifdef HAVE_floatqidf2
3264 if (HAVE_floatqidf2)
3265 floattab[(int) DFmode][(int) QImode][0] = CODE_FOR_floatqidf2;
3267 #ifdef HAVE_floathidf2
3268 if (HAVE_floathidf2)
3269 floattab[(int) DFmode][(int) HImode][0] = CODE_FOR_floathidf2;
3271 #ifdef HAVE_floatsidf2
3272 if (HAVE_floatsidf2)
3273 floattab[(int) DFmode][(int) SImode][0] = CODE_FOR_floatsidf2;
3275 #ifdef HAVE_floatdidf2
3276 if (HAVE_floatdidf2)
3277 floattab[(int) DFmode][(int) DImode][0] = CODE_FOR_floatdidf2;
3279 #ifdef HAVE_floattidf2
3280 if (HAVE_floattidf2)
3281 floattab[(int) DFmode][(int) TImode][0] = CODE_FOR_floattidf2;
3284 #ifdef HAVE_floatqixf2
3285 if (HAVE_floatqixf2)
3286 floattab[(int) XFmode][(int) QImode][0] = CODE_FOR_floatqixf2;
3288 #ifdef HAVE_floathixf2
3289 if (HAVE_floathixf2)
3290 floattab[(int) XFmode][(int) HImode][0] = CODE_FOR_floathixf2;
3292 #ifdef HAVE_floatsixf2
3293 if (HAVE_floatsixf2)
3294 floattab[(int) XFmode][(int) SImode][0] = CODE_FOR_floatsixf2;
3296 #ifdef HAVE_floatdixf2
3297 if (HAVE_floatdixf2)
3298 floattab[(int) XFmode][(int) DImode][0] = CODE_FOR_floatdixf2;
3300 #ifdef HAVE_floattixf2
3301 if (HAVE_floattixf2)
3302 floattab[(int) XFmode][(int) TImode][0] = CODE_FOR_floattixf2;
3305 #ifdef HAVE_floatqitf2
3306 if (HAVE_floatqitf2)
3307 floattab[(int) TFmode][(int) QImode][0] = CODE_FOR_floatqitf2;
3309 #ifdef HAVE_floathitf2
3310 if (HAVE_floathitf2)
3311 floattab[(int) TFmode][(int) HImode][0] = CODE_FOR_floathitf2;
3313 #ifdef HAVE_floatsitf2
3314 if (HAVE_floatsitf2)
3315 floattab[(int) TFmode][(int) SImode][0] = CODE_FOR_floatsitf2;
3317 #ifdef HAVE_floatditf2
3318 if (HAVE_floatditf2)
3319 floattab[(int) TFmode][(int) DImode][0] = CODE_FOR_floatditf2;
3321 #ifdef HAVE_floattitf2
3322 if (HAVE_floattitf2)
3323 floattab[(int) TFmode][(int) TImode][0] = CODE_FOR_floattitf2;
3326 #ifdef HAVE_floatunsqiqf2
3327 if (HAVE_floatunsqiqf2)
3328 floattab[(int) QFmode][(int) QImode][0] = CODE_FOR_floatunsqiqf2;
3330 #ifdef HAVE_floatunshiqf2
3331 if (HAVE_floatunshiqf2)
3332 floattab[(int) QFmode][(int) HImode][0] = CODE_FOR_floatunshiqf2;
3334 #ifdef HAVE_floatunssiqf2
3335 if (HAVE_floatunsqsiqf2)
3336 floattab[(int) QFmode][(int) SImode][0] = CODE_FOR_floatunssiqf2;
3338 #ifdef HAVE_floatunsdiqf2
3339 if (HAVE_floatunsdiqf2)
3340 floattab[(int) QFmode][(int) DImode][0] = CODE_FOR_floatunsdiqf2;
3342 #ifdef HAVE_floatunstiqf2
3343 if (HAVE_floatunstiqf2)
3344 floattab[(int) QFmode][(int) TImode][0] = CODE_FOR_floatunstiqf2;
3347 #ifdef HAVE_floatunsqihf2
3348 if (HAVE_floatunsqihf2)
3349 floattab[(int) HFmode][(int) QImode][0] = CODE_FOR_floatunsqihf2;
3351 #ifdef HAVE_floatunshihf2
3352 if (HAVE_floatunshihf2)
3353 floattab[(int) HFmode][(int) HImode][0] = CODE_FOR_floatunshihf2;
3355 #ifdef HAVE_floatunssihf2
3356 if (HAVE_floatunssihf2)
3357 floattab[(int) HFmode][(int) SImode][0] = CODE_FOR_floatunssihf2;
3359 #ifdef HAVE_floatunsdihf2
3360 if (HAVE_floatunsdihf2)
3361 floattab[(int) HFmode][(int) DImode][0] = CODE_FOR_floatunsdihf2;
3363 #ifdef HAVE_floatunstihf2
3364 if (HAVE_floatunstihf2)
3365 floattab[(int) HFmode][(int) TImode][0] = CODE_FOR_floatunstihf2;
3368 #ifdef HAVE_floatqunsqisf2
3369 if (HAVE_floatunsqisf2)
3370 floattab[(int) SFmode][(int) QImode][1] = CODE_FOR_floatunsqisf2;
3372 #ifdef HAVE_floatunshisf2
3373 if (HAVE_floatunshisf2)
3374 floattab[(int) SFmode][(int) HImode][1] = CODE_FOR_floatunshisf2;
3376 #ifdef HAVE_floatunssisf2
3377 if (HAVE_floatunssisf2)
3378 floattab[(int) SFmode][(int) SImode][1] = CODE_FOR_floatunssisf2;
3380 #ifdef HAVE_floatunsdisf2
3381 if (HAVE_floatunsdisf2)
3382 floattab[(int) SFmode][(int) DImode][1] = CODE_FOR_floatunsdisf2;
3384 #ifdef HAVE_floatunstisf2
3385 if (HAVE_floatunstisf2)
3386 floattab[(int) SFmode][(int) TImode][1] = CODE_FOR_floatunstisf2;
3389 #ifdef HAVE_floatunsqidf2
3390 if (HAVE_floatunsqidf2)
3391 floattab[(int) DFmode][(int) QImode][1] = CODE_FOR_floatunsqidf2;
3393 #ifdef HAVE_floatunshidf2
3394 if (HAVE_floatunshidf2)
3395 floattab[(int) DFmode][(int) HImode][1] = CODE_FOR_floatunshidf2;
3397 #ifdef HAVE_floatunssidf2
3398 if (HAVE_floatunssidf2)
3399 floattab[(int) DFmode][(int) SImode][1] = CODE_FOR_floatunssidf2;
3401 #ifdef HAVE_floatunsdidf2
3402 if (HAVE_floatunsdidf2)
3403 floattab[(int) DFmode][(int) DImode][1] = CODE_FOR_floatunsdidf2;
3405 #ifdef HAVE_floatunstidf2
3406 if (HAVE_floatunstidf2)
3407 floattab[(int) DFmode][(int) TImode][1] = CODE_FOR_floatunstidf2;
3410 #ifdef HAVE_floatunsqixf2
3411 if (HAVE_floatunsqixf2)
3412 floattab[(int) XFmode][(int) QImode][1] = CODE_FOR_floatunsqixf2;
3414 #ifdef HAVE_floatunshixf2
3415 if (HAVE_floatunshixf2)
3416 floattab[(int) XFmode][(int) HImode][1] = CODE_FOR_floatunshixf2;
3418 #ifdef HAVE_floatunssixf2
3419 if (HAVE_floatunssixf2)
3420 floattab[(int) XFmode][(int) SImode][1] = CODE_FOR_floatunssixf2;
3422 #ifdef HAVE_floatunsdixf2
3423 if (HAVE_floatunsdixf2)
3424 floattab[(int) XFmode][(int) DImode][1] = CODE_FOR_floatunsdixf2;
3426 #ifdef HAVE_floatunstixf2
3427 if (HAVE_floatunstixf2)
3428 floattab[(int) XFmode][(int) TImode][1] = CODE_FOR_floatunstixf2;
3431 #ifdef HAVE_floatunsqitf2
3432 if (HAVE_floatunsqitf2)
3433 floattab[(int) TFmode][(int) QImode][1] = CODE_FOR_floatunsqitf2;
3435 #ifdef HAVE_floatunshitf2
3436 if (HAVE_floatunshitf2)
3437 floattab[(int) TFmode][(int) HImode][1] = CODE_FOR_floatunshitf2;
3439 #ifdef HAVE_floatunssitf2
3440 if (HAVE_floatunssitf2)
3441 floattab[(int) TFmode][(int) SImode][1] = CODE_FOR_floatunssitf2;
3443 #ifdef HAVE_floatunsditf2
3444 if (HAVE_floatunsditf2)
3445 floattab[(int) TFmode][(int) DImode][1] = CODE_FOR_floatunsditf2;
3447 #ifdef HAVE_floatunstitf2
3448 if (HAVE_floatunstitf2)
3449 floattab[(int) TFmode][(int) TImode][1] = CODE_FOR_floatunstitf2;
3453 /* Generate code to convert FROM to floating point
3454 and store in TO. FROM must be fixed point and not VOIDmode.
3455 UNSIGNEDP nonzero means regard FROM as unsigned.
3456 Normally this is done by correcting the final value
3457 if it is negative. */
3460 expand_float (to, from, unsignedp)
3464 enum insn_code icode;
3465 register rtx target = to;
3466 enum machine_mode fmode, imode;
3468 /* Crash now, because we won't be able to decide which mode to use. */
3469 if (GET_MODE (from) == VOIDmode)
3472 /* Look for an insn to do the conversion. Do it in the specified
3473 modes if possible; otherwise convert either input, output or both to
3474 wider mode. If the integer mode is wider than the mode of FROM,
3475 we can do the conversion signed even if the input is unsigned. */
3477 for (imode = GET_MODE (from); imode != VOIDmode;
3478 imode = GET_MODE_WIDER_MODE (imode))
3479 for (fmode = GET_MODE (to); fmode != VOIDmode;
3480 fmode = GET_MODE_WIDER_MODE (fmode))
3482 int doing_unsigned = unsignedp;
3484 icode = can_float_p (fmode, imode, unsignedp);
3485 if (icode == CODE_FOR_nothing && imode != GET_MODE (from) && unsignedp)
3486 icode = can_float_p (fmode, imode, 0), doing_unsigned = 0;
3488 if (icode != CODE_FOR_nothing)
3490 to = protect_from_queue (to, 1);
3491 from = protect_from_queue (from, 0);
3493 if (imode != GET_MODE (from))
3494 from = convert_to_mode (imode, from, unsignedp);
3496 if (fmode != GET_MODE (to))
3497 target = gen_reg_rtx (fmode);
3499 emit_unop_insn (icode, target, from,
3500 doing_unsigned ? UNSIGNED_FLOAT : FLOAT);
3503 convert_move (to, target, 0);
3508 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
3510 /* Unsigned integer, and no way to convert directly.
3511 Convert as signed, then conditionally adjust the result. */
3514 rtx label = gen_label_rtx ();
3516 REAL_VALUE_TYPE offset;
3520 to = protect_from_queue (to, 1);
3521 from = protect_from_queue (from, 0);
3524 from = force_not_mem (from);
3526 /* If we are about to do some arithmetic to correct for an
3527 unsigned operand, do it in a pseudo-register. */
3529 if (GET_CODE (to) != REG || REGNO (to) <= LAST_VIRTUAL_REGISTER)
3530 target = gen_reg_rtx (GET_MODE (to));
3532 /* Convert as signed integer to floating. */
3533 expand_float (target, from, 0);
3535 /* If FROM is negative (and therefore TO is negative),
3536 correct its value by 2**bitwidth. */
3538 do_pending_stack_adjust ();
3539 emit_cmp_insn (from, const0_rtx, GE, NULL_RTX, GET_MODE (from), 0, 0);
3540 emit_jump_insn (gen_bge (label));
3541 /* On SCO 3.2.1, ldexp rejects values outside [0.5, 1).
3542 Rather than setting up a dconst_dot_5, let's hope SCO
3544 offset = REAL_VALUE_LDEXP (dconst1, GET_MODE_BITSIZE (GET_MODE (from)));
3545 temp = expand_binop (GET_MODE (to), add_optab, target,
3546 immed_real_const_1 (offset, GET_MODE (to)),
3547 target, 0, OPTAB_LIB_WIDEN);
3549 emit_move_insn (target, temp);
3550 do_pending_stack_adjust ();
3556 /* No hardware instruction available; call a library rotine to convert from
3557 SImode, DImode, or TImode into SFmode, DFmode, XFmode, or TFmode. */
3562 to = protect_from_queue (to, 1);
3563 from = protect_from_queue (from, 0);
3565 if (GET_MODE_SIZE (GET_MODE (from)) < GET_MODE_SIZE (SImode))
3566 from = convert_to_mode (SImode, from, unsignedp);
3569 from = force_not_mem (from);
3571 if (GET_MODE (to) == SFmode)
3573 if (GET_MODE (from) == SImode)
3574 libfcn = floatsisf_libfunc;
3575 else if (GET_MODE (from) == DImode)
3576 libfcn = floatdisf_libfunc;
3577 else if (GET_MODE (from) == TImode)
3578 libfcn = floattisf_libfunc;
3582 else if (GET_MODE (to) == DFmode)
3584 if (GET_MODE (from) == SImode)
3585 libfcn = floatsidf_libfunc;
3586 else if (GET_MODE (from) == DImode)
3587 libfcn = floatdidf_libfunc;
3588 else if (GET_MODE (from) == TImode)
3589 libfcn = floattidf_libfunc;
3593 else if (GET_MODE (to) == XFmode)
3595 if (GET_MODE (from) == SImode)
3596 libfcn = floatsixf_libfunc;
3597 else if (GET_MODE (from) == DImode)
3598 libfcn = floatdixf_libfunc;
3599 else if (GET_MODE (from) == TImode)
3600 libfcn = floattixf_libfunc;
3604 else if (GET_MODE (to) == TFmode)
3606 if (GET_MODE (from) == SImode)
3607 libfcn = floatsitf_libfunc;
3608 else if (GET_MODE (from) == DImode)
3609 libfcn = floatditf_libfunc;
3610 else if (GET_MODE (from) == TImode)
3611 libfcn = floattitf_libfunc;
3620 emit_library_call (libfcn, 1, GET_MODE (to), 1, from, GET_MODE (from));
3621 insns = get_insns ();
3624 emit_libcall_block (insns, target, hard_libcall_value (GET_MODE (to)),
3625 gen_rtx (FLOAT, GET_MODE (to), from));
3628 /* Copy result to requested destination
3629 if we have been computing in a temp location. */
3633 if (GET_MODE (target) == GET_MODE (to))
3634 emit_move_insn (to, target);
3636 convert_move (to, target, 0);
3640 /* expand_fix: generate code to convert FROM to fixed point
3641 and store in TO. FROM must be floating point. */
3647 rtx temp = gen_reg_rtx (GET_MODE (x));
3648 return expand_unop (GET_MODE (x), ftrunc_optab, x, temp, 0);
3652 expand_fix (to, from, unsignedp)
3653 register rtx to, from;
3656 enum insn_code icode;
3657 register rtx target = to;
3658 enum machine_mode fmode, imode;
3662 /* We first try to find a pair of modes, one real and one integer, at
3663 least as wide as FROM and TO, respectively, in which we can open-code
3664 this conversion. If the integer mode is wider than the mode of TO,
3665 we can do the conversion either signed or unsigned. */
3667 for (imode = GET_MODE (to); imode != VOIDmode;
3668 imode = GET_MODE_WIDER_MODE (imode))
3669 for (fmode = GET_MODE (from); fmode != VOIDmode;
3670 fmode = GET_MODE_WIDER_MODE (fmode))
3672 int doing_unsigned = unsignedp;
3674 icode = can_fix_p (imode, fmode, unsignedp, &must_trunc);
3675 if (icode == CODE_FOR_nothing && imode != GET_MODE (to) && unsignedp)
3676 icode = can_fix_p (imode, fmode, 0, &must_trunc), doing_unsigned = 0;
3678 if (icode != CODE_FOR_nothing)
3680 to = protect_from_queue (to, 1);
3681 from = protect_from_queue (from, 0);
3683 if (fmode != GET_MODE (from))
3684 from = convert_to_mode (fmode, from, 0);
3687 from = ftruncify (from);
3689 if (imode != GET_MODE (to))
3690 target = gen_reg_rtx (imode);
3692 emit_unop_insn (icode, target, from,
3693 doing_unsigned ? UNSIGNED_FIX : FIX);
3695 convert_move (to, target, unsignedp);
3700 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
3701 /* For an unsigned conversion, there is one more way to do it.
3702 If we have a signed conversion, we generate code that compares
3703 the real value to the largest representable positive number. If if
3704 is smaller, the conversion is done normally. Otherwise, subtract
3705 one plus the highest signed number, convert, and add it back.
3707 We only need to check all real modes, since we know we didn't find
3708 anything with a wider integer mode. */
3710 if (unsignedp && GET_MODE_BITSIZE (GET_MODE (to)) <= HOST_BITS_PER_WIDE_INT)
3711 for (fmode = GET_MODE (from); fmode != VOIDmode;
3712 fmode = GET_MODE_WIDER_MODE (fmode))
3713 /* Make sure we won't lose significant bits doing this. */
3714 if (GET_MODE_BITSIZE (fmode) > GET_MODE_BITSIZE (GET_MODE (to))
3715 && CODE_FOR_nothing != can_fix_p (GET_MODE (to), fmode, 0,
3718 int bitsize = GET_MODE_BITSIZE (GET_MODE (to));
3719 REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (dconst1, bitsize - 1);
3720 rtx limit = immed_real_const_1 (offset, fmode);
3721 rtx lab1 = gen_label_rtx ();
3722 rtx lab2 = gen_label_rtx ();
3726 to = protect_from_queue (to, 1);
3727 from = protect_from_queue (from, 0);
3730 from = force_not_mem (from);
3732 if (fmode != GET_MODE (from))
3733 from = convert_to_mode (fmode, from, 0);
3735 /* See if we need to do the subtraction. */
3736 do_pending_stack_adjust ();
3737 emit_cmp_insn (from, limit, GE, NULL_RTX, GET_MODE (from), 0, 0);
3738 emit_jump_insn (gen_bge (lab1));
3740 /* If not, do the signed "fix" and branch around fixup code. */
3741 expand_fix (to, from, 0);
3742 emit_jump_insn (gen_jump (lab2));
3745 /* Otherwise, subtract 2**(N-1), convert to signed number,
3746 then add 2**(N-1). Do the addition using XOR since this
3747 will often generate better code. */
3749 target = expand_binop (GET_MODE (from), sub_optab, from, limit,
3750 NULL_RTX, 0, OPTAB_LIB_WIDEN);
3751 expand_fix (to, target, 0);
3752 target = expand_binop (GET_MODE (to), xor_optab, to,
3753 GEN_INT ((HOST_WIDE_INT) 1 << (bitsize - 1)),
3754 to, 1, OPTAB_LIB_WIDEN);
3757 emit_move_insn (to, target);
3761 /* Make a place for a REG_NOTE and add it. */
3762 insn = emit_move_insn (to, to);
3763 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL,
3764 gen_rtx (UNSIGNED_FIX, GET_MODE (to),
3765 from), REG_NOTES (insn));
3771 /* We can't do it with an insn, so use a library call. But first ensure
3772 that the mode of TO is at least as wide as SImode, since those are the
3773 only library calls we know about. */
3775 if (GET_MODE_SIZE (GET_MODE (to)) < GET_MODE_SIZE (SImode))
3777 target = gen_reg_rtx (SImode);
3779 expand_fix (target, from, unsignedp);
3781 else if (GET_MODE (from) == SFmode)
3783 if (GET_MODE (to) == SImode)
3784 libfcn = unsignedp ? fixunssfsi_libfunc : fixsfsi_libfunc;
3785 else if (GET_MODE (to) == DImode)
3786 libfcn = unsignedp ? fixunssfdi_libfunc : fixsfdi_libfunc;
3787 else if (GET_MODE (to) == TImode)
3788 libfcn = unsignedp ? fixunssfti_libfunc : fixsfti_libfunc;
3792 else if (GET_MODE (from) == DFmode)
3794 if (GET_MODE (to) == SImode)
3795 libfcn = unsignedp ? fixunsdfsi_libfunc : fixdfsi_libfunc;
3796 else if (GET_MODE (to) == DImode)
3797 libfcn = unsignedp ? fixunsdfdi_libfunc : fixdfdi_libfunc;
3798 else if (GET_MODE (to) == TImode)
3799 libfcn = unsignedp ? fixunsdfti_libfunc : fixdfti_libfunc;
3803 else if (GET_MODE (from) == XFmode)
3805 if (GET_MODE (to) == SImode)
3806 libfcn = unsignedp ? fixunsxfsi_libfunc : fixxfsi_libfunc;
3807 else if (GET_MODE (to) == DImode)
3808 libfcn = unsignedp ? fixunsxfdi_libfunc : fixxfdi_libfunc;
3809 else if (GET_MODE (to) == TImode)
3810 libfcn = unsignedp ? fixunsxfti_libfunc : fixxfti_libfunc;
3814 else if (GET_MODE (from) == TFmode)
3816 if (GET_MODE (to) == SImode)
3817 libfcn = unsignedp ? fixunstfsi_libfunc : fixtfsi_libfunc;
3818 else if (GET_MODE (to) == DImode)
3819 libfcn = unsignedp ? fixunstfdi_libfunc : fixtfdi_libfunc;
3820 else if (GET_MODE (to) == TImode)
3821 libfcn = unsignedp ? fixunstfti_libfunc : fixtfti_libfunc;
3832 to = protect_from_queue (to, 1);
3833 from = protect_from_queue (from, 0);
3836 from = force_not_mem (from);
3840 emit_library_call (libfcn, 1, GET_MODE (to), 1, from, GET_MODE (from));
3841 insns = get_insns ();
3844 emit_libcall_block (insns, target, hard_libcall_value (GET_MODE (to)),
3845 gen_rtx (unsignedp ? FIX : UNSIGNED_FIX,
3846 GET_MODE (to), from));
3849 if (GET_MODE (to) == GET_MODE (target))
3850 emit_move_insn (to, target);
3852 convert_move (to, target, 0);
3860 optab op = (optab) xmalloc (sizeof (struct optab));
3862 for (i = 0; i < NUM_MACHINE_MODES; i++)
3864 op->handlers[i].insn_code = CODE_FOR_nothing;
3865 op->handlers[i].libfunc = 0;
3870 /* Initialize the libfunc fields of an entire group of entries in some
3871 optab. Each entry is set equal to a string consisting of a leading
3872 pair of underscores followed by a generic operation name followed by
3873 a mode name (downshifted to lower case) followed by a single character
3874 representing the number of operands for the given operation (which is
3875 usually one of the characters '2', '3', or '4').
3877 OPTABLE is the table in which libfunc fields are to be initialized.
3878 FIRST_MODE is the first machine mode index in the given optab to
3880 LAST_MODE is the last machine mode index in the given optab to
3882 OPNAME is the generic (string) name of the operation.
3883 SUFFIX is the character which specifies the number of operands for
3884 the given generic operation.
3888 init_libfuncs (optable, first_mode, last_mode, opname, suffix)
3889 register optab optable;
3890 register char *opname;
3891 register enum machine_mode first_mode;
3892 register enum machine_mode last_mode;
3893 register char suffix;
3895 register enum machine_mode mode;
3896 register unsigned opname_len = strlen (opname);
3898 for (mode = first_mode; (int) mode <= (int) last_mode;
3899 mode = (enum machine_mode) ((int) mode + 1))
3901 register char *mname = mode_name[(int) mode];
3902 register unsigned mname_len = strlen (mname);
3903 register char *libfunc_name
3904 = (char *) xmalloc (2 + opname_len + mname_len + 1 + 1);
3911 for (q = opname; *q; )
3913 for (q = mname; *q; q++)
3914 *p++ = tolower (*q);
3917 optable->handlers[(int) mode].libfunc
3918 = gen_rtx (SYMBOL_REF, Pmode, libfunc_name);
3922 /* Initialize the libfunc fields of an entire group of entries in some
3923 optab which correspond to all integer mode operations. The parameters
3924 have the same meaning as similarly named ones for the `init_libfuncs'
3925 routine. (See above). */
3928 init_integral_libfuncs (optable, opname, suffix)
3929 register optab optable;
3930 register char *opname;
3931 register char suffix;
3933 init_libfuncs (optable, SImode, TImode, opname, suffix);
3936 /* Initialize the libfunc fields of an entire group of entries in some
3937 optab which correspond to all real mode operations. The parameters
3938 have the same meaning as similarly named ones for the `init_libfuncs'
3939 routine. (See above). */
3942 init_floating_libfuncs (optable, opname, suffix)
3943 register optab optable;
3944 register char *opname;
3945 register char suffix;
3947 init_libfuncs (optable, SFmode, TFmode, opname, suffix);
3950 /* Initialize the libfunc fields of an entire group of entries in some
3951 optab which correspond to all complex floating modes. The parameters
3952 have the same meaning as similarly named ones for the `init_libfuncs'
3953 routine. (See above). */
3956 init_complex_libfuncs (optable, opname, suffix)
3957 register optab optable;
3958 register char *opname;
3959 register char suffix;
3961 init_libfuncs (optable, SCmode, TCmode, opname, suffix);
3964 /* Call this once to initialize the contents of the optabs
3965 appropriately for the current target machine. */
3976 add_optab = init_optab (PLUS);
3977 sub_optab = init_optab (MINUS);
3978 smul_optab = init_optab (MULT);
3979 smul_widen_optab = init_optab (UNKNOWN);
3980 umul_widen_optab = init_optab (UNKNOWN);
3981 sdiv_optab = init_optab (DIV);
3982 sdivmod_optab = init_optab (UNKNOWN);
3983 udiv_optab = init_optab (UDIV);
3984 udivmod_optab = init_optab (UNKNOWN);
3985 smod_optab = init_optab (MOD);
3986 umod_optab = init_optab (UMOD);
3987 flodiv_optab = init_optab (DIV);
3988 ftrunc_optab = init_optab (UNKNOWN);
3989 and_optab = init_optab (AND);
3990 ior_optab = init_optab (IOR);
3991 xor_optab = init_optab (XOR);
3992 ashl_optab = init_optab (ASHIFT);
3993 ashr_optab = init_optab (ASHIFTRT);
3994 lshl_optab = init_optab (LSHIFT);
3995 lshr_optab = init_optab (LSHIFTRT);
3996 rotl_optab = init_optab (ROTATE);
3997 rotr_optab = init_optab (ROTATERT);
3998 smin_optab = init_optab (SMIN);
3999 smax_optab = init_optab (SMAX);
4000 umin_optab = init_optab (UMIN);
4001 umax_optab = init_optab (UMAX);
4002 mov_optab = init_optab (UNKNOWN);
4003 movstrict_optab = init_optab (UNKNOWN);
4004 cmp_optab = init_optab (UNKNOWN);
4005 ucmp_optab = init_optab (UNKNOWN);
4006 tst_optab = init_optab (UNKNOWN);
4007 neg_optab = init_optab (NEG);
4008 abs_optab = init_optab (ABS);
4009 one_cmpl_optab = init_optab (NOT);
4010 ffs_optab = init_optab (FFS);
4011 sqrt_optab = init_optab (SQRT);
4012 sin_optab = init_optab (UNKNOWN);
4013 cos_optab = init_optab (UNKNOWN);
4014 strlen_optab = init_optab (UNKNOWN);
4018 add_optab->handlers[(int) QImode].insn_code = CODE_FOR_addqi3;
4022 add_optab->handlers[(int) HImode].insn_code = CODE_FOR_addhi3;
4026 add_optab->handlers[(int) PSImode].insn_code = CODE_FOR_addpsi3;
4030 add_optab->handlers[(int) SImode].insn_code = CODE_FOR_addsi3;
4034 add_optab->handlers[(int) DImode].insn_code = CODE_FOR_adddi3;
4038 add_optab->handlers[(int) TImode].insn_code = CODE_FOR_addti3;
4042 add_optab->handlers[(int) QFmode].insn_code = CODE_FOR_addqf3;
4046 add_optab->handlers[(int) HFmode].insn_code = CODE_FOR_addhf3;
4050 add_optab->handlers[(int) SFmode].insn_code = CODE_FOR_addsf3;
4054 add_optab->handlers[(int) DFmode].insn_code = CODE_FOR_adddf3;
4058 add_optab->handlers[(int) XFmode].insn_code = CODE_FOR_addxf3;
4062 add_optab->handlers[(int) TFmode].insn_code = CODE_FOR_addtf3;
4064 init_integral_libfuncs (add_optab, "add", '3');
4065 init_floating_libfuncs (add_optab, "add", '3');
4069 sub_optab->handlers[(int) QImode].insn_code = CODE_FOR_subqi3;
4073 sub_optab->handlers[(int) HImode].insn_code = CODE_FOR_subhi3;
4077 sub_optab->handlers[(int) PSImode].insn_code = CODE_FOR_subpsi3;
4081 sub_optab->handlers[(int) SImode].insn_code = CODE_FOR_subsi3;
4085 sub_optab->handlers[(int) DImode].insn_code = CODE_FOR_subdi3;
4089 sub_optab->handlers[(int) TImode].insn_code = CODE_FOR_subti3;
4093 sub_optab->handlers[(int) QFmode].insn_code = CODE_FOR_subqf3;
4097 sub_optab->handlers[(int) HFmode].insn_code = CODE_FOR_subhf3;
4101 sub_optab->handlers[(int) SFmode].insn_code = CODE_FOR_subsf3;
4105 sub_optab->handlers[(int) DFmode].insn_code = CODE_FOR_subdf3;
4109 sub_optab->handlers[(int) XFmode].insn_code = CODE_FOR_subxf3;
4113 sub_optab->handlers[(int) TFmode].insn_code = CODE_FOR_subtf3;
4115 init_integral_libfuncs (sub_optab, "sub", '3');
4116 init_floating_libfuncs (sub_optab, "sub", '3');
4120 smul_optab->handlers[(int) QImode].insn_code = CODE_FOR_mulqi3;
4124 smul_optab->handlers[(int) HImode].insn_code = CODE_FOR_mulhi3;
4128 smul_optab->handlers[(int) PSImode].insn_code = CODE_FOR_mulpsi3;
4132 smul_optab->handlers[(int) SImode].insn_code = CODE_FOR_mulsi3;
4136 smul_optab->handlers[(int) DImode].insn_code = CODE_FOR_muldi3;
4140 smul_optab->handlers[(int) TImode].insn_code = CODE_FOR_multi3;
4144 smul_optab->handlers[(int) QFmode].insn_code = CODE_FOR_mulqf3;
4148 smul_optab->handlers[(int) HFmode].insn_code = CODE_FOR_mulhf3;
4152 smul_optab->handlers[(int) SFmode].insn_code = CODE_FOR_mulsf3;
4156 smul_optab->handlers[(int) DFmode].insn_code = CODE_FOR_muldf3;
4160 smul_optab->handlers[(int) XFmode].insn_code = CODE_FOR_mulxf3;
4164 smul_optab->handlers[(int) TFmode].insn_code = CODE_FOR_multf3;
4166 init_integral_libfuncs (smul_optab, "mul", '3');
4167 init_floating_libfuncs (smul_optab, "mul", '3');
4169 #ifdef MULSI3_LIBCALL
4170 smul_optab->handlers[(int) SImode].libfunc
4171 = gen_rtx (SYMBOL_REF, Pmode, MULSI3_LIBCALL);
4173 #ifdef MULDI3_LIBCALL
4174 smul_optab->handlers[(int) DImode].libfunc
4175 = gen_rtx (SYMBOL_REF, Pmode, MULDI3_LIBCALL);
4177 #ifdef MULTI3_LIBCALL
4178 smul_optab->handlers[(int) TImode].libfunc
4179 = gen_rtx (SYMBOL_REF, Pmode, MULTI3_LIBCALL);
4182 #ifdef HAVE_mulqihi3
4184 smul_widen_optab->handlers[(int) HImode].insn_code = CODE_FOR_mulqihi3;
4186 #ifdef HAVE_mulhisi3
4188 smul_widen_optab->handlers[(int) SImode].insn_code = CODE_FOR_mulhisi3;
4190 #ifdef HAVE_mulsidi3
4192 smul_widen_optab->handlers[(int) DImode].insn_code = CODE_FOR_mulsidi3;
4194 #ifdef HAVE_mulditi3
4196 smul_widen_optab->handlers[(int) TImode].insn_code = CODE_FOR_mulditi3;
4199 #ifdef HAVE_umulqihi3
4201 umul_widen_optab->handlers[(int) HImode].insn_code = CODE_FOR_umulqihi3;
4203 #ifdef HAVE_umulhisi3
4205 umul_widen_optab->handlers[(int) SImode].insn_code = CODE_FOR_umulhisi3;
4207 #ifdef HAVE_umulsidi3
4209 umul_widen_optab->handlers[(int) DImode].insn_code = CODE_FOR_umulsidi3;
4211 #ifdef HAVE_umulditi3
4213 umul_widen_optab->handlers[(int) TImode].insn_code = CODE_FOR_umulditi3;
4218 sdiv_optab->handlers[(int) QImode].insn_code = CODE_FOR_divqi3;
4222 sdiv_optab->handlers[(int) HImode].insn_code = CODE_FOR_divhi3;
4226 sdiv_optab->handlers[(int) PSImode].insn_code = CODE_FOR_divpsi3;
4230 sdiv_optab->handlers[(int) SImode].insn_code = CODE_FOR_divsi3;
4234 sdiv_optab->handlers[(int) DImode].insn_code = CODE_FOR_divdi3;
4238 sdiv_optab->handlers[(int) TImode].insn_code = CODE_FOR_divti3;
4240 init_integral_libfuncs (sdiv_optab, "div", '3');
4242 #ifdef DIVSI3_LIBCALL
4243 sdiv_optab->handlers[(int) SImode].libfunc
4244 = gen_rtx (SYMBOL_REF, Pmode, DIVSI3_LIBCALL);
4246 #ifdef DIVDI3_LIBCALL
4247 sdiv_optab->handlers[(int) DImode].libfunc
4248 = gen_rtx (SYMBOL_REF, Pmode, DIVDI3_LIBCALL);
4250 #ifdef DIVTI3_LIBCALL
4251 sdiv_optab->handlers[(int) TImode].libfunc
4252 = gen_rtx (SYMBOL_REF, Pmode, DIVTI3_LIBCALL);
4257 udiv_optab->handlers[(int) QImode].insn_code = CODE_FOR_udivqi3;
4261 udiv_optab->handlers[(int) HImode].insn_code = CODE_FOR_udivhi3;
4263 #ifdef HAVE_udivpsi3
4265 udiv_optab->handlers[(int) PSImode].insn_code = CODE_FOR_udivpsi3;
4269 udiv_optab->handlers[(int) SImode].insn_code = CODE_FOR_udivsi3;
4273 udiv_optab->handlers[(int) DImode].insn_code = CODE_FOR_udivdi3;
4277 udiv_optab->handlers[(int) TImode].insn_code = CODE_FOR_udivti3;
4279 init_integral_libfuncs (udiv_optab, "udiv", '3');
4281 #ifdef UDIVSI3_LIBCALL
4282 udiv_optab->handlers[(int) SImode].libfunc
4283 = gen_rtx (SYMBOL_REF, Pmode, UDIVSI3_LIBCALL);
4285 #ifdef UDIVDI3_LIBCALL
4286 udiv_optab->handlers[(int) DImode].libfunc
4287 = gen_rtx (SYMBOL_REF, Pmode, UDIVDI3_LIBCALL);
4289 #ifdef UDIVTI3_LIBCALL
4290 udiv_optab->handlers[(int) TImode].libfunc
4291 = gen_rtx (SYMBOL_REF, Pmode, UDIVTI3_LIBCALL);
4294 #ifdef HAVE_divmodqi4
4296 sdivmod_optab->handlers[(int) QImode].insn_code = CODE_FOR_divmodqi4;
4298 #ifdef HAVE_divmodhi4
4300 sdivmod_optab->handlers[(int) HImode].insn_code = CODE_FOR_divmodhi4;
4302 #ifdef HAVE_divmodsi4
4304 sdivmod_optab->handlers[(int) SImode].insn_code = CODE_FOR_divmodsi4;
4306 #ifdef HAVE_divmoddi4
4308 sdivmod_optab->handlers[(int) DImode].insn_code = CODE_FOR_divmoddi4;
4310 #ifdef HAVE_divmodti4
4312 sdivmod_optab->handlers[(int) TImode].insn_code = CODE_FOR_divmodti4;
4314 init_integral_libfuncs (sdivmod_optab, "divmod", '4');
4316 #ifdef HAVE_udivmodqi4
4317 if (HAVE_udivmodqi4)
4318 udivmod_optab->handlers[(int) QImode].insn_code = CODE_FOR_udivmodqi4;
4320 #ifdef HAVE_udivmodhi4
4321 if (HAVE_udivmodhi4)
4322 udivmod_optab->handlers[(int) HImode].insn_code = CODE_FOR_udivmodhi4;
4324 #ifdef HAVE_udivmodsi4
4325 if (HAVE_udivmodsi4)
4326 udivmod_optab->handlers[(int) SImode].insn_code = CODE_FOR_udivmodsi4;
4328 #ifdef HAVE_udivmoddi4
4329 if (HAVE_udivmoddi4)
4330 udivmod_optab->handlers[(int) DImode].insn_code = CODE_FOR_udivmoddi4;
4332 #ifdef HAVE_udivmodti4
4333 if (HAVE_udivmodti4)
4334 udivmod_optab->handlers[(int) TImode].insn_code = CODE_FOR_udivmodti4;
4336 init_integral_libfuncs (udivmod_optab, "udivmod", '4');
4340 smod_optab->handlers[(int) QImode].insn_code = CODE_FOR_modqi3;
4344 smod_optab->handlers[(int) HImode].insn_code = CODE_FOR_modhi3;
4348 smod_optab->handlers[(int) PSImode].insn_code = CODE_FOR_modpsi3;
4352 smod_optab->handlers[(int) SImode].insn_code = CODE_FOR_modsi3;
4356 smod_optab->handlers[(int) DImode].insn_code = CODE_FOR_moddi3;
4360 smod_optab->handlers[(int) TImode].insn_code = CODE_FOR_modti3;
4362 init_integral_libfuncs (smod_optab, "mod", '3');
4364 #ifdef MODSI3_LIBCALL
4365 smod_optab->handlers[(int) SImode].libfunc
4366 = gen_rtx (SYMBOL_REF, Pmode, MODSI3_LIBCALL);
4368 #ifdef MODDI3_LIBCALL
4369 smod_optab->handlers[(int) DImode].libfunc
4370 = gen_rtx (SYMBOL_REF, Pmode, MODDI3_LIBCALL);
4372 #ifdef MODTI3_LIBCALL
4373 smod_optab->handlers[(int) TImode].libfunc
4374 = gen_rtx (SYMBOL_REF, Pmode, MODTI3_LIBCALL);
4379 umod_optab->handlers[(int) QImode].insn_code = CODE_FOR_umodqi3;
4383 umod_optab->handlers[(int) HImode].insn_code = CODE_FOR_umodhi3;
4385 #ifdef HAVE_umodpsi3
4387 umod_optab->handlers[(int) PSImode].insn_code = CODE_FOR_umodpsi3;
4391 umod_optab->handlers[(int) SImode].insn_code = CODE_FOR_umodsi3;
4395 umod_optab->handlers[(int) DImode].insn_code = CODE_FOR_umoddi3;
4399 umod_optab->handlers[(int) TImode].insn_code = CODE_FOR_umodti3;
4401 init_integral_libfuncs (umod_optab, "umod", '3');
4403 #ifdef UMODSI3_LIBCALL
4404 umod_optab->handlers[(int) SImode].libfunc
4405 = gen_rtx (SYMBOL_REF, Pmode, UMODSI3_LIBCALL);
4407 #ifdef UMODDI3_LIBCALL
4408 umod_optab->handlers[(int) DImode].libfunc
4409 = gen_rtx (SYMBOL_REF, Pmode, UMODDI3_LIBCALL);
4411 #ifdef UMODTI3_LIBCALL
4412 umod_optab->handlers[(int) TImode].libfunc
4413 = gen_rtx (SYMBOL_REF, Pmode, UMODTI3_LIBCALL);
4418 flodiv_optab->handlers[(int) QFmode].insn_code = CODE_FOR_divqf3;
4422 flodiv_optab->handlers[(int) HFmode].insn_code = CODE_FOR_divhf3;
4426 flodiv_optab->handlers[(int) SFmode].insn_code = CODE_FOR_divsf3;
4430 flodiv_optab->handlers[(int) DFmode].insn_code = CODE_FOR_divdf3;
4434 flodiv_optab->handlers[(int) XFmode].insn_code = CODE_FOR_divxf3;
4438 flodiv_optab->handlers[(int) TFmode].insn_code = CODE_FOR_divtf3;
4440 init_floating_libfuncs (flodiv_optab, "div", '3');
4442 #ifdef HAVE_ftruncqf2
4444 ftrunc_optab->handlers[(int) QFmode].insn_code = CODE_FOR_ftruncqf2;
4446 #ifdef HAVE_ftrunchf2
4448 ftrunc_optab->handlers[(int) HFmode].insn_code = CODE_FOR_ftrunchf3;
4450 #ifdef HAVE_ftruncsf2
4452 ftrunc_optab->handlers[(int) SFmode].insn_code = CODE_FOR_ftruncsf2;
4454 #ifdef HAVE_ftruncdf2
4456 ftrunc_optab->handlers[(int) DFmode].insn_code = CODE_FOR_ftruncdf2;
4458 #ifdef HAVE_ftruncxf2
4460 ftrunc_optab->handlers[(int) XFmode].insn_code = CODE_FOR_ftruncxf2;
4462 #ifdef HAVE_ftrunctf2
4464 ftrunc_optab->handlers[(int) TFmode].insn_code = CODE_FOR_ftrunctf2;
4466 init_floating_libfuncs (ftrunc_optab, "ftrunc", '2');
4470 and_optab->handlers[(int) QImode].insn_code = CODE_FOR_andqi3;
4474 and_optab->handlers[(int) HImode].insn_code = CODE_FOR_andhi3;
4478 and_optab->handlers[(int) PSImode].insn_code = CODE_FOR_andpsi3;
4482 and_optab->handlers[(int) SImode].insn_code = CODE_FOR_andsi3;
4486 and_optab->handlers[(int) DImode].insn_code = CODE_FOR_anddi3;
4490 and_optab->handlers[(int) TImode].insn_code = CODE_FOR_andti3;
4492 init_integral_libfuncs (and_optab, "and", '3');
4496 ior_optab->handlers[(int) QImode].insn_code = CODE_FOR_iorqi3;
4500 ior_optab->handlers[(int) HImode].insn_code = CODE_FOR_iorhi3;
4504 ior_optab->handlers[(int) PSImode].insn_code = CODE_FOR_iorpsi3;
4508 ior_optab->handlers[(int) SImode].insn_code = CODE_FOR_iorsi3;
4512 ior_optab->handlers[(int) DImode].insn_code = CODE_FOR_iordi3;
4516 ior_optab->handlers[(int) TImode].insn_code = CODE_FOR_iorti3;
4518 init_integral_libfuncs (ior_optab, "ior", '3');
4522 xor_optab->handlers[(int) QImode].insn_code = CODE_FOR_xorqi3;
4526 xor_optab->handlers[(int) HImode].insn_code = CODE_FOR_xorhi3;
4530 xor_optab->handlers[(int) PSImode].insn_code = CODE_FOR_xorpsi3;
4534 xor_optab->handlers[(int) SImode].insn_code = CODE_FOR_xorsi3;
4538 xor_optab->handlers[(int) DImode].insn_code = CODE_FOR_xordi3;
4542 xor_optab->handlers[(int) TImode].insn_code = CODE_FOR_xorti3;
4544 init_integral_libfuncs (xor_optab, "xor", '3');
4548 ashl_optab->handlers[(int) QImode].insn_code = CODE_FOR_ashlqi3;
4552 ashl_optab->handlers[(int) HImode].insn_code = CODE_FOR_ashlhi3;
4554 #ifdef HAVE_ashlpsi3
4556 ashl_optab->handlers[(int) PSImode].insn_code = CODE_FOR_ashlpsi3;
4560 ashl_optab->handlers[(int) SImode].insn_code = CODE_FOR_ashlsi3;
4564 ashl_optab->handlers[(int) DImode].insn_code = CODE_FOR_ashldi3;
4568 ashl_optab->handlers[(int) TImode].insn_code = CODE_FOR_ashlti3;
4570 init_integral_libfuncs (ashl_optab, "ashl", '3');
4574 ashr_optab->handlers[(int) QImode].insn_code = CODE_FOR_ashrqi3;
4578 ashr_optab->handlers[(int) HImode].insn_code = CODE_FOR_ashrhi3;
4580 #ifdef HAVE_ashrpsi3
4582 ashr_optab->handlers[(int) PSImode].insn_code = CODE_FOR_ashrpsi3;
4586 ashr_optab->handlers[(int) SImode].insn_code = CODE_FOR_ashrsi3;
4590 ashr_optab->handlers[(int) DImode].insn_code = CODE_FOR_ashrdi3;
4594 ashr_optab->handlers[(int) TImode].insn_code = CODE_FOR_ashrti3;
4596 init_integral_libfuncs (ashr_optab, "ashr", '3');
4600 lshl_optab->handlers[(int) QImode].insn_code = CODE_FOR_lshlqi3;
4604 lshl_optab->handlers[(int) HImode].insn_code = CODE_FOR_lshlhi3;
4606 #ifdef HAVE_lshlpsi3
4608 lshl_optab->handlers[(int) PSImode].insn_code = CODE_FOR_lshlpsi3;
4612 lshl_optab->handlers[(int) SImode].insn_code = CODE_FOR_lshlsi3;
4616 lshl_optab->handlers[(int) DImode].insn_code = CODE_FOR_lshldi3;
4620 lshl_optab->handlers[(int) TImode].insn_code = CODE_FOR_lshlti3;
4622 init_integral_libfuncs (lshl_optab, "lshl", '3');
4626 lshr_optab->handlers[(int) QImode].insn_code = CODE_FOR_lshrqi3;
4630 lshr_optab->handlers[(int) HImode].insn_code = CODE_FOR_lshrhi3;
4632 #ifdef HAVE_lshrpsi3
4634 lshr_optab->handlers[(int) PSImode].insn_code = CODE_FOR_lshrpsi3;
4638 lshr_optab->handlers[(int) SImode].insn_code = CODE_FOR_lshrsi3;
4642 lshr_optab->handlers[(int) DImode].insn_code = CODE_FOR_lshrdi3;
4646 lshr_optab->handlers[(int) TImode].insn_code = CODE_FOR_lshrti3;
4648 init_integral_libfuncs (lshr_optab, "lshr", '3');
4652 rotl_optab->handlers[(int) QImode].insn_code = CODE_FOR_rotlqi3;
4656 rotl_optab->handlers[(int) HImode].insn_code = CODE_FOR_rotlhi3;
4658 #ifdef HAVE_rotlpsi3
4660 rotl_optab->handlers[(int) PSImode].insn_code = CODE_FOR_rotlpsi3;
4664 rotl_optab->handlers[(int) SImode].insn_code = CODE_FOR_rotlsi3;
4668 rotl_optab->handlers[(int) DImode].insn_code = CODE_FOR_rotldi3;
4672 rotl_optab->handlers[(int) TImode].insn_code = CODE_FOR_rotlti3;
4674 init_integral_libfuncs (rotl_optab, "rotl", '3');
4678 rotr_optab->handlers[(int) QImode].insn_code = CODE_FOR_rotrqi3;
4682 rotr_optab->handlers[(int) HImode].insn_code = CODE_FOR_rotrhi3;
4684 #ifdef HAVE_rotrpsi3
4686 rotr_optab->handlers[(int) PSImode].insn_code = CODE_FOR_rotrpsi3;
4690 rotr_optab->handlers[(int) SImode].insn_code = CODE_FOR_rotrsi3;
4694 rotr_optab->handlers[(int) DImode].insn_code = CODE_FOR_rotrdi3;
4698 rotr_optab->handlers[(int) TImode].insn_code = CODE_FOR_rotrti3;
4700 init_integral_libfuncs (rotr_optab, "rotr", '3');
4704 smin_optab->handlers[(int) QImode].insn_code = CODE_FOR_sminqi3;
4708 smin_optab->handlers[(int) HImode].insn_code = CODE_FOR_sminhi3;
4712 smin_optab->handlers[(int) SImode].insn_code = CODE_FOR_sminsi3;
4716 smin_optab->handlers[(int) DImode].insn_code = CODE_FOR_smindi3;
4720 smin_optab->handlers[(int) TImode].insn_code = CODE_FOR_sminti3;
4724 smin_optab->handlers[(int) QFmode].insn_code = CODE_FOR_minqf3;
4728 smin_optab->handlers[(int) HFmode].insn_code = CODE_FOR_minhf3;
4732 smin_optab->handlers[(int) SFmode].insn_code = CODE_FOR_minsf3;
4736 smin_optab->handlers[(int) DFmode].insn_code = CODE_FOR_mindf3;
4740 smin_optab->handlers[(int) XFmode].insn_code = CODE_FOR_minxf3;
4744 smin_optab->handlers[(int) TFmode].insn_code = CODE_FOR_mintf3;
4746 init_integral_libfuncs (smin_optab, "min", '3');
4747 init_floating_libfuncs (smin_optab, "min", '3');
4751 smax_optab->handlers[(int) QImode].insn_code = CODE_FOR_smaxqi3;
4755 smax_optab->handlers[(int) HImode].insn_code = CODE_FOR_smaxhi3;
4759 smax_optab->handlers[(int) SImode].insn_code = CODE_FOR_smaxsi3;
4763 smax_optab->handlers[(int) DImode].insn_code = CODE_FOR_smaxdi3;
4767 smax_optab->handlers[(int) TImode].insn_code = CODE_FOR_smaxti3;
4771 smax_optab->handlers[(int) QFmode].insn_code = CODE_FOR_maxqf3;
4775 smax_optab->handlers[(int) HFmode].insn_code = CODE_FOR_maxhf3;
4779 smax_optab->handlers[(int) SFmode].insn_code = CODE_FOR_maxsf3;
4783 smax_optab->handlers[(int) DFmode].insn_code = CODE_FOR_maxdf3;
4787 smax_optab->handlers[(int) XFmode].insn_code = CODE_FOR_maxxf3;
4791 smax_optab->handlers[(int) TFmode].insn_code = CODE_FOR_maxtf3;
4793 init_integral_libfuncs (smax_optab, "max", '3');
4794 init_floating_libfuncs (smax_optab, "max", '3');
4798 umin_optab->handlers[(int) QImode].insn_code = CODE_FOR_uminqi3;
4802 umin_optab->handlers[(int) HImode].insn_code = CODE_FOR_uminhi3;
4806 umin_optab->handlers[(int) SImode].insn_code = CODE_FOR_uminsi3;
4810 umin_optab->handlers[(int) DImode].insn_code = CODE_FOR_umindi3;
4814 umin_optab->handlers[(int) TImode].insn_code = CODE_FOR_uminti3;
4816 init_integral_libfuncs (umin_optab, "umin", '3');
4820 umax_optab->handlers[(int) QImode].insn_code = CODE_FOR_umaxqi3;
4824 umax_optab->handlers[(int) HImode].insn_code = CODE_FOR_umaxhi3;
4828 umax_optab->handlers[(int) SImode].insn_code = CODE_FOR_umaxsi3;
4832 umax_optab->handlers[(int) DImode].insn_code = CODE_FOR_umaxdi3;
4836 umax_optab->handlers[(int) TImode].insn_code = CODE_FOR_umaxti3;
4838 init_integral_libfuncs (umax_optab, "umax", '3');
4842 neg_optab->handlers[(int) QImode].insn_code = CODE_FOR_negqi2;
4846 neg_optab->handlers[(int) HImode].insn_code = CODE_FOR_neghi2;
4850 neg_optab->handlers[(int) PSImode].insn_code = CODE_FOR_negpsi2;
4854 neg_optab->handlers[(int) SImode].insn_code = CODE_FOR_negsi2;
4858 neg_optab->handlers[(int) DImode].insn_code = CODE_FOR_negdi2;
4862 neg_optab->handlers[(int) TImode].insn_code = CODE_FOR_negti2;
4866 neg_optab->handlers[(int) QFmode].insn_code = CODE_FOR_negqf2;
4870 neg_optab->handlers[(int) HFmode].insn_code = CODE_FOR_neghf2;
4874 neg_optab->handlers[(int) SFmode].insn_code = CODE_FOR_negsf2;
4878 neg_optab->handlers[(int) DFmode].insn_code = CODE_FOR_negdf2;
4882 neg_optab->handlers[(int) XFmode].insn_code = CODE_FOR_negxf2;
4886 neg_optab->handlers[(int) TFmode].insn_code = CODE_FOR_negtf2;
4888 init_integral_libfuncs (neg_optab, "neg", '2');
4889 init_floating_libfuncs (neg_optab, "neg", '2');
4893 abs_optab->handlers[(int) QImode].insn_code = CODE_FOR_absqi2;
4897 abs_optab->handlers[(int) HImode].insn_code = CODE_FOR_abshi2;
4901 abs_optab->handlers[(int) PSImode].insn_code = CODE_FOR_abspsi2;
4905 abs_optab->handlers[(int) SImode].insn_code = CODE_FOR_abssi2;
4909 abs_optab->handlers[(int) DImode].insn_code = CODE_FOR_absdi2;
4913 abs_optab->handlers[(int) TImode].insn_code = CODE_FOR_absti2;
4917 abs_optab->handlers[(int) QFmode].insn_code = CODE_FOR_absqf2;
4921 abs_optab->handlers[(int) HFmode].insn_code = CODE_FOR_abshf22;
4925 abs_optab->handlers[(int) SFmode].insn_code = CODE_FOR_abssf2;
4929 abs_optab->handlers[(int) DFmode].insn_code = CODE_FOR_absdf2;
4933 abs_optab->handlers[(int) XFmode].insn_code = CODE_FOR_absxf2;
4937 abs_optab->handlers[(int) TFmode].insn_code = CODE_FOR_abstf2;
4940 /* Use cabs for DC complex abs, since systems generally have cabs.
4941 Don't define any libcall for SCmode, so that cabs will be used. */
4942 abs_optab->handlers[(int) DCmode].libfunc
4943 = gen_rtx (SYMBOL_REF, Pmode, "cabs");
4947 sqrt_optab->handlers[(int) QImode].insn_code = CODE_FOR_sqrtqi2;
4951 sqrt_optab->handlers[(int) HImode].insn_code = CODE_FOR_sqrthi2;
4953 #ifdef HAVE_sqrtpsi2
4955 sqrt_optab->handlers[(int) PSImode].insn_code = CODE_FOR_sqrtpsi2;
4959 sqrt_optab->handlers[(int) SImode].insn_code = CODE_FOR_sqrtsi2;
4963 sqrt_optab->handlers[(int) DImode].insn_code = CODE_FOR_sqrtdi2;
4967 sqrt_optab->handlers[(int) TImode].insn_code = CODE_FOR_sqrtti2;
4971 sqrt_optab->handlers[(int) QFmode].insn_code = CODE_FOR_sqrtqf2;
4975 sqrt_optab->handlers[(int) HFmode].insn_code = CODE_FOR_sqrthf2;
4979 sqrt_optab->handlers[(int) SFmode].insn_code = CODE_FOR_sqrtsf2;
4983 sqrt_optab->handlers[(int) DFmode].insn_code = CODE_FOR_sqrtdf2;
4987 sqrt_optab->handlers[(int) TFmode].insn_code = CODE_FOR_sqrttf2;
4989 /* No library calls here! If there is no sqrt instruction expand_builtin
4990 should force the library call. */
4994 sin_optab->handlers[(int) QFmode].insn_code = CODE_FOR_sinqf2;
4998 sin_optab->handlers[(int) HFmode].insn_code = CODE_FOR_sinhf2;
5002 sin_optab->handlers[(int) SFmode].insn_code = CODE_FOR_sinsf2;
5006 sin_optab->handlers[(int) DFmode].insn_code = CODE_FOR_sindf2;
5010 sin_optab->handlers[(int) TFmode].insn_code = CODE_FOR_sintf2;
5012 /* No library calls here! If there is no sin instruction expand_builtin
5013 should force the library call. */
5017 cos_optab->handlers[(int) QFmode].insn_code = CODE_FOR_cosqf2;
5021 cos_optab->handlers[(int) HFmode].insn_code = CODE_FOR_coshf2;
5025 cos_optab->handlers[(int) SFmode].insn_code = CODE_FOR_cossf2;
5029 cos_optab->handlers[(int) DFmode].insn_code = CODE_FOR_cosdf2;
5033 cos_optab->handlers[(int) TFmode].insn_code = CODE_FOR_costf2;
5035 /* No library calls here! If there is no cos instruction expand_builtin
5036 should force the library call. */
5038 #ifdef HAVE_strlenqi
5040 strlen_optab->handlers[(int) QImode].insn_code = CODE_FOR_strlenqi;
5042 #ifdef HAVE_strlenhi
5044 strlen_optab->handlers[(int) HImode].insn_code = CODE_FOR_strlenhi;
5046 #ifdef HAVE_strlenpsi
5048 strlen_optab->handlers[(int) PSImode].insn_code = CODE_FOR_strlenpsi;
5050 #ifdef HAVE_strlensi
5052 strlen_optab->handlers[(int) SImode].insn_code = CODE_FOR_strlensi;
5054 #ifdef HAVE_strlendi
5056 strlen_optab->handlers[(int) DImode].insn_code = CODE_FOR_strlendi;
5058 #ifdef HAVE_strlenti
5060 strlen_optab->handlers[(int) TImode].insn_code = CODE_FOR_strlenti;
5062 /* No library calls here! If there is no strlen instruction expand_builtin
5063 should force the library call. */
5065 #ifdef HAVE_one_cmplqi2
5066 if (HAVE_one_cmplqi2)
5067 one_cmpl_optab->handlers[(int) QImode].insn_code = CODE_FOR_one_cmplqi2;
5069 #ifdef HAVE_one_cmplhi2
5070 if (HAVE_one_cmplhi2)
5071 one_cmpl_optab->handlers[(int) HImode].insn_code = CODE_FOR_one_cmplhi2;
5073 #ifdef HAVE_one_cmplpsi2
5074 if (HAVE_one_cmplpsi2)
5075 one_cmpl_optab->handlers[(int) PSImode].insn_code = CODE_FOR_one_cmplpsi2;
5077 #ifdef HAVE_one_cmplsi2
5078 if (HAVE_one_cmplsi2)
5079 one_cmpl_optab->handlers[(int) SImode].insn_code = CODE_FOR_one_cmplsi2;
5081 #ifdef HAVE_one_cmpldi2
5082 if (HAVE_one_cmpldi2)
5083 one_cmpl_optab->handlers[(int) DImode].insn_code = CODE_FOR_one_cmpldi2;
5085 #ifdef HAVE_one_cmplti2
5086 if (HAVE_one_cmplti2)
5087 one_cmpl_optab->handlers[(int) TImode].insn_code = CODE_FOR_one_cmplti2;
5089 init_integral_libfuncs (one_cmpl_optab, "one_cmpl", '2');
5093 ffs_optab->handlers[(int) QImode].insn_code = CODE_FOR_ffsqi2;
5097 ffs_optab->handlers[(int) HImode].insn_code = CODE_FOR_ffshi2;
5101 ffs_optab->handlers[(int) PSImode].insn_code = CODE_FOR_ffspsi2;
5105 ffs_optab->handlers[(int) SImode].insn_code = CODE_FOR_ffssi2;
5109 ffs_optab->handlers[(int) DImode].insn_code = CODE_FOR_ffsdi2;
5113 ffs_optab->handlers[(int) TImode].insn_code = CODE_FOR_ffsti2;
5115 init_integral_libfuncs (ffs_optab, "ffs", '2');
5116 ffs_optab->handlers[(int) SImode].libfunc
5117 = gen_rtx (SYMBOL_REF, Pmode, "ffs");
5121 mov_optab->handlers[(int) QImode].insn_code = CODE_FOR_movqi;
5125 mov_optab->handlers[(int) HImode].insn_code = CODE_FOR_movhi;
5129 mov_optab->handlers[(int) PSImode].insn_code = CODE_FOR_movpsi;
5133 mov_optab->handlers[(int) SImode].insn_code = CODE_FOR_movsi;
5137 mov_optab->handlers[(int) DImode].insn_code = CODE_FOR_movdi;
5141 mov_optab->handlers[(int) TImode].insn_code = CODE_FOR_movti;
5145 mov_optab->handlers[(int) QFmode].insn_code = CODE_FOR_movqf;
5149 mov_optab->handlers[(int) HFmode].insn_code = CODE_FOR_movhf;
5153 mov_optab->handlers[(int) SFmode].insn_code = CODE_FOR_movsf;
5157 mov_optab->handlers[(int) DFmode].insn_code = CODE_FOR_movdf;
5161 mov_optab->handlers[(int) XFmode].insn_code = CODE_FOR_movxf;
5165 mov_optab->handlers[(int) TFmode].insn_code = CODE_FOR_movtf;
5169 mov_optab->handlers[(int) CCmode].insn_code = CODE_FOR_movcc;
5172 #ifdef EXTRA_CC_MODES
5176 #ifdef HAVE_movstrictqi
5177 if (HAVE_movstrictqi)
5178 movstrict_optab->handlers[(int) QImode].insn_code = CODE_FOR_movstrictqi;
5180 #ifdef HAVE_movstricthi
5181 if (HAVE_movstricthi)
5182 movstrict_optab->handlers[(int) HImode].insn_code = CODE_FOR_movstricthi;
5184 #ifdef HAVE_movstrictpsi
5185 if (HAVE_movstrictpsi)
5186 movstrict_optab->handlers[(int) PSImode].insn_code = CODE_FOR_movstrictpsi;
5188 #ifdef HAVE_movstrictsi
5189 if (HAVE_movstrictsi)
5190 movstrict_optab->handlers[(int) SImode].insn_code = CODE_FOR_movstrictsi;
5192 #ifdef HAVE_movstrictdi
5193 if (HAVE_movstrictdi)
5194 movstrict_optab->handlers[(int) DImode].insn_code = CODE_FOR_movstrictdi;
5196 #ifdef HAVE_movstrictti
5197 if (HAVE_movstrictti)
5198 movstrict_optab->handlers[(int) TImode].insn_code = CODE_FOR_movstrictti;
5203 cmp_optab->handlers[(int) QImode].insn_code = CODE_FOR_cmpqi;
5207 cmp_optab->handlers[(int) HImode].insn_code = CODE_FOR_cmphi;
5211 cmp_optab->handlers[(int) PSImode].insn_code = CODE_FOR_cmppsi;
5215 cmp_optab->handlers[(int) SImode].insn_code = CODE_FOR_cmpsi;
5219 cmp_optab->handlers[(int) DImode].insn_code = CODE_FOR_cmpdi;
5223 cmp_optab->handlers[(int) TImode].insn_code = CODE_FOR_cmpti;
5227 cmp_optab->handlers[(int) QFmode].insn_code = CODE_FOR_cmpqf;
5231 cmp_optab->handlers[(int) HFmode].insn_code = CODE_FOR_cmphf;
5235 cmp_optab->handlers[(int) SFmode].insn_code = CODE_FOR_cmpsf;
5239 cmp_optab->handlers[(int) DFmode].insn_code = CODE_FOR_cmpdf;
5243 cmp_optab->handlers[(int) XFmode].insn_code = CODE_FOR_cmpxf;
5247 cmp_optab->handlers[(int) TFmode].insn_code = CODE_FOR_cmptf;
5249 /* Comparison libcalls for integers MUST come in pairs, signed/unsigned. */
5250 init_integral_libfuncs (cmp_optab, "cmp", '2');
5251 init_integral_libfuncs (ucmp_optab, "ucmp", '2');
5252 init_floating_libfuncs (cmp_optab, "cmp", '2');
5256 tst_optab->handlers[(int) QImode].insn_code = CODE_FOR_tstqi;
5260 tst_optab->handlers[(int) HImode].insn_code = CODE_FOR_tsthi;
5264 tst_optab->handlers[(int) PSImode].insn_code = CODE_FOR_tstpsi;
5268 tst_optab->handlers[(int) SImode].insn_code = CODE_FOR_tstsi;
5272 tst_optab->handlers[(int) DImode].insn_code = CODE_FOR_tstdi;
5276 tst_optab->handlers[(int) TImode].insn_code = CODE_FOR_tstti;
5280 tst_optab->handlers[(int) QFmode].insn_code = CODE_FOR_tstqf;
5284 tst_optab->handlers[(int) HFmode].insn_code = CODE_FOR_tsthf;
5288 tst_optab->handlers[(int) SFmode].insn_code = CODE_FOR_tstsf;
5292 tst_optab->handlers[(int) DFmode].insn_code = CODE_FOR_tstdf;
5296 tst_optab->handlers[(int) XFmode].insn_code = CODE_FOR_tstxf;
5300 tst_optab->handlers[(int) TFmode].insn_code = CODE_FOR_tsttf;
5305 bcc_gen_fctn[(int) EQ] = gen_beq;
5309 bcc_gen_fctn[(int) NE] = gen_bne;
5313 bcc_gen_fctn[(int) GT] = gen_bgt;
5317 bcc_gen_fctn[(int) GE] = gen_bge;
5321 bcc_gen_fctn[(int) GTU] = gen_bgtu;
5325 bcc_gen_fctn[(int) GEU] = gen_bgeu;
5329 bcc_gen_fctn[(int) LT] = gen_blt;
5333 bcc_gen_fctn[(int) LE] = gen_ble;
5337 bcc_gen_fctn[(int) LTU] = gen_bltu;
5341 bcc_gen_fctn[(int) LEU] = gen_bleu;
5344 for (i = 0; i < NUM_RTX_CODE; i++)
5345 setcc_gen_code[i] = CODE_FOR_nothing;
5349 setcc_gen_code[(int) EQ] = CODE_FOR_seq;
5353 setcc_gen_code[(int) NE] = CODE_FOR_sne;
5357 setcc_gen_code[(int) GT] = CODE_FOR_sgt;
5361 setcc_gen_code[(int) GE] = CODE_FOR_sge;
5365 setcc_gen_code[(int) GTU] = CODE_FOR_sgtu;
5369 setcc_gen_code[(int) GEU] = CODE_FOR_sgeu;
5373 setcc_gen_code[(int) LT] = CODE_FOR_slt;
5377 setcc_gen_code[(int) LE] = CODE_FOR_sle;
5381 setcc_gen_code[(int) LTU] = CODE_FOR_sltu;
5385 setcc_gen_code[(int) LEU] = CODE_FOR_sleu;
5388 extendsfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extendsfdf2");
5389 extendsfxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extendsfxf2");
5390 extendsftf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extendsftf2");
5391 extenddfxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extenddfxf2");
5392 extenddftf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extenddftf2");
5394 truncdfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__truncdfsf2");
5395 truncxfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__truncxfsf2");
5396 trunctfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__trunctfsf2");
5397 truncxfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__truncxfdf2");
5398 trunctfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__trunctfdf2");
5400 memcpy_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memcpy");
5401 bcopy_libfunc = gen_rtx (SYMBOL_REF, Pmode, "bcopy");
5402 memcmp_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memcmp");
5403 bcmp_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gcc_bcmp");
5404 memset_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memset");
5405 bzero_libfunc = gen_rtx (SYMBOL_REF, Pmode, "bzero");
5407 eqsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqsf2");
5408 nesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nesf2");
5409 gtsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtsf2");
5410 gesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gesf2");
5411 ltsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltsf2");
5412 lesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lesf2");
5414 eqdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqdf2");
5415 nedf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nedf2");
5416 gtdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtdf2");
5417 gedf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gedf2");
5418 ltdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltdf2");
5419 ledf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ledf2");
5421 eqxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqxf2");
5422 nexf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nexf2");
5423 gtxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtxf2");
5424 gexf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gexf2");
5425 ltxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltxf2");
5426 lexf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lexf2");
5428 eqtf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqtf2");
5429 netf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__netf2");
5430 gttf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gttf2");
5431 getf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__getf2");
5432 lttf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lttf2");
5433 letf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__letf2");
5435 floatsisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsisf");
5436 floatdisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatdisf");
5437 floattisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattisf");
5439 floatsidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsidf");
5440 floatdidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatdidf");
5441 floattidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattidf");
5443 floatsixf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsixf");
5444 floatdixf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatdixf");
5445 floattixf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattixf");
5447 floatsitf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsitf");
5448 floatditf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatditf");
5449 floattitf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattitf");
5451 fixsfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixsfsi");
5452 fixsfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixsfdi");
5453 fixsfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixsfti");
5455 fixdfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixdfsi");
5456 fixdfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixdfdi");
5457 fixdfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixdfti");
5459 fixxfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixxfsi");
5460 fixxfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixxfdi");
5461 fixxfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixxfti");
5463 fixtfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixtfsi");
5464 fixtfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixtfdi");
5465 fixtfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixtfti");
5467 fixunssfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunssfsi");
5468 fixunssfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunssfdi");
5469 fixunssfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunssfti");
5471 fixunsdfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsdfsi");
5472 fixunsdfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsdfdi");
5473 fixunsdfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsdfti");
5475 fixunsxfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsxfsi");
5476 fixunsxfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsxfdi");
5477 fixunsxfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsxfti");
5479 fixunstfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunstfsi");
5480 fixunstfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunstfdi");
5481 fixunstfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunstfti");
5486 /* SCO 3.2 apparently has a broken ldexp. */
5499 #endif /* BROKEN_LDEXP */