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);
285 class = GET_MODE_CLASS (mode);
287 op0 = protect_from_queue (op0, 0);
288 op1 = protect_from_queue (op1, 0);
290 target = protect_from_queue (target, 1);
294 op0 = force_not_mem (op0);
295 op1 = force_not_mem (op1);
298 /* If subtracting an integer constant, convert this into an addition of
299 the negated constant. */
301 if (binoptab == sub_optab && GET_CODE (op1) == CONST_INT)
303 op1 = negate_rtx (mode, op1);
304 binoptab = add_optab;
307 /* If we are inside an appropriately-short loop and one operand is an
308 expensive constant, force it into a register. */
309 if (CONSTANT_P (op0) && preserve_subexpressions_p ()
310 && rtx_cost (op0, binoptab->code) > 2)
311 op0 = force_reg (mode, op0);
313 if (CONSTANT_P (op1) && preserve_subexpressions_p ()
314 && rtx_cost (op1, binoptab->code) > 2)
315 op1 = force_reg (shift_op ? word_mode : mode, op1);
317 /* Record where to delete back to if we backtrack. */
318 last = get_last_insn ();
320 /* If operation is commutative,
321 try to make the first operand a register.
322 Even better, try to make it the same as the target.
323 Also try to make the last operand a constant. */
324 if (GET_RTX_CLASS (binoptab->code) == 'c'
325 || binoptab == smul_widen_optab
326 || binoptab == umul_widen_optab)
330 if (((target == 0 || GET_CODE (target) == REG)
331 ? ((GET_CODE (op1) == REG
332 && GET_CODE (op0) != REG)
334 : rtx_equal_p (op1, target))
335 || GET_CODE (op0) == CONST_INT)
343 /* If we can do it with a three-operand insn, do so. */
345 if (methods != OPTAB_MUST_WIDEN
346 && binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
348 int icode = (int) binoptab->handlers[(int) mode].insn_code;
349 enum machine_mode mode0 = insn_operand_mode[icode][1];
350 enum machine_mode mode1 = insn_operand_mode[icode][2];
352 rtx xop0 = op0, xop1 = op1;
357 temp = gen_reg_rtx (mode);
359 /* If it is a commutative operator and the modes would match
360 if we would swap the operands, we can save the conversions. */
363 if (GET_MODE (op0) != mode0 && GET_MODE (op1) != mode1
364 && GET_MODE (op0) == mode1 && GET_MODE (op1) == mode0)
368 tmp = op0; op0 = op1; op1 = tmp;
369 tmp = xop0; xop0 = xop1; xop1 = tmp;
373 /* In case the insn wants input operands in modes different from
374 the result, convert the operands. */
376 if (GET_MODE (op0) != VOIDmode
377 && GET_MODE (op0) != mode0)
378 xop0 = convert_to_mode (mode0, xop0, unsignedp);
380 if (GET_MODE (xop1) != VOIDmode
381 && GET_MODE (xop1) != mode1)
382 xop1 = convert_to_mode (mode1, xop1, unsignedp);
384 /* Now, if insn's predicates don't allow our operands, put them into
387 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
388 xop0 = copy_to_mode_reg (mode0, xop0);
390 if (! (*insn_operand_predicate[icode][2]) (xop1, mode1))
391 xop1 = copy_to_mode_reg (mode1, xop1);
393 if (! (*insn_operand_predicate[icode][0]) (temp, mode))
394 temp = gen_reg_rtx (mode);
396 pat = GEN_FCN (icode) (temp, xop0, xop1);
399 /* If PAT is a multi-insn sequence, try to add an appropriate
400 REG_EQUAL note to it. If we can't because TEMP conflicts with an
401 operand, call ourselves again, this time without a target. */
402 if (GET_CODE (pat) == SEQUENCE
403 && ! add_equal_note (pat, temp, binoptab->code, xop0, xop1))
405 delete_insns_since (last);
406 return expand_binop (mode, binoptab, op0, op1, NULL_RTX,
414 delete_insns_since (last);
417 /* If this is a multiply, see if we can do a widening operation that
418 takes operands of this mode and makes a wider mode. */
420 if (binoptab == smul_optab && GET_MODE_WIDER_MODE (mode) != VOIDmode
421 && (((unsignedp ? umul_widen_optab : smul_widen_optab)
422 ->handlers[(int) GET_MODE_WIDER_MODE (mode)].insn_code)
423 != CODE_FOR_nothing))
425 temp = expand_binop (GET_MODE_WIDER_MODE (mode),
426 unsignedp ? umul_widen_optab : smul_widen_optab,
427 op0, op1, 0, unsignedp, OPTAB_DIRECT);
429 if (GET_MODE_CLASS (mode) == MODE_INT)
430 return gen_lowpart (mode, temp);
432 return convert_to_mode (mode, temp, unsignedp);
435 /* Look for a wider mode of the same class for which we think we
436 can open-code the operation. Check for a widening multiply at the
437 wider mode as well. */
439 if ((class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
440 && methods != OPTAB_DIRECT && methods != OPTAB_LIB)
441 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
442 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
444 if (binoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing
445 || (binoptab == smul_optab
446 && GET_MODE_WIDER_MODE (wider_mode) != VOIDmode
447 && (((unsignedp ? umul_widen_optab : smul_widen_optab)
448 ->handlers[(int) GET_MODE_WIDER_MODE (wider_mode)].insn_code)
449 != CODE_FOR_nothing)))
451 rtx xop0 = op0, xop1 = op1;
454 /* For certain integer operations, we need not actually extend
455 the narrow operands, as long as we will truncate
456 the results to the same narrowness. Don't do this when
457 WIDER_MODE is wider than a word since a paradoxical SUBREG
458 isn't valid for such modes. */
460 if ((binoptab == ior_optab || binoptab == and_optab
461 || binoptab == xor_optab
462 || binoptab == add_optab || binoptab == sub_optab
463 || binoptab == smul_optab
464 || binoptab == ashl_optab || binoptab == lshl_optab)
466 && GET_MODE_SIZE (wider_mode) <= UNITS_PER_WORD)
469 /* If an operand is a constant integer, we might as well
470 convert it since that is more efficient than using a SUBREG,
471 unlike the case for other operands. Similarly for
472 SUBREGs that were made due to promoted objects. */
474 if (no_extend && GET_MODE (xop0) != VOIDmode
475 && ! (GET_CODE (xop0) == SUBREG
476 && SUBREG_PROMOTED_VAR_P (xop0)))
477 xop0 = gen_rtx (SUBREG, wider_mode,
478 force_reg (GET_MODE (xop0), xop0), 0);
480 xop0 = convert_to_mode (wider_mode, xop0, unsignedp);
482 if (no_extend && GET_MODE (xop1) != VOIDmode
483 && ! (GET_CODE (xop1) == SUBREG
484 && SUBREG_PROMOTED_VAR_P (xop1)))
485 xop1 = gen_rtx (SUBREG, wider_mode,
486 force_reg (GET_MODE (xop1), xop1), 0);
488 xop1 = convert_to_mode (wider_mode, xop1, unsignedp);
490 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
491 unsignedp, OPTAB_DIRECT);
494 if (class != MODE_INT)
497 target = gen_reg_rtx (mode);
498 convert_move (target, temp, 0);
502 return gen_lowpart (mode, temp);
505 delete_insns_since (last);
509 /* These can be done a word at a time. */
510 if ((binoptab == and_optab || binoptab == ior_optab || binoptab == xor_optab)
512 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
513 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
519 /* If TARGET is the same as one of the operands, the REG_EQUAL note
520 won't be accurate, so use a new target. */
521 if (target == 0 || target == op0 || target == op1)
522 target = gen_reg_rtx (mode);
526 /* Do the actual arithmetic. */
527 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
529 rtx target_piece = operand_subword (target, i, 1, mode);
530 rtx x = expand_binop (word_mode, binoptab,
531 operand_subword_force (op0, i, mode),
532 operand_subword_force (op1, i, mode),
533 target_piece, unsignedp, methods);
534 if (target_piece != x)
535 emit_move_insn (target_piece, x);
538 insns = get_insns ();
541 if (binoptab->code != UNKNOWN)
542 equiv_value = gen_rtx (binoptab->code, mode, op0, op1);
546 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
550 /* These can be done a word at a time by propagating carries. */
551 if ((binoptab == add_optab || binoptab == sub_optab)
553 && GET_MODE_SIZE (mode) >= 2 * UNITS_PER_WORD
554 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
557 rtx carry_tmp = gen_reg_rtx (word_mode);
558 optab otheroptab = binoptab == add_optab ? sub_optab : add_optab;
559 int nwords = GET_MODE_BITSIZE (mode) / BITS_PER_WORD;
560 rtx carry_in, carry_out;
563 /* We can handle either a 1 or -1 value for the carry. If STORE_FLAG
564 value is one of those, use it. Otherwise, use 1 since it is the
565 one easiest to get. */
566 #if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
567 int normalizep = STORE_FLAG_VALUE;
572 /* Prepare the operands. */
573 xop0 = force_reg (mode, op0);
574 xop1 = force_reg (mode, op1);
576 if (target == 0 || GET_CODE (target) != REG
577 || target == xop0 || target == xop1)
578 target = gen_reg_rtx (mode);
580 /* Do the actual arithmetic. */
581 for (i = 0; i < nwords; i++)
583 int index = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i);
584 rtx target_piece = operand_subword (target, index, 1, mode);
585 rtx op0_piece = operand_subword_force (xop0, index, mode);
586 rtx op1_piece = operand_subword_force (xop1, index, mode);
589 /* Main add/subtract of the input operands. */
590 x = expand_binop (word_mode, binoptab,
591 op0_piece, op1_piece,
592 target_piece, unsignedp, methods);
598 /* Store carry from main add/subtract. */
599 carry_out = gen_reg_rtx (word_mode);
600 carry_out = emit_store_flag (carry_out,
601 binoptab == add_optab ? LTU : GTU,
603 word_mode, 1, normalizep);
610 /* Add/subtract previous carry to main result. */
611 x = expand_binop (word_mode,
612 normalizep == 1 ? binoptab : otheroptab,
614 target_piece, 1, methods);
615 if (target_piece != x)
616 emit_move_insn (target_piece, x);
620 /* THIS CODE HAS NOT BEEN TESTED. */
621 /* Get out carry from adding/subtracting carry in. */
622 carry_tmp = emit_store_flag (carry_tmp,
623 binoptab == add_optab
626 word_mode, 1, normalizep);
627 /* Logical-ior the two poss. carry together. */
628 carry_out = expand_binop (word_mode, ior_optab,
629 carry_out, carry_tmp,
630 carry_out, 0, methods);
636 carry_in = carry_out;
639 if (i == GET_MODE_BITSIZE (mode) / BITS_PER_WORD)
643 temp = emit_move_insn (target, target);
644 REG_NOTES (temp) = gen_rtx (EXPR_LIST, REG_EQUAL,
645 gen_rtx (binoptab->code, mode, xop0, xop1),
650 delete_insns_since (last);
653 /* If we want to multiply two two-word values and have normal and widening
654 multiplies of single-word values, we can do this with three smaller
655 multiplications. Note that we do not make a REG_NO_CONFLICT block here
656 because we are not operating on one word at a time.
658 The multiplication proceeds as follows:
659 _______________________
660 [__op0_high_|__op0_low__]
661 _______________________
662 * [__op1_high_|__op1_low__]
663 _______________________________________________
664 _______________________
665 (1) [__op0_low__*__op1_low__]
666 _______________________
667 (2a) [__op0_low__*__op1_high_]
668 _______________________
669 (2b) [__op0_high_*__op1_low__]
670 _______________________
671 (3) [__op0_high_*__op1_high_]
674 This gives a 4-word result. Since we are only interested in the
675 lower 2 words, partial result (3) and the upper words of (2a) and
676 (2b) don't need to be calculated. Hence (2a) and (2b) can be
677 calculated using non-widening multiplication.
679 (1), however, needs to be calculated with an unsigned widening
680 multiplication. If this operation is not directly supported we
681 try using a signed widening multiplication and adjust the result.
682 This adjustment works as follows:
684 If both operands are positive then no adjustment is needed.
686 If the operands have different signs, for example op0_low < 0 and
687 op1_low >= 0, the instruction treats the most significant bit of
688 op0_low as a sign bit instead of a bit with significance
689 2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low
690 with 2**BITS_PER_WORD - op0_low, and two's complements the
691 result. Conclusion: We need to add op1_low * 2**BITS_PER_WORD to
694 Similarly, if both operands are negative, we need to add
695 (op0_low + op1_low) * 2**BITS_PER_WORD.
697 We use a trick to adjust quickly. We logically shift op0_low right
698 (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to
699 op0_high (op1_high) before it is used to calculate 2b (2a). If no
700 logical shift exists, we do an arithmetic right shift and subtract
703 if (binoptab == smul_optab
705 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
706 && smul_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
707 && add_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
708 && ((umul_widen_optab->handlers[(int) mode].insn_code
710 || (smul_widen_optab->handlers[(int) mode].insn_code
711 != CODE_FOR_nothing)))
713 int low = (WORDS_BIG_ENDIAN ? 1 : 0);
714 int high = (WORDS_BIG_ENDIAN ? 0 : 1);
715 rtx op0_high = operand_subword_force (op0, high, mode);
716 rtx op0_low = operand_subword_force (op0, low, mode);
717 rtx op1_high = operand_subword_force (op1, high, mode);
718 rtx op1_low = operand_subword_force (op1, low, mode);
723 /* If the target is the same as one of the inputs, don't use it. This
724 prevents problems with the REG_EQUAL note. */
725 if (target == op0 || target == op1)
728 /* Multiply the two lower words to get a double-word product.
729 If unsigned widening multiplication is available, use that;
730 otherwise use the signed form and compensate. */
732 if (umul_widen_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
734 product = expand_binop (mode, umul_widen_optab, op0_low, op1_low,
735 target, 1, OPTAB_DIRECT);
737 /* If we didn't succeed, delete everything we did so far. */
739 delete_insns_since (last);
741 op0_xhigh = op0_high, op1_xhigh = op1_high;
745 && smul_widen_optab->handlers[(int) mode].insn_code
748 rtx wordm1 = GEN_INT (BITS_PER_WORD - 1);
749 product = expand_binop (mode, smul_widen_optab, op0_low, op1_low,
750 target, 1, OPTAB_DIRECT);
751 op0_xhigh = expand_binop (word_mode, lshr_optab, op0_low, wordm1,
752 NULL_RTX, 1, OPTAB_DIRECT);
754 op0_xhigh = expand_binop (word_mode, add_optab, op0_high,
755 op0_xhigh, op0_xhigh, 0, OPTAB_DIRECT);
758 op0_xhigh = expand_binop (word_mode, ashr_optab, op0_low, wordm1,
759 NULL_RTX, 0, OPTAB_DIRECT);
761 op0_xhigh = expand_binop (word_mode, sub_optab, op0_high,
762 op0_xhigh, op0_xhigh, 0,
766 op1_xhigh = expand_binop (word_mode, lshr_optab, op1_low, wordm1,
767 NULL_RTX, 1, OPTAB_DIRECT);
769 op1_xhigh = expand_binop (word_mode, add_optab, op1_high,
770 op1_xhigh, op1_xhigh, 0, OPTAB_DIRECT);
773 op1_xhigh = expand_binop (word_mode, ashr_optab, op1_low, wordm1,
774 NULL_RTX, 0, OPTAB_DIRECT);
776 op1_xhigh = expand_binop (word_mode, sub_optab, op1_high,
777 op1_xhigh, op1_xhigh, 0,
782 /* If we have been able to directly compute the product of the
783 low-order words of the operands and perform any required adjustments
784 of the operands, we proceed by trying two more multiplications
785 and then computing the appropriate sum.
787 We have checked above that the required addition is provided.
788 Full-word addition will normally always succeed, especially if
789 it is provided at all, so we don't worry about its failure. The
790 multiplication may well fail, however, so we do handle that. */
792 if (product && op0_xhigh && op1_xhigh)
795 rtx product_high = operand_subword (product, high, 1, mode);
796 rtx temp = expand_binop (word_mode, binoptab, op0_low, op1_xhigh,
797 NULL_RTX, 0, OPTAB_DIRECT);
801 product_piece = expand_binop (word_mode, add_optab, temp,
802 product_high, product_high,
804 if (product_piece != product_high)
805 emit_move_insn (product_high, product_piece);
807 temp = expand_binop (word_mode, binoptab, op1_low, op0_xhigh,
808 NULL_RTX, 0, OPTAB_DIRECT);
810 product_piece = expand_binop (word_mode, add_optab, temp,
811 product_high, product_high,
813 if (product_piece != product_high)
814 emit_move_insn (product_high, product_piece);
816 temp = emit_move_insn (product, product);
817 REG_NOTES (temp) = gen_rtx (EXPR_LIST, REG_EQUAL,
818 gen_rtx (MULT, mode, op0, op1),
825 /* If we get here, we couldn't do it for some reason even though we
826 originally thought we could. Delete anything we've emitted in
829 delete_insns_since (last);
832 /* We need to open-code the complex type operations: '+, -, * and /' */
834 /* At this point we allow operations between two similar complex
835 numbers, and also if one of the operands is not a complex number
836 but rather of MODE_FLOAT or MODE_INT. However, the caller
837 must make sure that the MODE of the non-complex operand matches
838 the SUBMODE of the complex operand. */
840 if (class == MODE_COMPLEX_FLOAT || class == MODE_COMPLEX_INT)
852 /* Find the correct mode for the real and imaginary parts */
853 enum machine_mode submode
854 = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
855 class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
858 if (submode == BLKmode)
862 target = gen_reg_rtx (mode);
866 realr = gen_realpart (submode, target);
867 imagr = gen_imagpart (submode, target);
869 if (GET_MODE (op0) == mode)
871 real0 = gen_realpart (submode, op0);
872 imag0 = gen_imagpart (submode, op0);
877 if (GET_MODE (op1) == mode)
879 real1 = gen_realpart (submode, op1);
880 imag1 = gen_imagpart (submode, op1);
885 if (! real0 || ! real1 || ! (imag0 || imag1))
888 switch (binoptab->code)
892 res = expand_binop (submode, binoptab, real0, real1,
893 realr, unsignedp, methods);
895 emit_move_insn (realr, res);
898 res = expand_binop (submode, binoptab, imag0, imag1,
899 imagr, unsignedp, methods);
902 else if (binoptab->code == MINUS)
903 res = expand_unop (submode, neg_optab, imag1, imagr, unsignedp);
908 emit_move_insn (imagr, res);
912 /* (a+ib) * (c+id) = (ac-bd) + i(ad+cb) */
914 res = expand_binop (submode, binoptab, real0, real1,
915 realr, unsignedp, methods);
920 expand_binop (submode, sub_optab, res,
921 expand_binop (submode, binoptab, imag0, imag1,
922 0, unsignedp, methods),
923 realr, unsignedp, methods);
926 emit_move_insn (realr, temp);
928 res = expand_binop (submode, add_optab,
929 expand_binop (submode, binoptab,
931 0, unsignedp, methods),
932 expand_binop (submode, binoptab,
934 0, unsignedp, methods),
935 imagr, unsignedp, methods);
937 emit_move_insn (imagr, res);
942 emit_move_insn (realr, res);
945 res = expand_binop (submode, binoptab,
946 real1, imag0, imagr, unsignedp, methods);
948 res = expand_binop (submode, binoptab,
949 real0, imag1, imagr, unsignedp, methods);
951 emit_move_insn (imagr, res);
956 /* (c+id)/(a+ib) == ((c+id)*(a-ib))/(a*a+b*b) */
960 /* Simply divide the real and imaginary parts by `a' */
961 res = expand_binop (submode, binoptab, real0, real1,
962 realr, unsignedp, methods);
964 emit_move_insn (realr, res);
966 res = expand_binop (submode, binoptab, imag0, real1,
967 imagr, unsignedp, methods);
969 emit_move_insn (imagr, res);
971 else /* Divider is of complex type */
978 optab mulopt = unsignedp ? umul_widen_optab : smul_optab;
980 /* Divider: a*a + b*b */
981 divider = expand_binop (submode, add_optab,
982 expand_binop (submode, mulopt,
984 0, unsignedp, methods),
985 expand_binop (submode, mulopt,
987 0, unsignedp, methods),
988 0, unsignedp, methods);
990 if (! imag0) /* ((c)(a-ib))/divider */
992 /* Calculate the divident */
993 real_t = expand_binop (submode, mulopt, real0, real1,
994 0, unsignedp, methods);
997 = expand_unop (submode, neg_optab,
998 expand_binop (submode, mulopt, real0, imag1,
999 0, unsignedp, methods),
1002 else /* ((c+id)(a-ib))/divider */
1004 /* Calculate the divident */
1005 real_t = expand_binop (submode, add_optab,
1006 expand_binop (submode, mulopt,
1008 0, unsignedp, methods),
1009 expand_binop (submode, mulopt,
1011 0, unsignedp, methods),
1012 0, unsignedp, methods);
1014 imag_t = expand_binop (submode, sub_optab,
1015 expand_binop (submode, mulopt,
1017 0, unsignedp, methods),
1018 expand_binop (submode, mulopt,
1020 0, unsignedp, methods),
1021 0, unsignedp, methods);
1025 res = expand_binop (submode, binoptab, real_t, divider,
1026 realr, unsignedp, methods);
1028 emit_move_insn (realr, res);
1030 res = expand_binop (submode, binoptab, imag_t, divider,
1031 imagr, unsignedp, methods);
1033 emit_move_insn (imagr, res);
1044 if (binoptab->code != UNKNOWN)
1045 equiv_value = gen_rtx (binoptab->code, mode, op0, op1);
1049 emit_no_conflict_block (seq, target, op0, op1, equiv_value);
1054 /* It can't be open-coded in this mode.
1055 Use a library call if one is available and caller says that's ok. */
1057 if (binoptab->handlers[(int) mode].libfunc
1058 && (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN))
1061 rtx funexp = binoptab->handlers[(int) mode].libfunc;
1063 enum machine_mode op1_mode = mode;
1069 op1_mode = word_mode;
1070 /* Specify unsigned here,
1071 since negative shift counts are meaningless. */
1072 op1x = convert_to_mode (word_mode, op1, 1);
1075 /* Pass 1 for NO_QUEUE so we don't lose any increments
1076 if the libcall is cse'd or moved. */
1077 emit_library_call (binoptab->handlers[(int) mode].libfunc,
1078 1, mode, 2, op0, mode, op1x, op1_mode);
1080 insns = get_insns ();
1083 target = gen_reg_rtx (mode);
1084 emit_libcall_block (insns, target, hard_libcall_value (mode),
1085 gen_rtx (binoptab->code, mode, op0, op1));
1090 delete_insns_since (last);
1092 /* It can't be done in this mode. Can we do it in a wider mode? */
1094 if (! (methods == OPTAB_WIDEN || methods == OPTAB_LIB_WIDEN
1095 || methods == OPTAB_MUST_WIDEN))
1096 return 0; /* Caller says, don't even try. */
1098 /* Compute the value of METHODS to pass to recursive calls.
1099 Don't allow widening to be tried recursively. */
1101 methods = (methods == OPTAB_LIB_WIDEN ? OPTAB_LIB : OPTAB_DIRECT);
1103 /* Look for a wider mode of the same class for which it appears we can do
1106 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1108 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1109 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1111 if ((binoptab->handlers[(int) wider_mode].insn_code
1112 != CODE_FOR_nothing)
1113 || (methods == OPTAB_LIB
1114 && binoptab->handlers[(int) wider_mode].libfunc))
1116 rtx xop0 = op0, xop1 = op1;
1119 /* For certain integer operations, we need not actually extend
1120 the narrow operands, as long as we will truncate
1121 the results to the same narrowness. Don't do this when
1122 WIDER_MODE is wider than a word since a paradoxical SUBREG
1123 isn't valid for such modes. */
1125 if ((binoptab == ior_optab || binoptab == and_optab
1126 || binoptab == xor_optab
1127 || binoptab == add_optab || binoptab == sub_optab
1128 || binoptab == smul_optab
1129 || binoptab == ashl_optab || binoptab == lshl_optab)
1130 && class == MODE_INT
1131 && GET_MODE_SIZE (wider_mode) <= UNITS_PER_WORD)
1134 /* If an operand is a constant integer, we might as well
1135 convert it since that is more efficient than using a SUBREG,
1136 unlike the case for other operands. Similarly for
1137 SUBREGs that were made due to promoted objects.*/
1139 if (no_extend && GET_MODE (xop0) != VOIDmode
1140 && ! (GET_CODE (xop0) == SUBREG
1141 && SUBREG_PROMOTED_VAR_P (xop0)))
1142 xop0 = gen_rtx (SUBREG, wider_mode,
1143 force_reg (GET_MODE (xop0), xop0), 0);
1145 xop0 = convert_to_mode (wider_mode, xop0, unsignedp);
1147 if (no_extend && GET_MODE (xop1) != VOIDmode
1148 && ! (GET_CODE (xop1) == SUBREG
1149 && SUBREG_PROMOTED_VAR_P (xop1)))
1150 xop1 = gen_rtx (SUBREG, wider_mode,
1151 force_reg (GET_MODE (xop1), xop1), 0);
1153 xop1 = convert_to_mode (wider_mode, xop1, unsignedp);
1155 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
1156 unsignedp, methods);
1159 if (class != MODE_INT)
1162 target = gen_reg_rtx (mode);
1163 convert_move (target, temp, 0);
1167 return gen_lowpart (mode, temp);
1170 delete_insns_since (last);
1178 /* Expand a binary operator which has both signed and unsigned forms.
1179 UOPTAB is the optab for unsigned operations, and SOPTAB is for
1182 If we widen unsigned operands, we may use a signed wider operation instead
1183 of an unsigned wider operation, since the result would be the same. */
1186 sign_expand_binop (mode, uoptab, soptab, op0, op1, target, unsignedp, methods)
1187 enum machine_mode mode;
1188 optab uoptab, soptab;
1189 rtx op0, op1, target;
1191 enum optab_methods methods;
1194 optab direct_optab = unsignedp ? uoptab : soptab;
1195 struct optab wide_soptab;
1197 /* Do it without widening, if possible. */
1198 temp = expand_binop (mode, direct_optab, op0, op1, target,
1199 unsignedp, OPTAB_DIRECT);
1200 if (temp || methods == OPTAB_DIRECT)
1203 /* Try widening to a signed int. Make a fake signed optab that
1204 hides any signed insn for direct use. */
1205 wide_soptab = *soptab;
1206 wide_soptab.handlers[(int) mode].insn_code = CODE_FOR_nothing;
1207 wide_soptab.handlers[(int) mode].libfunc = 0;
1209 temp = expand_binop (mode, &wide_soptab, op0, op1, target,
1210 unsignedp, OPTAB_WIDEN);
1212 /* For unsigned operands, try widening to an unsigned int. */
1213 if (temp == 0 && unsignedp)
1214 temp = expand_binop (mode, uoptab, op0, op1, target,
1215 unsignedp, OPTAB_WIDEN);
1216 if (temp || methods == OPTAB_WIDEN)
1219 /* Use the right width lib call if that exists. */
1220 temp = expand_binop (mode, direct_optab, op0, op1, target, unsignedp, OPTAB_LIB);
1221 if (temp || methods == OPTAB_LIB)
1224 /* Must widen and use a lib call, use either signed or unsigned. */
1225 temp = expand_binop (mode, &wide_soptab, op0, op1, target,
1226 unsignedp, methods);
1230 return expand_binop (mode, uoptab, op0, op1, target,
1231 unsignedp, methods);
1235 /* Generate code to perform an operation specified by BINOPTAB
1236 on operands OP0 and OP1, with two results to TARG1 and TARG2.
1237 We assume that the order of the operands for the instruction
1238 is TARG0, OP0, OP1, TARG1, which would fit a pattern like
1239 [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
1241 Either TARG0 or TARG1 may be zero, but what that means is that
1242 that result is not actually wanted. We will generate it into
1243 a dummy pseudo-reg and discard it. They may not both be zero.
1245 Returns 1 if this operation can be performed; 0 if not. */
1248 expand_twoval_binop (binoptab, op0, op1, targ0, targ1, unsignedp)
1254 enum machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
1255 enum mode_class class;
1256 enum machine_mode wider_mode;
1259 class = GET_MODE_CLASS (mode);
1261 op0 = protect_from_queue (op0, 0);
1262 op1 = protect_from_queue (op1, 0);
1266 op0 = force_not_mem (op0);
1267 op1 = force_not_mem (op1);
1270 /* If we are inside an appropriately-short loop and one operand is an
1271 expensive constant, force it into a register. */
1272 if (CONSTANT_P (op0) && preserve_subexpressions_p ()
1273 && rtx_cost (op0, binoptab->code) > 2)
1274 op0 = force_reg (mode, op0);
1276 if (CONSTANT_P (op1) && preserve_subexpressions_p ()
1277 && rtx_cost (op1, binoptab->code) > 2)
1278 op1 = force_reg (mode, op1);
1281 targ0 = protect_from_queue (targ0, 1);
1283 targ0 = gen_reg_rtx (mode);
1285 targ1 = protect_from_queue (targ1, 1);
1287 targ1 = gen_reg_rtx (mode);
1289 /* Record where to go back to if we fail. */
1290 last = get_last_insn ();
1292 if (binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1294 int icode = (int) binoptab->handlers[(int) mode].insn_code;
1295 enum machine_mode mode0 = insn_operand_mode[icode][1];
1296 enum machine_mode mode1 = insn_operand_mode[icode][2];
1298 rtx xop0 = op0, xop1 = op1;
1300 /* In case this insn wants input operands in modes different from the
1301 result, convert the operands. */
1302 if (GET_MODE (op0) != VOIDmode && GET_MODE (op0) != mode0)
1303 xop0 = convert_to_mode (mode0, xop0, unsignedp);
1305 if (GET_MODE (op1) != VOIDmode && GET_MODE (op1) != mode1)
1306 xop1 = convert_to_mode (mode1, xop1, unsignedp);
1308 /* Now, if insn doesn't accept these operands, put them into pseudos. */
1309 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
1310 xop0 = copy_to_mode_reg (mode0, xop0);
1312 if (! (*insn_operand_predicate[icode][2]) (xop1, mode1))
1313 xop1 = copy_to_mode_reg (mode1, xop1);
1315 /* We could handle this, but we should always be called with a pseudo
1316 for our targets and all insns should take them as outputs. */
1317 if (! (*insn_operand_predicate[icode][0]) (targ0, mode)
1318 || ! (*insn_operand_predicate[icode][3]) (targ1, mode))
1321 pat = GEN_FCN (icode) (targ0, xop0, xop1, targ1);
1328 delete_insns_since (last);
1331 /* It can't be done in this mode. Can we do it in a wider mode? */
1333 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1335 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1336 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1338 if (binoptab->handlers[(int) wider_mode].insn_code
1339 != CODE_FOR_nothing)
1341 register rtx t0 = gen_reg_rtx (wider_mode);
1342 register rtx t1 = gen_reg_rtx (wider_mode);
1344 if (expand_twoval_binop (binoptab,
1345 convert_to_mode (wider_mode, op0,
1347 convert_to_mode (wider_mode, op1,
1351 convert_move (targ0, t0, unsignedp);
1352 convert_move (targ1, t1, unsignedp);
1356 delete_insns_since (last);
1364 /* Generate code to perform an operation specified by UNOPTAB
1365 on operand OP0, with result having machine-mode MODE.
1367 UNSIGNEDP is for the case where we have to widen the operands
1368 to perform the operation. It says to use zero-extension.
1370 If TARGET is nonzero, the value
1371 is generated there, if it is convenient to do so.
1372 In all cases an rtx is returned for the locus of the value;
1373 this may or may not be TARGET. */
1376 expand_unop (mode, unoptab, op0, target, unsignedp)
1377 enum machine_mode mode;
1383 enum mode_class class;
1384 enum machine_mode wider_mode;
1386 rtx last = get_last_insn ();
1389 class = GET_MODE_CLASS (mode);
1391 op0 = protect_from_queue (op0, 0);
1395 op0 = force_not_mem (op0);
1399 target = protect_from_queue (target, 1);
1401 if (unoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1403 int icode = (int) unoptab->handlers[(int) mode].insn_code;
1404 enum machine_mode mode0 = insn_operand_mode[icode][1];
1410 temp = gen_reg_rtx (mode);
1412 if (GET_MODE (xop0) != VOIDmode
1413 && GET_MODE (xop0) != mode0)
1414 xop0 = convert_to_mode (mode0, xop0, unsignedp);
1416 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
1418 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
1419 xop0 = copy_to_mode_reg (mode0, xop0);
1421 if (! (*insn_operand_predicate[icode][0]) (temp, mode))
1422 temp = gen_reg_rtx (mode);
1424 pat = GEN_FCN (icode) (temp, xop0);
1427 if (GET_CODE (pat) == SEQUENCE
1428 && ! add_equal_note (pat, temp, unoptab->code, xop0, NULL_RTX))
1430 delete_insns_since (last);
1431 return expand_unop (mode, unoptab, op0, NULL_RTX, unsignedp);
1439 delete_insns_since (last);
1442 /* It can't be done in this mode. Can we open-code it in a wider mode? */
1444 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1445 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1446 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1448 if (unoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing)
1452 /* For certain operations, we need not actually extend
1453 the narrow operand, as long as we will truncate the
1454 results to the same narrowness. But it is faster to
1455 convert a SUBREG due to mode promotion. */
1457 if ((unoptab == neg_optab || unoptab == one_cmpl_optab)
1458 && GET_MODE_SIZE (wider_mode) <= UNITS_PER_WORD
1459 && class == MODE_INT
1460 && ! (GET_CODE (xop0) == SUBREG
1461 && SUBREG_PROMOTED_VAR_P (xop0)))
1462 xop0 = gen_rtx (SUBREG, wider_mode, force_reg (mode, xop0), 0);
1464 xop0 = convert_to_mode (wider_mode, xop0, unsignedp);
1466 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
1471 if (class != MODE_INT)
1474 target = gen_reg_rtx (mode);
1475 convert_move (target, temp, 0);
1479 return gen_lowpart (mode, temp);
1482 delete_insns_since (last);
1486 /* These can be done a word at a time. */
1487 if (unoptab == one_cmpl_optab
1488 && class == MODE_INT
1489 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
1490 && unoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
1495 if (target == 0 || target == op0)
1496 target = gen_reg_rtx (mode);
1500 /* Do the actual arithmetic. */
1501 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
1503 rtx target_piece = operand_subword (target, i, 1, mode);
1504 rtx x = expand_unop (word_mode, unoptab,
1505 operand_subword_force (op0, i, mode),
1506 target_piece, unsignedp);
1507 if (target_piece != x)
1508 emit_move_insn (target_piece, x);
1511 insns = get_insns ();
1514 emit_no_conflict_block (insns, target, op0, NULL_RTX,
1515 gen_rtx (unoptab->code, mode, op0));
1519 /* Open-code the complex negation operation. */
1520 else if (unoptab == neg_optab
1521 && (class == MODE_COMPLEX_FLOAT || class == MODE_COMPLEX_INT))
1527 /* Find the correct mode for the real and imaginary parts */
1528 enum machine_mode submode
1529 = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
1530 class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
1533 if (submode == BLKmode)
1537 target = gen_reg_rtx (mode);
1541 target_piece = gen_imagpart (submode, target);
1542 x = expand_unop (submode, unoptab,
1543 gen_imagpart (submode, op0),
1544 target_piece, unsignedp);
1545 if (target_piece != x)
1546 emit_move_insn (target_piece, x);
1548 target_piece = gen_realpart (submode, target);
1549 x = expand_unop (submode, unoptab,
1550 gen_realpart (submode, op0),
1551 target_piece, unsignedp);
1552 if (target_piece != x)
1553 emit_move_insn (target_piece, x);
1558 emit_no_conflict_block (seq, target, op0, 0,
1559 gen_rtx (unoptab->code, mode, op0));
1563 /* Now try a library call in this mode. */
1564 if (unoptab->handlers[(int) mode].libfunc)
1567 rtx funexp = unoptab->handlers[(int) mode].libfunc;
1571 /* Pass 1 for NO_QUEUE so we don't lose any increments
1572 if the libcall is cse'd or moved. */
1573 emit_library_call (unoptab->handlers[(int) mode].libfunc,
1574 1, mode, 1, op0, mode);
1575 insns = get_insns ();
1578 target = gen_reg_rtx (mode);
1579 emit_libcall_block (insns, target, hard_libcall_value (mode),
1580 gen_rtx (unoptab->code, mode, op0));
1585 /* It can't be done in this mode. Can we do it in a wider mode? */
1587 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1589 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1590 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1592 if ((unoptab->handlers[(int) wider_mode].insn_code
1593 != CODE_FOR_nothing)
1594 || unoptab->handlers[(int) wider_mode].libfunc)
1598 /* For certain operations, we need not actually extend
1599 the narrow operand, as long as we will truncate the
1600 results to the same narrowness. */
1602 if ((unoptab == neg_optab || unoptab == one_cmpl_optab)
1603 && GET_MODE_SIZE (wider_mode) <= UNITS_PER_WORD
1604 && class == MODE_INT
1605 && ! (GET_CODE (xop0) == SUBREG
1606 && SUBREG_PROMOTED_VAR_P (xop0)))
1607 xop0 = gen_rtx (SUBREG, wider_mode, force_reg (mode, xop0), 0);
1609 xop0 = convert_to_mode (wider_mode, xop0, unsignedp);
1611 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
1616 if (class != MODE_INT)
1619 target = gen_reg_rtx (mode);
1620 convert_move (target, temp, 0);
1624 return gen_lowpart (mode, temp);
1627 delete_insns_since (last);
1635 /* Emit code to compute the absolute value of OP0, with result to
1636 TARGET if convenient. (TARGET may be 0.) The return value says
1637 where the result actually is to be found.
1639 MODE is the mode of the operand; the mode of the result is
1640 different but can be deduced from MODE.
1642 UNSIGNEDP is relevant for complex integer modes. */
1645 expand_complex_abs (mode, op0, target, unsignedp)
1646 enum machine_mode mode;
1651 enum mode_class class = GET_MODE_CLASS (mode);
1652 enum machine_mode wider_mode;
1654 rtx last = get_last_insn ();
1657 /* Find the correct mode for the real and imaginary parts. */
1658 enum machine_mode submode
1659 = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
1660 class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
1663 if (submode == BLKmode)
1666 op0 = protect_from_queue (op0, 0);
1670 op0 = force_not_mem (op0);
1674 target = protect_from_queue (target, 1);
1676 if (abs_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1678 int icode = (int) abs_optab->handlers[(int) mode].insn_code;
1679 enum machine_mode mode0 = insn_operand_mode[icode][1];
1685 temp = gen_reg_rtx (submode);
1687 if (GET_MODE (xop0) != VOIDmode
1688 && GET_MODE (xop0) != mode0)
1689 xop0 = convert_to_mode (mode0, xop0, unsignedp);
1691 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
1693 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
1694 xop0 = copy_to_mode_reg (mode0, xop0);
1696 if (! (*insn_operand_predicate[icode][0]) (temp, submode))
1697 temp = gen_reg_rtx (submode);
1699 pat = GEN_FCN (icode) (temp, xop0);
1702 if (GET_CODE (pat) == SEQUENCE
1703 && ! add_equal_note (pat, temp, abs_optab->code, xop0, NULL_RTX))
1705 delete_insns_since (last);
1706 return expand_unop (mode, abs_optab, op0, NULL_RTX, unsignedp);
1714 delete_insns_since (last);
1717 /* It can't be done in this mode. Can we open-code it in a wider mode? */
1719 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1720 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1722 if (abs_optab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing)
1726 xop0 = convert_to_mode (wider_mode, xop0, unsignedp);
1727 temp = expand_complex_abs (wider_mode, xop0, NULL_RTX, unsignedp);
1731 if (class != MODE_COMPLEX_INT)
1734 target = gen_reg_rtx (submode);
1735 convert_move (target, temp, 0);
1739 return gen_lowpart (submode, temp);
1742 delete_insns_since (last);
1746 /* Open-code the complex absolute-value operation
1747 if we can open-code sqrt. Otherwise it's not worth while. */
1748 if (sqrt_optab->handlers[(int) submode].insn_code != CODE_FOR_nothing)
1750 rtx real, imag, total;
1752 real = gen_realpart (submode, op0);
1753 imag = gen_imagpart (submode, op0);
1754 /* Square both parts. */
1755 real = expand_mult (mode, real, real, NULL_RTX, 0);
1756 imag = expand_mult (mode, imag, imag, NULL_RTX, 0);
1757 /* Sum the parts. */
1758 total = expand_binop (submode, add_optab, real, imag, 0,
1759 0, OPTAB_LIB_WIDEN);
1760 /* Get sqrt in TARGET. Set TARGET to where the result is. */
1761 target = expand_unop (submode, sqrt_optab, total, target, 0);
1763 delete_insns_since (last);
1768 /* Now try a library call in this mode. */
1769 if (abs_optab->handlers[(int) mode].libfunc)
1772 rtx funexp = abs_optab->handlers[(int) mode].libfunc;
1776 /* Pass 1 for NO_QUEUE so we don't lose any increments
1777 if the libcall is cse'd or moved. */
1778 emit_library_call (abs_optab->handlers[(int) mode].libfunc,
1779 1, mode, 1, op0, mode);
1780 insns = get_insns ();
1783 target = gen_reg_rtx (submode);
1784 emit_libcall_block (insns, target, hard_libcall_value (submode),
1785 gen_rtx (abs_optab->code, mode, op0));
1790 /* It can't be done in this mode. Can we do it in a wider mode? */
1792 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1793 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1795 if ((abs_optab->handlers[(int) wider_mode].insn_code
1796 != CODE_FOR_nothing)
1797 || abs_optab->handlers[(int) wider_mode].libfunc)
1801 xop0 = convert_to_mode (wider_mode, xop0, unsignedp);
1803 temp = expand_complex_abs (wider_mode, xop0, NULL_RTX, unsignedp);
1807 if (class != MODE_COMPLEX_INT)
1810 target = gen_reg_rtx (submode);
1811 convert_move (target, temp, 0);
1815 return gen_lowpart (submode, temp);
1818 delete_insns_since (last);
1825 /* Generate an instruction whose insn-code is INSN_CODE,
1826 with two operands: an output TARGET and an input OP0.
1827 TARGET *must* be nonzero, and the output is always stored there.
1828 CODE is an rtx code such that (CODE OP0) is an rtx that describes
1829 the value that is stored into TARGET. */
1832 emit_unop_insn (icode, target, op0, code)
1839 enum machine_mode mode0 = insn_operand_mode[icode][1];
1842 temp = target = protect_from_queue (target, 1);
1844 op0 = protect_from_queue (op0, 0);
1847 op0 = force_not_mem (op0);
1849 /* Now, if insn does not accept our operands, put them into pseudos. */
1851 if (! (*insn_operand_predicate[icode][1]) (op0, mode0))
1852 op0 = copy_to_mode_reg (mode0, op0);
1854 if (! (*insn_operand_predicate[icode][0]) (temp, GET_MODE (temp))
1855 || (flag_force_mem && GET_CODE (temp) == MEM))
1856 temp = gen_reg_rtx (GET_MODE (temp));
1858 pat = GEN_FCN (icode) (temp, op0);
1860 if (GET_CODE (pat) == SEQUENCE && code != UNKNOWN)
1861 add_equal_note (pat, temp, code, op0, NULL_RTX);
1866 emit_move_insn (target, temp);
1869 /* Emit code to perform a series of operations on a multi-word quantity, one
1872 Such a block is preceded by a CLOBBER of the output, consists of multiple
1873 insns, each setting one word of the output, and followed by a SET copying
1874 the output to itself.
1876 Each of the insns setting words of the output receives a REG_NO_CONFLICT
1877 note indicating that it doesn't conflict with the (also multi-word)
1878 inputs. The entire block is surrounded by REG_LIBCALL and REG_RETVAL
1881 INSNS is a block of code generated to perform the operation, not including
1882 the CLOBBER and final copy. All insns that compute intermediate values
1883 are first emitted, followed by the block as described above. Only
1884 INSNs are allowed in the block; no library calls or jumps may be
1887 TARGET, OP0, and OP1 are the output and inputs of the operations,
1888 respectively. OP1 may be zero for a unary operation.
1890 EQUIV, if non-zero, is an expression to be placed into a REG_EQUAL note
1893 If TARGET is not a register, INSNS is simply emitted with no special
1896 The final insn emitted is returned. */
1899 emit_no_conflict_block (insns, target, op0, op1, equiv)
1905 rtx prev, next, first, last, insn;
1907 if (GET_CODE (target) != REG || reload_in_progress)
1908 return emit_insns (insns);
1910 /* First emit all insns that do not store into words of the output and remove
1911 these from the list. */
1912 for (insn = insns; insn; insn = next)
1917 next = NEXT_INSN (insn);
1919 if (GET_CODE (insn) != INSN)
1922 if (GET_CODE (PATTERN (insn)) == SET)
1923 set = PATTERN (insn);
1924 else if (GET_CODE (PATTERN (insn)) == PARALLEL)
1926 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
1927 if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET)
1929 set = XVECEXP (PATTERN (insn), 0, i);
1937 if (! reg_overlap_mentioned_p (target, SET_DEST (set)))
1939 if (PREV_INSN (insn))
1940 NEXT_INSN (PREV_INSN (insn)) = next;
1945 PREV_INSN (next) = PREV_INSN (insn);
1951 prev = get_last_insn ();
1953 /* Now write the CLOBBER of the output, followed by the setting of each
1954 of the words, followed by the final copy. */
1955 if (target != op0 && target != op1)
1956 emit_insn (gen_rtx (CLOBBER, VOIDmode, target));
1958 for (insn = insns; insn; insn = next)
1960 next = NEXT_INSN (insn);
1963 if (op1 && GET_CODE (op1) == REG)
1964 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_NO_CONFLICT, op1,
1967 if (op0 && GET_CODE (op0) == REG)
1968 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_NO_CONFLICT, op0,
1972 last = emit_move_insn (target, target);
1974 REG_NOTES (last) = gen_rtx (EXPR_LIST, REG_EQUAL, equiv, REG_NOTES (last));
1977 first = get_insns ();
1979 first = NEXT_INSN (prev);
1981 /* Encapsulate the block so it gets manipulated as a unit. */
1982 REG_NOTES (first) = gen_rtx (INSN_LIST, REG_LIBCALL, last,
1984 REG_NOTES (last) = gen_rtx (INSN_LIST, REG_RETVAL, first, REG_NOTES (last));
1989 /* Emit code to make a call to a constant function or a library call.
1991 INSNS is a list containing all insns emitted in the call.
1992 These insns leave the result in RESULT. Our block is to copy RESULT
1993 to TARGET, which is logically equivalent to EQUIV.
1995 We first emit any insns that set a pseudo on the assumption that these are
1996 loading constants into registers; doing so allows them to be safely cse'ed
1997 between blocks. Then we emit all the other insns in the block, followed by
1998 an insn to move RESULT to TARGET. This last insn will have a REQ_EQUAL
1999 note with an operand of EQUIV.
2001 Moving assignments to pseudos outside of the block is done to improve
2002 the generated code, but is not required to generate correct code,
2003 hence being unable to move an assignment is not grounds for not making
2004 a libcall block. There are two reasons why it is safe to leave these
2005 insns inside the block: First, we know that these pseudos cannot be
2006 used in generated RTL outside the block since they are created for
2007 temporary purposes within the block. Second, CSE will not record the
2008 values of anything set inside a libcall block, so we know they must
2009 be dead at the end of the block.
2011 Except for the first group of insns (the ones setting pseudos), the
2012 block is delimited by REG_RETVAL and REG_LIBCALL notes. */
2015 emit_libcall_block (insns, target, result, equiv)
2021 rtx prev, next, first, last, insn;
2023 /* First emit all insns that set pseudos. Remove them from the list as
2024 we go. Avoid insns that set pseudo which were referenced in previous
2025 insns. These can be generated by move_by_pieces, for example,
2026 to update an address. */
2028 for (insn = insns; insn; insn = next)
2030 rtx set = single_set (insn);
2032 next = NEXT_INSN (insn);
2034 if (set != 0 && GET_CODE (SET_DEST (set)) == REG
2035 && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER
2037 || (! reg_mentioned_p (SET_DEST (set), PATTERN (insns))
2038 && ! reg_used_between_p (SET_DEST (set), insns, insn))))
2040 if (PREV_INSN (insn))
2041 NEXT_INSN (PREV_INSN (insn)) = next;
2046 PREV_INSN (next) = PREV_INSN (insn);
2052 prev = get_last_insn ();
2054 /* Write the remaining insns followed by the final copy. */
2056 for (insn = insns; insn; insn = next)
2058 next = NEXT_INSN (insn);
2063 last = emit_move_insn (target, result);
2064 REG_NOTES (last) = gen_rtx (EXPR_LIST, REG_EQUAL, equiv, REG_NOTES (last));
2067 first = get_insns ();
2069 first = NEXT_INSN (prev);
2071 /* Encapsulate the block so it gets manipulated as a unit. */
2072 REG_NOTES (first) = gen_rtx (INSN_LIST, REG_LIBCALL, last,
2074 REG_NOTES (last) = gen_rtx (INSN_LIST, REG_RETVAL, first, REG_NOTES (last));
2077 /* Generate code to store zero in X. */
2083 emit_move_insn (x, const0_rtx);
2086 /* Generate code to store 1 in X
2087 assuming it contains zero beforehand. */
2090 emit_0_to_1_insn (x)
2093 emit_move_insn (x, const1_rtx);
2096 /* Generate code to compare X with Y
2097 so that the condition codes are set.
2099 MODE is the mode of the inputs (in case they are const_int).
2100 UNSIGNEDP nonzero says that X and Y are unsigned;
2101 this matters if they need to be widened.
2103 If they have mode BLKmode, then SIZE specifies the size of both X and Y,
2104 and ALIGN specifies the known shared alignment of X and Y.
2106 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).
2107 It is ignored for fixed-point and block comparisons;
2108 it is used only for floating-point comparisons. */
2111 emit_cmp_insn (x, y, comparison, size, mode, unsignedp, align)
2113 enum rtx_code comparison;
2115 enum machine_mode mode;
2119 enum mode_class class;
2120 enum machine_mode wider_mode;
2122 class = GET_MODE_CLASS (mode);
2124 /* They could both be VOIDmode if both args are immediate constants,
2125 but we should fold that at an earlier stage.
2126 With no special code here, this will call abort,
2127 reminding the programmer to implement such folding. */
2129 if (mode != BLKmode && flag_force_mem)
2131 x = force_not_mem (x);
2132 y = force_not_mem (y);
2135 /* If we are inside an appropriately-short loop and one operand is an
2136 expensive constant, force it into a register. */
2137 if (CONSTANT_P (x) && preserve_subexpressions_p () && rtx_cost (x, COMPARE) > 2)
2138 x = force_reg (mode, x);
2140 if (CONSTANT_P (y) && preserve_subexpressions_p () && rtx_cost (y, COMPARE) > 2)
2141 y = force_reg (mode, y);
2143 /* Don't let both operands fail to indicate the mode. */
2144 if (GET_MODE (x) == VOIDmode && GET_MODE (y) == VOIDmode)
2145 x = force_reg (mode, x);
2147 /* Handle all BLKmode compares. */
2149 if (mode == BLKmode)
2152 x = protect_from_queue (x, 0);
2153 y = protect_from_queue (y, 0);
2157 #ifdef HAVE_cmpstrqi
2159 && GET_CODE (size) == CONST_INT
2160 && INTVAL (size) < (1 << GET_MODE_BITSIZE (QImode)))
2162 enum machine_mode result_mode
2163 = insn_operand_mode[(int) CODE_FOR_cmpstrqi][0];
2164 rtx result = gen_reg_rtx (result_mode);
2165 emit_insn (gen_cmpstrqi (result, x, y, size, GEN_INT (align)));
2166 emit_cmp_insn (result, const0_rtx, comparison, NULL_RTX,
2171 #ifdef HAVE_cmpstrhi
2173 && GET_CODE (size) == CONST_INT
2174 && INTVAL (size) < (1 << GET_MODE_BITSIZE (HImode)))
2176 enum machine_mode result_mode
2177 = insn_operand_mode[(int) CODE_FOR_cmpstrhi][0];
2178 rtx result = gen_reg_rtx (result_mode);
2179 emit_insn (gen_cmpstrhi (result, x, y, size, GEN_INT (align)));
2180 emit_cmp_insn (result, const0_rtx, comparison, NULL_RTX,
2185 #ifdef HAVE_cmpstrsi
2188 enum machine_mode result_mode
2189 = insn_operand_mode[(int) CODE_FOR_cmpstrsi][0];
2190 rtx result = gen_reg_rtx (result_mode);
2191 size = protect_from_queue (size, 0);
2192 emit_insn (gen_cmpstrsi (result, x, y,
2193 convert_to_mode (SImode, size, 1),
2195 emit_cmp_insn (result, const0_rtx, comparison, NULL_RTX,
2201 #ifdef TARGET_MEM_FUNCTIONS
2202 emit_library_call (memcmp_libfunc, 0,
2203 TYPE_MODE (integer_type_node), 3,
2204 XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
2207 emit_library_call (bcmp_libfunc, 0,
2208 TYPE_MODE (integer_type_node), 3,
2209 XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
2212 emit_cmp_insn (hard_libcall_value (TYPE_MODE (integer_type_node)),
2213 const0_rtx, comparison, NULL_RTX,
2214 TYPE_MODE (integer_type_node), 0, 0);
2219 /* Handle some compares against zero. */
2221 if (y == CONST0_RTX (mode)
2222 && tst_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2224 int icode = (int) tst_optab->handlers[(int) mode].insn_code;
2227 x = protect_from_queue (x, 0);
2228 y = protect_from_queue (y, 0);
2230 /* Now, if insn does accept these operands, put them into pseudos. */
2231 if (! (*insn_operand_predicate[icode][0])
2232 (x, insn_operand_mode[icode][0]))
2233 x = copy_to_mode_reg (insn_operand_mode[icode][0], x);
2235 emit_insn (GEN_FCN (icode) (x));
2239 /* Handle compares for which there is a directly suitable insn. */
2241 if (cmp_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2243 int icode = (int) cmp_optab->handlers[(int) mode].insn_code;
2246 x = protect_from_queue (x, 0);
2247 y = protect_from_queue (y, 0);
2249 /* Now, if insn doesn't accept these operands, put them into pseudos. */
2250 if (! (*insn_operand_predicate[icode][0])
2251 (x, insn_operand_mode[icode][0]))
2252 x = copy_to_mode_reg (insn_operand_mode[icode][0], x);
2254 if (! (*insn_operand_predicate[icode][1])
2255 (y, insn_operand_mode[icode][1]))
2256 y = copy_to_mode_reg (insn_operand_mode[icode][1], y);
2258 emit_insn (GEN_FCN (icode) (x, y));
2262 /* Try widening if we can find a direct insn that way. */
2264 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
2266 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2267 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2269 if (cmp_optab->handlers[(int) wider_mode].insn_code
2270 != CODE_FOR_nothing)
2272 x = protect_from_queue (x, 0);
2273 y = protect_from_queue (y, 0);
2274 x = convert_to_mode (wider_mode, x, unsignedp);
2275 y = convert_to_mode (wider_mode, y, unsignedp);
2276 emit_cmp_insn (x, y, comparison, NULL_RTX,
2277 wider_mode, unsignedp, align);
2283 /* Handle a lib call just for the mode we are using. */
2285 if (cmp_optab->handlers[(int) mode].libfunc
2286 && class != MODE_FLOAT)
2288 rtx libfunc = cmp_optab->handlers[(int) mode].libfunc;
2289 /* If we want unsigned, and this mode has a distinct unsigned
2290 comparison routine, use that. */
2291 if (unsignedp && ucmp_optab->handlers[(int) mode].libfunc)
2292 libfunc = ucmp_optab->handlers[(int) mode].libfunc;
2294 emit_library_call (libfunc, 1,
2295 SImode, 2, x, mode, y, mode);
2297 /* Integer comparison returns a result that must be compared against 1,
2298 so that even if we do an unsigned compare afterward,
2299 there is still a value that can represent the result "less than". */
2301 emit_cmp_insn (hard_libcall_value (SImode), const1_rtx,
2302 comparison, NULL_RTX, SImode, unsignedp, 0);
2306 if (class == MODE_FLOAT)
2307 emit_float_lib_cmp (x, y, comparison);
2313 /* Nonzero if a compare of mode MODE can be done straightforwardly
2314 (without splitting it into pieces). */
2317 can_compare_p (mode)
2318 enum machine_mode mode;
2322 if (cmp_optab->handlers[(int)mode].insn_code != CODE_FOR_nothing)
2324 mode = GET_MODE_WIDER_MODE (mode);
2325 } while (mode != VOIDmode);
2330 /* Emit a library call comparison between floating point X and Y.
2331 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */
2334 emit_float_lib_cmp (x, y, comparison)
2336 enum rtx_code comparison;
2338 enum machine_mode mode = GET_MODE (x);
2345 libfunc = eqsf2_libfunc;
2349 libfunc = nesf2_libfunc;
2353 libfunc = gtsf2_libfunc;
2357 libfunc = gesf2_libfunc;
2361 libfunc = ltsf2_libfunc;
2365 libfunc = lesf2_libfunc;
2368 else if (mode == DFmode)
2372 libfunc = eqdf2_libfunc;
2376 libfunc = nedf2_libfunc;
2380 libfunc = gtdf2_libfunc;
2384 libfunc = gedf2_libfunc;
2388 libfunc = ltdf2_libfunc;
2392 libfunc = ledf2_libfunc;
2395 else if (mode == XFmode)
2399 libfunc = eqxf2_libfunc;
2403 libfunc = nexf2_libfunc;
2407 libfunc = gtxf2_libfunc;
2411 libfunc = gexf2_libfunc;
2415 libfunc = ltxf2_libfunc;
2419 libfunc = lexf2_libfunc;
2422 else if (mode == TFmode)
2426 libfunc = eqtf2_libfunc;
2430 libfunc = netf2_libfunc;
2434 libfunc = gttf2_libfunc;
2438 libfunc = getf2_libfunc;
2442 libfunc = lttf2_libfunc;
2446 libfunc = letf2_libfunc;
2451 enum machine_mode wider_mode;
2453 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2454 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2456 if ((cmp_optab->handlers[(int) wider_mode].insn_code
2457 != CODE_FOR_nothing)
2458 || (cmp_optab->handlers[(int) wider_mode].libfunc != 0))
2460 x = protect_from_queue (x, 0);
2461 y = protect_from_queue (y, 0);
2462 x = convert_to_mode (wider_mode, x, 0);
2463 y = convert_to_mode (wider_mode, y, 0);
2464 emit_float_lib_cmp (x, y, comparison);
2471 emit_library_call (libfunc, 1,
2472 SImode, 2, x, mode, y, mode);
2474 emit_cmp_insn (hard_libcall_value (SImode), const0_rtx, comparison,
2475 NULL_RTX, SImode, 0, 0);
2478 /* Generate code to indirectly jump to a location given in the rtx LOC. */
2481 emit_indirect_jump (loc)
2484 if (! ((*insn_operand_predicate[(int)CODE_FOR_indirect_jump][0])
2486 loc = copy_to_mode_reg (insn_operand_mode[(int)CODE_FOR_indirect_jump][0],
2489 emit_jump_insn (gen_indirect_jump (loc));
2493 /* These three functions generate an insn body and return it
2494 rather than emitting the insn.
2496 They do not protect from queued increments,
2497 because they may be used 1) in protect_from_queue itself
2498 and 2) in other passes where there is no queue. */
2500 /* Generate and return an insn body to add Y to X. */
2503 gen_add2_insn (x, y)
2506 int icode = (int) add_optab->handlers[(int) GET_MODE (x)].insn_code;
2508 if (! (*insn_operand_predicate[icode][0]) (x, insn_operand_mode[icode][0])
2509 || ! (*insn_operand_predicate[icode][1]) (x, insn_operand_mode[icode][1])
2510 || ! (*insn_operand_predicate[icode][2]) (y, insn_operand_mode[icode][2]))
2513 return (GEN_FCN (icode) (x, x, y));
2517 have_add2_insn (mode)
2518 enum machine_mode mode;
2520 return add_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
2523 /* Generate and return an insn body to subtract Y from X. */
2526 gen_sub2_insn (x, y)
2529 int icode = (int) sub_optab->handlers[(int) GET_MODE (x)].insn_code;
2531 if (! (*insn_operand_predicate[icode][0]) (x, insn_operand_mode[icode][0])
2532 || ! (*insn_operand_predicate[icode][1]) (x, insn_operand_mode[icode][1])
2533 || ! (*insn_operand_predicate[icode][2]) (y, insn_operand_mode[icode][2]))
2536 return (GEN_FCN (icode) (x, x, y));
2540 have_sub2_insn (mode)
2541 enum machine_mode mode;
2543 return sub_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
2546 /* Generate the body of an instruction to copy Y into X. */
2549 gen_move_insn (x, y)
2552 register enum machine_mode mode = GET_MODE (x);
2553 enum insn_code insn_code;
2555 if (mode == VOIDmode)
2556 mode = GET_MODE (y);
2558 insn_code = mov_optab->handlers[(int) mode].insn_code;
2560 /* Handle MODE_CC modes: If we don't have a special move insn for this mode,
2561 find a mode to do it in. If we have a movcc, use it. Otherwise,
2562 find the MODE_INT mode of the same width. */
2564 if (insn_code == CODE_FOR_nothing)
2566 enum machine_mode tmode = VOIDmode;
2569 if (GET_MODE_CLASS (mode) == MODE_CC && mode != CCmode
2570 && mov_optab->handlers[(int) CCmode].insn_code != CODE_FOR_nothing)
2572 else if (GET_MODE_CLASS (mode) == MODE_CC)
2573 for (tmode = QImode; tmode != VOIDmode;
2574 tmode = GET_MODE_WIDER_MODE (tmode))
2575 if (GET_MODE_SIZE (tmode) == GET_MODE_SIZE (mode))
2578 if (tmode == VOIDmode)
2581 /* Get X and Y in TMODE. We can't use gen_lowpart here because it
2582 may call change_address which is not appropriate if we were
2583 called when a reload was in progress. We don't have to worry
2584 about changing the address since the size in bytes is supposed to
2585 be the same. Copy the MEM to change the mode and move any
2586 substitutions from the old MEM to the new one. */
2588 if (reload_in_progress)
2590 x = gen_lowpart_common (tmode, x1);
2591 if (x == 0 && GET_CODE (x1) == MEM)
2593 x = gen_rtx (MEM, tmode, XEXP (x1, 0));
2594 RTX_UNCHANGING_P (x) = RTX_UNCHANGING_P (x1);
2595 MEM_IN_STRUCT_P (x) = MEM_IN_STRUCT_P (x1);
2596 MEM_VOLATILE_P (x) = MEM_VOLATILE_P (x1);
2597 copy_replacements (x1, x);
2600 y = gen_lowpart_common (tmode, y1);
2601 if (y == 0 && GET_CODE (y1) == MEM)
2603 y = gen_rtx (MEM, tmode, XEXP (y1, 0));
2604 RTX_UNCHANGING_P (y) = RTX_UNCHANGING_P (y1);
2605 MEM_IN_STRUCT_P (y) = MEM_IN_STRUCT_P (y1);
2606 MEM_VOLATILE_P (y) = MEM_VOLATILE_P (y1);
2607 copy_replacements (y1, y);
2612 x = gen_lowpart (tmode, x);
2613 y = gen_lowpart (tmode, y);
2616 insn_code = mov_optab->handlers[(int) tmode].insn_code;
2619 return (GEN_FCN (insn_code) (x, y));
2622 /* Tables of patterns for extending one integer mode to another. */
2623 static enum insn_code extendtab[MAX_MACHINE_MODE][MAX_MACHINE_MODE][2];
2625 /* Return the insn code used to extend FROM_MODE to TO_MODE.
2626 UNSIGNEDP specifies zero-extension instead of sign-extension. If
2627 no such operation exists, CODE_FOR_nothing will be returned. */
2630 can_extend_p (to_mode, from_mode, unsignedp)
2631 enum machine_mode to_mode, from_mode;
2634 return extendtab[(int) to_mode][(int) from_mode][unsignedp];
2637 /* Generate the body of an insn to extend Y (with mode MFROM)
2638 into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */
2641 gen_extend_insn (x, y, mto, mfrom, unsignedp)
2643 enum machine_mode mto, mfrom;
2646 return (GEN_FCN (extendtab[(int) mto][(int) mfrom][unsignedp]) (x, y));
2654 for (p = extendtab[0][0];
2655 p < extendtab[0][0] + sizeof extendtab / sizeof extendtab[0][0][0];
2657 *p = CODE_FOR_nothing;
2659 #ifdef HAVE_extendditi2
2660 if (HAVE_extendditi2)
2661 extendtab[(int) TImode][(int) DImode][0] = CODE_FOR_extendditi2;
2663 #ifdef HAVE_extendsiti2
2664 if (HAVE_extendsiti2)
2665 extendtab[(int) TImode][(int) SImode][0] = CODE_FOR_extendsiti2;
2667 #ifdef HAVE_extendhiti2
2668 if (HAVE_extendhiti2)
2669 extendtab[(int) TImode][(int) HImode][0] = CODE_FOR_extendhiti2;
2671 #ifdef HAVE_extendqiti2
2672 if (HAVE_extendqiti2)
2673 extendtab[(int) TImode][(int) QImode][0] = CODE_FOR_extendqiti2;
2675 #ifdef HAVE_extendsidi2
2676 if (HAVE_extendsidi2)
2677 extendtab[(int) DImode][(int) SImode][0] = CODE_FOR_extendsidi2;
2679 #ifdef HAVE_extendhidi2
2680 if (HAVE_extendhidi2)
2681 extendtab[(int) DImode][(int) HImode][0] = CODE_FOR_extendhidi2;
2683 #ifdef HAVE_extendqidi2
2684 if (HAVE_extendqidi2)
2685 extendtab[(int) DImode][(int) QImode][0] = CODE_FOR_extendqidi2;
2687 #ifdef HAVE_extendhisi2
2688 if (HAVE_extendhisi2)
2689 extendtab[(int) SImode][(int) HImode][0] = CODE_FOR_extendhisi2;
2691 #ifdef HAVE_extendqisi2
2692 if (HAVE_extendqisi2)
2693 extendtab[(int) SImode][(int) QImode][0] = CODE_FOR_extendqisi2;
2695 #ifdef HAVE_extendqihi2
2696 if (HAVE_extendqihi2)
2697 extendtab[(int) HImode][(int) QImode][0] = CODE_FOR_extendqihi2;
2700 #ifdef HAVE_zero_extendditi2
2701 if (HAVE_zero_extendsiti2)
2702 extendtab[(int) TImode][(int) DImode][1] = CODE_FOR_zero_extendditi2;
2704 #ifdef HAVE_zero_extendsiti2
2705 if (HAVE_zero_extendsiti2)
2706 extendtab[(int) TImode][(int) SImode][1] = CODE_FOR_zero_extendsiti2;
2708 #ifdef HAVE_zero_extendhiti2
2709 if (HAVE_zero_extendhiti2)
2710 extendtab[(int) TImode][(int) HImode][1] = CODE_FOR_zero_extendhiti2;
2712 #ifdef HAVE_zero_extendqiti2
2713 if (HAVE_zero_extendqiti2)
2714 extendtab[(int) TImode][(int) QImode][1] = CODE_FOR_zero_extendqiti2;
2716 #ifdef HAVE_zero_extendsidi2
2717 if (HAVE_zero_extendsidi2)
2718 extendtab[(int) DImode][(int) SImode][1] = CODE_FOR_zero_extendsidi2;
2720 #ifdef HAVE_zero_extendhidi2
2721 if (HAVE_zero_extendhidi2)
2722 extendtab[(int) DImode][(int) HImode][1] = CODE_FOR_zero_extendhidi2;
2724 #ifdef HAVE_zero_extendqidi2
2725 if (HAVE_zero_extendqidi2)
2726 extendtab[(int) DImode][(int) QImode][1] = CODE_FOR_zero_extendqidi2;
2728 #ifdef HAVE_zero_extendhisi2
2729 if (HAVE_zero_extendhisi2)
2730 extendtab[(int) SImode][(int) HImode][1] = CODE_FOR_zero_extendhisi2;
2732 #ifdef HAVE_zero_extendqisi2
2733 if (HAVE_zero_extendqisi2)
2734 extendtab[(int) SImode][(int) QImode][1] = CODE_FOR_zero_extendqisi2;
2736 #ifdef HAVE_zero_extendqihi2
2737 if (HAVE_zero_extendqihi2)
2738 extendtab[(int) HImode][(int) QImode][1] = CODE_FOR_zero_extendqihi2;
2742 /* can_fix_p and can_float_p say whether the target machine
2743 can directly convert a given fixed point type to
2744 a given floating point type, or vice versa.
2745 The returned value is the CODE_FOR_... value to use,
2746 or CODE_FOR_nothing if these modes cannot be directly converted. */
2748 static enum insn_code fixtab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
2749 static enum insn_code fixtrunctab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
2750 static enum insn_code floattab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
2752 /* *TRUNCP_PTR is set to 1 if it is necessary to output
2753 an explicit FTRUNC insn before the fix insn; otherwise 0. */
2755 static enum insn_code
2756 can_fix_p (fixmode, fltmode, unsignedp, truncp_ptr)
2757 enum machine_mode fltmode, fixmode;
2762 if (fixtrunctab[(int) fltmode][(int) fixmode][unsignedp] != CODE_FOR_nothing)
2763 return fixtrunctab[(int) fltmode][(int) fixmode][unsignedp];
2765 if (ftrunc_optab->handlers[(int) fltmode].insn_code != CODE_FOR_nothing)
2768 return fixtab[(int) fltmode][(int) fixmode][unsignedp];
2770 return CODE_FOR_nothing;
2773 static enum insn_code
2774 can_float_p (fltmode, fixmode, unsignedp)
2775 enum machine_mode fixmode, fltmode;
2778 return floattab[(int) fltmode][(int) fixmode][unsignedp];
2785 for (p = fixtab[0][0];
2786 p < fixtab[0][0] + sizeof fixtab / sizeof (fixtab[0][0][0]);
2788 *p = CODE_FOR_nothing;
2789 for (p = fixtrunctab[0][0];
2790 p < fixtrunctab[0][0] + sizeof fixtrunctab / sizeof (fixtrunctab[0][0][0]);
2792 *p = CODE_FOR_nothing;
2794 #ifdef HAVE_fixsfqi2
2796 fixtab[(int) SFmode][(int) QImode][0] = CODE_FOR_fixsfqi2;
2798 #ifdef HAVE_fixsfhi2
2800 fixtab[(int) SFmode][(int) HImode][0] = CODE_FOR_fixsfhi2;
2802 #ifdef HAVE_fixsfsi2
2804 fixtab[(int) SFmode][(int) SImode][0] = CODE_FOR_fixsfsi2;
2806 #ifdef HAVE_fixsfdi2
2808 fixtab[(int) SFmode][(int) DImode][0] = CODE_FOR_fixsfdi2;
2811 #ifdef HAVE_fixdfqi2
2813 fixtab[(int) DFmode][(int) QImode][0] = CODE_FOR_fixdfqi2;
2815 #ifdef HAVE_fixdfhi2
2817 fixtab[(int) DFmode][(int) HImode][0] = CODE_FOR_fixdfhi2;
2819 #ifdef HAVE_fixdfsi2
2821 fixtab[(int) DFmode][(int) SImode][0] = CODE_FOR_fixdfsi2;
2823 #ifdef HAVE_fixdfdi2
2825 fixtab[(int) DFmode][(int) DImode][0] = CODE_FOR_fixdfdi2;
2827 #ifdef HAVE_fixdfti2
2829 fixtab[(int) DFmode][(int) TImode][0] = CODE_FOR_fixdfti2;
2832 #ifdef HAVE_fixxfqi2
2834 fixtab[(int) XFmode][(int) QImode][0] = CODE_FOR_fixxfqi2;
2836 #ifdef HAVE_fixxfhi2
2838 fixtab[(int) XFmode][(int) HImode][0] = CODE_FOR_fixxfhi2;
2840 #ifdef HAVE_fixxfsi2
2842 fixtab[(int) XFmode][(int) SImode][0] = CODE_FOR_fixxfsi2;
2844 #ifdef HAVE_fixxfdi2
2846 fixtab[(int) XFmode][(int) DImode][0] = CODE_FOR_fixxfdi2;
2848 #ifdef HAVE_fixxfti2
2850 fixtab[(int) XFmode][(int) TImode][0] = CODE_FOR_fixxfti2;
2853 #ifdef HAVE_fixtfqi2
2855 fixtab[(int) TFmode][(int) QImode][0] = CODE_FOR_fixtfqi2;
2857 #ifdef HAVE_fixtfhi2
2859 fixtab[(int) TFmode][(int) HImode][0] = CODE_FOR_fixtfhi2;
2861 #ifdef HAVE_fixtfsi2
2863 fixtab[(int) TFmode][(int) SImode][0] = CODE_FOR_fixtfsi2;
2865 #ifdef HAVE_fixtfdi2
2867 fixtab[(int) TFmode][(int) DImode][0] = CODE_FOR_fixtfdi2;
2869 #ifdef HAVE_fixtfti2
2871 fixtab[(int) TFmode][(int) TImode][0] = CODE_FOR_fixtfti2;
2874 #ifdef HAVE_fixunssfqi2
2875 if (HAVE_fixunssfqi2)
2876 fixtab[(int) SFmode][(int) QImode][1] = CODE_FOR_fixunssfqi2;
2878 #ifdef HAVE_fixunssfhi2
2879 if (HAVE_fixunssfhi2)
2880 fixtab[(int) SFmode][(int) HImode][1] = CODE_FOR_fixunssfhi2;
2882 #ifdef HAVE_fixunssfsi2
2883 if (HAVE_fixunssfsi2)
2884 fixtab[(int) SFmode][(int) SImode][1] = CODE_FOR_fixunssfsi2;
2886 #ifdef HAVE_fixunssfdi2
2887 if (HAVE_fixunssfdi2)
2888 fixtab[(int) SFmode][(int) DImode][1] = CODE_FOR_fixunssfdi2;
2891 #ifdef HAVE_fixunsdfqi2
2892 if (HAVE_fixunsdfqi2)
2893 fixtab[(int) DFmode][(int) QImode][1] = CODE_FOR_fixunsdfqi2;
2895 #ifdef HAVE_fixunsdfhi2
2896 if (HAVE_fixunsdfhi2)
2897 fixtab[(int) DFmode][(int) HImode][1] = CODE_FOR_fixunsdfhi2;
2899 #ifdef HAVE_fixunsdfsi2
2900 if (HAVE_fixunsdfsi2)
2901 fixtab[(int) DFmode][(int) SImode][1] = CODE_FOR_fixunsdfsi2;
2903 #ifdef HAVE_fixunsdfdi2
2904 if (HAVE_fixunsdfdi2)
2905 fixtab[(int) DFmode][(int) DImode][1] = CODE_FOR_fixunsdfdi2;
2907 #ifdef HAVE_fixunsdfti2
2908 if (HAVE_fixunsdfti2)
2909 fixtab[(int) DFmode][(int) TImode][1] = CODE_FOR_fixunsdfti2;
2912 #ifdef HAVE_fixunsxfqi2
2913 if (HAVE_fixunsxfqi2)
2914 fixtab[(int) XFmode][(int) QImode][1] = CODE_FOR_fixunsxfqi2;
2916 #ifdef HAVE_fixunsxfhi2
2917 if (HAVE_fixunsxfhi2)
2918 fixtab[(int) XFmode][(int) HImode][1] = CODE_FOR_fixunsxfhi2;
2920 #ifdef HAVE_fixunsxfsi2
2921 if (HAVE_fixunsxfsi2)
2922 fixtab[(int) XFmode][(int) SImode][1] = CODE_FOR_fixunsxfsi2;
2924 #ifdef HAVE_fixunsxfdi2
2925 if (HAVE_fixunsxfdi2)
2926 fixtab[(int) XFmode][(int) DImode][1] = CODE_FOR_fixunsxfdi2;
2928 #ifdef HAVE_fixunsxfti2
2929 if (HAVE_fixunsxfti2)
2930 fixtab[(int) XFmode][(int) TImode][1] = CODE_FOR_fixunsxfti2;
2933 #ifdef HAVE_fixunstfqi2
2934 if (HAVE_fixunstfqi2)
2935 fixtab[(int) TFmode][(int) QImode][1] = CODE_FOR_fixunstfqi2;
2937 #ifdef HAVE_fixunstfhi2
2938 if (HAVE_fixunstfhi2)
2939 fixtab[(int) TFmode][(int) HImode][1] = CODE_FOR_fixunstfhi2;
2941 #ifdef HAVE_fixunstfsi2
2942 if (HAVE_fixunstfsi2)
2943 fixtab[(int) TFmode][(int) SImode][1] = CODE_FOR_fixunstfsi2;
2945 #ifdef HAVE_fixunstfdi2
2946 if (HAVE_fixunstfdi2)
2947 fixtab[(int) TFmode][(int) DImode][1] = CODE_FOR_fixunstfdi2;
2949 #ifdef HAVE_fixunstfti2
2950 if (HAVE_fixunstfti2)
2951 fixtab[(int) TFmode][(int) TImode][1] = CODE_FOR_fixunstfti2;
2954 #ifdef HAVE_fix_truncsfqi2
2955 if (HAVE_fix_truncsfqi2)
2956 fixtrunctab[(int) SFmode][(int) QImode][0] = CODE_FOR_fix_truncsfqi2;
2958 #ifdef HAVE_fix_truncsfhi2
2959 if (HAVE_fix_truncsfhi2)
2960 fixtrunctab[(int) SFmode][(int) HImode][0] = CODE_FOR_fix_truncsfhi2;
2962 #ifdef HAVE_fix_truncsfsi2
2963 if (HAVE_fix_truncsfsi2)
2964 fixtrunctab[(int) SFmode][(int) SImode][0] = CODE_FOR_fix_truncsfsi2;
2966 #ifdef HAVE_fix_truncsfdi2
2967 if (HAVE_fix_truncsfdi2)
2968 fixtrunctab[(int) SFmode][(int) DImode][0] = CODE_FOR_fix_truncsfdi2;
2971 #ifdef HAVE_fix_truncdfqi2
2972 if (HAVE_fix_truncdfqi2)
2973 fixtrunctab[(int) DFmode][(int) QImode][0] = CODE_FOR_fix_truncdfqi2;
2975 #ifdef HAVE_fix_truncdfhi2
2976 if (HAVE_fix_truncdfhi2)
2977 fixtrunctab[(int) DFmode][(int) HImode][0] = CODE_FOR_fix_truncdfhi2;
2979 #ifdef HAVE_fix_truncdfsi2
2980 if (HAVE_fix_truncdfsi2)
2981 fixtrunctab[(int) DFmode][(int) SImode][0] = CODE_FOR_fix_truncdfsi2;
2983 #ifdef HAVE_fix_truncdfdi2
2984 if (HAVE_fix_truncdfdi2)
2985 fixtrunctab[(int) DFmode][(int) DImode][0] = CODE_FOR_fix_truncdfdi2;
2987 #ifdef HAVE_fix_truncdfti2
2988 if (HAVE_fix_truncdfti2)
2989 fixtrunctab[(int) DFmode][(int) TImode][0] = CODE_FOR_fix_truncdfti2;
2992 #ifdef HAVE_fix_truncxfqi2
2993 if (HAVE_fix_truncxfqi2)
2994 fixtrunctab[(int) XFmode][(int) QImode][0] = CODE_FOR_fix_truncxfqi2;
2996 #ifdef HAVE_fix_truncxfhi2
2997 if (HAVE_fix_truncxfhi2)
2998 fixtrunctab[(int) XFmode][(int) HImode][0] = CODE_FOR_fix_truncxfhi2;
3000 #ifdef HAVE_fix_truncxfsi2
3001 if (HAVE_fix_truncxfsi2)
3002 fixtrunctab[(int) XFmode][(int) SImode][0] = CODE_FOR_fix_truncxfsi2;
3004 #ifdef HAVE_fix_truncxfdi2
3005 if (HAVE_fix_truncxfdi2)
3006 fixtrunctab[(int) XFmode][(int) DImode][0] = CODE_FOR_fix_truncxfdi2;
3008 #ifdef HAVE_fix_truncxfti2
3009 if (HAVE_fix_truncxfti2)
3010 fixtrunctab[(int) XFmode][(int) TImode][0] = CODE_FOR_fix_truncxfti2;
3013 #ifdef HAVE_fix_trunctfqi2
3014 if (HAVE_fix_trunctfqi2)
3015 fixtrunctab[(int) TFmode][(int) QImode][0] = CODE_FOR_fix_trunctfqi2;
3017 #ifdef HAVE_fix_trunctfhi2
3018 if (HAVE_fix_trunctfhi2)
3019 fixtrunctab[(int) TFmode][(int) HImode][0] = CODE_FOR_fix_trunctfhi2;
3021 #ifdef HAVE_fix_trunctfsi2
3022 if (HAVE_fix_trunctfsi2)
3023 fixtrunctab[(int) TFmode][(int) SImode][0] = CODE_FOR_fix_trunctfsi2;
3025 #ifdef HAVE_fix_trunctfdi2
3026 if (HAVE_fix_trunctfdi2)
3027 fixtrunctab[(int) TFmode][(int) DImode][0] = CODE_FOR_fix_trunctfdi2;
3029 #ifdef HAVE_fix_trunctfti2
3030 if (HAVE_fix_trunctfti2)
3031 fixtrunctab[(int) TFmode][(int) TImode][0] = CODE_FOR_fix_trunctfti2;
3034 #ifdef HAVE_fixuns_truncsfqi2
3035 if (HAVE_fixuns_truncsfqi2)
3036 fixtrunctab[(int) SFmode][(int) QImode][1] = CODE_FOR_fixuns_truncsfqi2;
3038 #ifdef HAVE_fixuns_truncsfhi2
3039 if (HAVE_fixuns_truncsfhi2)
3040 fixtrunctab[(int) SFmode][(int) HImode][1] = CODE_FOR_fixuns_truncsfhi2;
3042 #ifdef HAVE_fixuns_truncsfsi2
3043 if (HAVE_fixuns_truncsfsi2)
3044 fixtrunctab[(int) SFmode][(int) SImode][1] = CODE_FOR_fixuns_truncsfsi2;
3046 #ifdef HAVE_fixuns_truncsfdi2
3047 if (HAVE_fixuns_truncsfdi2)
3048 fixtrunctab[(int) SFmode][(int) DImode][1] = CODE_FOR_fixuns_truncsfdi2;
3051 #ifdef HAVE_fixuns_truncdfqi2
3052 if (HAVE_fixuns_truncdfqi2)
3053 fixtrunctab[(int) DFmode][(int) QImode][1] = CODE_FOR_fixuns_truncdfqi2;
3055 #ifdef HAVE_fixuns_truncdfhi2
3056 if (HAVE_fixuns_truncdfhi2)
3057 fixtrunctab[(int) DFmode][(int) HImode][1] = CODE_FOR_fixuns_truncdfhi2;
3059 #ifdef HAVE_fixuns_truncdfsi2
3060 if (HAVE_fixuns_truncdfsi2)
3061 fixtrunctab[(int) DFmode][(int) SImode][1] = CODE_FOR_fixuns_truncdfsi2;
3063 #ifdef HAVE_fixuns_truncdfdi2
3064 if (HAVE_fixuns_truncdfdi2)
3065 fixtrunctab[(int) DFmode][(int) DImode][1] = CODE_FOR_fixuns_truncdfdi2;
3067 #ifdef HAVE_fixuns_truncdfti2
3068 if (HAVE_fixuns_truncdfti2)
3069 fixtrunctab[(int) DFmode][(int) TImode][1] = CODE_FOR_fixuns_truncdfti2;
3072 #ifdef HAVE_fixuns_truncxfqi2
3073 if (HAVE_fixuns_truncxfqi2)
3074 fixtrunctab[(int) XFmode][(int) QImode][1] = CODE_FOR_fixuns_truncxfqi2;
3076 #ifdef HAVE_fixuns_truncxfhi2
3077 if (HAVE_fixuns_truncxfhi2)
3078 fixtrunctab[(int) XFmode][(int) HImode][1] = CODE_FOR_fixuns_truncxfhi2;
3080 #ifdef HAVE_fixuns_truncxfsi2
3081 if (HAVE_fixuns_truncxfsi2)
3082 fixtrunctab[(int) XFmode][(int) SImode][1] = CODE_FOR_fixuns_truncxfsi2;
3084 #ifdef HAVE_fixuns_truncxfdi2
3085 if (HAVE_fixuns_truncxfdi2)
3086 fixtrunctab[(int) XFmode][(int) DImode][1] = CODE_FOR_fixuns_truncxfdi2;
3088 #ifdef HAVE_fixuns_truncxfti2
3089 if (HAVE_fixuns_truncxfti2)
3090 fixtrunctab[(int) XFmode][(int) TImode][1] = CODE_FOR_fixuns_truncxfti2;
3093 #ifdef HAVE_fixuns_trunctfqi2
3094 if (HAVE_fixuns_trunctfqi2)
3095 fixtrunctab[(int) TFmode][(int) QImode][1] = CODE_FOR_fixuns_trunctfqi2;
3097 #ifdef HAVE_fixuns_trunctfhi2
3098 if (HAVE_fixuns_trunctfhi2)
3099 fixtrunctab[(int) TFmode][(int) HImode][1] = CODE_FOR_fixuns_trunctfhi2;
3101 #ifdef HAVE_fixuns_trunctfsi2
3102 if (HAVE_fixuns_trunctfsi2)
3103 fixtrunctab[(int) TFmode][(int) SImode][1] = CODE_FOR_fixuns_trunctfsi2;
3105 #ifdef HAVE_fixuns_trunctfdi2
3106 if (HAVE_fixuns_trunctfdi2)
3107 fixtrunctab[(int) TFmode][(int) DImode][1] = CODE_FOR_fixuns_trunctfdi2;
3109 #ifdef HAVE_fixuns_trunctfti2
3110 if (HAVE_fixuns_trunctfti2)
3111 fixtrunctab[(int) TFmode][(int) TImode][1] = CODE_FOR_fixuns_trunctfti2;
3114 #ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC
3115 /* This flag says the same insns that convert to a signed fixnum
3116 also convert validly to an unsigned one. */
3120 for (i = 0; i < NUM_MACHINE_MODES; i++)
3121 for (j = 0; j < NUM_MACHINE_MODES; j++)
3122 fixtrunctab[i][j][1] = fixtrunctab[i][j][0];
3131 for (p = floattab[0][0];
3132 p < floattab[0][0] + sizeof floattab / sizeof (floattab[0][0][0]);
3134 *p = CODE_FOR_nothing;
3136 #ifdef HAVE_floatqisf2
3137 if (HAVE_floatqisf2)
3138 floattab[(int) SFmode][(int) QImode][0] = CODE_FOR_floatqisf2;
3140 #ifdef HAVE_floathisf2
3141 if (HAVE_floathisf2)
3142 floattab[(int) SFmode][(int) HImode][0] = CODE_FOR_floathisf2;
3144 #ifdef HAVE_floatsisf2
3145 if (HAVE_floatsisf2)
3146 floattab[(int) SFmode][(int) SImode][0] = CODE_FOR_floatsisf2;
3148 #ifdef HAVE_floatdisf2
3149 if (HAVE_floatdisf2)
3150 floattab[(int) SFmode][(int) DImode][0] = CODE_FOR_floatdisf2;
3152 #ifdef HAVE_floattisf2
3153 if (HAVE_floattisf2)
3154 floattab[(int) SFmode][(int) TImode][0] = CODE_FOR_floattisf2;
3157 #ifdef HAVE_floatqidf2
3158 if (HAVE_floatqidf2)
3159 floattab[(int) DFmode][(int) QImode][0] = CODE_FOR_floatqidf2;
3161 #ifdef HAVE_floathidf2
3162 if (HAVE_floathidf2)
3163 floattab[(int) DFmode][(int) HImode][0] = CODE_FOR_floathidf2;
3165 #ifdef HAVE_floatsidf2
3166 if (HAVE_floatsidf2)
3167 floattab[(int) DFmode][(int) SImode][0] = CODE_FOR_floatsidf2;
3169 #ifdef HAVE_floatdidf2
3170 if (HAVE_floatdidf2)
3171 floattab[(int) DFmode][(int) DImode][0] = CODE_FOR_floatdidf2;
3173 #ifdef HAVE_floattidf2
3174 if (HAVE_floattidf2)
3175 floattab[(int) DFmode][(int) TImode][0] = CODE_FOR_floattidf2;
3178 #ifdef HAVE_floatqixf2
3179 if (HAVE_floatqixf2)
3180 floattab[(int) XFmode][(int) QImode][0] = CODE_FOR_floatqixf2;
3182 #ifdef HAVE_floathixf2
3183 if (HAVE_floathixf2)
3184 floattab[(int) XFmode][(int) HImode][0] = CODE_FOR_floathixf2;
3186 #ifdef HAVE_floatsixf2
3187 if (HAVE_floatsixf2)
3188 floattab[(int) XFmode][(int) SImode][0] = CODE_FOR_floatsixf2;
3190 #ifdef HAVE_floatdixf2
3191 if (HAVE_floatdixf2)
3192 floattab[(int) XFmode][(int) DImode][0] = CODE_FOR_floatdixf2;
3194 #ifdef HAVE_floattixf2
3195 if (HAVE_floattixf2)
3196 floattab[(int) XFmode][(int) TImode][0] = CODE_FOR_floattixf2;
3199 #ifdef HAVE_floatqitf2
3200 if (HAVE_floatqitf2)
3201 floattab[(int) TFmode][(int) QImode][0] = CODE_FOR_floatqitf2;
3203 #ifdef HAVE_floathitf2
3204 if (HAVE_floathitf2)
3205 floattab[(int) TFmode][(int) HImode][0] = CODE_FOR_floathitf2;
3207 #ifdef HAVE_floatsitf2
3208 if (HAVE_floatsitf2)
3209 floattab[(int) TFmode][(int) SImode][0] = CODE_FOR_floatsitf2;
3211 #ifdef HAVE_floatditf2
3212 if (HAVE_floatditf2)
3213 floattab[(int) TFmode][(int) DImode][0] = CODE_FOR_floatditf2;
3215 #ifdef HAVE_floattitf2
3216 if (HAVE_floattitf2)
3217 floattab[(int) TFmode][(int) TImode][0] = CODE_FOR_floattitf2;
3220 #ifdef HAVE_floatunsqisf2
3221 if (HAVE_floatunsqisf2)
3222 floattab[(int) SFmode][(int) QImode][1] = CODE_FOR_floatunsqisf2;
3224 #ifdef HAVE_floatunshisf2
3225 if (HAVE_floatunshisf2)
3226 floattab[(int) SFmode][(int) HImode][1] = CODE_FOR_floatunshisf2;
3228 #ifdef HAVE_floatunssisf2
3229 if (HAVE_floatunssisf2)
3230 floattab[(int) SFmode][(int) SImode][1] = CODE_FOR_floatunssisf2;
3232 #ifdef HAVE_floatunsdisf2
3233 if (HAVE_floatunsdisf2)
3234 floattab[(int) SFmode][(int) DImode][1] = CODE_FOR_floatunsdisf2;
3236 #ifdef HAVE_floatunstisf2
3237 if (HAVE_floatunstisf2)
3238 floattab[(int) SFmode][(int) TImode][1] = CODE_FOR_floatunstisf2;
3241 #ifdef HAVE_floatunsqidf2
3242 if (HAVE_floatunsqidf2)
3243 floattab[(int) DFmode][(int) QImode][1] = CODE_FOR_floatunsqidf2;
3245 #ifdef HAVE_floatunshidf2
3246 if (HAVE_floatunshidf2)
3247 floattab[(int) DFmode][(int) HImode][1] = CODE_FOR_floatunshidf2;
3249 #ifdef HAVE_floatunssidf2
3250 if (HAVE_floatunssidf2)
3251 floattab[(int) DFmode][(int) SImode][1] = CODE_FOR_floatunssidf2;
3253 #ifdef HAVE_floatunsdidf2
3254 if (HAVE_floatunsdidf2)
3255 floattab[(int) DFmode][(int) DImode][1] = CODE_FOR_floatunsdidf2;
3257 #ifdef HAVE_floatunstidf2
3258 if (HAVE_floatunstidf2)
3259 floattab[(int) DFmode][(int) TImode][1] = CODE_FOR_floatunstidf2;
3262 #ifdef HAVE_floatunsqixf2
3263 if (HAVE_floatunsqixf2)
3264 floattab[(int) XFmode][(int) QImode][1] = CODE_FOR_floatunsqixf2;
3266 #ifdef HAVE_floatunshixf2
3267 if (HAVE_floatunshixf2)
3268 floattab[(int) XFmode][(int) HImode][1] = CODE_FOR_floatunshixf2;
3270 #ifdef HAVE_floatunssixf2
3271 if (HAVE_floatunssixf2)
3272 floattab[(int) XFmode][(int) SImode][1] = CODE_FOR_floatunssixf2;
3274 #ifdef HAVE_floatunsdixf2
3275 if (HAVE_floatunsdixf2)
3276 floattab[(int) XFmode][(int) DImode][1] = CODE_FOR_floatunsdixf2;
3278 #ifdef HAVE_floatunstixf2
3279 if (HAVE_floatunstixf2)
3280 floattab[(int) XFmode][(int) TImode][1] = CODE_FOR_floatunstixf2;
3283 #ifdef HAVE_floatunsqitf2
3284 if (HAVE_floatunsqitf2)
3285 floattab[(int) TFmode][(int) QImode][1] = CODE_FOR_floatunsqitf2;
3287 #ifdef HAVE_floatunshitf2
3288 if (HAVE_floatunshitf2)
3289 floattab[(int) TFmode][(int) HImode][1] = CODE_FOR_floatunshitf2;
3291 #ifdef HAVE_floatunssitf2
3292 if (HAVE_floatunssitf2)
3293 floattab[(int) TFmode][(int) SImode][1] = CODE_FOR_floatunssitf2;
3295 #ifdef HAVE_floatunsditf2
3296 if (HAVE_floatunsditf2)
3297 floattab[(int) TFmode][(int) DImode][1] = CODE_FOR_floatunsditf2;
3299 #ifdef HAVE_floatunstitf2
3300 if (HAVE_floatunstitf2)
3301 floattab[(int) TFmode][(int) TImode][1] = CODE_FOR_floatunstitf2;
3305 /* Generate code to convert FROM to floating point
3306 and store in TO. FROM must be fixed point and not VOIDmode.
3307 UNSIGNEDP nonzero means regard FROM as unsigned.
3308 Normally this is done by correcting the final value
3309 if it is negative. */
3312 expand_float (to, from, unsignedp)
3316 enum insn_code icode;
3317 register rtx target = to;
3318 enum machine_mode fmode, imode;
3320 /* Crash now, because we won't be able to decide which mode to use. */
3321 if (GET_MODE (from) == VOIDmode)
3324 /* Look for an insn to do the conversion. Do it in the specified
3325 modes if possible; otherwise convert either input, output or both to
3326 wider mode. If the integer mode is wider than the mode of FROM,
3327 we can do the conversion signed even if the input is unsigned. */
3329 for (imode = GET_MODE (from); imode != VOIDmode;
3330 imode = GET_MODE_WIDER_MODE (imode))
3331 for (fmode = GET_MODE (to); fmode != VOIDmode;
3332 fmode = GET_MODE_WIDER_MODE (fmode))
3334 int doing_unsigned = unsignedp;
3336 icode = can_float_p (fmode, imode, unsignedp);
3337 if (icode == CODE_FOR_nothing && imode != GET_MODE (from) && unsignedp)
3338 icode = can_float_p (fmode, imode, 0), doing_unsigned = 0;
3340 if (icode != CODE_FOR_nothing)
3342 to = protect_from_queue (to, 1);
3343 from = protect_from_queue (from, 0);
3345 if (imode != GET_MODE (from))
3346 from = convert_to_mode (imode, from, unsignedp);
3348 if (fmode != GET_MODE (to))
3349 target = gen_reg_rtx (fmode);
3351 emit_unop_insn (icode, target, from,
3352 doing_unsigned ? UNSIGNED_FLOAT : FLOAT);
3355 convert_move (to, target, 0);
3360 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
3362 /* Unsigned integer, and no way to convert directly.
3363 Convert as signed, then conditionally adjust the result. */
3366 rtx label = gen_label_rtx ();
3368 REAL_VALUE_TYPE offset;
3372 to = protect_from_queue (to, 1);
3373 from = protect_from_queue (from, 0);
3376 from = force_not_mem (from);
3378 /* If we are about to do some arithmetic to correct for an
3379 unsigned operand, do it in a pseudo-register. */
3381 if (GET_CODE (to) != REG || REGNO (to) <= LAST_VIRTUAL_REGISTER)
3382 target = gen_reg_rtx (GET_MODE (to));
3384 /* Convert as signed integer to floating. */
3385 expand_float (target, from, 0);
3387 /* If FROM is negative (and therefore TO is negative),
3388 correct its value by 2**bitwidth. */
3390 do_pending_stack_adjust ();
3391 emit_cmp_insn (from, const0_rtx, GE, NULL_RTX, GET_MODE (from), 0, 0);
3392 emit_jump_insn (gen_bge (label));
3393 /* On SCO 3.2.1, ldexp rejects values outside [0.5, 1).
3394 Rather than setting up a dconst_dot_5, let's hope SCO
3396 offset = REAL_VALUE_LDEXP (dconst1, GET_MODE_BITSIZE (GET_MODE (from)));
3397 temp = expand_binop (GET_MODE (to), add_optab, target,
3398 immed_real_const_1 (offset, GET_MODE (to)),
3399 target, 0, OPTAB_LIB_WIDEN);
3401 emit_move_insn (target, temp);
3402 do_pending_stack_adjust ();
3408 /* No hardware instruction available; call a library rotine to convert from
3409 SImode, DImode, or TImode into SFmode, DFmode, XFmode, or TFmode. */
3414 to = protect_from_queue (to, 1);
3415 from = protect_from_queue (from, 0);
3417 if (GET_MODE_SIZE (GET_MODE (from)) < GET_MODE_SIZE (SImode))
3418 from = convert_to_mode (SImode, from, unsignedp);
3421 from = force_not_mem (from);
3423 if (GET_MODE (to) == SFmode)
3425 if (GET_MODE (from) == SImode)
3426 libfcn = floatsisf_libfunc;
3427 else if (GET_MODE (from) == DImode)
3428 libfcn = floatdisf_libfunc;
3429 else if (GET_MODE (from) == TImode)
3430 libfcn = floattisf_libfunc;
3434 else if (GET_MODE (to) == DFmode)
3436 if (GET_MODE (from) == SImode)
3437 libfcn = floatsidf_libfunc;
3438 else if (GET_MODE (from) == DImode)
3439 libfcn = floatdidf_libfunc;
3440 else if (GET_MODE (from) == TImode)
3441 libfcn = floattidf_libfunc;
3445 else if (GET_MODE (to) == XFmode)
3447 if (GET_MODE (from) == SImode)
3448 libfcn = floatsixf_libfunc;
3449 else if (GET_MODE (from) == DImode)
3450 libfcn = floatdixf_libfunc;
3451 else if (GET_MODE (from) == TImode)
3452 libfcn = floattixf_libfunc;
3456 else if (GET_MODE (to) == TFmode)
3458 if (GET_MODE (from) == SImode)
3459 libfcn = floatsitf_libfunc;
3460 else if (GET_MODE (from) == DImode)
3461 libfcn = floatditf_libfunc;
3462 else if (GET_MODE (from) == TImode)
3463 libfcn = floattitf_libfunc;
3472 emit_library_call (libfcn, 1, GET_MODE (to), 1, from, GET_MODE (from));
3473 insns = get_insns ();
3476 emit_libcall_block (insns, target, hard_libcall_value (GET_MODE (to)),
3477 gen_rtx (FLOAT, GET_MODE (to), from));
3480 /* Copy result to requested destination
3481 if we have been computing in a temp location. */
3485 if (GET_MODE (target) == GET_MODE (to))
3486 emit_move_insn (to, target);
3488 convert_move (to, target, 0);
3492 /* expand_fix: generate code to convert FROM to fixed point
3493 and store in TO. FROM must be floating point. */
3499 rtx temp = gen_reg_rtx (GET_MODE (x));
3500 return expand_unop (GET_MODE (x), ftrunc_optab, x, temp, 0);
3504 expand_fix (to, from, unsignedp)
3505 register rtx to, from;
3508 enum insn_code icode;
3509 register rtx target = to;
3510 enum machine_mode fmode, imode;
3514 /* We first try to find a pair of modes, one real and one integer, at
3515 least as wide as FROM and TO, respectively, in which we can open-code
3516 this conversion. If the integer mode is wider than the mode of TO,
3517 we can do the conversion either signed or unsigned. */
3519 for (imode = GET_MODE (to); imode != VOIDmode;
3520 imode = GET_MODE_WIDER_MODE (imode))
3521 for (fmode = GET_MODE (from); fmode != VOIDmode;
3522 fmode = GET_MODE_WIDER_MODE (fmode))
3524 int doing_unsigned = unsignedp;
3526 icode = can_fix_p (imode, fmode, unsignedp, &must_trunc);
3527 if (icode == CODE_FOR_nothing && imode != GET_MODE (to) && unsignedp)
3528 icode = can_fix_p (imode, fmode, 0, &must_trunc), doing_unsigned = 0;
3530 if (icode != CODE_FOR_nothing)
3532 to = protect_from_queue (to, 1);
3533 from = protect_from_queue (from, 0);
3535 if (fmode != GET_MODE (from))
3536 from = convert_to_mode (fmode, from, 0);
3539 from = ftruncify (from);
3541 if (imode != GET_MODE (to))
3542 target = gen_reg_rtx (imode);
3544 emit_unop_insn (icode, target, from,
3545 doing_unsigned ? UNSIGNED_FIX : FIX);
3547 convert_move (to, target, unsignedp);
3552 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
3553 /* For an unsigned conversion, there is one more way to do it.
3554 If we have a signed conversion, we generate code that compares
3555 the real value to the largest representable positive number. If if
3556 is smaller, the conversion is done normally. Otherwise, subtract
3557 one plus the highest signed number, convert, and add it back.
3559 We only need to check all real modes, since we know we didn't find
3560 anything with a wider integer mode. */
3562 if (unsignedp && GET_MODE_BITSIZE (GET_MODE (to)) <= HOST_BITS_PER_WIDE_INT)
3563 for (fmode = GET_MODE (from); fmode != VOIDmode;
3564 fmode = GET_MODE_WIDER_MODE (fmode))
3565 /* Make sure we won't lose significant bits doing this. */
3566 if (GET_MODE_BITSIZE (fmode) > GET_MODE_BITSIZE (GET_MODE (to))
3567 && CODE_FOR_nothing != can_fix_p (GET_MODE (to), fmode, 0,
3570 int bitsize = GET_MODE_BITSIZE (GET_MODE (to));
3571 REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (dconst1, bitsize - 1);
3572 rtx limit = immed_real_const_1 (offset, fmode);
3573 rtx lab1 = gen_label_rtx ();
3574 rtx lab2 = gen_label_rtx ();
3578 to = protect_from_queue (to, 1);
3579 from = protect_from_queue (from, 0);
3582 from = force_not_mem (from);
3584 if (fmode != GET_MODE (from))
3585 from = convert_to_mode (fmode, from, 0);
3587 /* See if we need to do the subtraction. */
3588 do_pending_stack_adjust ();
3589 emit_cmp_insn (from, limit, GE, NULL_RTX, GET_MODE (from), 0, 0);
3590 emit_jump_insn (gen_bge (lab1));
3592 /* If not, do the signed "fix" and branch around fixup code. */
3593 expand_fix (to, from, 0);
3594 emit_jump_insn (gen_jump (lab2));
3597 /* Otherwise, subtract 2**(N-1), convert to signed number,
3598 then add 2**(N-1). Do the addition using XOR since this
3599 will often generate better code. */
3601 target = expand_binop (GET_MODE (from), sub_optab, from, limit,
3602 NULL_RTX, 0, OPTAB_LIB_WIDEN);
3603 expand_fix (to, target, 0);
3604 target = expand_binop (GET_MODE (to), xor_optab, to,
3605 GEN_INT ((HOST_WIDE_INT) 1 << (bitsize - 1)),
3606 to, 1, OPTAB_LIB_WIDEN);
3609 emit_move_insn (to, target);
3613 /* Make a place for a REG_NOTE and add it. */
3614 insn = emit_move_insn (to, to);
3615 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL,
3616 gen_rtx (UNSIGNED_FIX, GET_MODE (to),
3617 from), REG_NOTES (insn));
3623 /* We can't do it with an insn, so use a library call. But first ensure
3624 that the mode of TO is at least as wide as SImode, since those are the
3625 only library calls we know about. */
3627 if (GET_MODE_SIZE (GET_MODE (to)) < GET_MODE_SIZE (SImode))
3629 target = gen_reg_rtx (SImode);
3631 expand_fix (target, from, unsignedp);
3633 else if (GET_MODE (from) == SFmode)
3635 if (GET_MODE (to) == SImode)
3636 libfcn = unsignedp ? fixunssfsi_libfunc : fixsfsi_libfunc;
3637 else if (GET_MODE (to) == DImode)
3638 libfcn = unsignedp ? fixunssfdi_libfunc : fixsfdi_libfunc;
3639 else if (GET_MODE (to) == TImode)
3640 libfcn = unsignedp ? fixunssfti_libfunc : fixsfti_libfunc;
3644 else if (GET_MODE (from) == DFmode)
3646 if (GET_MODE (to) == SImode)
3647 libfcn = unsignedp ? fixunsdfsi_libfunc : fixdfsi_libfunc;
3648 else if (GET_MODE (to) == DImode)
3649 libfcn = unsignedp ? fixunsdfdi_libfunc : fixdfdi_libfunc;
3650 else if (GET_MODE (to) == TImode)
3651 libfcn = unsignedp ? fixunsdfti_libfunc : fixdfti_libfunc;
3655 else if (GET_MODE (from) == XFmode)
3657 if (GET_MODE (to) == SImode)
3658 libfcn = unsignedp ? fixunsxfsi_libfunc : fixxfsi_libfunc;
3659 else if (GET_MODE (to) == DImode)
3660 libfcn = unsignedp ? fixunsxfdi_libfunc : fixxfdi_libfunc;
3661 else if (GET_MODE (to) == TImode)
3662 libfcn = unsignedp ? fixunsxfti_libfunc : fixxfti_libfunc;
3666 else if (GET_MODE (from) == TFmode)
3668 if (GET_MODE (to) == SImode)
3669 libfcn = unsignedp ? fixunstfsi_libfunc : fixtfsi_libfunc;
3670 else if (GET_MODE (to) == DImode)
3671 libfcn = unsignedp ? fixunstfdi_libfunc : fixtfdi_libfunc;
3672 else if (GET_MODE (to) == TImode)
3673 libfcn = unsignedp ? fixunstfti_libfunc : fixtfti_libfunc;
3684 to = protect_from_queue (to, 1);
3685 from = protect_from_queue (from, 0);
3688 from = force_not_mem (from);
3692 emit_library_call (libfcn, 1, GET_MODE (to), 1, from, GET_MODE (from));
3693 insns = get_insns ();
3696 emit_libcall_block (insns, target, hard_libcall_value (GET_MODE (to)),
3697 gen_rtx (unsignedp ? FIX : UNSIGNED_FIX,
3698 GET_MODE (to), from));
3701 if (GET_MODE (to) == GET_MODE (target))
3702 emit_move_insn (to, target);
3704 convert_move (to, target, 0);
3712 optab op = (optab) xmalloc (sizeof (struct optab));
3714 for (i = 0; i < NUM_MACHINE_MODES; i++)
3716 op->handlers[i].insn_code = CODE_FOR_nothing;
3717 op->handlers[i].libfunc = 0;
3722 /* Initialize the libfunc fields of an entire group of entries in some
3723 optab. Each entry is set equal to a string consisting of a leading
3724 pair of underscores followed by a generic operation name followed by
3725 a mode name (downshifted to lower case) followed by a single character
3726 representing the number of operands for the given operation (which is
3727 usually one of the characters '2', '3', or '4').
3729 OPTABLE is the table in which libfunc fields are to be initialized.
3730 FIRST_MODE is the first machine mode index in the given optab to
3732 LAST_MODE is the last machine mode index in the given optab to
3734 OPNAME is the generic (string) name of the operation.
3735 SUFFIX is the character which specifies the number of operands for
3736 the given generic operation.
3740 init_libfuncs (optable, first_mode, last_mode, opname, suffix)
3741 register optab optable;
3742 register char *opname;
3743 register enum machine_mode first_mode;
3744 register enum machine_mode last_mode;
3745 register char suffix;
3747 register enum machine_mode mode;
3748 register unsigned opname_len = strlen (opname);
3750 for (mode = first_mode; (int) mode <= (int) last_mode;
3751 mode = (enum machine_mode) ((int) mode + 1))
3753 register char *mname = mode_name[(int) mode];
3754 register unsigned mname_len = strlen (mname);
3755 register char *libfunc_name
3756 = (char *) xmalloc (2 + opname_len + mname_len + 1 + 1);
3763 for (q = opname; *q; )
3765 for (q = mname; *q; q++)
3766 *p++ = tolower (*q);
3769 optable->handlers[(int) mode].libfunc
3770 = gen_rtx (SYMBOL_REF, Pmode, libfunc_name);
3774 /* Initialize the libfunc fields of an entire group of entries in some
3775 optab which correspond to all integer mode operations. The parameters
3776 have the same meaning as similarly named ones for the `init_libfuncs'
3777 routine. (See above). */
3780 init_integral_libfuncs (optable, opname, suffix)
3781 register optab optable;
3782 register char *opname;
3783 register char suffix;
3785 init_libfuncs (optable, SImode, TImode, opname, suffix);
3788 /* Initialize the libfunc fields of an entire group of entries in some
3789 optab which correspond to all real mode operations. The parameters
3790 have the same meaning as similarly named ones for the `init_libfuncs'
3791 routine. (See above). */
3794 init_floating_libfuncs (optable, opname, suffix)
3795 register optab optable;
3796 register char *opname;
3797 register char suffix;
3799 init_libfuncs (optable, SFmode, TFmode, opname, suffix);
3802 /* Initialize the libfunc fields of an entire group of entries in some
3803 optab which correspond to all complex floating modes. The parameters
3804 have the same meaning as similarly named ones for the `init_libfuncs'
3805 routine. (See above). */
3808 init_complex_libfuncs (optable, opname, suffix)
3809 register optab optable;
3810 register char *opname;
3811 register char suffix;
3813 init_libfuncs (optable, SCmode, TCmode, opname, suffix);
3816 /* Call this once to initialize the contents of the optabs
3817 appropriately for the current target machine. */
3828 add_optab = init_optab (PLUS);
3829 sub_optab = init_optab (MINUS);
3830 smul_optab = init_optab (MULT);
3831 smul_widen_optab = init_optab (UNKNOWN);
3832 umul_widen_optab = init_optab (UNKNOWN);
3833 sdiv_optab = init_optab (DIV);
3834 sdivmod_optab = init_optab (UNKNOWN);
3835 udiv_optab = init_optab (UDIV);
3836 udivmod_optab = init_optab (UNKNOWN);
3837 smod_optab = init_optab (MOD);
3838 umod_optab = init_optab (UMOD);
3839 flodiv_optab = init_optab (DIV);
3840 ftrunc_optab = init_optab (UNKNOWN);
3841 and_optab = init_optab (AND);
3842 ior_optab = init_optab (IOR);
3843 xor_optab = init_optab (XOR);
3844 ashl_optab = init_optab (ASHIFT);
3845 ashr_optab = init_optab (ASHIFTRT);
3846 lshl_optab = init_optab (LSHIFT);
3847 lshr_optab = init_optab (LSHIFTRT);
3848 rotl_optab = init_optab (ROTATE);
3849 rotr_optab = init_optab (ROTATERT);
3850 smin_optab = init_optab (SMIN);
3851 smax_optab = init_optab (SMAX);
3852 umin_optab = init_optab (UMIN);
3853 umax_optab = init_optab (UMAX);
3854 mov_optab = init_optab (UNKNOWN);
3855 movstrict_optab = init_optab (UNKNOWN);
3856 cmp_optab = init_optab (UNKNOWN);
3857 ucmp_optab = init_optab (UNKNOWN);
3858 tst_optab = init_optab (UNKNOWN);
3859 neg_optab = init_optab (NEG);
3860 abs_optab = init_optab (ABS);
3861 one_cmpl_optab = init_optab (NOT);
3862 ffs_optab = init_optab (FFS);
3863 sqrt_optab = init_optab (SQRT);
3864 sin_optab = init_optab (UNKNOWN);
3865 cos_optab = init_optab (UNKNOWN);
3866 strlen_optab = init_optab (UNKNOWN);
3870 add_optab->handlers[(int) QImode].insn_code = CODE_FOR_addqi3;
3874 add_optab->handlers[(int) HImode].insn_code = CODE_FOR_addhi3;
3878 add_optab->handlers[(int) PSImode].insn_code = CODE_FOR_addpsi3;
3882 add_optab->handlers[(int) SImode].insn_code = CODE_FOR_addsi3;
3886 add_optab->handlers[(int) DImode].insn_code = CODE_FOR_adddi3;
3890 add_optab->handlers[(int) TImode].insn_code = CODE_FOR_addti3;
3894 add_optab->handlers[(int) SFmode].insn_code = CODE_FOR_addsf3;
3898 add_optab->handlers[(int) DFmode].insn_code = CODE_FOR_adddf3;
3902 add_optab->handlers[(int) XFmode].insn_code = CODE_FOR_addxf3;
3906 add_optab->handlers[(int) TFmode].insn_code = CODE_FOR_addtf3;
3908 init_integral_libfuncs (add_optab, "add", '3');
3909 init_floating_libfuncs (add_optab, "add", '3');
3913 sub_optab->handlers[(int) QImode].insn_code = CODE_FOR_subqi3;
3917 sub_optab->handlers[(int) HImode].insn_code = CODE_FOR_subhi3;
3921 sub_optab->handlers[(int) PSImode].insn_code = CODE_FOR_subpsi3;
3925 sub_optab->handlers[(int) SImode].insn_code = CODE_FOR_subsi3;
3929 sub_optab->handlers[(int) DImode].insn_code = CODE_FOR_subdi3;
3933 sub_optab->handlers[(int) TImode].insn_code = CODE_FOR_subti3;
3937 sub_optab->handlers[(int) SFmode].insn_code = CODE_FOR_subsf3;
3941 sub_optab->handlers[(int) DFmode].insn_code = CODE_FOR_subdf3;
3945 sub_optab->handlers[(int) XFmode].insn_code = CODE_FOR_subxf3;
3949 sub_optab->handlers[(int) TFmode].insn_code = CODE_FOR_subtf3;
3951 init_integral_libfuncs (sub_optab, "sub", '3');
3952 init_floating_libfuncs (sub_optab, "sub", '3');
3956 smul_optab->handlers[(int) QImode].insn_code = CODE_FOR_mulqi3;
3960 smul_optab->handlers[(int) HImode].insn_code = CODE_FOR_mulhi3;
3964 smul_optab->handlers[(int) PSImode].insn_code = CODE_FOR_mulpsi3;
3968 smul_optab->handlers[(int) SImode].insn_code = CODE_FOR_mulsi3;
3972 smul_optab->handlers[(int) DImode].insn_code = CODE_FOR_muldi3;
3976 smul_optab->handlers[(int) TImode].insn_code = CODE_FOR_multi3;
3980 smul_optab->handlers[(int) SFmode].insn_code = CODE_FOR_mulsf3;
3984 smul_optab->handlers[(int) DFmode].insn_code = CODE_FOR_muldf3;
3988 smul_optab->handlers[(int) XFmode].insn_code = CODE_FOR_mulxf3;
3992 smul_optab->handlers[(int) TFmode].insn_code = CODE_FOR_multf3;
3994 init_integral_libfuncs (smul_optab, "mul", '3');
3995 init_floating_libfuncs (smul_optab, "mul", '3');
3997 #ifdef MULSI3_LIBCALL
3998 smul_optab->handlers[(int) SImode].libfunc
3999 = gen_rtx (SYMBOL_REF, Pmode, MULSI3_LIBCALL);
4001 #ifdef MULDI3_LIBCALL
4002 smul_optab->handlers[(int) DImode].libfunc
4003 = gen_rtx (SYMBOL_REF, Pmode, MULDI3_LIBCALL);
4005 #ifdef MULTI3_LIBCALL
4006 smul_optab->handlers[(int) TImode].libfunc
4007 = gen_rtx (SYMBOL_REF, Pmode, MULTI3_LIBCALL);
4010 #ifdef HAVE_mulqihi3
4012 smul_widen_optab->handlers[(int) HImode].insn_code = CODE_FOR_mulqihi3;
4014 #ifdef HAVE_mulhisi3
4016 smul_widen_optab->handlers[(int) SImode].insn_code = CODE_FOR_mulhisi3;
4018 #ifdef HAVE_mulsidi3
4020 smul_widen_optab->handlers[(int) DImode].insn_code = CODE_FOR_mulsidi3;
4022 #ifdef HAVE_mulditi3
4024 smul_widen_optab->handlers[(int) TImode].insn_code = CODE_FOR_mulditi3;
4027 #ifdef HAVE_umulqihi3
4029 umul_widen_optab->handlers[(int) HImode].insn_code = CODE_FOR_umulqihi3;
4031 #ifdef HAVE_umulhisi3
4033 umul_widen_optab->handlers[(int) SImode].insn_code = CODE_FOR_umulhisi3;
4035 #ifdef HAVE_umulsidi3
4037 umul_widen_optab->handlers[(int) DImode].insn_code = CODE_FOR_umulsidi3;
4039 #ifdef HAVE_umulditi3
4041 umul_widen_optab->handlers[(int) TImode].insn_code = CODE_FOR_umulditi3;
4046 sdiv_optab->handlers[(int) QImode].insn_code = CODE_FOR_divqi3;
4050 sdiv_optab->handlers[(int) HImode].insn_code = CODE_FOR_divhi3;
4054 sdiv_optab->handlers[(int) PSImode].insn_code = CODE_FOR_divpsi3;
4058 sdiv_optab->handlers[(int) SImode].insn_code = CODE_FOR_divsi3;
4062 sdiv_optab->handlers[(int) DImode].insn_code = CODE_FOR_divdi3;
4066 sdiv_optab->handlers[(int) TImode].insn_code = CODE_FOR_divti3;
4068 init_integral_libfuncs (sdiv_optab, "div", '3');
4070 #ifdef DIVSI3_LIBCALL
4071 sdiv_optab->handlers[(int) SImode].libfunc
4072 = gen_rtx (SYMBOL_REF, Pmode, DIVSI3_LIBCALL);
4074 #ifdef DIVDI3_LIBCALL
4075 sdiv_optab->handlers[(int) DImode].libfunc
4076 = gen_rtx (SYMBOL_REF, Pmode, DIVDI3_LIBCALL);
4078 #ifdef DIVTI3_LIBCALL
4079 sdiv_optab->handlers[(int) TImode].libfunc
4080 = gen_rtx (SYMBOL_REF, Pmode, DIVTI3_LIBCALL);
4085 udiv_optab->handlers[(int) QImode].insn_code = CODE_FOR_udivqi3;
4089 udiv_optab->handlers[(int) HImode].insn_code = CODE_FOR_udivhi3;
4091 #ifdef HAVE_udivpsi3
4093 udiv_optab->handlers[(int) PSImode].insn_code = CODE_FOR_udivpsi3;
4097 udiv_optab->handlers[(int) SImode].insn_code = CODE_FOR_udivsi3;
4101 udiv_optab->handlers[(int) DImode].insn_code = CODE_FOR_udivdi3;
4105 udiv_optab->handlers[(int) TImode].insn_code = CODE_FOR_udivti3;
4107 init_integral_libfuncs (udiv_optab, "udiv", '3');
4109 #ifdef UDIVSI3_LIBCALL
4110 udiv_optab->handlers[(int) SImode].libfunc
4111 = gen_rtx (SYMBOL_REF, Pmode, UDIVSI3_LIBCALL);
4113 #ifdef UDIVDI3_LIBCALL
4114 udiv_optab->handlers[(int) DImode].libfunc
4115 = gen_rtx (SYMBOL_REF, Pmode, UDIVDI3_LIBCALL);
4117 #ifdef UDIVTI3_LIBCALL
4118 udiv_optab->handlers[(int) TImode].libfunc
4119 = gen_rtx (SYMBOL_REF, Pmode, UDIVTI3_LIBCALL);
4122 #ifdef HAVE_divmodqi4
4124 sdivmod_optab->handlers[(int) QImode].insn_code = CODE_FOR_divmodqi4;
4126 #ifdef HAVE_divmodhi4
4128 sdivmod_optab->handlers[(int) HImode].insn_code = CODE_FOR_divmodhi4;
4130 #ifdef HAVE_divmodsi4
4132 sdivmod_optab->handlers[(int) SImode].insn_code = CODE_FOR_divmodsi4;
4134 #ifdef HAVE_divmoddi4
4136 sdivmod_optab->handlers[(int) DImode].insn_code = CODE_FOR_divmoddi4;
4138 #ifdef HAVE_divmodti4
4140 sdivmod_optab->handlers[(int) TImode].insn_code = CODE_FOR_divmodti4;
4142 init_integral_libfuncs (sdivmod_optab, "divmod", '4');
4144 #ifdef HAVE_udivmodqi4
4145 if (HAVE_udivmodqi4)
4146 udivmod_optab->handlers[(int) QImode].insn_code = CODE_FOR_udivmodqi4;
4148 #ifdef HAVE_udivmodhi4
4149 if (HAVE_udivmodhi4)
4150 udivmod_optab->handlers[(int) HImode].insn_code = CODE_FOR_udivmodhi4;
4152 #ifdef HAVE_udivmodsi4
4153 if (HAVE_udivmodsi4)
4154 udivmod_optab->handlers[(int) SImode].insn_code = CODE_FOR_udivmodsi4;
4156 #ifdef HAVE_udivmoddi4
4157 if (HAVE_udivmoddi4)
4158 udivmod_optab->handlers[(int) DImode].insn_code = CODE_FOR_udivmoddi4;
4160 #ifdef HAVE_udivmodti4
4161 if (HAVE_udivmodti4)
4162 udivmod_optab->handlers[(int) TImode].insn_code = CODE_FOR_udivmodti4;
4164 init_integral_libfuncs (udivmod_optab, "udivmod", '4');
4168 smod_optab->handlers[(int) QImode].insn_code = CODE_FOR_modqi3;
4172 smod_optab->handlers[(int) HImode].insn_code = CODE_FOR_modhi3;
4176 smod_optab->handlers[(int) PSImode].insn_code = CODE_FOR_modpsi3;
4180 smod_optab->handlers[(int) SImode].insn_code = CODE_FOR_modsi3;
4184 smod_optab->handlers[(int) DImode].insn_code = CODE_FOR_moddi3;
4188 smod_optab->handlers[(int) TImode].insn_code = CODE_FOR_modti3;
4190 init_integral_libfuncs (smod_optab, "mod", '3');
4192 #ifdef MODSI3_LIBCALL
4193 smod_optab->handlers[(int) SImode].libfunc
4194 = gen_rtx (SYMBOL_REF, Pmode, MODSI3_LIBCALL);
4196 #ifdef MODDI3_LIBCALL
4197 smod_optab->handlers[(int) DImode].libfunc
4198 = gen_rtx (SYMBOL_REF, Pmode, MODDI3_LIBCALL);
4200 #ifdef MODTI3_LIBCALL
4201 smod_optab->handlers[(int) TImode].libfunc
4202 = gen_rtx (SYMBOL_REF, Pmode, MODTI3_LIBCALL);
4207 umod_optab->handlers[(int) QImode].insn_code = CODE_FOR_umodqi3;
4211 umod_optab->handlers[(int) HImode].insn_code = CODE_FOR_umodhi3;
4213 #ifdef HAVE_umodpsi3
4215 umod_optab->handlers[(int) PSImode].insn_code = CODE_FOR_umodpsi3;
4219 umod_optab->handlers[(int) SImode].insn_code = CODE_FOR_umodsi3;
4223 umod_optab->handlers[(int) DImode].insn_code = CODE_FOR_umoddi3;
4227 umod_optab->handlers[(int) TImode].insn_code = CODE_FOR_umodti3;
4229 init_integral_libfuncs (umod_optab, "umod", '3');
4231 #ifdef UMODSI3_LIBCALL
4232 umod_optab->handlers[(int) SImode].libfunc
4233 = gen_rtx (SYMBOL_REF, Pmode, UMODSI3_LIBCALL);
4235 #ifdef UMODDI3_LIBCALL
4236 umod_optab->handlers[(int) DImode].libfunc
4237 = gen_rtx (SYMBOL_REF, Pmode, UMODDI3_LIBCALL);
4239 #ifdef UMODTI3_LIBCALL
4240 umod_optab->handlers[(int) TImode].libfunc
4241 = gen_rtx (SYMBOL_REF, Pmode, UMODTI3_LIBCALL);
4246 flodiv_optab->handlers[(int) SFmode].insn_code = CODE_FOR_divsf3;
4250 flodiv_optab->handlers[(int) DFmode].insn_code = CODE_FOR_divdf3;
4254 flodiv_optab->handlers[(int) XFmode].insn_code = CODE_FOR_divxf3;
4258 flodiv_optab->handlers[(int) TFmode].insn_code = CODE_FOR_divtf3;
4260 init_floating_libfuncs (flodiv_optab, "div", '3');
4262 #ifdef HAVE_ftruncsf2
4264 ftrunc_optab->handlers[(int) SFmode].insn_code = CODE_FOR_ftruncsf2;
4266 #ifdef HAVE_ftruncdf2
4268 ftrunc_optab->handlers[(int) DFmode].insn_code = CODE_FOR_ftruncdf2;
4270 #ifdef HAVE_ftruncxf2
4272 ftrunc_optab->handlers[(int) XFmode].insn_code = CODE_FOR_ftruncxf2;
4274 #ifdef HAVE_ftrunctf2
4276 ftrunc_optab->handlers[(int) TFmode].insn_code = CODE_FOR_ftrunctf2;
4278 init_floating_libfuncs (ftrunc_optab, "ftrunc", '2');
4282 and_optab->handlers[(int) QImode].insn_code = CODE_FOR_andqi3;
4286 and_optab->handlers[(int) HImode].insn_code = CODE_FOR_andhi3;
4290 and_optab->handlers[(int) PSImode].insn_code = CODE_FOR_andpsi3;
4294 and_optab->handlers[(int) SImode].insn_code = CODE_FOR_andsi3;
4298 and_optab->handlers[(int) DImode].insn_code = CODE_FOR_anddi3;
4302 and_optab->handlers[(int) TImode].insn_code = CODE_FOR_andti3;
4304 init_integral_libfuncs (and_optab, "and", '3');
4308 ior_optab->handlers[(int) QImode].insn_code = CODE_FOR_iorqi3;
4312 ior_optab->handlers[(int) HImode].insn_code = CODE_FOR_iorhi3;
4316 ior_optab->handlers[(int) PSImode].insn_code = CODE_FOR_iorpsi3;
4320 ior_optab->handlers[(int) SImode].insn_code = CODE_FOR_iorsi3;
4324 ior_optab->handlers[(int) DImode].insn_code = CODE_FOR_iordi3;
4328 ior_optab->handlers[(int) TImode].insn_code = CODE_FOR_iorti3;
4330 init_integral_libfuncs (ior_optab, "ior", '3');
4334 xor_optab->handlers[(int) QImode].insn_code = CODE_FOR_xorqi3;
4338 xor_optab->handlers[(int) HImode].insn_code = CODE_FOR_xorhi3;
4342 xor_optab->handlers[(int) PSImode].insn_code = CODE_FOR_xorpsi3;
4346 xor_optab->handlers[(int) SImode].insn_code = CODE_FOR_xorsi3;
4350 xor_optab->handlers[(int) DImode].insn_code = CODE_FOR_xordi3;
4354 xor_optab->handlers[(int) TImode].insn_code = CODE_FOR_xorti3;
4356 init_integral_libfuncs (xor_optab, "xor", '3');
4360 ashl_optab->handlers[(int) QImode].insn_code = CODE_FOR_ashlqi3;
4364 ashl_optab->handlers[(int) HImode].insn_code = CODE_FOR_ashlhi3;
4366 #ifdef HAVE_ashlpsi3
4368 ashl_optab->handlers[(int) PSImode].insn_code = CODE_FOR_ashlpsi3;
4372 ashl_optab->handlers[(int) SImode].insn_code = CODE_FOR_ashlsi3;
4376 ashl_optab->handlers[(int) DImode].insn_code = CODE_FOR_ashldi3;
4380 ashl_optab->handlers[(int) TImode].insn_code = CODE_FOR_ashlti3;
4382 init_integral_libfuncs (ashl_optab, "ashl", '3');
4386 ashr_optab->handlers[(int) QImode].insn_code = CODE_FOR_ashrqi3;
4390 ashr_optab->handlers[(int) HImode].insn_code = CODE_FOR_ashrhi3;
4392 #ifdef HAVE_ashrpsi3
4394 ashr_optab->handlers[(int) PSImode].insn_code = CODE_FOR_ashrpsi3;
4398 ashr_optab->handlers[(int) SImode].insn_code = CODE_FOR_ashrsi3;
4402 ashr_optab->handlers[(int) DImode].insn_code = CODE_FOR_ashrdi3;
4406 ashr_optab->handlers[(int) TImode].insn_code = CODE_FOR_ashrti3;
4408 init_integral_libfuncs (ashr_optab, "ashr", '3');
4412 lshl_optab->handlers[(int) QImode].insn_code = CODE_FOR_lshlqi3;
4416 lshl_optab->handlers[(int) HImode].insn_code = CODE_FOR_lshlhi3;
4418 #ifdef HAVE_lshlpsi3
4420 lshl_optab->handlers[(int) PSImode].insn_code = CODE_FOR_lshlpsi3;
4424 lshl_optab->handlers[(int) SImode].insn_code = CODE_FOR_lshlsi3;
4428 lshl_optab->handlers[(int) DImode].insn_code = CODE_FOR_lshldi3;
4432 lshl_optab->handlers[(int) TImode].insn_code = CODE_FOR_lshlti3;
4434 init_integral_libfuncs (lshl_optab, "lshl", '3');
4438 lshr_optab->handlers[(int) QImode].insn_code = CODE_FOR_lshrqi3;
4442 lshr_optab->handlers[(int) HImode].insn_code = CODE_FOR_lshrhi3;
4444 #ifdef HAVE_lshrpsi3
4446 lshr_optab->handlers[(int) PSImode].insn_code = CODE_FOR_lshrpsi3;
4450 lshr_optab->handlers[(int) SImode].insn_code = CODE_FOR_lshrsi3;
4454 lshr_optab->handlers[(int) DImode].insn_code = CODE_FOR_lshrdi3;
4458 lshr_optab->handlers[(int) TImode].insn_code = CODE_FOR_lshrti3;
4460 init_integral_libfuncs (lshr_optab, "lshr", '3');
4464 rotl_optab->handlers[(int) QImode].insn_code = CODE_FOR_rotlqi3;
4468 rotl_optab->handlers[(int) HImode].insn_code = CODE_FOR_rotlhi3;
4470 #ifdef HAVE_rotlpsi3
4472 rotl_optab->handlers[(int) PSImode].insn_code = CODE_FOR_rotlpsi3;
4476 rotl_optab->handlers[(int) SImode].insn_code = CODE_FOR_rotlsi3;
4480 rotl_optab->handlers[(int) DImode].insn_code = CODE_FOR_rotldi3;
4484 rotl_optab->handlers[(int) TImode].insn_code = CODE_FOR_rotlti3;
4486 init_integral_libfuncs (rotl_optab, "rotl", '3');
4490 rotr_optab->handlers[(int) QImode].insn_code = CODE_FOR_rotrqi3;
4494 rotr_optab->handlers[(int) HImode].insn_code = CODE_FOR_rotrhi3;
4496 #ifdef HAVE_rotrpsi3
4498 rotr_optab->handlers[(int) PSImode].insn_code = CODE_FOR_rotrpsi3;
4502 rotr_optab->handlers[(int) SImode].insn_code = CODE_FOR_rotrsi3;
4506 rotr_optab->handlers[(int) DImode].insn_code = CODE_FOR_rotrdi3;
4510 rotr_optab->handlers[(int) TImode].insn_code = CODE_FOR_rotrti3;
4512 init_integral_libfuncs (rotr_optab, "rotr", '3');
4516 smin_optab->handlers[(int) QImode].insn_code = CODE_FOR_sminqi3;
4520 smin_optab->handlers[(int) HImode].insn_code = CODE_FOR_sminhi3;
4524 smin_optab->handlers[(int) SImode].insn_code = CODE_FOR_sminsi3;
4528 smin_optab->handlers[(int) DImode].insn_code = CODE_FOR_smindi3;
4532 smin_optab->handlers[(int) TImode].insn_code = CODE_FOR_sminti3;
4536 smin_optab->handlers[(int) SFmode].insn_code = CODE_FOR_minsf3;
4540 smin_optab->handlers[(int) DFmode].insn_code = CODE_FOR_mindf3;
4544 smin_optab->handlers[(int) XFmode].insn_code = CODE_FOR_minxf3;
4548 smin_optab->handlers[(int) TFmode].insn_code = CODE_FOR_mintf3;
4550 init_integral_libfuncs (smin_optab, "min", '3');
4551 init_floating_libfuncs (smin_optab, "min", '3');
4555 smax_optab->handlers[(int) QImode].insn_code = CODE_FOR_smaxqi3;
4559 smax_optab->handlers[(int) HImode].insn_code = CODE_FOR_smaxhi3;
4563 smax_optab->handlers[(int) SImode].insn_code = CODE_FOR_smaxsi3;
4567 smax_optab->handlers[(int) DImode].insn_code = CODE_FOR_smaxdi3;
4571 smax_optab->handlers[(int) TImode].insn_code = CODE_FOR_smaxti3;
4575 smax_optab->handlers[(int) SFmode].insn_code = CODE_FOR_maxsf3;
4579 smax_optab->handlers[(int) DFmode].insn_code = CODE_FOR_maxdf3;
4583 smax_optab->handlers[(int) XFmode].insn_code = CODE_FOR_maxxf3;
4587 smax_optab->handlers[(int) TFmode].insn_code = CODE_FOR_maxtf3;
4589 init_integral_libfuncs (smax_optab, "max", '3');
4590 init_floating_libfuncs (smax_optab, "max", '3');
4594 umin_optab->handlers[(int) QImode].insn_code = CODE_FOR_uminqi3;
4598 umin_optab->handlers[(int) HImode].insn_code = CODE_FOR_uminhi3;
4602 umin_optab->handlers[(int) SImode].insn_code = CODE_FOR_uminsi3;
4606 umin_optab->handlers[(int) DImode].insn_code = CODE_FOR_umindi3;
4610 umin_optab->handlers[(int) TImode].insn_code = CODE_FOR_uminti3;
4612 init_integral_libfuncs (umin_optab, "umin", '3');
4616 umax_optab->handlers[(int) QImode].insn_code = CODE_FOR_umaxqi3;
4620 umax_optab->handlers[(int) HImode].insn_code = CODE_FOR_umaxhi3;
4624 umax_optab->handlers[(int) SImode].insn_code = CODE_FOR_umaxsi3;
4628 umax_optab->handlers[(int) DImode].insn_code = CODE_FOR_umaxdi3;
4632 umax_optab->handlers[(int) TImode].insn_code = CODE_FOR_umaxti3;
4634 init_integral_libfuncs (umax_optab, "umax", '3');
4638 neg_optab->handlers[(int) QImode].insn_code = CODE_FOR_negqi2;
4642 neg_optab->handlers[(int) HImode].insn_code = CODE_FOR_neghi2;
4646 neg_optab->handlers[(int) PSImode].insn_code = CODE_FOR_negpsi2;
4650 neg_optab->handlers[(int) SImode].insn_code = CODE_FOR_negsi2;
4654 neg_optab->handlers[(int) DImode].insn_code = CODE_FOR_negdi2;
4658 neg_optab->handlers[(int) TImode].insn_code = CODE_FOR_negti2;
4662 neg_optab->handlers[(int) SFmode].insn_code = CODE_FOR_negsf2;
4666 neg_optab->handlers[(int) DFmode].insn_code = CODE_FOR_negdf2;
4670 neg_optab->handlers[(int) XFmode].insn_code = CODE_FOR_negxf2;
4674 neg_optab->handlers[(int) TFmode].insn_code = CODE_FOR_negtf2;
4676 init_integral_libfuncs (neg_optab, "neg", '2');
4677 init_floating_libfuncs (neg_optab, "neg", '2');
4681 abs_optab->handlers[(int) QImode].insn_code = CODE_FOR_absqi2;
4685 abs_optab->handlers[(int) HImode].insn_code = CODE_FOR_abshi2;
4689 abs_optab->handlers[(int) PSImode].insn_code = CODE_FOR_abspsi2;
4693 abs_optab->handlers[(int) SImode].insn_code = CODE_FOR_abssi2;
4697 abs_optab->handlers[(int) DImode].insn_code = CODE_FOR_absdi2;
4701 abs_optab->handlers[(int) TImode].insn_code = CODE_FOR_absti2;
4705 abs_optab->handlers[(int) SFmode].insn_code = CODE_FOR_abssf2;
4709 abs_optab->handlers[(int) DFmode].insn_code = CODE_FOR_absdf2;
4713 abs_optab->handlers[(int) XFmode].insn_code = CODE_FOR_absxf2;
4717 abs_optab->handlers[(int) TFmode].insn_code = CODE_FOR_abstf2;
4720 /* Use cabs for DC complex abs, since systems generally have cabs.
4721 Don't define any libcall for SCmode, so that cabs will be used. */
4722 abs_optab->handlers[(int) DCmode].libfunc
4723 = gen_rtx (SYMBOL_REF, Pmode, "cabs");
4727 sqrt_optab->handlers[(int) QImode].insn_code = CODE_FOR_sqrtqi2;
4731 sqrt_optab->handlers[(int) HImode].insn_code = CODE_FOR_sqrthi2;
4733 #ifdef HAVE_sqrtpsi2
4735 sqrt_optab->handlers[(int) PSImode].insn_code = CODE_FOR_sqrtpsi2;
4739 sqrt_optab->handlers[(int) SImode].insn_code = CODE_FOR_sqrtsi2;
4743 sqrt_optab->handlers[(int) DImode].insn_code = CODE_FOR_sqrtdi2;
4747 sqrt_optab->handlers[(int) TImode].insn_code = CODE_FOR_sqrtti2;
4751 sqrt_optab->handlers[(int) SFmode].insn_code = CODE_FOR_sqrtsf2;
4755 sqrt_optab->handlers[(int) DFmode].insn_code = CODE_FOR_sqrtdf2;
4759 sqrt_optab->handlers[(int) TFmode].insn_code = CODE_FOR_sqrttf2;
4761 /* No library calls here! If there is no sqrt instruction expand_builtin
4762 should force the library call. */
4766 sin_optab->handlers[(int) SFmode].insn_code = CODE_FOR_sinsf2;
4770 sin_optab->handlers[(int) DFmode].insn_code = CODE_FOR_sindf2;
4774 sin_optab->handlers[(int) TFmode].insn_code = CODE_FOR_sintf2;
4776 /* No library calls here! If there is no sin instruction expand_builtin
4777 should force the library call. */
4781 cos_optab->handlers[(int) SFmode].insn_code = CODE_FOR_cossf2;
4785 cos_optab->handlers[(int) DFmode].insn_code = CODE_FOR_cosdf2;
4789 cos_optab->handlers[(int) TFmode].insn_code = CODE_FOR_costf2;
4791 /* No library calls here! If there is no cos instruction expand_builtin
4792 should force the library call. */
4794 #ifdef HAVE_strlenqi
4796 strlen_optab->handlers[(int) QImode].insn_code = CODE_FOR_strlenqi;
4798 #ifdef HAVE_strlenhi
4800 strlen_optab->handlers[(int) HImode].insn_code = CODE_FOR_strlenhi;
4802 #ifdef HAVE_strlenpsi
4804 strlen_optab->handlers[(int) PSImode].insn_code = CODE_FOR_strlenpsi;
4806 #ifdef HAVE_strlensi
4808 strlen_optab->handlers[(int) SImode].insn_code = CODE_FOR_strlensi;
4810 #ifdef HAVE_strlendi
4812 strlen_optab->handlers[(int) DImode].insn_code = CODE_FOR_strlendi;
4814 #ifdef HAVE_strlenti
4816 strlen_optab->handlers[(int) TImode].insn_code = CODE_FOR_strlenti;
4818 /* No library calls here! If there is no strlen instruction expand_builtin
4819 should force the library call. */
4821 #ifdef HAVE_one_cmplqi2
4822 if (HAVE_one_cmplqi2)
4823 one_cmpl_optab->handlers[(int) QImode].insn_code = CODE_FOR_one_cmplqi2;
4825 #ifdef HAVE_one_cmplhi2
4826 if (HAVE_one_cmplhi2)
4827 one_cmpl_optab->handlers[(int) HImode].insn_code = CODE_FOR_one_cmplhi2;
4829 #ifdef HAVE_one_cmplpsi2
4830 if (HAVE_one_cmplpsi2)
4831 one_cmpl_optab->handlers[(int) PSImode].insn_code = CODE_FOR_one_cmplpsi2;
4833 #ifdef HAVE_one_cmplsi2
4834 if (HAVE_one_cmplsi2)
4835 one_cmpl_optab->handlers[(int) SImode].insn_code = CODE_FOR_one_cmplsi2;
4837 #ifdef HAVE_one_cmpldi2
4838 if (HAVE_one_cmpldi2)
4839 one_cmpl_optab->handlers[(int) DImode].insn_code = CODE_FOR_one_cmpldi2;
4841 #ifdef HAVE_one_cmplti2
4842 if (HAVE_one_cmplti2)
4843 one_cmpl_optab->handlers[(int) TImode].insn_code = CODE_FOR_one_cmplti2;
4845 init_integral_libfuncs (one_cmpl_optab, "one_cmpl", '2');
4849 ffs_optab->handlers[(int) QImode].insn_code = CODE_FOR_ffsqi2;
4853 ffs_optab->handlers[(int) HImode].insn_code = CODE_FOR_ffshi2;
4857 ffs_optab->handlers[(int) PSImode].insn_code = CODE_FOR_ffspsi2;
4861 ffs_optab->handlers[(int) SImode].insn_code = CODE_FOR_ffssi2;
4865 ffs_optab->handlers[(int) DImode].insn_code = CODE_FOR_ffsdi2;
4869 ffs_optab->handlers[(int) TImode].insn_code = CODE_FOR_ffsti2;
4871 init_integral_libfuncs (ffs_optab, "ffs", '2');
4875 mov_optab->handlers[(int) QImode].insn_code = CODE_FOR_movqi;
4879 mov_optab->handlers[(int) HImode].insn_code = CODE_FOR_movhi;
4883 mov_optab->handlers[(int) PSImode].insn_code = CODE_FOR_movpsi;
4887 mov_optab->handlers[(int) SImode].insn_code = CODE_FOR_movsi;
4891 mov_optab->handlers[(int) DImode].insn_code = CODE_FOR_movdi;
4895 mov_optab->handlers[(int) TImode].insn_code = CODE_FOR_movti;
4899 mov_optab->handlers[(int) SFmode].insn_code = CODE_FOR_movsf;
4903 mov_optab->handlers[(int) DFmode].insn_code = CODE_FOR_movdf;
4907 mov_optab->handlers[(int) XFmode].insn_code = CODE_FOR_movxf;
4911 mov_optab->handlers[(int) TFmode].insn_code = CODE_FOR_movtf;
4915 mov_optab->handlers[(int) CCmode].insn_code = CODE_FOR_movcc;
4918 #ifdef EXTRA_CC_MODES
4922 #ifdef HAVE_movstrictqi
4923 if (HAVE_movstrictqi)
4924 movstrict_optab->handlers[(int) QImode].insn_code = CODE_FOR_movstrictqi;
4926 #ifdef HAVE_movstricthi
4927 if (HAVE_movstricthi)
4928 movstrict_optab->handlers[(int) HImode].insn_code = CODE_FOR_movstricthi;
4930 #ifdef HAVE_movstrictpsi
4931 if (HAVE_movstrictpsi)
4932 movstrict_optab->handlers[(int) PSImode].insn_code = CODE_FOR_movstrictpsi;
4934 #ifdef HAVE_movstrictsi
4935 if (HAVE_movstrictsi)
4936 movstrict_optab->handlers[(int) SImode].insn_code = CODE_FOR_movstrictsi;
4938 #ifdef HAVE_movstrictdi
4939 if (HAVE_movstrictdi)
4940 movstrict_optab->handlers[(int) DImode].insn_code = CODE_FOR_movstrictdi;
4942 #ifdef HAVE_movstrictti
4943 if (HAVE_movstrictti)
4944 movstrict_optab->handlers[(int) TImode].insn_code = CODE_FOR_movstrictti;
4949 cmp_optab->handlers[(int) QImode].insn_code = CODE_FOR_cmpqi;
4953 cmp_optab->handlers[(int) HImode].insn_code = CODE_FOR_cmphi;
4957 cmp_optab->handlers[(int) PSImode].insn_code = CODE_FOR_cmppsi;
4961 cmp_optab->handlers[(int) SImode].insn_code = CODE_FOR_cmpsi;
4965 cmp_optab->handlers[(int) DImode].insn_code = CODE_FOR_cmpdi;
4969 cmp_optab->handlers[(int) TImode].insn_code = CODE_FOR_cmpti;
4973 cmp_optab->handlers[(int) SFmode].insn_code = CODE_FOR_cmpsf;
4977 cmp_optab->handlers[(int) DFmode].insn_code = CODE_FOR_cmpdf;
4981 cmp_optab->handlers[(int) XFmode].insn_code = CODE_FOR_cmpxf;
4985 cmp_optab->handlers[(int) TFmode].insn_code = CODE_FOR_cmptf;
4987 /* Comparison libcalls for integers MUST come in pairs, signed/unsigned. */
4988 init_integral_libfuncs (cmp_optab, "cmp", '2');
4989 init_integral_libfuncs (ucmp_optab, "ucmp", '2');
4990 init_floating_libfuncs (cmp_optab, "cmp", '2');
4994 tst_optab->handlers[(int) QImode].insn_code = CODE_FOR_tstqi;
4998 tst_optab->handlers[(int) HImode].insn_code = CODE_FOR_tsthi;
5002 tst_optab->handlers[(int) PSImode].insn_code = CODE_FOR_tstpsi;
5006 tst_optab->handlers[(int) SImode].insn_code = CODE_FOR_tstsi;
5010 tst_optab->handlers[(int) DImode].insn_code = CODE_FOR_tstdi;
5014 tst_optab->handlers[(int) TImode].insn_code = CODE_FOR_tstti;
5018 tst_optab->handlers[(int) SFmode].insn_code = CODE_FOR_tstsf;
5022 tst_optab->handlers[(int) DFmode].insn_code = CODE_FOR_tstdf;
5026 tst_optab->handlers[(int) XFmode].insn_code = CODE_FOR_tstxf;
5030 tst_optab->handlers[(int) TFmode].insn_code = CODE_FOR_tsttf;
5035 bcc_gen_fctn[(int) EQ] = gen_beq;
5039 bcc_gen_fctn[(int) NE] = gen_bne;
5043 bcc_gen_fctn[(int) GT] = gen_bgt;
5047 bcc_gen_fctn[(int) GE] = gen_bge;
5051 bcc_gen_fctn[(int) GTU] = gen_bgtu;
5055 bcc_gen_fctn[(int) GEU] = gen_bgeu;
5059 bcc_gen_fctn[(int) LT] = gen_blt;
5063 bcc_gen_fctn[(int) LE] = gen_ble;
5067 bcc_gen_fctn[(int) LTU] = gen_bltu;
5071 bcc_gen_fctn[(int) LEU] = gen_bleu;
5074 for (i = 0; i < NUM_RTX_CODE; i++)
5075 setcc_gen_code[i] = CODE_FOR_nothing;
5079 setcc_gen_code[(int) EQ] = CODE_FOR_seq;
5083 setcc_gen_code[(int) NE] = CODE_FOR_sne;
5087 setcc_gen_code[(int) GT] = CODE_FOR_sgt;
5091 setcc_gen_code[(int) GE] = CODE_FOR_sge;
5095 setcc_gen_code[(int) GTU] = CODE_FOR_sgtu;
5099 setcc_gen_code[(int) GEU] = CODE_FOR_sgeu;
5103 setcc_gen_code[(int) LT] = CODE_FOR_slt;
5107 setcc_gen_code[(int) LE] = CODE_FOR_sle;
5111 setcc_gen_code[(int) LTU] = CODE_FOR_sltu;
5115 setcc_gen_code[(int) LEU] = CODE_FOR_sleu;
5118 extendsfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extendsfdf2");
5119 extendsfxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extendsfxf2");
5120 extendsftf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extendsftf2");
5121 extenddfxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extenddfxf2");
5122 extenddftf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extenddftf2");
5124 truncdfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__truncdfsf2");
5125 truncxfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__truncxfsf2");
5126 trunctfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__trunctfsf2");
5127 truncxfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__truncxfdf2");
5128 trunctfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__trunctfdf2");
5130 memcpy_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memcpy");
5131 bcopy_libfunc = gen_rtx (SYMBOL_REF, Pmode, "bcopy");
5132 memcmp_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memcmp");
5133 bcmp_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gcc_bcmp");
5134 memset_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memset");
5135 bzero_libfunc = gen_rtx (SYMBOL_REF, Pmode, "bzero");
5137 eqsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqsf2");
5138 nesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nesf2");
5139 gtsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtsf2");
5140 gesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gesf2");
5141 ltsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltsf2");
5142 lesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lesf2");
5144 eqdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqdf2");
5145 nedf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nedf2");
5146 gtdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtdf2");
5147 gedf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gedf2");
5148 ltdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltdf2");
5149 ledf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ledf2");
5151 eqxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqxf2");
5152 nexf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nexf2");
5153 gtxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtxf2");
5154 gexf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gexf2");
5155 ltxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltxf2");
5156 lexf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lexf2");
5158 eqtf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqtf2");
5159 netf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__netf2");
5160 gttf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gttf2");
5161 getf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__getf2");
5162 lttf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lttf2");
5163 letf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__letf2");
5165 floatsisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsisf");
5166 floatdisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatdisf");
5167 floattisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattisf");
5169 floatsidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsidf");
5170 floatdidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatdidf");
5171 floattidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattidf");
5173 floatsixf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsixf");
5174 floatdixf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatdixf");
5175 floattixf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattixf");
5177 floatsitf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsitf");
5178 floatditf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatditf");
5179 floattitf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattitf");
5181 fixsfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixsfsi");
5182 fixsfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixsfdi");
5183 fixsfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixsfti");
5185 fixdfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixdfsi");
5186 fixdfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixdfdi");
5187 fixdfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixdfti");
5189 fixxfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixxfsi");
5190 fixxfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixxfdi");
5191 fixxfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixxfti");
5193 fixtfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixtfsi");
5194 fixtfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixtfdi");
5195 fixtfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixtfti");
5197 fixunssfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunssfsi");
5198 fixunssfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunssfdi");
5199 fixunssfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunssfti");
5201 fixunsdfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsdfsi");
5202 fixunsdfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsdfdi");
5203 fixunsdfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsdfti");
5205 fixunsxfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsxfsi");
5206 fixunsxfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsxfdi");
5207 fixunsxfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsxfti");
5209 fixunstfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunstfsi");
5210 fixunstfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunstfdi");
5211 fixunstfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunstfti");
5216 /* SCO 3.2 apparently has a broken ldexp. */
5229 #endif /* BROKEN_LDEXP */