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;
78 optab ucmp_optab; /* Used only for libcalls for unsigned comparisons. */
83 /* SYMBOL_REF rtx's for the library functions that are called
84 implicitly and not via optabs. */
86 rtx extendsfdf2_libfunc;
87 rtx extendsfxf2_libfunc;
88 rtx extendsftf2_libfunc;
89 rtx extenddfxf2_libfunc;
90 rtx extenddftf2_libfunc;
92 rtx truncdfsf2_libfunc;
93 rtx truncxfsf2_libfunc;
94 rtx trunctfsf2_libfunc;
95 rtx truncxfdf2_libfunc;
96 rtx trunctfdf2_libfunc;
133 rtx floatsisf_libfunc;
134 rtx floatdisf_libfunc;
135 rtx floattisf_libfunc;
137 rtx floatsidf_libfunc;
138 rtx floatdidf_libfunc;
139 rtx floattidf_libfunc;
141 rtx floatsixf_libfunc;
142 rtx floatdixf_libfunc;
143 rtx floattixf_libfunc;
145 rtx floatsitf_libfunc;
146 rtx floatditf_libfunc;
147 rtx floattitf_libfunc;
165 rtx fixunssfsi_libfunc;
166 rtx fixunssfdi_libfunc;
167 rtx fixunssfti_libfunc;
169 rtx fixunsdfsi_libfunc;
170 rtx fixunsdfdi_libfunc;
171 rtx fixunsdfti_libfunc;
173 rtx fixunsxfsi_libfunc;
174 rtx fixunsxfdi_libfunc;
175 rtx fixunsxfti_libfunc;
177 rtx fixunstfsi_libfunc;
178 rtx fixunstfdi_libfunc;
179 rtx fixunstfti_libfunc;
181 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
182 gives the gen_function to make a branch to test that condition. */
184 rtxfun bcc_gen_fctn[NUM_RTX_CODE];
186 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
187 gives the insn code to make a store-condition insn
188 to test that condition. */
190 enum insn_code setcc_gen_code[NUM_RTX_CODE];
192 static void emit_float_lib_cmp ();
194 /* Add a REG_EQUAL note to the last insn in SEQ. TARGET is being set to
195 the result of operation CODE applied to OP0 (and OP1 if it is a binary
198 If the last insn does not set TARGET, don't do anything, but return 1.
200 If a previous insn sets TARGET and TARGET is one of OP0 or OP1,
201 don't add the REG_EQUAL note but return 0. Our caller can then try
202 again, ensuring that TARGET is not one of the operands. */
205 add_equal_note (seq, target, code, op0, op1)
215 if ((GET_RTX_CLASS (code) != '1' && GET_RTX_CLASS (code) != '2'
216 && GET_RTX_CLASS (code) != 'c' && GET_RTX_CLASS (code) != '<')
217 || GET_CODE (seq) != SEQUENCE
218 || (set = single_set (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1))) == 0
219 || GET_CODE (target) == ZERO_EXTRACT
220 || (! rtx_equal_p (SET_DEST (set), target)
221 /* For a STRICT_LOW_PART, the REG_NOTE applies to what is inside the
223 && (GET_CODE (SET_DEST (set)) != STRICT_LOW_PART
224 || ! rtx_equal_p (SUBREG_REG (XEXP (SET_DEST (set), 0)),
228 /* If TARGET is in OP0 or OP1, check if anything in SEQ sets TARGET
229 besides the last insn. */
230 if (reg_overlap_mentioned_p (target, op0)
231 || (op1 && reg_overlap_mentioned_p (target, op1)))
232 for (i = XVECLEN (seq, 0) - 2; i >= 0; i--)
233 if (reg_set_p (target, XVECEXP (seq, 0, i)))
236 if (GET_RTX_CLASS (code) == '1')
237 note = gen_rtx (code, GET_MODE (target), op0);
239 note = gen_rtx (code, GET_MODE (target), op0, op1);
241 REG_NOTES (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1))
242 = gen_rtx (EXPR_LIST, REG_EQUAL, note,
243 REG_NOTES (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1)));
248 /* Generate code to perform an operation specified by BINOPTAB
249 on operands OP0 and OP1, with result having machine-mode MODE.
251 UNSIGNEDP is for the case where we have to widen the operands
252 to perform the operation. It says to use zero-extension.
254 If TARGET is nonzero, the value
255 is generated there, if it is convenient to do so.
256 In all cases an rtx is returned for the locus of the value;
257 this may or may not be TARGET. */
260 expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods)
261 enum machine_mode mode;
266 enum optab_methods methods;
268 enum mode_class class;
269 enum machine_mode wider_mode;
271 int commutative_op = 0;
272 int shift_op = (binoptab->code == ASHIFT
273 || binoptab->code == ASHIFTRT
274 || binoptab->code == LSHIFT
275 || binoptab->code == LSHIFTRT
276 || binoptab->code == ROTATE
277 || binoptab->code == ROTATERT);
280 class = GET_MODE_CLASS (mode);
282 op0 = protect_from_queue (op0, 0);
283 op1 = protect_from_queue (op1, 0);
285 target = protect_from_queue (target, 1);
289 op0 = force_not_mem (op0);
290 op1 = force_not_mem (op1);
293 /* If we are inside an appropriately-short loop and one operand is an
294 expensive constant, force it into a register. */
295 if (CONSTANT_P (op0) && preserve_subexpressions_p ()
296 && rtx_cost (op0, binoptab->code) > 2)
297 op0 = force_reg (mode, op0);
299 if (CONSTANT_P (op1) && preserve_subexpressions_p ()
300 && rtx_cost (op1, binoptab->code) > 2)
301 op1 = force_reg (shift_op ? word_mode : mode, op1);
303 #if 0 /* Turned off because it seems to be a kludgy method. */
304 /* If subtracting integer from pointer, and the pointer has a special mode,
305 then change it to an add. We use the add insn of Pmode for combining
306 integers with pointers, and the sub insn to subtract two pointers. */
308 if (binoptab == sub_optab
309 && GET_MODE (op0) == Pmode && GET_MODE (op1) != Pmode)
311 op1 = negate_rtx (GET_MODE(op1), op1);
312 binoptab = add_optab;
316 /* Record where to delete back to if we backtrack. */
317 last = get_last_insn ();
319 /* If operation is commutative,
320 try to make the first operand a register.
321 Even better, try to make it the same as the target.
322 Also try to make the last operand a constant. */
323 if (GET_RTX_CLASS (binoptab->code) == 'c'
324 || binoptab == smul_widen_optab
325 || binoptab == umul_widen_optab)
329 if (((target == 0 || GET_CODE (target) == REG)
330 ? ((GET_CODE (op1) == REG
331 && GET_CODE (op0) != REG)
333 : rtx_equal_p (op1, target))
334 || GET_CODE (op0) == CONST_INT)
342 /* If we can do it with a three-operand insn, do so. */
344 if (methods != OPTAB_MUST_WIDEN
345 && binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
347 int icode = (int) binoptab->handlers[(int) mode].insn_code;
348 enum machine_mode mode0 = insn_operand_mode[icode][1];
349 enum machine_mode mode1 = insn_operand_mode[icode][2];
351 rtx xop0 = op0, xop1 = op1;
356 temp = gen_reg_rtx (mode);
358 /* If it is a commutative operator and the modes would match
359 if we would swap the operands, we can save the conversions. */
362 if (GET_MODE (op0) != mode0 && GET_MODE (op1) != mode1
363 && GET_MODE (op0) == mode1 && GET_MODE (op1) == mode0)
367 tmp = op0; op0 = op1; op1 = tmp;
368 tmp = xop0; xop0 = xop1; xop1 = tmp;
372 /* In case the insn wants input operands in modes different from
373 the result, convert the operands. */
375 if (GET_MODE (op0) != VOIDmode
376 && GET_MODE (op0) != mode0)
377 xop0 = convert_to_mode (mode0, xop0, unsignedp);
379 if (GET_MODE (xop1) != VOIDmode
380 && GET_MODE (xop1) != mode1)
381 xop1 = convert_to_mode (mode1, xop1, unsignedp);
383 /* Now, if insn's predicates don't allow our operands, put them into
386 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
387 xop0 = copy_to_mode_reg (mode0, xop0);
389 if (! (*insn_operand_predicate[icode][2]) (xop1, mode1))
390 xop1 = copy_to_mode_reg (mode1, xop1);
392 if (! (*insn_operand_predicate[icode][0]) (temp, mode))
393 temp = gen_reg_rtx (mode);
395 pat = GEN_FCN (icode) (temp, xop0, xop1);
398 /* If PAT is a multi-insn sequence, try to add an appropriate
399 REG_EQUAL note to it. If we can't because TEMP conflicts with an
400 operand, call ourselves again, this time without a target. */
401 if (GET_CODE (pat) == SEQUENCE
402 && ! add_equal_note (pat, temp, binoptab->code, xop0, xop1))
404 delete_insns_since (last);
405 return expand_binop (mode, binoptab, op0, op1, NULL_RTX,
413 delete_insns_since (last);
416 /* Look for a wider mode of the same class for which we think we
417 can open-code the operation. */
419 if ((class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
420 && mode != OPTAB_DIRECT && mode != OPTAB_LIB)
421 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
422 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
424 if (binoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing)
426 rtx xop0 = op0, xop1 = op1;
429 /* For certain integer operations, we need not actually extend
430 the narrow operands, as long as we will truncate
431 the results to the same narrowness. */
433 if ((binoptab == ior_optab || binoptab == and_optab
434 || binoptab == xor_optab
435 || binoptab == add_optab || binoptab == sub_optab
436 || binoptab == smul_optab
437 || binoptab == ashl_optab || binoptab == lshl_optab)
438 && class == MODE_INT)
441 /* If an operand is a constant integer, we might as well
442 convert it since that is more efficient than using a SUBREG,
443 unlike the case for other operands. */
445 if (no_extend && GET_MODE (xop0) != VOIDmode)
446 xop0 = gen_rtx (SUBREG, wider_mode,
447 force_reg (GET_MODE (xop0), xop0), 0);
449 xop0 = convert_to_mode (wider_mode, xop0, unsignedp);
451 if (no_extend && GET_MODE (xop1) != VOIDmode)
452 xop1 = gen_rtx (SUBREG, wider_mode,
453 force_reg (GET_MODE (xop1), xop1), 0);
455 xop1 = convert_to_mode (wider_mode, xop1, unsignedp);
457 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
458 unsignedp, OPTAB_DIRECT);
461 if (class != MODE_INT)
464 target = gen_reg_rtx (mode);
465 convert_move (target, temp, 0);
469 return gen_lowpart (mode, temp);
472 delete_insns_since (last);
476 /* These can be done a word at a time. */
477 if ((binoptab == and_optab || binoptab == ior_optab || binoptab == xor_optab)
479 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
480 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
486 /* If TARGET is the same as one of the operands, the REG_EQUAL note
487 won't be accurate, so use a new target. */
488 if (target == 0 || target == op0 || target == op1)
489 target = gen_reg_rtx (mode);
493 /* Do the actual arithmetic. */
494 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
496 rtx target_piece = operand_subword (target, i, 1, mode);
497 rtx x = expand_binop (word_mode, binoptab,
498 operand_subword_force (op0, i, mode),
499 operand_subword_force (op1, i, mode),
500 target_piece, unsignedp, methods);
501 if (target_piece != x)
502 emit_move_insn (target_piece, x);
505 insns = get_insns ();
508 if (binoptab->code != UNKNOWN)
509 equiv_value = gen_rtx (binoptab->code, mode, op0, op1);
513 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
517 /* These can be done a word at a time by propagating carries. */
518 if ((binoptab == add_optab || binoptab == sub_optab)
520 && GET_MODE_SIZE (mode) >= 2 * UNITS_PER_WORD
521 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
524 rtx carry_tmp = gen_reg_rtx (word_mode);
525 optab otheroptab = binoptab == add_optab ? sub_optab : add_optab;
526 int nwords = GET_MODE_BITSIZE (mode) / BITS_PER_WORD;
527 rtx carry_in, carry_out;
529 /* We can handle either a 1 or -1 value for the carry. If STORE_FLAG
530 value is one of those, use it. Otherwise, use 1 since it is the
531 one easiest to get. */
532 #if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
533 int normalizep = STORE_FLAG_VALUE;
538 /* Prepare the operands. */
539 op0 = force_reg (mode, op0);
540 op1 = force_reg (mode, op1);
542 if (target == 0 || GET_CODE (target) != REG
543 || target == op0 || target == op1)
544 target = gen_reg_rtx (mode);
546 /* Do the actual arithmetic. */
547 for (i = 0; i < nwords; i++)
549 int index = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i);
550 rtx target_piece = operand_subword (target, index, 1, mode);
551 rtx op0_piece = operand_subword_force (op0, index, mode);
552 rtx op1_piece = operand_subword_force (op1, index, mode);
555 /* Main add/subtract of the input operands. */
556 x = expand_binop (word_mode, binoptab,
557 op0_piece, op1_piece,
558 target_piece, unsignedp, methods);
564 /* Store carry from main add/subtract. */
565 carry_out = gen_reg_rtx (word_mode);
566 carry_out = emit_store_flag (carry_out,
567 binoptab == add_optab ? LTU : GTU,
569 word_mode, 1, normalizep);
576 /* Add/subtract previous carry to main result. */
577 x = expand_binop (word_mode,
578 normalizep == 1 ? binoptab : otheroptab,
580 target_piece, 1, methods);
581 if (target_piece != x)
582 emit_move_insn (target_piece, x);
586 /* THIS CODE HAS NOT BEEN TESTED. */
587 /* Get out carry from adding/subtracting carry in. */
588 carry_tmp = emit_store_flag (carry_tmp,
589 binoptab == add_optab
592 word_mode, 1, normalizep);
593 /* Logical-ior the two poss. carry together. */
594 carry_out = expand_binop (word_mode, ior_optab,
595 carry_out, carry_tmp,
596 carry_out, 0, methods);
602 carry_in = carry_out;
605 if (i == GET_MODE_BITSIZE (mode) / BITS_PER_WORD)
609 temp = emit_move_insn (target, target);
610 REG_NOTES (temp) = gen_rtx (EXPR_LIST, REG_EQUAL,
611 gen_rtx (binoptab->code, mode, op0, op1),
616 delete_insns_since (last);
619 /* If we want to multiply two two-word values and have normal and widening
620 multiplies of single-word values, we can do this with three smaller
621 multiplications. Note that we do not make a REG_NO_CONFLICT block here
622 because we are not operating on one word at a time.
624 The multiplication proceeds as follows:
625 _______________________
626 [__op0_high_|__op0_low__]
627 _______________________
628 * [__op1_high_|__op1_low__]
629 _______________________________________________
630 _______________________
631 (1) [__op0_low__*__op1_low__]
632 _______________________
633 (2a) [__op0_low__*__op1_high_]
634 _______________________
635 (2b) [__op0_high_*__op1_low__]
636 _______________________
637 (3) [__op0_high_*__op1_high_]
640 This gives a 4-word result. Since we are only interested in the
641 lower 2 words, partial result (3) and the upper words of (2a) and
642 (2b) don't need to be calculated. Hence (2a) and (2b) can be
643 calculated using non-widening multiplication.
645 (1), however, needs to be calculated with an unsigned widening
646 multiplication. If this operation is not directly supported we
647 try using a signed widening multiplication and adjust the result.
648 This adjustment works as follows:
650 If both operands are positive then no adjustment is needed.
652 If the operands have different signs, for example op0_low < 0 and
653 op1_low >= 0, the instruction treats the most significant bit of
654 op0_low as a sign bit instead of a bit with significance
655 2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low
656 with 2**BITS_PER_WORD - op0_low, and two's complements the
657 result. Conclusion: We need to add op1_low * 2**BITS_PER_WORD to
660 Similarly, if both operands are negative, we need to add
661 (op0_low + op1_low) * 2**BITS_PER_WORD.
663 We use a trick to adjust quickly. We logically shift op0_low right
664 (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to
665 op0_high (op1_high) before it is used to calculate 2b (2a). If no
666 logical shift exists, we do an arithmetic right shift and subtract
669 if (binoptab == smul_optab
671 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
672 && smul_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
673 && add_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
674 && ((umul_widen_optab->handlers[(int) mode].insn_code
676 || (smul_widen_optab->handlers[(int) mode].insn_code
677 != CODE_FOR_nothing)))
679 int low = (WORDS_BIG_ENDIAN ? 1 : 0);
680 int high = (WORDS_BIG_ENDIAN ? 0 : 1);
681 rtx op0_high = operand_subword_force (op0, high, mode);
682 rtx op0_low = operand_subword_force (op0, low, mode);
683 rtx op1_high = operand_subword_force (op1, high, mode);
684 rtx op1_low = operand_subword_force (op1, low, mode);
689 /* If the target is the same as one of the inputs, don't use it. This
690 prevents problems with the REG_EQUAL note. */
691 if (target == op0 || target == op1)
694 /* Multiply the two lower words to get a double-word product.
695 If unsigned widening multiplication is available, use that;
696 otherwise use the signed form and compensate. */
698 if (umul_widen_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
700 product = expand_binop (mode, umul_widen_optab, op0_low, op1_low,
701 target, 1, OPTAB_DIRECT);
703 /* If we didn't succeed, delete everything we did so far. */
705 delete_insns_since (last);
707 op0_xhigh = op0_high, op1_xhigh = op1_high;
711 && smul_widen_optab->handlers[(int) mode].insn_code
714 rtx wordm1 = GEN_INT (BITS_PER_WORD - 1);
715 product = expand_binop (mode, smul_widen_optab, op0_low, op1_low,
716 target, 1, OPTAB_DIRECT);
717 op0_xhigh = expand_binop (word_mode, lshr_optab, op0_low, wordm1,
718 NULL_RTX, 1, OPTAB_DIRECT);
720 op0_xhigh = expand_binop (word_mode, add_optab, op0_high,
721 op0_xhigh, op0_xhigh, 0, OPTAB_DIRECT);
724 op0_xhigh = expand_binop (word_mode, ashr_optab, op0_low, wordm1,
725 NULL_RTX, 0, OPTAB_DIRECT);
727 op0_xhigh = expand_binop (word_mode, sub_optab, op0_high,
728 op0_xhigh, op0_xhigh, 0,
732 op1_xhigh = expand_binop (word_mode, lshr_optab, op1_low, wordm1,
733 NULL_RTX, 1, OPTAB_DIRECT);
735 op1_xhigh = expand_binop (word_mode, add_optab, op1_high,
736 op1_xhigh, op1_xhigh, 0, OPTAB_DIRECT);
739 op1_xhigh = expand_binop (word_mode, ashr_optab, op1_low, wordm1,
740 NULL_RTX, 0, OPTAB_DIRECT);
742 op1_xhigh = expand_binop (word_mode, sub_optab, op1_high,
743 op1_xhigh, op1_xhigh, 0,
748 /* If we have been able to directly compute the product of the
749 low-order words of the operands and perform any required adjustments
750 of the operands, we proceed by trying two more multiplications
751 and then computing the appropriate sum.
753 We have checked above that the required addition is provided.
754 Full-word addition will normally always succeed, especially if
755 it is provided at all, so we don't worry about its failure. The
756 multiplication may well fail, however, so we do handle that. */
758 if (product && op0_xhigh && op1_xhigh)
761 rtx product_high = operand_subword (product, high, 1, mode);
762 rtx temp = expand_binop (word_mode, binoptab, op0_low, op1_xhigh,
763 NULL_RTX, 0, OPTAB_DIRECT);
767 product_piece = expand_binop (word_mode, add_optab, temp,
768 product_high, product_high,
770 if (product_piece != product_high)
771 emit_move_insn (product_high, product_piece);
773 temp = expand_binop (word_mode, binoptab, op1_low, op0_xhigh,
774 NULL_RTX, 0, OPTAB_DIRECT);
776 product_piece = expand_binop (word_mode, add_optab, temp,
777 product_high, product_high,
779 if (product_piece != product_high)
780 emit_move_insn (product_high, product_piece);
782 temp = emit_move_insn (product, product);
783 REG_NOTES (temp) = gen_rtx (EXPR_LIST, REG_EQUAL,
784 gen_rtx (MULT, mode, op0, op1),
791 /* If we get here, we couldn't do it for some reason even though we
792 originally thought we could. Delete anything we've emitted in
795 delete_insns_since (last);
798 /* It can't be open-coded in this mode.
799 Use a library call if one is available and caller says that's ok. */
801 if (binoptab->handlers[(int) mode].libfunc
802 && (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN))
805 rtx funexp = binoptab->handlers[(int) mode].libfunc;
809 /* Pass 1 for NO_QUEUE so we don't lose any increments
810 if the libcall is cse'd or moved. */
811 emit_library_call (binoptab->handlers[(int) mode].libfunc,
812 1, mode, 2, op0, mode, op1,
813 (shift_op ? word_mode : mode));
815 insns = get_insns ();
818 target = gen_reg_rtx (mode);
819 emit_libcall_block (insns, target, hard_libcall_value (mode),
820 gen_rtx (binoptab->code, mode, op0, op1));
825 delete_insns_since (last);
827 /* It can't be done in this mode. Can we do it in a wider mode? */
829 if (! (methods == OPTAB_WIDEN || methods == OPTAB_LIB_WIDEN
830 || methods == OPTAB_MUST_WIDEN))
831 return 0; /* Caller says, don't even try. */
833 /* Compute the value of METHODS to pass to recursive calls.
834 Don't allow widening to be tried recursively. */
836 methods = (methods == OPTAB_LIB_WIDEN ? OPTAB_LIB : OPTAB_DIRECT);
838 /* Look for a wider mode of the same class for which it appears we can do
841 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
843 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
844 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
846 if ((binoptab->handlers[(int) wider_mode].insn_code
848 || (methods == OPTAB_LIB
849 && binoptab->handlers[(int) wider_mode].libfunc))
851 rtx xop0 = op0, xop1 = op1;
854 /* For certain integer operations, we need not actually extend
855 the narrow operands, as long as we will truncate
856 the results to the same narrowness. */
858 if ((binoptab == ior_optab || binoptab == and_optab
859 || binoptab == xor_optab
860 || binoptab == add_optab || binoptab == sub_optab
861 || binoptab == smul_optab
862 || binoptab == ashl_optab || binoptab == lshl_optab)
863 && class == MODE_INT)
866 /* If an operand is a constant integer, we might as well
867 convert it since that is more efficient than using a SUBREG,
868 unlike the case for other operands. */
870 if (no_extend && GET_MODE (xop0) != VOIDmode)
871 xop0 = gen_rtx (SUBREG, wider_mode,
872 force_reg (GET_MODE (xop0), xop0), 0);
874 xop0 = convert_to_mode (wider_mode, xop0, unsignedp);
876 if (no_extend && GET_MODE (xop1) != VOIDmode)
877 xop1 = gen_rtx (SUBREG, wider_mode,
878 force_reg (GET_MODE (xop1), xop1), 0);
880 xop1 = convert_to_mode (wider_mode, xop1, unsignedp);
882 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
886 if (class != MODE_INT)
889 target = gen_reg_rtx (mode);
890 convert_move (target, temp, 0);
894 return gen_lowpart (mode, temp);
897 delete_insns_since (last);
905 /* Expand a binary operator which has both signed and unsigned forms.
906 UOPTAB is the optab for unsigned operations, and SOPTAB is for
909 If we widen unsigned operands, we may use a signed wider operation instead
910 of an unsigned wider operation, since the result would be the same. */
913 sign_expand_binop (mode, uoptab, soptab, op0, op1, target, unsignedp, methods)
914 enum machine_mode mode;
915 optab uoptab, soptab;
916 rtx op0, op1, target;
918 enum optab_methods methods;
921 optab direct_optab = unsignedp ? uoptab : soptab;
922 struct optab wide_soptab;
924 /* Do it without widening, if possible. */
925 temp = expand_binop (mode, direct_optab, op0, op1, target,
926 unsignedp, OPTAB_DIRECT);
927 if (temp || methods == OPTAB_DIRECT)
930 /* Try widening to a signed int. Make a fake signed optab that
931 hides any signed insn for direct use. */
932 wide_soptab = *soptab;
933 wide_soptab.handlers[(int) mode].insn_code = CODE_FOR_nothing;
934 wide_soptab.handlers[(int) mode].libfunc = 0;
936 temp = expand_binop (mode, &wide_soptab, op0, op1, target,
937 unsignedp, OPTAB_WIDEN);
939 /* For unsigned operands, try widening to an unsigned int. */
940 if (temp == 0 && unsignedp)
941 temp = expand_binop (mode, uoptab, op0, op1, target,
942 unsignedp, OPTAB_WIDEN);
943 if (temp || methods == OPTAB_WIDEN)
946 /* Use the right width lib call if that exists. */
947 temp = expand_binop (mode, direct_optab, op0, op1, target, unsignedp, OPTAB_LIB);
948 if (temp || methods == OPTAB_LIB)
951 /* Must widen and use a lib call, use either signed or unsigned. */
952 temp = expand_binop (mode, &wide_soptab, op0, op1, target,
957 return expand_binop (mode, uoptab, op0, op1, target,
962 /* Generate code to perform an operation specified by BINOPTAB
963 on operands OP0 and OP1, with two results to TARG1 and TARG2.
964 We assume that the order of the operands for the instruction
965 is TARG0, OP0, OP1, TARG1, which would fit a pattern like
966 [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
968 Either TARG0 or TARG1 may be zero, but what that means is that
969 that result is not actually wanted. We will generate it into
970 a dummy pseudo-reg and discard it. They may not both be zero.
972 Returns 1 if this operation can be performed; 0 if not. */
975 expand_twoval_binop (binoptab, op0, op1, targ0, targ1, unsignedp)
981 enum machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
982 enum mode_class class;
983 enum machine_mode wider_mode;
986 class = GET_MODE_CLASS (mode);
988 op0 = protect_from_queue (op0, 0);
989 op1 = protect_from_queue (op1, 0);
993 op0 = force_not_mem (op0);
994 op1 = force_not_mem (op1);
997 /* If we are inside an appropriately-short loop and one operand is an
998 expensive constant, force it into a register. */
999 if (CONSTANT_P (op0) && preserve_subexpressions_p ()
1000 && rtx_cost (op0, binoptab->code) > 2)
1001 op0 = force_reg (mode, op0);
1003 if (CONSTANT_P (op1) && preserve_subexpressions_p ()
1004 && rtx_cost (op1, binoptab->code) > 2)
1005 op1 = force_reg (mode, op1);
1008 targ0 = protect_from_queue (targ0, 1);
1010 targ0 = gen_reg_rtx (mode);
1012 targ1 = protect_from_queue (targ1, 1);
1014 targ1 = gen_reg_rtx (mode);
1016 /* Record where to go back to if we fail. */
1017 last = get_last_insn ();
1019 if (binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1021 int icode = (int) binoptab->handlers[(int) mode].insn_code;
1022 enum machine_mode mode0 = insn_operand_mode[icode][1];
1023 enum machine_mode mode1 = insn_operand_mode[icode][2];
1025 rtx xop0 = op0, xop1 = op1;
1027 /* In case this insn wants input operands in modes different from the
1028 result, convert the operands. */
1029 if (GET_MODE (op0) != VOIDmode && GET_MODE (op0) != mode0)
1030 xop0 = convert_to_mode (mode0, xop0, unsignedp);
1032 if (GET_MODE (op1) != VOIDmode && GET_MODE (op1) != mode1)
1033 xop1 = convert_to_mode (mode1, xop1, unsignedp);
1035 /* Now, if insn doesn't accept these operands, put them into pseudos. */
1036 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
1037 xop0 = copy_to_mode_reg (mode0, xop0);
1039 if (! (*insn_operand_predicate[icode][2]) (xop1, mode1))
1040 xop1 = copy_to_mode_reg (mode1, xop1);
1042 /* We could handle this, but we should always be called with a pseudo
1043 for our targets and all insns should take them as outputs. */
1044 if (! (*insn_operand_predicate[icode][0]) (targ0, mode)
1045 || ! (*insn_operand_predicate[icode][3]) (targ1, mode))
1048 pat = GEN_FCN (icode) (targ0, xop0, xop1, targ1);
1055 delete_insns_since (last);
1058 /* It can't be done in this mode. Can we do it in a wider mode? */
1060 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1062 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1063 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1065 if (binoptab->handlers[(int) wider_mode].insn_code
1066 != CODE_FOR_nothing)
1068 register rtx t0 = gen_reg_rtx (wider_mode);
1069 register rtx t1 = gen_reg_rtx (wider_mode);
1071 if (expand_twoval_binop (binoptab,
1072 convert_to_mode (wider_mode, op0,
1074 convert_to_mode (wider_mode, op1,
1078 convert_move (targ0, t0, unsignedp);
1079 convert_move (targ1, t1, unsignedp);
1083 delete_insns_since (last);
1091 /* Generate code to perform an operation specified by UNOPTAB
1092 on operand OP0, with result having machine-mode MODE.
1094 UNSIGNEDP is for the case where we have to widen the operands
1095 to perform the operation. It says to use zero-extension.
1097 If TARGET is nonzero, the value
1098 is generated there, if it is convenient to do so.
1099 In all cases an rtx is returned for the locus of the value;
1100 this may or may not be TARGET. */
1103 expand_unop (mode, unoptab, op0, target, unsignedp)
1104 enum machine_mode mode;
1110 enum mode_class class;
1111 enum machine_mode wider_mode;
1113 rtx last = get_last_insn ();
1116 class = GET_MODE_CLASS (mode);
1118 op0 = protect_from_queue (op0, 0);
1122 op0 = force_not_mem (op0);
1126 target = protect_from_queue (target, 1);
1128 if (unoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1130 int icode = (int) unoptab->handlers[(int) mode].insn_code;
1131 enum machine_mode mode0 = insn_operand_mode[icode][1];
1137 temp = gen_reg_rtx (mode);
1139 if (GET_MODE (xop0) != VOIDmode
1140 && GET_MODE (xop0) != mode0)
1141 xop0 = convert_to_mode (mode0, xop0, unsignedp);
1143 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
1145 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
1146 xop0 = copy_to_mode_reg (mode0, xop0);
1148 if (! (*insn_operand_predicate[icode][0]) (temp, mode))
1149 temp = gen_reg_rtx (mode);
1151 pat = GEN_FCN (icode) (temp, xop0);
1154 if (GET_CODE (pat) == SEQUENCE
1155 && ! add_equal_note (pat, temp, unoptab->code, xop0, NULL_RTX))
1157 delete_insns_since (last);
1158 return expand_unop (mode, unoptab, op0, NULL_RTX, unsignedp);
1166 delete_insns_since (last);
1169 /* It can't be done in this mode. Can we open-code it in a wider mode? */
1171 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1172 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1173 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1175 if (unoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing)
1179 /* For certain operations, we need not actually extend
1180 the narrow operand, as long as we will truncate the
1181 results to the same narrowness. */
1183 if ((unoptab == neg_optab || unoptab == one_cmpl_optab)
1184 && class == MODE_INT)
1185 xop0 = gen_rtx (SUBREG, wider_mode, force_reg (mode, xop0), 0);
1187 xop0 = convert_to_mode (wider_mode, xop0, unsignedp);
1189 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
1194 if (class != MODE_INT)
1197 target = gen_reg_rtx (mode);
1198 convert_move (target, temp, 0);
1202 return gen_lowpart (mode, temp);
1205 delete_insns_since (last);
1209 /* These can be done a word at a time. */
1210 if (unoptab == one_cmpl_optab
1211 && class == MODE_INT
1212 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
1213 && unoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
1218 if (target == 0 || target == op0)
1219 target = gen_reg_rtx (mode);
1223 /* Do the actual arithmetic. */
1224 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
1226 rtx target_piece = operand_subword (target, i, 1, mode);
1227 rtx x = expand_unop (word_mode, unoptab,
1228 operand_subword_force (op0, i, mode),
1229 target_piece, unsignedp);
1230 if (target_piece != x)
1231 emit_move_insn (target_piece, x);
1234 insns = get_insns ();
1237 emit_no_conflict_block (insns, target, op0, NULL_RTX,
1238 gen_rtx (unoptab->code, mode, op0));
1242 if (unoptab->handlers[(int) mode].libfunc)
1245 rtx funexp = unoptab->handlers[(int) mode].libfunc;
1249 /* Pass 1 for NO_QUEUE so we don't lose any increments
1250 if the libcall is cse'd or moved. */
1251 emit_library_call (unoptab->handlers[(int) mode].libfunc,
1252 1, mode, 1, op0, mode);
1253 insns = get_insns ();
1256 target = gen_reg_rtx (mode);
1257 emit_libcall_block (insns, target, hard_libcall_value (mode),
1258 gen_rtx (unoptab->code, mode, op0));
1263 /* It can't be done in this mode. Can we do it in a wider mode? */
1265 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1267 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1268 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1270 if ((unoptab->handlers[(int) wider_mode].insn_code
1271 != CODE_FOR_nothing)
1272 || unoptab->handlers[(int) wider_mode].libfunc)
1276 /* For certain operations, we need not actually extend
1277 the narrow operand, as long as we will truncate the
1278 results to the same narrowness. */
1280 if ((unoptab == neg_optab || unoptab == one_cmpl_optab)
1281 && class == MODE_INT)
1282 xop0 = gen_rtx (SUBREG, wider_mode, force_reg (mode, xop0), 0);
1284 xop0 = convert_to_mode (wider_mode, xop0, unsignedp);
1286 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
1291 if (class != MODE_INT)
1294 target = gen_reg_rtx (mode);
1295 convert_move (target, temp, 0);
1299 return gen_lowpart (mode, temp);
1302 delete_insns_since (last);
1310 /* Generate an instruction whose insn-code is INSN_CODE,
1311 with two operands: an output TARGET and an input OP0.
1312 TARGET *must* be nonzero, and the output is always stored there.
1313 CODE is an rtx code such that (CODE OP0) is an rtx that describes
1314 the value that is stored into TARGET. */
1317 emit_unop_insn (icode, target, op0, code)
1324 enum machine_mode mode0 = insn_operand_mode[icode][1];
1327 temp = target = protect_from_queue (target, 1);
1329 op0 = protect_from_queue (op0, 0);
1332 op0 = force_not_mem (op0);
1334 /* Now, if insn does not accept our operands, put them into pseudos. */
1336 if (! (*insn_operand_predicate[icode][1]) (op0, mode0))
1337 op0 = copy_to_mode_reg (mode0, op0);
1339 if (! (*insn_operand_predicate[icode][0]) (temp, GET_MODE (temp))
1340 || (flag_force_mem && GET_CODE (temp) == MEM))
1341 temp = gen_reg_rtx (GET_MODE (temp));
1343 pat = GEN_FCN (icode) (temp, op0);
1345 if (GET_CODE (pat) == SEQUENCE && code != UNKNOWN)
1346 add_equal_note (pat, temp, code, op0, NULL_RTX);
1351 emit_move_insn (target, temp);
1354 /* Emit code to perform a series of operations on a multi-word quantity, one
1357 Such a block is preceded by a CLOBBER of the output, consists of multiple
1358 insns, each setting one word of the output, and followed by a SET copying
1359 the output to itself.
1361 Each of the insns setting words of the output receives a REG_NO_CONFLICT
1362 note indicating that it doesn't conflict with the (also multi-word)
1363 inputs. The entire block is surrounded by REG_LIBCALL and REG_RETVAL
1366 INSNS is a block of code generated to perform the operation, not including
1367 the CLOBBER and final copy. All insns that compute intermediate values
1368 are first emitted, followed by the block as described above. Only
1369 INSNs are allowed in the block; no library calls or jumps may be
1372 TARGET, OP0, and OP1 are the output and inputs of the operations,
1373 respectively. OP1 may be zero for a unary operation.
1375 EQUIV, if non-zero, is an expression to be placed into a REG_EQUAL note
1378 If TARGET is not a register, INSNS is simply emitted with no special
1381 The final insn emitted is returned. */
1384 emit_no_conflict_block (insns, target, op0, op1, equiv)
1390 rtx prev, next, first, last, insn;
1392 if (GET_CODE (target) != REG || reload_in_progress)
1393 return emit_insns (insns);
1395 /* First emit all insns that do not store into words of the output and remove
1396 these from the list. */
1397 for (insn = insns; insn; insn = next)
1402 next = NEXT_INSN (insn);
1404 if (GET_CODE (insn) != INSN)
1407 if (GET_CODE (PATTERN (insn)) == SET)
1408 set = PATTERN (insn);
1409 else if (GET_CODE (PATTERN (insn)) == PARALLEL)
1411 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
1412 if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET)
1414 set = XVECEXP (PATTERN (insn), 0, i);
1422 if (! reg_overlap_mentioned_p (target, SET_DEST (set)))
1424 if (PREV_INSN (insn))
1425 NEXT_INSN (PREV_INSN (insn)) = next;
1430 PREV_INSN (next) = PREV_INSN (insn);
1436 prev = get_last_insn ();
1438 /* Now write the CLOBBER of the output, followed by the setting of each
1439 of the words, followed by the final copy. */
1440 if (target != op0 && target != op1)
1441 emit_insn (gen_rtx (CLOBBER, VOIDmode, target));
1443 for (insn = insns; insn; insn = next)
1445 next = NEXT_INSN (insn);
1448 if (op1 && GET_CODE (op1) == REG)
1449 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_NO_CONFLICT, op1,
1452 if (op0 && GET_CODE (op0) == REG)
1453 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_NO_CONFLICT, op0,
1457 last = emit_move_insn (target, target);
1459 REG_NOTES (last) = gen_rtx (EXPR_LIST, REG_EQUAL, equiv, REG_NOTES (last));
1462 first = get_insns ();
1464 first = NEXT_INSN (prev);
1466 /* Encapsulate the block so it gets manipulated as a unit. */
1467 REG_NOTES (first) = gen_rtx (INSN_LIST, REG_LIBCALL, last,
1469 REG_NOTES (last) = gen_rtx (INSN_LIST, REG_RETVAL, first, REG_NOTES (last));
1474 /* Emit code to make a call to a constant function or a library call.
1476 INSNS is a list containing all insns emitted in the call.
1477 These insns leave the result in RESULT. Our block is to copy RESULT
1478 to TARGET, which is logically equivalent to EQUIV.
1480 We first emit any insns that set a pseudo on the assumption that these are
1481 loading constants into registers; doing so allows them to be safely cse'ed
1482 between blocks. Then we emit all the other insns in the block, followed by
1483 an insn to move RESULT to TARGET. This last insn will have a REQ_EQUAL
1484 note with an operand of EQUIV.
1486 Moving assignments to pseudos outside of the block is done to improve
1487 the generated code, but is not required to generate correct code,
1488 hence being unable to move an assignment is not grounds for not making
1489 a libcall block. There are two reasons why it is safe to leave these
1490 insns inside the block: First, we know that these pseudos cannot be
1491 used in generated RTL outside the block since they are created for
1492 temporary purposes within the block. Second, CSE will not record the
1493 values of anything set inside a libcall block, so we know they must
1494 be dead at the end of the block.
1496 Except for the first group of insns (the ones setting pseudos), the
1497 block is delimited by REG_RETVAL and REG_LIBCALL notes. */
1500 emit_libcall_block (insns, target, result, equiv)
1506 rtx prev, next, first, last, insn;
1508 /* First emit all insns that set pseudos. Remove them from the list as
1509 we go. Avoid insns that set pseudo which were referenced in previous
1510 insns. These can be generated by move_by_pieces, for example,
1511 to update an address. */
1513 for (insn = insns; insn; insn = next)
1515 rtx set = single_set (insn);
1517 next = NEXT_INSN (insn);
1519 if (set != 0 && GET_CODE (SET_DEST (set)) == REG
1520 && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER
1522 || (! reg_mentioned_p (SET_DEST (set), PATTERN (insns))
1523 && ! reg_used_between_p (SET_DEST (set), insns, insn))))
1525 if (PREV_INSN (insn))
1526 NEXT_INSN (PREV_INSN (insn)) = next;
1531 PREV_INSN (next) = PREV_INSN (insn);
1537 prev = get_last_insn ();
1539 /* Write the remaining insns followed by the final copy. */
1541 for (insn = insns; insn; insn = next)
1543 next = NEXT_INSN (insn);
1548 last = emit_move_insn (target, result);
1549 REG_NOTES (last) = gen_rtx (EXPR_LIST, REG_EQUAL, equiv, REG_NOTES (last));
1552 first = get_insns ();
1554 first = NEXT_INSN (prev);
1556 /* Encapsulate the block so it gets manipulated as a unit. */
1557 REG_NOTES (first) = gen_rtx (INSN_LIST, REG_LIBCALL, last,
1559 REG_NOTES (last) = gen_rtx (INSN_LIST, REG_RETVAL, first, REG_NOTES (last));
1562 /* Generate code to store zero in X. */
1568 emit_move_insn (x, const0_rtx);
1571 /* Generate code to store 1 in X
1572 assuming it contains zero beforehand. */
1575 emit_0_to_1_insn (x)
1578 emit_move_insn (x, const1_rtx);
1581 /* Generate code to compare X with Y
1582 so that the condition codes are set.
1584 MODE is the mode of the inputs (in case they are const_int).
1585 UNSIGNEDP nonzero says that X and Y are unsigned;
1586 this matters if they need to be widened.
1588 If they have mode BLKmode, then SIZE specifies the size of both X and Y,
1589 and ALIGN specifies the known shared alignment of X and Y.
1591 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).
1592 It is ignored for fixed-point and block comparisons;
1593 it is used only for floating-point comparisons. */
1596 emit_cmp_insn (x, y, comparison, size, mode, unsignedp, align)
1598 enum rtx_code comparison;
1600 enum machine_mode mode;
1604 enum mode_class class;
1605 enum machine_mode wider_mode;
1607 class = GET_MODE_CLASS (mode);
1609 /* They could both be VOIDmode if both args are immediate constants,
1610 but we should fold that at an earlier stage.
1611 With no special code here, this will call abort,
1612 reminding the programmer to implement such folding. */
1614 if (mode != BLKmode && flag_force_mem)
1616 x = force_not_mem (x);
1617 y = force_not_mem (y);
1620 /* If we are inside an appropriately-short loop and one operand is an
1621 expensive constant, force it into a register. */
1622 if (CONSTANT_P (x) && preserve_subexpressions_p () && rtx_cost (x, COMPARE) > 2)
1623 x = force_reg (mode, x);
1625 if (CONSTANT_P (y) && preserve_subexpressions_p () && rtx_cost (y, COMPARE) > 2)
1626 y = force_reg (mode, y);
1628 /* Don't let both operands fail to indicate the mode. */
1629 if (GET_MODE (x) == VOIDmode && GET_MODE (y) == VOIDmode)
1630 x = force_reg (mode, x);
1632 /* Handle all BLKmode compares. */
1634 if (mode == BLKmode)
1637 x = protect_from_queue (x, 0);
1638 y = protect_from_queue (y, 0);
1642 #ifdef HAVE_cmpstrqi
1644 && GET_CODE (size) == CONST_INT
1645 && INTVAL (size) < (1 << GET_MODE_BITSIZE (QImode)))
1647 enum machine_mode result_mode
1648 = insn_operand_mode[(int) CODE_FOR_cmpstrqi][0];
1649 rtx result = gen_reg_rtx (result_mode);
1650 emit_insn (gen_cmpstrqi (result, x, y, size, GEN_INT (align)));
1651 emit_cmp_insn (result, const0_rtx, comparison, NULL_RTX,
1656 #ifdef HAVE_cmpstrhi
1658 && GET_CODE (size) == CONST_INT
1659 && INTVAL (size) < (1 << GET_MODE_BITSIZE (HImode)))
1661 enum machine_mode result_mode
1662 = insn_operand_mode[(int) CODE_FOR_cmpstrhi][0];
1663 rtx result = gen_reg_rtx (result_mode);
1664 emit_insn (gen_cmpstrhi (result, x, y, size, GEN_INT (align)));
1665 emit_cmp_insn (result, const0_rtx, comparison, NULL_RTX,
1670 #ifdef HAVE_cmpstrsi
1673 enum machine_mode result_mode
1674 = insn_operand_mode[(int) CODE_FOR_cmpstrsi][0];
1675 rtx result = gen_reg_rtx (result_mode);
1676 size = protect_from_queue (size, 0);
1677 emit_insn (gen_cmpstrsi (result, x, y,
1678 convert_to_mode (SImode, size, 1),
1680 emit_cmp_insn (result, const0_rtx, comparison, NULL_RTX,
1686 #ifdef TARGET_MEM_FUNCTIONS
1687 emit_library_call (memcmp_libfunc, 1,
1688 TYPE_MODE (integer_type_node), 3,
1689 XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
1692 emit_library_call (bcmp_libfunc, 1,
1693 TYPE_MODE (integer_type_node), 3,
1694 XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
1697 emit_cmp_insn (hard_libcall_value (TYPE_MODE (integer_type_node)),
1698 const0_rtx, comparison, NULL_RTX,
1699 TYPE_MODE (integer_type_node), 0, 0);
1704 /* Handle some compares against zero. */
1706 if (y == CONST0_RTX (mode)
1707 && tst_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1709 int icode = (int) tst_optab->handlers[(int) mode].insn_code;
1712 x = protect_from_queue (x, 0);
1713 y = protect_from_queue (y, 0);
1715 /* Now, if insn does accept these operands, put them into pseudos. */
1716 if (! (*insn_operand_predicate[icode][0])
1717 (x, insn_operand_mode[icode][0]))
1718 x = copy_to_mode_reg (insn_operand_mode[icode][0], x);
1720 emit_insn (GEN_FCN (icode) (x));
1724 /* Handle compares for which there is a directly suitable insn. */
1726 if (cmp_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1728 int icode = (int) cmp_optab->handlers[(int) mode].insn_code;
1731 x = protect_from_queue (x, 0);
1732 y = protect_from_queue (y, 0);
1734 /* Now, if insn doesn't accept these operands, put them into pseudos. */
1735 if (! (*insn_operand_predicate[icode][0])
1736 (x, insn_operand_mode[icode][0]))
1737 x = copy_to_mode_reg (insn_operand_mode[icode][0], x);
1739 if (! (*insn_operand_predicate[icode][1])
1740 (y, insn_operand_mode[icode][1]))
1741 y = copy_to_mode_reg (insn_operand_mode[icode][1], y);
1743 emit_insn (GEN_FCN (icode) (x, y));
1747 /* Try widening if we can find a direct insn that way. */
1749 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1751 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1752 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1754 if (cmp_optab->handlers[(int) wider_mode].insn_code
1755 != CODE_FOR_nothing)
1757 x = protect_from_queue (x, 0);
1758 y = protect_from_queue (y, 0);
1759 x = convert_to_mode (wider_mode, x, unsignedp);
1760 y = convert_to_mode (wider_mode, y, unsignedp);
1761 emit_cmp_insn (x, y, comparison, NULL_RTX,
1762 wider_mode, unsignedp, align);
1768 /* Handle a lib call just for the mode we are using. */
1770 if (cmp_optab->handlers[(int) mode].libfunc
1771 && class != MODE_FLOAT)
1773 rtx libfunc = cmp_optab->handlers[(int) mode].libfunc;
1774 /* If we want unsigned, and this mode has a distinct unsigned
1775 comparison routine, use that. */
1776 if (unsignedp && ucmp_optab->handlers[(int) mode].libfunc)
1777 libfunc = ucmp_optab->handlers[(int) mode].libfunc;
1779 emit_library_call (libfunc, 1,
1780 SImode, 2, x, mode, y, mode);
1782 /* Integer comparison returns a result that must be compared against 1,
1783 so that even if we do an unsigned compare afterward,
1784 there is still a value that can represent the result "less than". */
1786 emit_cmp_insn (hard_libcall_value (SImode), const1_rtx,
1787 comparison, NULL_RTX, SImode, unsignedp, 0);
1791 if (class == MODE_FLOAT)
1792 emit_float_lib_cmp (x, y, comparison);
1798 /* Nonzero if a compare of mode MODE can be done straightforwardly
1799 (without splitting it into pieces). */
1802 can_compare_p (mode)
1803 enum machine_mode mode;
1807 if (cmp_optab->handlers[(int)mode].insn_code != CODE_FOR_nothing)
1809 mode = GET_MODE_WIDER_MODE (mode);
1810 } while (mode != VOIDmode);
1815 /* Emit a library call comparison between floating point X and Y.
1816 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */
1819 emit_float_lib_cmp (x, y, comparison)
1821 enum rtx_code comparison;
1823 enum machine_mode mode = GET_MODE (x);
1830 libfunc = eqsf2_libfunc;
1834 libfunc = nesf2_libfunc;
1838 libfunc = gtsf2_libfunc;
1842 libfunc = gesf2_libfunc;
1846 libfunc = ltsf2_libfunc;
1850 libfunc = lesf2_libfunc;
1853 else if (mode == DFmode)
1857 libfunc = eqdf2_libfunc;
1861 libfunc = nedf2_libfunc;
1865 libfunc = gtdf2_libfunc;
1869 libfunc = gedf2_libfunc;
1873 libfunc = ltdf2_libfunc;
1877 libfunc = ledf2_libfunc;
1880 else if (mode == XFmode)
1884 libfunc = eqxf2_libfunc;
1888 libfunc = nexf2_libfunc;
1892 libfunc = gtxf2_libfunc;
1896 libfunc = gexf2_libfunc;
1900 libfunc = ltxf2_libfunc;
1904 libfunc = lexf2_libfunc;
1907 else if (mode == TFmode)
1911 libfunc = eqtf2_libfunc;
1915 libfunc = netf2_libfunc;
1919 libfunc = gttf2_libfunc;
1923 libfunc = getf2_libfunc;
1927 libfunc = lttf2_libfunc;
1931 libfunc = letf2_libfunc;
1936 enum machine_mode wider_mode;
1938 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1939 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1941 if ((cmp_optab->handlers[(int) wider_mode].insn_code
1942 != CODE_FOR_nothing)
1943 || (cmp_optab->handlers[(int) wider_mode].libfunc != 0))
1945 x = protect_from_queue (x, 0);
1946 y = protect_from_queue (y, 0);
1947 x = convert_to_mode (wider_mode, x, 0);
1948 y = convert_to_mode (wider_mode, y, 0);
1949 emit_float_lib_cmp (x, y, comparison);
1956 emit_library_call (libfunc, 1,
1957 SImode, 2, x, mode, y, mode);
1959 emit_cmp_insn (hard_libcall_value (SImode), const0_rtx, comparison,
1960 NULL_RTX, SImode, 0, 0);
1963 /* Generate code to indirectly jump to a location given in the rtx LOC. */
1966 emit_indirect_jump (loc)
1969 if (! ((*insn_operand_predicate[(int)CODE_FOR_indirect_jump][0])
1971 loc = copy_to_mode_reg (insn_operand_mode[(int)CODE_FOR_indirect_jump][0],
1974 emit_jump_insn (gen_indirect_jump (loc));
1978 /* These three functions generate an insn body and return it
1979 rather than emitting the insn.
1981 They do not protect from queued increments,
1982 because they may be used 1) in protect_from_queue itself
1983 and 2) in other passes where there is no queue. */
1985 /* Generate and return an insn body to add Y to X. */
1988 gen_add2_insn (x, y)
1991 int icode = (int) add_optab->handlers[(int) GET_MODE (x)].insn_code;
1993 if (! (*insn_operand_predicate[icode][0]) (x, insn_operand_mode[icode][0])
1994 || ! (*insn_operand_predicate[icode][1]) (x, insn_operand_mode[icode][1])
1995 || ! (*insn_operand_predicate[icode][2]) (y, insn_operand_mode[icode][2]))
1998 return (GEN_FCN (icode) (x, x, y));
2002 have_add2_insn (mode)
2003 enum machine_mode mode;
2005 return add_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
2008 /* Generate and return an insn body to subtract Y from X. */
2011 gen_sub2_insn (x, y)
2014 int icode = (int) sub_optab->handlers[(int) GET_MODE (x)].insn_code;
2016 if (! (*insn_operand_predicate[icode][0]) (x, insn_operand_mode[icode][0])
2017 || ! (*insn_operand_predicate[icode][1]) (x, insn_operand_mode[icode][1])
2018 || ! (*insn_operand_predicate[icode][2]) (y, insn_operand_mode[icode][2]))
2021 return (GEN_FCN (icode) (x, x, y));
2025 have_sub2_insn (mode)
2026 enum machine_mode mode;
2028 return sub_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
2031 /* Generate the body of an instruction to copy Y into X. */
2034 gen_move_insn (x, y)
2037 register enum machine_mode mode = GET_MODE (x);
2038 enum insn_code insn_code;
2040 if (mode == VOIDmode)
2041 mode = GET_MODE (y);
2043 insn_code = mov_optab->handlers[(int) mode].insn_code;
2045 /* Handle MODE_CC modes: If we don't have a special move insn for this mode,
2046 find a mode to do it in. If we have a movcc, use it. Otherwise,
2047 find the MODE_INT mode of the same width. */
2049 if (insn_code == CODE_FOR_nothing)
2051 enum machine_mode tmode = VOIDmode;
2054 if (GET_MODE_CLASS (mode) == MODE_CC && mode != CCmode
2055 && mov_optab->handlers[(int) CCmode].insn_code != CODE_FOR_nothing)
2057 else if (GET_MODE_CLASS (mode) == MODE_CC)
2058 for (tmode = QImode; tmode != VOIDmode;
2059 tmode = GET_MODE_WIDER_MODE (tmode))
2060 if (GET_MODE_SIZE (tmode) == GET_MODE_SIZE (mode))
2063 if (tmode == VOIDmode)
2066 /* Get X and Y in TMODE. We can't use gen_lowpart here because it
2067 may call change_address which is not appropriate if we were
2068 called when a reload was in progress. We don't have to worry
2069 about changing the address since the size in bytes is supposed to
2070 be the same. Copy the MEM to change the mode and move any
2071 substitutions from the old MEM to the new one. */
2073 if (reload_in_progress)
2075 x = gen_lowpart_common (tmode, x1);
2076 if (x == 0 && GET_CODE (x1) == MEM)
2078 x = gen_rtx (MEM, tmode, XEXP (x1, 0));
2079 RTX_UNCHANGING_P (x) = RTX_UNCHANGING_P (x1);
2080 MEM_IN_STRUCT_P (x) = MEM_IN_STRUCT_P (x1);
2081 MEM_VOLATILE_P (x) = MEM_VOLATILE_P (x1);
2082 copy_replacements (x1, x);
2085 y = gen_lowpart_common (tmode, y1);
2086 if (y == 0 && GET_CODE (y1) == MEM)
2088 y = gen_rtx (MEM, tmode, XEXP (y1, 0));
2089 RTX_UNCHANGING_P (y) = RTX_UNCHANGING_P (y1);
2090 MEM_IN_STRUCT_P (y) = MEM_IN_STRUCT_P (y1);
2091 MEM_VOLATILE_P (y) = MEM_VOLATILE_P (y1);
2092 copy_replacements (y1, y);
2097 x = gen_lowpart (tmode, x);
2098 y = gen_lowpart (tmode, y);
2101 insn_code = mov_optab->handlers[(int) tmode].insn_code;
2104 return (GEN_FCN (insn_code) (x, y));
2107 /* Tables of patterns for extending one integer mode to another. */
2108 static enum insn_code extendtab[MAX_MACHINE_MODE][MAX_MACHINE_MODE][2];
2110 /* Return the insn code used to extend FROM_MODE to TO_MODE.
2111 UNSIGNEDP specifies zero-extension instead of sign-extension. If
2112 no such operation exists, CODE_FOR_nothing will be returned. */
2115 can_extend_p (to_mode, from_mode, unsignedp)
2116 enum machine_mode to_mode, from_mode;
2119 return extendtab[(int) to_mode][(int) from_mode][unsignedp];
2122 /* Generate the body of an insn to extend Y (with mode MFROM)
2123 into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */
2126 gen_extend_insn (x, y, mto, mfrom, unsignedp)
2128 enum machine_mode mto, mfrom;
2131 return (GEN_FCN (extendtab[(int) mto][(int) mfrom][unsignedp]) (x, y));
2139 for (p = extendtab[0][0];
2140 p < extendtab[0][0] + sizeof extendtab / sizeof extendtab[0][0][0];
2142 *p = CODE_FOR_nothing;
2144 #ifdef HAVE_extendditi2
2145 if (HAVE_extendditi2)
2146 extendtab[(int) TImode][(int) DImode][0] = CODE_FOR_extendditi2;
2148 #ifdef HAVE_extendsiti2
2149 if (HAVE_extendsiti2)
2150 extendtab[(int) TImode][(int) SImode][0] = CODE_FOR_extendsiti2;
2152 #ifdef HAVE_extendhiti2
2153 if (HAVE_extendhiti2)
2154 extendtab[(int) TImode][(int) HImode][0] = CODE_FOR_extendhiti2;
2156 #ifdef HAVE_extendqiti2
2157 if (HAVE_extendqiti2)
2158 extendtab[(int) TImode][(int) QImode][0] = CODE_FOR_extendqiti2;
2160 #ifdef HAVE_extendsidi2
2161 if (HAVE_extendsidi2)
2162 extendtab[(int) DImode][(int) SImode][0] = CODE_FOR_extendsidi2;
2164 #ifdef HAVE_extendhidi2
2165 if (HAVE_extendhidi2)
2166 extendtab[(int) DImode][(int) HImode][0] = CODE_FOR_extendhidi2;
2168 #ifdef HAVE_extendqidi2
2169 if (HAVE_extendqidi2)
2170 extendtab[(int) DImode][(int) QImode][0] = CODE_FOR_extendqidi2;
2172 #ifdef HAVE_extendhisi2
2173 if (HAVE_extendhisi2)
2174 extendtab[(int) SImode][(int) HImode][0] = CODE_FOR_extendhisi2;
2176 #ifdef HAVE_extendqisi2
2177 if (HAVE_extendqisi2)
2178 extendtab[(int) SImode][(int) QImode][0] = CODE_FOR_extendqisi2;
2180 #ifdef HAVE_extendqihi2
2181 if (HAVE_extendqihi2)
2182 extendtab[(int) HImode][(int) QImode][0] = CODE_FOR_extendqihi2;
2185 #ifdef HAVE_zero_extendditi2
2186 if (HAVE_zero_extendsiti2)
2187 extendtab[(int) TImode][(int) DImode][1] = CODE_FOR_zero_extendditi2;
2189 #ifdef HAVE_zero_extendsiti2
2190 if (HAVE_zero_extendsiti2)
2191 extendtab[(int) TImode][(int) SImode][1] = CODE_FOR_zero_extendsiti2;
2193 #ifdef HAVE_zero_extendhiti2
2194 if (HAVE_zero_extendhiti2)
2195 extendtab[(int) TImode][(int) HImode][1] = CODE_FOR_zero_extendhiti2;
2197 #ifdef HAVE_zero_extendqiti2
2198 if (HAVE_zero_extendqiti2)
2199 extendtab[(int) TImode][(int) QImode][1] = CODE_FOR_zero_extendqiti2;
2201 #ifdef HAVE_zero_extendsidi2
2202 if (HAVE_zero_extendsidi2)
2203 extendtab[(int) DImode][(int) SImode][1] = CODE_FOR_zero_extendsidi2;
2205 #ifdef HAVE_zero_extendhidi2
2206 if (HAVE_zero_extendhidi2)
2207 extendtab[(int) DImode][(int) HImode][1] = CODE_FOR_zero_extendhidi2;
2209 #ifdef HAVE_zero_extendqidi2
2210 if (HAVE_zero_extendqidi2)
2211 extendtab[(int) DImode][(int) QImode][1] = CODE_FOR_zero_extendqidi2;
2213 #ifdef HAVE_zero_extendhisi2
2214 if (HAVE_zero_extendhisi2)
2215 extendtab[(int) SImode][(int) HImode][1] = CODE_FOR_zero_extendhisi2;
2217 #ifdef HAVE_zero_extendqisi2
2218 if (HAVE_zero_extendqisi2)
2219 extendtab[(int) SImode][(int) QImode][1] = CODE_FOR_zero_extendqisi2;
2221 #ifdef HAVE_zero_extendqihi2
2222 if (HAVE_zero_extendqihi2)
2223 extendtab[(int) HImode][(int) QImode][1] = CODE_FOR_zero_extendqihi2;
2227 /* can_fix_p and can_float_p say whether the target machine
2228 can directly convert a given fixed point type to
2229 a given floating point type, or vice versa.
2230 The returned value is the CODE_FOR_... value to use,
2231 or CODE_FOR_nothing if these modes cannot be directly converted. */
2233 static enum insn_code fixtab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
2234 static enum insn_code fixtrunctab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
2235 static enum insn_code floattab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
2237 /* *TRUNCP_PTR is set to 1 if it is necessary to output
2238 an explicit FTRUNC insn before the fix insn; otherwise 0. */
2240 static enum insn_code
2241 can_fix_p (fixmode, fltmode, unsignedp, truncp_ptr)
2242 enum machine_mode fltmode, fixmode;
2247 if (fixtrunctab[(int) fltmode][(int) fixmode][unsignedp] != CODE_FOR_nothing)
2248 return fixtrunctab[(int) fltmode][(int) fixmode][unsignedp];
2250 if (ftrunc_optab->handlers[(int) fltmode].insn_code != CODE_FOR_nothing)
2253 return fixtab[(int) fltmode][(int) fixmode][unsignedp];
2255 return CODE_FOR_nothing;
2258 static enum insn_code
2259 can_float_p (fltmode, fixmode, unsignedp)
2260 enum machine_mode fixmode, fltmode;
2263 return floattab[(int) fltmode][(int) fixmode][unsignedp];
2270 for (p = fixtab[0][0];
2271 p < fixtab[0][0] + sizeof fixtab / sizeof (fixtab[0][0][0]);
2273 *p = CODE_FOR_nothing;
2274 for (p = fixtrunctab[0][0];
2275 p < fixtrunctab[0][0] + sizeof fixtrunctab / sizeof (fixtrunctab[0][0][0]);
2277 *p = CODE_FOR_nothing;
2279 #ifdef HAVE_fixsfqi2
2281 fixtab[(int) SFmode][(int) QImode][0] = CODE_FOR_fixsfqi2;
2283 #ifdef HAVE_fixsfhi2
2285 fixtab[(int) SFmode][(int) HImode][0] = CODE_FOR_fixsfhi2;
2287 #ifdef HAVE_fixsfsi2
2289 fixtab[(int) SFmode][(int) SImode][0] = CODE_FOR_fixsfsi2;
2291 #ifdef HAVE_fixsfdi2
2293 fixtab[(int) SFmode][(int) DImode][0] = CODE_FOR_fixsfdi2;
2296 #ifdef HAVE_fixdfqi2
2298 fixtab[(int) DFmode][(int) QImode][0] = CODE_FOR_fixdfqi2;
2300 #ifdef HAVE_fixdfhi2
2302 fixtab[(int) DFmode][(int) HImode][0] = CODE_FOR_fixdfhi2;
2304 #ifdef HAVE_fixdfsi2
2306 fixtab[(int) DFmode][(int) SImode][0] = CODE_FOR_fixdfsi2;
2308 #ifdef HAVE_fixdfdi2
2310 fixtab[(int) DFmode][(int) DImode][0] = CODE_FOR_fixdfdi2;
2312 #ifdef HAVE_fixdfti2
2314 fixtab[(int) DFmode][(int) TImode][0] = CODE_FOR_fixdfti2;
2317 #ifdef HAVE_fixxfqi2
2319 fixtab[(int) XFmode][(int) QImode][0] = CODE_FOR_fixxfqi2;
2321 #ifdef HAVE_fixxfhi2
2323 fixtab[(int) XFmode][(int) HImode][0] = CODE_FOR_fixxfhi2;
2325 #ifdef HAVE_fixxfsi2
2327 fixtab[(int) XFmode][(int) SImode][0] = CODE_FOR_fixxfsi2;
2329 #ifdef HAVE_fixxfdi2
2331 fixtab[(int) XFmode][(int) DImode][0] = CODE_FOR_fixxfdi2;
2333 #ifdef HAVE_fixxfti2
2335 fixtab[(int) XFmode][(int) TImode][0] = CODE_FOR_fixxfti2;
2338 #ifdef HAVE_fixtfqi2
2340 fixtab[(int) TFmode][(int) QImode][0] = CODE_FOR_fixtfqi2;
2342 #ifdef HAVE_fixtfhi2
2344 fixtab[(int) TFmode][(int) HImode][0] = CODE_FOR_fixtfhi2;
2346 #ifdef HAVE_fixtfsi2
2348 fixtab[(int) TFmode][(int) SImode][0] = CODE_FOR_fixtfsi2;
2350 #ifdef HAVE_fixtfdi2
2352 fixtab[(int) TFmode][(int) DImode][0] = CODE_FOR_fixtfdi2;
2354 #ifdef HAVE_fixtfti2
2356 fixtab[(int) TFmode][(int) TImode][0] = CODE_FOR_fixtfti2;
2359 #ifdef HAVE_fixunssfqi2
2360 if (HAVE_fixunssfqi2)
2361 fixtab[(int) SFmode][(int) QImode][1] = CODE_FOR_fixunssfqi2;
2363 #ifdef HAVE_fixunssfhi2
2364 if (HAVE_fixunssfhi2)
2365 fixtab[(int) SFmode][(int) HImode][1] = CODE_FOR_fixunssfhi2;
2367 #ifdef HAVE_fixunssfsi2
2368 if (HAVE_fixunssfsi2)
2369 fixtab[(int) SFmode][(int) SImode][1] = CODE_FOR_fixunssfsi2;
2371 #ifdef HAVE_fixunssfdi2
2372 if (HAVE_fixunssfdi2)
2373 fixtab[(int) SFmode][(int) DImode][1] = CODE_FOR_fixunssfdi2;
2376 #ifdef HAVE_fixunsdfqi2
2377 if (HAVE_fixunsdfqi2)
2378 fixtab[(int) DFmode][(int) QImode][1] = CODE_FOR_fixunsdfqi2;
2380 #ifdef HAVE_fixunsdfhi2
2381 if (HAVE_fixunsdfhi2)
2382 fixtab[(int) DFmode][(int) HImode][1] = CODE_FOR_fixunsdfhi2;
2384 #ifdef HAVE_fixunsdfsi2
2385 if (HAVE_fixunsdfsi2)
2386 fixtab[(int) DFmode][(int) SImode][1] = CODE_FOR_fixunsdfsi2;
2388 #ifdef HAVE_fixunsdfdi2
2389 if (HAVE_fixunsdfdi2)
2390 fixtab[(int) DFmode][(int) DImode][1] = CODE_FOR_fixunsdfdi2;
2392 #ifdef HAVE_fixunsdfti2
2393 if (HAVE_fixunsdfti2)
2394 fixtab[(int) DFmode][(int) TImode][1] = CODE_FOR_fixunsdfti2;
2397 #ifdef HAVE_fixunsxfqi2
2398 if (HAVE_fixunsxfqi2)
2399 fixtab[(int) XFmode][(int) QImode][1] = CODE_FOR_fixunsxfqi2;
2401 #ifdef HAVE_fixunsxfhi2
2402 if (HAVE_fixunsxfhi2)
2403 fixtab[(int) XFmode][(int) HImode][1] = CODE_FOR_fixunsxfhi2;
2405 #ifdef HAVE_fixunsxfsi2
2406 if (HAVE_fixunsxfsi2)
2407 fixtab[(int) XFmode][(int) SImode][1] = CODE_FOR_fixunsxfsi2;
2409 #ifdef HAVE_fixunsxfdi2
2410 if (HAVE_fixunsxfdi2)
2411 fixtab[(int) XFmode][(int) DImode][1] = CODE_FOR_fixunsxfdi2;
2413 #ifdef HAVE_fixunsxfti2
2414 if (HAVE_fixunsxfti2)
2415 fixtab[(int) XFmode][(int) TImode][1] = CODE_FOR_fixunsxfti2;
2418 #ifdef HAVE_fixunstfqi2
2419 if (HAVE_fixunstfqi2)
2420 fixtab[(int) TFmode][(int) QImode][1] = CODE_FOR_fixunstfqi2;
2422 #ifdef HAVE_fixunstfhi2
2423 if (HAVE_fixunstfhi2)
2424 fixtab[(int) TFmode][(int) HImode][1] = CODE_FOR_fixunstfhi2;
2426 #ifdef HAVE_fixunstfsi2
2427 if (HAVE_fixunstfsi2)
2428 fixtab[(int) TFmode][(int) SImode][1] = CODE_FOR_fixunstfsi2;
2430 #ifdef HAVE_fixunstfdi2
2431 if (HAVE_fixunstfdi2)
2432 fixtab[(int) TFmode][(int) DImode][1] = CODE_FOR_fixunstfdi2;
2434 #ifdef HAVE_fixunstfti2
2435 if (HAVE_fixunstfti2)
2436 fixtab[(int) TFmode][(int) TImode][1] = CODE_FOR_fixunstfti2;
2439 #ifdef HAVE_fix_truncsfqi2
2440 if (HAVE_fix_truncsfqi2)
2441 fixtrunctab[(int) SFmode][(int) QImode][0] = CODE_FOR_fix_truncsfqi2;
2443 #ifdef HAVE_fix_truncsfhi2
2444 if (HAVE_fix_truncsfhi2)
2445 fixtrunctab[(int) SFmode][(int) HImode][0] = CODE_FOR_fix_truncsfhi2;
2447 #ifdef HAVE_fix_truncsfsi2
2448 if (HAVE_fix_truncsfsi2)
2449 fixtrunctab[(int) SFmode][(int) SImode][0] = CODE_FOR_fix_truncsfsi2;
2451 #ifdef HAVE_fix_truncsfdi2
2452 if (HAVE_fix_truncsfdi2)
2453 fixtrunctab[(int) SFmode][(int) DImode][0] = CODE_FOR_fix_truncsfdi2;
2456 #ifdef HAVE_fix_truncdfqi2
2457 if (HAVE_fix_truncdfsi2)
2458 fixtrunctab[(int) DFmode][(int) QImode][0] = CODE_FOR_fix_truncdfqi2;
2460 #ifdef HAVE_fix_truncdfhi2
2461 if (HAVE_fix_truncdfhi2)
2462 fixtrunctab[(int) DFmode][(int) HImode][0] = CODE_FOR_fix_truncdfhi2;
2464 #ifdef HAVE_fix_truncdfsi2
2465 if (HAVE_fix_truncdfsi2)
2466 fixtrunctab[(int) DFmode][(int) SImode][0] = CODE_FOR_fix_truncdfsi2;
2468 #ifdef HAVE_fix_truncdfdi2
2469 if (HAVE_fix_truncdfdi2)
2470 fixtrunctab[(int) DFmode][(int) DImode][0] = CODE_FOR_fix_truncdfdi2;
2472 #ifdef HAVE_fix_truncdfti2
2473 if (HAVE_fix_truncdfti2)
2474 fixtrunctab[(int) DFmode][(int) TImode][0] = CODE_FOR_fix_truncdfti2;
2477 #ifdef HAVE_fix_truncxfqi2
2478 if (HAVE_fix_truncxfqi2)
2479 fixtrunctab[(int) XFmode][(int) QImode][0] = CODE_FOR_fix_truncxfqi2;
2481 #ifdef HAVE_fix_truncxfhi2
2482 if (HAVE_fix_truncxfhi2)
2483 fixtrunctab[(int) XFmode][(int) HImode][0] = CODE_FOR_fix_truncxfhi2;
2485 #ifdef HAVE_fix_truncxfsi2
2486 if (HAVE_fix_truncxfsi2)
2487 fixtrunctab[(int) XFmode][(int) SImode][0] = CODE_FOR_fix_truncxfsi2;
2489 #ifdef HAVE_fix_truncxfdi2
2490 if (HAVE_fix_truncxfdi2)
2491 fixtrunctab[(int) XFmode][(int) DImode][0] = CODE_FOR_fix_truncxfdi2;
2493 #ifdef HAVE_fix_truncxfti2
2494 if (HAVE_fix_truncxfti2)
2495 fixtrunctab[(int) XFmode][(int) TImode][0] = CODE_FOR_fix_truncxfti2;
2498 #ifdef HAVE_fix_trunctfqi2
2499 if (HAVE_fix_trunctfqi2)
2500 fixtrunctab[(int) TFmode][(int) QImode][0] = CODE_FOR_fix_trunctfqi2;
2502 #ifdef HAVE_fix_trunctfhi2
2503 if (HAVE_fix_trunctfhi2)
2504 fixtrunctab[(int) TFmode][(int) HImode][0] = CODE_FOR_fix_trunctfhi2;
2506 #ifdef HAVE_fix_trunctfsi2
2507 if (HAVE_fix_trunctfsi2)
2508 fixtrunctab[(int) TFmode][(int) SImode][0] = CODE_FOR_fix_trunctfsi2;
2510 #ifdef HAVE_fix_trunctfdi2
2511 if (HAVE_fix_trunctfdi2)
2512 fixtrunctab[(int) TFmode][(int) DImode][0] = CODE_FOR_fix_trunctfdi2;
2514 #ifdef HAVE_fix_trunctfti2
2515 if (HAVE_fix_trunctfti2)
2516 fixtrunctab[(int) TFmode][(int) TImode][0] = CODE_FOR_fix_trunctfti2;
2519 #ifdef HAVE_fixuns_truncsfqi2
2520 if (HAVE_fixuns_truncsfqi2)
2521 fixtrunctab[(int) SFmode][(int) QImode][1] = CODE_FOR_fixuns_truncsfqi2;
2523 #ifdef HAVE_fixuns_truncsfhi2
2524 if (HAVE_fixuns_truncsfhi2)
2525 fixtrunctab[(int) SFmode][(int) HImode][1] = CODE_FOR_fixuns_truncsfhi2;
2527 #ifdef HAVE_fixuns_truncsfsi2
2528 if (HAVE_fixuns_truncsfsi2)
2529 fixtrunctab[(int) SFmode][(int) SImode][1] = CODE_FOR_fixuns_truncsfsi2;
2531 #ifdef HAVE_fixuns_truncsfdi2
2532 if (HAVE_fixuns_truncsfdi2)
2533 fixtrunctab[(int) SFmode][(int) DImode][1] = CODE_FOR_fixuns_truncsfdi2;
2536 #ifdef HAVE_fixuns_truncdfqi2
2537 if (HAVE_fixuns_truncdfqi2)
2538 fixtrunctab[(int) DFmode][(int) QImode][1] = CODE_FOR_fixuns_truncdfqi2;
2540 #ifdef HAVE_fixuns_truncdfhi2
2541 if (HAVE_fixuns_truncdfhi2)
2542 fixtrunctab[(int) DFmode][(int) HImode][1] = CODE_FOR_fixuns_truncdfhi2;
2544 #ifdef HAVE_fixuns_truncdfsi2
2545 if (HAVE_fixuns_truncdfsi2)
2546 fixtrunctab[(int) DFmode][(int) SImode][1] = CODE_FOR_fixuns_truncdfsi2;
2548 #ifdef HAVE_fixuns_truncdfdi2
2549 if (HAVE_fixuns_truncdfdi2)
2550 fixtrunctab[(int) DFmode][(int) DImode][1] = CODE_FOR_fixuns_truncdfdi2;
2552 #ifdef HAVE_fixuns_truncdfti2
2553 if (HAVE_fixuns_truncdfti2)
2554 fixtrunctab[(int) DFmode][(int) TImode][1] = CODE_FOR_fixuns_truncdfti2;
2557 #ifdef HAVE_fixuns_truncxfqi2
2558 if (HAVE_fixuns_truncxfqi2)
2559 fixtrunctab[(int) XFmode][(int) QImode][1] = CODE_FOR_fixuns_truncxfqi2;
2561 #ifdef HAVE_fixuns_truncxfhi2
2562 if (HAVE_fixuns_truncxfhi2)
2563 fixtrunctab[(int) XFmode][(int) HImode][1] = CODE_FOR_fixuns_truncxfhi2;
2565 #ifdef HAVE_fixuns_truncxfsi2
2566 if (HAVE_fixuns_truncxfsi2)
2567 fixtrunctab[(int) XFmode][(int) SImode][1] = CODE_FOR_fixuns_truncxfsi2;
2569 #ifdef HAVE_fixuns_truncxfdi2
2570 if (HAVE_fixuns_truncxfdi2)
2571 fixtrunctab[(int) XFmode][(int) DImode][1] = CODE_FOR_fixuns_truncxfdi2;
2573 #ifdef HAVE_fixuns_truncxfti2
2574 if (HAVE_fixuns_truncxfti2)
2575 fixtrunctab[(int) XFmode][(int) TImode][1] = CODE_FOR_fixuns_truncxfti2;
2578 #ifdef HAVE_fixuns_trunctfqi2
2579 if (HAVE_fixuns_trunctfqi2)
2580 fixtrunctab[(int) TFmode][(int) QImode][1] = CODE_FOR_fixuns_trunctfqi2;
2582 #ifdef HAVE_fixuns_trunctfhi2
2583 if (HAVE_fixuns_trunctfhi2)
2584 fixtrunctab[(int) TFmode][(int) HImode][1] = CODE_FOR_fixuns_trunctfhi2;
2586 #ifdef HAVE_fixuns_trunctfsi2
2587 if (HAVE_fixuns_trunctfsi2)
2588 fixtrunctab[(int) TFmode][(int) SImode][1] = CODE_FOR_fixuns_trunctfsi2;
2590 #ifdef HAVE_fixuns_trunctfdi2
2591 if (HAVE_fixuns_trunctfdi2)
2592 fixtrunctab[(int) TFmode][(int) DImode][1] = CODE_FOR_fixuns_trunctfdi2;
2594 #ifdef HAVE_fixuns_trunctfti2
2595 if (HAVE_fixuns_trunctfti2)
2596 fixtrunctab[(int) TFmode][(int) TImode][1] = CODE_FOR_fixuns_trunctfti2;
2599 #ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC
2600 /* This flag says the same insns that convert to a signed fixnum
2601 also convert validly to an unsigned one. */
2605 for (i = 0; i < NUM_MACHINE_MODES; i++)
2606 for (j = 0; j < NUM_MACHINE_MODES; j++)
2607 fixtrunctab[i][j][1] = fixtrunctab[i][j][0];
2616 for (p = floattab[0][0];
2617 p < floattab[0][0] + sizeof floattab / sizeof (floattab[0][0][0]);
2619 *p = CODE_FOR_nothing;
2621 #ifdef HAVE_floatqisf2
2622 if (HAVE_floatqisf2)
2623 floattab[(int) SFmode][(int) QImode][0] = CODE_FOR_floatqisf2;
2625 #ifdef HAVE_floathisf2
2626 if (HAVE_floathisf2)
2627 floattab[(int) SFmode][(int) HImode][0] = CODE_FOR_floathisf2;
2629 #ifdef HAVE_floatsisf2
2630 if (HAVE_floatsisf2)
2631 floattab[(int) SFmode][(int) SImode][0] = CODE_FOR_floatsisf2;
2633 #ifdef HAVE_floatdisf2
2634 if (HAVE_floatdisf2)
2635 floattab[(int) SFmode][(int) DImode][0] = CODE_FOR_floatdisf2;
2637 #ifdef HAVE_floattisf2
2638 if (HAVE_floattisf2)
2639 floattab[(int) SFmode][(int) TImode][0] = CODE_FOR_floattisf2;
2642 #ifdef HAVE_floatqidf2
2643 if (HAVE_floatqidf2)
2644 floattab[(int) DFmode][(int) QImode][0] = CODE_FOR_floatqidf2;
2646 #ifdef HAVE_floathidf2
2647 if (HAVE_floathidf2)
2648 floattab[(int) DFmode][(int) HImode][0] = CODE_FOR_floathidf2;
2650 #ifdef HAVE_floatsidf2
2651 if (HAVE_floatsidf2)
2652 floattab[(int) DFmode][(int) SImode][0] = CODE_FOR_floatsidf2;
2654 #ifdef HAVE_floatdidf2
2655 if (HAVE_floatdidf2)
2656 floattab[(int) DFmode][(int) DImode][0] = CODE_FOR_floatdidf2;
2658 #ifdef HAVE_floattidf2
2659 if (HAVE_floattidf2)
2660 floattab[(int) DFmode][(int) TImode][0] = CODE_FOR_floattidf2;
2663 #ifdef HAVE_floatqixf2
2664 if (HAVE_floatqixf2)
2665 floattab[(int) XFmode][(int) QImode][0] = CODE_FOR_floatqixf2;
2667 #ifdef HAVE_floathixf2
2668 if (HAVE_floathixf2)
2669 floattab[(int) XFmode][(int) HImode][0] = CODE_FOR_floathixf2;
2671 #ifdef HAVE_floatsixf2
2672 if (HAVE_floatsixf2)
2673 floattab[(int) XFmode][(int) SImode][0] = CODE_FOR_floatsixf2;
2675 #ifdef HAVE_floatdixf2
2676 if (HAVE_floatdixf2)
2677 floattab[(int) XFmode][(int) DImode][0] = CODE_FOR_floatdixf2;
2679 #ifdef HAVE_floattixf2
2680 if (HAVE_floattixf2)
2681 floattab[(int) XFmode][(int) TImode][0] = CODE_FOR_floattixf2;
2684 #ifdef HAVE_floatqitf2
2685 if (HAVE_floatqitf2)
2686 floattab[(int) TFmode][(int) QImode][0] = CODE_FOR_floatqitf2;
2688 #ifdef HAVE_floathitf2
2689 if (HAVE_floathitf2)
2690 floattab[(int) TFmode][(int) HImode][0] = CODE_FOR_floathitf2;
2692 #ifdef HAVE_floatsitf2
2693 if (HAVE_floatsitf2)
2694 floattab[(int) TFmode][(int) SImode][0] = CODE_FOR_floatsitf2;
2696 #ifdef HAVE_floatditf2
2697 if (HAVE_floatditf2)
2698 floattab[(int) TFmode][(int) DImode][0] = CODE_FOR_floatditf2;
2700 #ifdef HAVE_floattitf2
2701 if (HAVE_floattitf2)
2702 floattab[(int) TFmode][(int) TImode][0] = CODE_FOR_floattitf2;
2705 #ifdef HAVE_floatunsqisf2
2706 if (HAVE_floatunsqisf2)
2707 floattab[(int) SFmode][(int) QImode][1] = CODE_FOR_floatunsqisf2;
2709 #ifdef HAVE_floatunshisf2
2710 if (HAVE_floatunshisf2)
2711 floattab[(int) SFmode][(int) HImode][1] = CODE_FOR_floatunshisf2;
2713 #ifdef HAVE_floatunssisf2
2714 if (HAVE_floatunssisf2)
2715 floattab[(int) SFmode][(int) SImode][1] = CODE_FOR_floatunssisf2;
2717 #ifdef HAVE_floatunsdisf2
2718 if (HAVE_floatunsdisf2)
2719 floattab[(int) SFmode][(int) DImode][1] = CODE_FOR_floatunsdisf2;
2721 #ifdef HAVE_floatunstisf2
2722 if (HAVE_floatunstisf2)
2723 floattab[(int) SFmode][(int) TImode][1] = CODE_FOR_floatunstisf2;
2726 #ifdef HAVE_floatunsqidf2
2727 if (HAVE_floatunsqidf2)
2728 floattab[(int) DFmode][(int) QImode][1] = CODE_FOR_floatunsqidf2;
2730 #ifdef HAVE_floatunshidf2
2731 if (HAVE_floatunshidf2)
2732 floattab[(int) DFmode][(int) HImode][1] = CODE_FOR_floatunshidf2;
2734 #ifdef HAVE_floatunssidf2
2735 if (HAVE_floatunssidf2)
2736 floattab[(int) DFmode][(int) SImode][1] = CODE_FOR_floatunssidf2;
2738 #ifdef HAVE_floatunsdidf2
2739 if (HAVE_floatunsdidf2)
2740 floattab[(int) DFmode][(int) DImode][1] = CODE_FOR_floatunsdidf2;
2742 #ifdef HAVE_floatunstidf2
2743 if (HAVE_floatunstidf2)
2744 floattab[(int) DFmode][(int) TImode][1] = CODE_FOR_floatunstidf2;
2747 #ifdef HAVE_floatunsqixf2
2748 if (HAVE_floatunsqixf2)
2749 floattab[(int) XFmode][(int) QImode][1] = CODE_FOR_floatunsqixf2;
2751 #ifdef HAVE_floatunshixf2
2752 if (HAVE_floatunshixf2)
2753 floattab[(int) XFmode][(int) HImode][1] = CODE_FOR_floatunshixf2;
2755 #ifdef HAVE_floatunssixf2
2756 if (HAVE_floatunssixf2)
2757 floattab[(int) XFmode][(int) SImode][1] = CODE_FOR_floatunssixf2;
2759 #ifdef HAVE_floatunsdixf2
2760 if (HAVE_floatunsdixf2)
2761 floattab[(int) XFmode][(int) DImode][1] = CODE_FOR_floatunsdixf2;
2763 #ifdef HAVE_floatunstixf2
2764 if (HAVE_floatunstixf2)
2765 floattab[(int) XFmode][(int) TImode][1] = CODE_FOR_floatunstixf2;
2768 #ifdef HAVE_floatunsqitf2
2769 if (HAVE_floatunsqitf2)
2770 floattab[(int) TFmode][(int) QImode][1] = CODE_FOR_floatunsqitf2;
2772 #ifdef HAVE_floatunshitf2
2773 if (HAVE_floatunshitf2)
2774 floattab[(int) TFmode][(int) HImode][1] = CODE_FOR_floatunshitf2;
2776 #ifdef HAVE_floatunssitf2
2777 if (HAVE_floatunssitf2)
2778 floattab[(int) TFmode][(int) SImode][1] = CODE_FOR_floatunssitf2;
2780 #ifdef HAVE_floatunsditf2
2781 if (HAVE_floatunsditf2)
2782 floattab[(int) TFmode][(int) DImode][1] = CODE_FOR_floatunsditf2;
2784 #ifdef HAVE_floatunstitf2
2785 if (HAVE_floatunstitf2)
2786 floattab[(int) TFmode][(int) TImode][1] = CODE_FOR_floatunstitf2;
2790 /* Generate code to convert FROM to floating point
2791 and store in TO. FROM must be fixed point and not VOIDmode.
2792 UNSIGNEDP nonzero means regard FROM as unsigned.
2793 Normally this is done by correcting the final value
2794 if it is negative. */
2797 expand_float (to, from, unsignedp)
2801 enum insn_code icode;
2802 register rtx target = to;
2803 enum machine_mode fmode, imode;
2805 /* Crash now, because we won't be able to decide which mode to use. */
2806 if (GET_MODE (from) == VOIDmode)
2809 /* Look for an insn to do the conversion. Do it in the specified
2810 modes if possible; otherwise convert either input, output or both to
2811 wider mode. If the integer mode is wider than the mode of FROM,
2812 we can do the conversion signed even if the input is unsigned. */
2814 for (imode = GET_MODE (from); imode != VOIDmode;
2815 imode = GET_MODE_WIDER_MODE (imode))
2816 for (fmode = GET_MODE (to); fmode != VOIDmode;
2817 fmode = GET_MODE_WIDER_MODE (fmode))
2819 int doing_unsigned = unsignedp;
2821 icode = can_float_p (fmode, imode, unsignedp);
2822 if (icode == CODE_FOR_nothing && imode != GET_MODE (from) && unsignedp)
2823 icode = can_float_p (fmode, imode, 0), doing_unsigned = 0;
2825 if (icode != CODE_FOR_nothing)
2827 to = protect_from_queue (to, 1);
2828 from = protect_from_queue (from, 0);
2830 if (imode != GET_MODE (from))
2831 from = convert_to_mode (imode, from, unsignedp);
2833 if (fmode != GET_MODE (to))
2834 target = gen_reg_rtx (fmode);
2836 emit_unop_insn (icode, target, from,
2837 doing_unsigned ? UNSIGNED_FLOAT : FLOAT);
2840 convert_move (to, target, 0);
2845 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
2847 /* Unsigned integer, and no way to convert directly.
2848 Convert as signed, then conditionally adjust the result. */
2851 rtx label = gen_label_rtx ();
2853 REAL_VALUE_TYPE offset;
2857 to = protect_from_queue (to, 1);
2858 from = protect_from_queue (from, 0);
2861 from = force_not_mem (from);
2863 /* If we are about to do some arithmetic to correct for an
2864 unsigned operand, do it in a pseudo-register. */
2866 if (GET_CODE (to) != REG || REGNO (to) <= LAST_VIRTUAL_REGISTER)
2867 target = gen_reg_rtx (GET_MODE (to));
2869 /* Convert as signed integer to floating. */
2870 expand_float (target, from, 0);
2872 /* If FROM is negative (and therefore TO is negative),
2873 correct its value by 2**bitwidth. */
2875 do_pending_stack_adjust ();
2876 emit_cmp_insn (from, const0_rtx, GE, NULL_RTX, GET_MODE (from), 0, 0);
2877 emit_jump_insn (gen_bge (label));
2878 /* On SCO 3.2.1, ldexp rejects values outside [0.5, 1).
2879 Rather than setting up a dconst_dot_5, let's hope SCO
2881 offset = REAL_VALUE_LDEXP (dconst1, GET_MODE_BITSIZE (GET_MODE (from)));
2882 temp = expand_binop (GET_MODE (to), add_optab, target,
2883 immed_real_const_1 (offset, GET_MODE (to)),
2884 target, 0, OPTAB_LIB_WIDEN);
2886 emit_move_insn (target, temp);
2887 do_pending_stack_adjust ();
2893 /* No hardware instruction available; call a library rotine to convert from
2894 SImode, DImode, or TImode into SFmode, DFmode, XFmode, or TFmode. */
2899 to = protect_from_queue (to, 1);
2900 from = protect_from_queue (from, 0);
2902 if (GET_MODE_SIZE (GET_MODE (from)) < GET_MODE_SIZE (SImode))
2903 from = convert_to_mode (SImode, from, unsignedp);
2906 from = force_not_mem (from);
2908 if (GET_MODE (to) == SFmode)
2910 if (GET_MODE (from) == SImode)
2911 libfcn = floatsisf_libfunc;
2912 else if (GET_MODE (from) == DImode)
2913 libfcn = floatdisf_libfunc;
2914 else if (GET_MODE (from) == TImode)
2915 libfcn = floattisf_libfunc;
2919 else if (GET_MODE (to) == DFmode)
2921 if (GET_MODE (from) == SImode)
2922 libfcn = floatsidf_libfunc;
2923 else if (GET_MODE (from) == DImode)
2924 libfcn = floatdidf_libfunc;
2925 else if (GET_MODE (from) == TImode)
2926 libfcn = floattidf_libfunc;
2930 else if (GET_MODE (to) == XFmode)
2932 if (GET_MODE (from) == SImode)
2933 libfcn = floatsixf_libfunc;
2934 else if (GET_MODE (from) == DImode)
2935 libfcn = floatdixf_libfunc;
2936 else if (GET_MODE (from) == TImode)
2937 libfcn = floattixf_libfunc;
2941 else if (GET_MODE (to) == TFmode)
2943 if (GET_MODE (from) == SImode)
2944 libfcn = floatsitf_libfunc;
2945 else if (GET_MODE (from) == DImode)
2946 libfcn = floatditf_libfunc;
2947 else if (GET_MODE (from) == TImode)
2948 libfcn = floattitf_libfunc;
2957 emit_library_call (libfcn, 1, GET_MODE (to), 1, from, GET_MODE (from));
2958 insns = get_insns ();
2961 emit_libcall_block (insns, target, hard_libcall_value (GET_MODE (to)),
2962 gen_rtx (FLOAT, GET_MODE (to), from));
2965 /* Copy result to requested destination
2966 if we have been computing in a temp location. */
2970 if (GET_MODE (target) == GET_MODE (to))
2971 emit_move_insn (to, target);
2973 convert_move (to, target, 0);
2977 /* expand_fix: generate code to convert FROM to fixed point
2978 and store in TO. FROM must be floating point. */
2984 rtx temp = gen_reg_rtx (GET_MODE (x));
2985 return expand_unop (GET_MODE (x), ftrunc_optab, x, temp, 0);
2989 expand_fix (to, from, unsignedp)
2990 register rtx to, from;
2993 enum insn_code icode;
2994 register rtx target = to;
2995 enum machine_mode fmode, imode;
2999 /* We first try to find a pair of modes, one real and one integer, at
3000 least as wide as FROM and TO, respectively, in which we can open-code
3001 this conversion. If the integer mode is wider than the mode of TO,
3002 we can do the conversion either signed or unsigned. */
3004 for (imode = GET_MODE (to); imode != VOIDmode;
3005 imode = GET_MODE_WIDER_MODE (imode))
3006 for (fmode = GET_MODE (from); fmode != VOIDmode;
3007 fmode = GET_MODE_WIDER_MODE (fmode))
3009 int doing_unsigned = unsignedp;
3011 icode = can_fix_p (imode, fmode, unsignedp, &must_trunc);
3012 if (icode == CODE_FOR_nothing && imode != GET_MODE (to) && unsignedp)
3013 icode = can_fix_p (imode, fmode, 0, &must_trunc), doing_unsigned = 0;
3015 if (icode != CODE_FOR_nothing)
3017 to = protect_from_queue (to, 1);
3018 from = protect_from_queue (from, 0);
3020 if (fmode != GET_MODE (from))
3021 from = convert_to_mode (fmode, from, 0);
3024 from = ftruncify (from);
3026 if (imode != GET_MODE (to))
3027 target = gen_reg_rtx (imode);
3029 emit_unop_insn (icode, target, from,
3030 doing_unsigned ? UNSIGNED_FIX : FIX);
3032 convert_move (to, target, unsignedp);
3037 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
3038 /* For an unsigned conversion, there is one more way to do it.
3039 If we have a signed conversion, we generate code that compares
3040 the real value to the largest representable positive number. If if
3041 is smaller, the conversion is done normally. Otherwise, subtract
3042 one plus the highest signed number, convert, and add it back.
3044 We only need to check all real modes, since we know we didn't find
3045 anything with a wider integer mode. */
3047 if (unsignedp && GET_MODE_BITSIZE (GET_MODE (to)) <= HOST_BITS_PER_WIDE_INT)
3048 for (fmode = GET_MODE (from); fmode != VOIDmode;
3049 fmode = GET_MODE_WIDER_MODE (fmode))
3050 /* Make sure we won't lose significant bits doing this. */
3051 if (GET_MODE_BITSIZE (fmode) > GET_MODE_BITSIZE (GET_MODE (to))
3052 && CODE_FOR_nothing != can_fix_p (GET_MODE (to), fmode, 0,
3055 int bitsize = GET_MODE_BITSIZE (GET_MODE (to));
3056 REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (dconst1, bitsize - 1);
3057 rtx limit = immed_real_const_1 (offset, fmode);
3058 rtx lab1 = gen_label_rtx ();
3059 rtx lab2 = gen_label_rtx ();
3063 to = protect_from_queue (to, 1);
3064 from = protect_from_queue (from, 0);
3067 from = force_not_mem (from);
3069 if (fmode != GET_MODE (from))
3070 from = convert_to_mode (fmode, from, 0);
3072 /* See if we need to do the subtraction. */
3073 do_pending_stack_adjust ();
3074 emit_cmp_insn (from, limit, GE, NULL_RTX, GET_MODE (from), 0, 0);
3075 emit_jump_insn (gen_bge (lab1));
3077 /* If not, do the signed "fix" and branch around fixup code. */
3078 expand_fix (to, from, 0);
3079 emit_jump_insn (gen_jump (lab2));
3082 /* Otherwise, subtract 2**(N-1), convert to signed number,
3083 then add 2**(N-1). Do the addition using XOR since this
3084 will often generate better code. */
3086 target = expand_binop (GET_MODE (from), sub_optab, from, limit,
3087 NULL_RTX, 0, OPTAB_LIB_WIDEN);
3088 expand_fix (to, target, 0);
3089 target = expand_binop (GET_MODE (to), xor_optab, to,
3090 GEN_INT ((HOST_WIDE_INT) 1 << (bitsize - 1)),
3091 to, 1, OPTAB_LIB_WIDEN);
3094 emit_move_insn (to, target);
3098 /* Make a place for a REG_NOTE and add it. */
3099 insn = emit_move_insn (to, to);
3100 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL,
3101 gen_rtx (UNSIGNED_FIX, GET_MODE (to),
3102 from), REG_NOTES (insn));
3108 /* We can't do it with an insn, so use a library call. But first ensure
3109 that the mode of TO is at least as wide as SImode, since those are the
3110 only library calls we know about. */
3112 if (GET_MODE_SIZE (GET_MODE (to)) < GET_MODE_SIZE (SImode))
3114 target = gen_reg_rtx (SImode);
3116 expand_fix (target, from, unsignedp);
3118 else if (GET_MODE (from) == SFmode)
3120 if (GET_MODE (to) == SImode)
3121 libfcn = unsignedp ? fixunssfsi_libfunc : fixsfsi_libfunc;
3122 else if (GET_MODE (to) == DImode)
3123 libfcn = unsignedp ? fixunssfdi_libfunc : fixsfdi_libfunc;
3124 else if (GET_MODE (to) == TImode)
3125 libfcn = unsignedp ? fixunssfti_libfunc : fixsfti_libfunc;
3129 else if (GET_MODE (from) == DFmode)
3131 if (GET_MODE (to) == SImode)
3132 libfcn = unsignedp ? fixunsdfsi_libfunc : fixdfsi_libfunc;
3133 else if (GET_MODE (to) == DImode)
3134 libfcn = unsignedp ? fixunsdfdi_libfunc : fixdfdi_libfunc;
3135 else if (GET_MODE (to) == TImode)
3136 libfcn = unsignedp ? fixunsdfti_libfunc : fixdfti_libfunc;
3140 else if (GET_MODE (from) == XFmode)
3142 if (GET_MODE (to) == SImode)
3143 libfcn = unsignedp ? fixunsxfsi_libfunc : fixxfsi_libfunc;
3144 else if (GET_MODE (to) == DImode)
3145 libfcn = unsignedp ? fixunsxfdi_libfunc : fixxfdi_libfunc;
3146 else if (GET_MODE (to) == TImode)
3147 libfcn = unsignedp ? fixunsxfti_libfunc : fixxfti_libfunc;
3151 else if (GET_MODE (from) == TFmode)
3153 if (GET_MODE (to) == SImode)
3154 libfcn = unsignedp ? fixunstfsi_libfunc : fixtfsi_libfunc;
3155 else if (GET_MODE (to) == DImode)
3156 libfcn = unsignedp ? fixunstfdi_libfunc : fixtfdi_libfunc;
3157 else if (GET_MODE (to) == TImode)
3158 libfcn = unsignedp ? fixunstfti_libfunc : fixtfti_libfunc;
3169 to = protect_from_queue (to, 1);
3170 from = protect_from_queue (from, 0);
3173 from = force_not_mem (from);
3177 emit_library_call (libfcn, 1, GET_MODE (to), 1, from, GET_MODE (from));
3178 insns = get_insns ();
3181 emit_libcall_block (insns, target, hard_libcall_value (GET_MODE (to)),
3182 gen_rtx (unsignedp ? FIX : UNSIGNED_FIX,
3183 GET_MODE (to), from));
3186 if (GET_MODE (to) == GET_MODE (target))
3187 emit_move_insn (to, target);
3189 convert_move (to, target, 0);
3197 optab op = (optab) xmalloc (sizeof (struct optab));
3199 for (i = 0; i < NUM_MACHINE_MODES; i++)
3201 op->handlers[i].insn_code = CODE_FOR_nothing;
3202 op->handlers[i].libfunc = 0;
3207 /* Initialize the libfunc fields of an entire group of entries in some
3208 optab. Each entry is set equal to a string consisting of a leading
3209 pair of underscores followed by a generic operation name followed by
3210 a mode name (downshifted to lower case) followed by a single character
3211 representing the number of operands for the given operation (which is
3212 usually one of the characters '2', '3', or '4').
3214 OPTABLE is the table in which libfunc fields are to be initialized.
3215 FIRST_MODE is the first machine mode index in the given optab to
3217 LAST_MODE is the last machine mode index in the given optab to
3219 OPNAME is the generic (string) name of the operation.
3220 SUFFIX is the character which specifies the number of operands for
3221 the given generic operation.
3225 init_libfuncs (optable, first_mode, last_mode, opname, suffix)
3226 register optab optable;
3227 register char *opname;
3228 register enum machine_mode first_mode;
3229 register enum machine_mode last_mode;
3230 register char suffix;
3232 register enum machine_mode mode;
3233 register unsigned opname_len = strlen (opname);
3235 for (mode = first_mode; mode <= last_mode; mode++)
3237 register char *mname = mode_name[(int) mode];
3238 register unsigned mname_len = strlen (mname);
3239 register char *libfunc_name
3240 = (char *) xmalloc (2 + opname_len + mname_len + 1 + 1);
3247 for (q = opname; *q; )
3249 for (q = mname; *q; q++)
3250 *p++ = tolower (*q);
3253 optable->handlers[(int) mode].libfunc
3254 = gen_rtx (SYMBOL_REF, Pmode, libfunc_name);
3258 /* Initialize the libfunc fields of an entire group of entries in some
3259 optab which correspond to all integer mode operations. The parameters
3260 have the same meaning as similarly named ones for the `init_libfuncs'
3261 routine. (See above). */
3264 init_integral_libfuncs (optable, opname, suffix)
3265 register optab optable;
3266 register char *opname;
3267 register char suffix;
3269 init_libfuncs (optable, SImode, TImode, opname, suffix);
3272 /* Initialize the libfunc fields of an entire group of entries in some
3273 optab which correspond to all real mode operations. The parameters
3274 have the same meaning as similarly named ones for the `init_libfuncs'
3275 routine. (See above). */
3278 init_floating_libfuncs (optable, opname, suffix)
3279 register optab optable;
3280 register char *opname;
3281 register char suffix;
3283 init_libfuncs (optable, SFmode, TFmode, opname, suffix);
3286 /* Call this once to initialize the contents of the optabs
3287 appropriately for the current target machine. */
3298 add_optab = init_optab (PLUS);
3299 sub_optab = init_optab (MINUS);
3300 smul_optab = init_optab (MULT);
3301 smul_widen_optab = init_optab (UNKNOWN);
3302 umul_widen_optab = init_optab (UNKNOWN);
3303 sdiv_optab = init_optab (DIV);
3304 sdivmod_optab = init_optab (UNKNOWN);
3305 udiv_optab = init_optab (UDIV);
3306 udivmod_optab = init_optab (UNKNOWN);
3307 smod_optab = init_optab (MOD);
3308 umod_optab = init_optab (UMOD);
3309 flodiv_optab = init_optab (DIV);
3310 ftrunc_optab = init_optab (UNKNOWN);
3311 and_optab = init_optab (AND);
3312 ior_optab = init_optab (IOR);
3313 xor_optab = init_optab (XOR);
3314 ashl_optab = init_optab (ASHIFT);
3315 ashr_optab = init_optab (ASHIFTRT);
3316 lshl_optab = init_optab (LSHIFT);
3317 lshr_optab = init_optab (LSHIFTRT);
3318 rotl_optab = init_optab (ROTATE);
3319 rotr_optab = init_optab (ROTATERT);
3320 smin_optab = init_optab (SMIN);
3321 smax_optab = init_optab (SMAX);
3322 umin_optab = init_optab (UMIN);
3323 umax_optab = init_optab (UMAX);
3324 mov_optab = init_optab (UNKNOWN);
3325 movstrict_optab = init_optab (UNKNOWN);
3326 cmp_optab = init_optab (UNKNOWN);
3327 ucmp_optab = init_optab (UNKNOWN);
3328 tst_optab = init_optab (UNKNOWN);
3329 neg_optab = init_optab (NEG);
3330 abs_optab = init_optab (ABS);
3331 one_cmpl_optab = init_optab (NOT);
3332 ffs_optab = init_optab (FFS);
3333 sqrt_optab = init_optab (SQRT);
3334 strlen_optab = init_optab (UNKNOWN);
3338 add_optab->handlers[(int) QImode].insn_code = CODE_FOR_addqi3;
3342 add_optab->handlers[(int) HImode].insn_code = CODE_FOR_addhi3;
3346 add_optab->handlers[(int) PSImode].insn_code = CODE_FOR_addpsi3;
3350 add_optab->handlers[(int) SImode].insn_code = CODE_FOR_addsi3;
3354 add_optab->handlers[(int) DImode].insn_code = CODE_FOR_adddi3;
3358 add_optab->handlers[(int) TImode].insn_code = CODE_FOR_addti3;
3362 add_optab->handlers[(int) SFmode].insn_code = CODE_FOR_addsf3;
3366 add_optab->handlers[(int) DFmode].insn_code = CODE_FOR_adddf3;
3370 add_optab->handlers[(int) XFmode].insn_code = CODE_FOR_addxf3;
3374 add_optab->handlers[(int) TFmode].insn_code = CODE_FOR_addtf3;
3376 init_integral_libfuncs (add_optab, "add", '3');
3377 init_floating_libfuncs (add_optab, "add", '3');
3381 sub_optab->handlers[(int) QImode].insn_code = CODE_FOR_subqi3;
3385 sub_optab->handlers[(int) HImode].insn_code = CODE_FOR_subhi3;
3389 sub_optab->handlers[(int) PSImode].insn_code = CODE_FOR_subpsi3;
3393 sub_optab->handlers[(int) SImode].insn_code = CODE_FOR_subsi3;
3397 sub_optab->handlers[(int) DImode].insn_code = CODE_FOR_subdi3;
3401 sub_optab->handlers[(int) TImode].insn_code = CODE_FOR_subti3;
3405 sub_optab->handlers[(int) SFmode].insn_code = CODE_FOR_subsf3;
3409 sub_optab->handlers[(int) DFmode].insn_code = CODE_FOR_subdf3;
3413 sub_optab->handlers[(int) XFmode].insn_code = CODE_FOR_subxf3;
3417 sub_optab->handlers[(int) TFmode].insn_code = CODE_FOR_subtf3;
3419 init_integral_libfuncs (sub_optab, "sub", '3');
3420 init_floating_libfuncs (sub_optab, "sub", '3');
3424 smul_optab->handlers[(int) QImode].insn_code = CODE_FOR_mulqi3;
3428 smul_optab->handlers[(int) HImode].insn_code = CODE_FOR_mulhi3;
3432 smul_optab->handlers[(int) PSImode].insn_code = CODE_FOR_mulpsi3;
3436 smul_optab->handlers[(int) SImode].insn_code = CODE_FOR_mulsi3;
3440 smul_optab->handlers[(int) DImode].insn_code = CODE_FOR_muldi3;
3444 smul_optab->handlers[(int) TImode].insn_code = CODE_FOR_multi3;
3448 smul_optab->handlers[(int) SFmode].insn_code = CODE_FOR_mulsf3;
3452 smul_optab->handlers[(int) DFmode].insn_code = CODE_FOR_muldf3;
3456 smul_optab->handlers[(int) XFmode].insn_code = CODE_FOR_mulxf3;
3460 smul_optab->handlers[(int) TFmode].insn_code = CODE_FOR_multf3;
3462 init_integral_libfuncs (smul_optab, "mul", '3');
3463 init_floating_libfuncs (smul_optab, "mul", '3');
3465 #ifdef MULSI3_LIBCALL
3466 smul_optab->handlers[(int) SImode].libfunc
3467 = gen_rtx (SYMBOL_REF, Pmode, MULSI3_LIBCALL);
3469 #ifdef MULDI3_LIBCALL
3470 smul_optab->handlers[(int) DImode].libfunc
3471 = gen_rtx (SYMBOL_REF, Pmode, MULDI3_LIBCALL);
3473 #ifdef MULTI3_LIBCALL
3474 smul_optab->handlers[(int) TImode].libfunc
3475 = gen_rtx (SYMBOL_REF, Pmode, MULTI3_LIBCALL);
3478 #ifdef HAVE_mulqihi3
3480 smul_widen_optab->handlers[(int) HImode].insn_code = CODE_FOR_mulqihi3;
3482 #ifdef HAVE_mulhisi3
3484 smul_widen_optab->handlers[(int) SImode].insn_code = CODE_FOR_mulhisi3;
3486 #ifdef HAVE_mulsidi3
3488 smul_widen_optab->handlers[(int) DImode].insn_code = CODE_FOR_mulsidi3;
3490 #ifdef HAVE_mulditi3
3492 smul_widen_optab->handlers[(int) TImode].insn_code = CODE_FOR_mulditi3;
3495 #ifdef HAVE_umulqihi3
3497 umul_widen_optab->handlers[(int) HImode].insn_code = CODE_FOR_umulqihi3;
3499 #ifdef HAVE_umulhisi3
3501 umul_widen_optab->handlers[(int) SImode].insn_code = CODE_FOR_umulhisi3;
3503 #ifdef HAVE_umulsidi3
3505 umul_widen_optab->handlers[(int) DImode].insn_code = CODE_FOR_umulsidi3;
3507 #ifdef HAVE_umulditi3
3509 umul_widen_optab->handlers[(int) TImode].insn_code = CODE_FOR_umulditi3;
3514 sdiv_optab->handlers[(int) QImode].insn_code = CODE_FOR_divqi3;
3518 sdiv_optab->handlers[(int) HImode].insn_code = CODE_FOR_divhi3;
3522 sdiv_optab->handlers[(int) PSImode].insn_code = CODE_FOR_divpsi3;
3526 sdiv_optab->handlers[(int) SImode].insn_code = CODE_FOR_divsi3;
3530 sdiv_optab->handlers[(int) DImode].insn_code = CODE_FOR_divdi3;
3534 sdiv_optab->handlers[(int) TImode].insn_code = CODE_FOR_divti3;
3536 init_integral_libfuncs (sdiv_optab, "div", '3');
3538 #ifdef DIVSI3_LIBCALL
3539 sdiv_optab->handlers[(int) SImode].libfunc
3540 = gen_rtx (SYMBOL_REF, Pmode, DIVSI3_LIBCALL);
3542 #ifdef DIVDI3_LIBCALL
3543 sdiv_optab->handlers[(int) DImode].libfunc
3544 = gen_rtx (SYMBOL_REF, Pmode, DIVDI3_LIBCALL);
3546 #ifdef DIVTI3_LIBCALL
3547 sdiv_optab->handlers[(int) TImode].libfunc
3548 = gen_rtx (SYMBOL_REF, Pmode, DIVTI3_LIBCALL);
3553 udiv_optab->handlers[(int) QImode].insn_code = CODE_FOR_udivqi3;
3557 udiv_optab->handlers[(int) HImode].insn_code = CODE_FOR_udivhi3;
3559 #ifdef HAVE_udivpsi3
3561 udiv_optab->handlers[(int) PSImode].insn_code = CODE_FOR_udivpsi3;
3565 udiv_optab->handlers[(int) SImode].insn_code = CODE_FOR_udivsi3;
3569 udiv_optab->handlers[(int) DImode].insn_code = CODE_FOR_udivdi3;
3573 udiv_optab->handlers[(int) TImode].insn_code = CODE_FOR_udivti3;
3575 init_integral_libfuncs (udiv_optab, "udiv", '3');
3577 #ifdef UDIVSI3_LIBCALL
3578 udiv_optab->handlers[(int) SImode].libfunc
3579 = gen_rtx (SYMBOL_REF, Pmode, UDIVSI3_LIBCALL);
3581 #ifdef UDIVDI3_LIBCALL
3582 udiv_optab->handlers[(int) DImode].libfunc
3583 = gen_rtx (SYMBOL_REF, Pmode, UDIVDI3_LIBCALL);
3585 #ifdef UDIVTI3_LIBCALL
3586 udiv_optab->handlers[(int) TImode].libfunc
3587 = gen_rtx (SYMBOL_REF, Pmode, UDIVTI3_LIBCALL);
3590 #ifdef HAVE_divmodqi4
3592 sdivmod_optab->handlers[(int) QImode].insn_code = CODE_FOR_divmodqi4;
3594 #ifdef HAVE_divmodhi4
3596 sdivmod_optab->handlers[(int) HImode].insn_code = CODE_FOR_divmodhi4;
3598 #ifdef HAVE_divmodsi4
3600 sdivmod_optab->handlers[(int) SImode].insn_code = CODE_FOR_divmodsi4;
3602 #ifdef HAVE_divmoddi4
3604 sdivmod_optab->handlers[(int) DImode].insn_code = CODE_FOR_divmoddi4;
3606 #ifdef HAVE_divmodti4
3608 sdivmod_optab->handlers[(int) TImode].insn_code = CODE_FOR_divmodti4;
3610 init_integral_libfuncs (sdivmod_optab, "divmod", '4');
3612 #ifdef HAVE_udivmodqi4
3613 if (HAVE_udivmodqi4)
3614 udivmod_optab->handlers[(int) QImode].insn_code = CODE_FOR_udivmodqi4;
3616 #ifdef HAVE_udivmodhi4
3617 if (HAVE_udivmodhi4)
3618 udivmod_optab->handlers[(int) HImode].insn_code = CODE_FOR_udivmodhi4;
3620 #ifdef HAVE_udivmodsi4
3621 if (HAVE_udivmodsi4)
3622 udivmod_optab->handlers[(int) SImode].insn_code = CODE_FOR_udivmodsi4;
3624 #ifdef HAVE_udivmoddi4
3625 if (HAVE_udivmoddi4)
3626 udivmod_optab->handlers[(int) DImode].insn_code = CODE_FOR_udivmoddi4;
3628 #ifdef HAVE_udivmodti4
3629 if (HAVE_udivmodti4)
3630 udivmod_optab->handlers[(int) TImode].insn_code = CODE_FOR_udivmodti4;
3632 init_integral_libfuncs (udivmod_optab, "udivmod", '4');
3636 smod_optab->handlers[(int) QImode].insn_code = CODE_FOR_modqi3;
3640 smod_optab->handlers[(int) HImode].insn_code = CODE_FOR_modhi3;
3644 smod_optab->handlers[(int) PSImode].insn_code = CODE_FOR_modpsi3;
3648 smod_optab->handlers[(int) SImode].insn_code = CODE_FOR_modsi3;
3652 smod_optab->handlers[(int) DImode].insn_code = CODE_FOR_moddi3;
3656 smod_optab->handlers[(int) TImode].insn_code = CODE_FOR_modti3;
3658 init_integral_libfuncs (smod_optab, "mod", '3');
3660 #ifdef MODSI3_LIBCALL
3661 smod_optab->handlers[(int) SImode].libfunc
3662 = gen_rtx (SYMBOL_REF, Pmode, MODSI3_LIBCALL);
3664 #ifdef MODDI3_LIBCALL
3665 smod_optab->handlers[(int) DImode].libfunc
3666 = gen_rtx (SYMBOL_REF, Pmode, MODDI3_LIBCALL);
3668 #ifdef MODTI3_LIBCALL
3669 smod_optab->handlers[(int) TImode].libfunc
3670 = gen_rtx (SYMBOL_REF, Pmode, MODTI3_LIBCALL);
3675 umod_optab->handlers[(int) QImode].insn_code = CODE_FOR_umodqi3;
3679 umod_optab->handlers[(int) HImode].insn_code = CODE_FOR_umodhi3;
3681 #ifdef HAVE_umodpsi3
3683 umod_optab->handlers[(int) PSImode].insn_code = CODE_FOR_umodpsi3;
3687 umod_optab->handlers[(int) SImode].insn_code = CODE_FOR_umodsi3;
3691 umod_optab->handlers[(int) DImode].insn_code = CODE_FOR_umoddi3;
3695 umod_optab->handlers[(int) TImode].insn_code = CODE_FOR_umodti3;
3697 init_integral_libfuncs (umod_optab, "umod", '3');
3699 #ifdef UMODSI3_LIBCALL
3700 umod_optab->handlers[(int) SImode].libfunc
3701 = gen_rtx (SYMBOL_REF, Pmode, UMODSI3_LIBCALL);
3703 #ifdef UMODDI3_LIBCALL
3704 umod_optab->handlers[(int) DImode].libfunc
3705 = gen_rtx (SYMBOL_REF, Pmode, UMODDI3_LIBCALL);
3707 #ifdef UMODTI3_LIBCALL
3708 umod_optab->handlers[(int) TImode].libfunc
3709 = gen_rtx (SYMBOL_REF, Pmode, UMODTI3_LIBCALL);
3714 flodiv_optab->handlers[(int) SFmode].insn_code = CODE_FOR_divsf3;
3718 flodiv_optab->handlers[(int) DFmode].insn_code = CODE_FOR_divdf3;
3722 flodiv_optab->handlers[(int) XFmode].insn_code = CODE_FOR_divxf3;
3726 flodiv_optab->handlers[(int) TFmode].insn_code = CODE_FOR_divtf3;
3728 init_floating_libfuncs (flodiv_optab, "div", '3');
3730 #ifdef HAVE_ftruncsf2
3732 ftrunc_optab->handlers[(int) SFmode].insn_code = CODE_FOR_ftruncsf2;
3734 #ifdef HAVE_ftruncdf2
3736 ftrunc_optab->handlers[(int) DFmode].insn_code = CODE_FOR_ftruncdf2;
3738 #ifdef HAVE_ftruncxf2
3740 ftrunc_optab->handlers[(int) XFmode].insn_code = CODE_FOR_ftruncxf2;
3742 #ifdef HAVE_ftrunctf2
3744 ftrunc_optab->handlers[(int) TFmode].insn_code = CODE_FOR_ftrunctf2;
3746 init_floating_libfuncs (ftrunc_optab, "ftrunc", '2');
3750 and_optab->handlers[(int) QImode].insn_code = CODE_FOR_andqi3;
3754 and_optab->handlers[(int) HImode].insn_code = CODE_FOR_andhi3;
3758 and_optab->handlers[(int) PSImode].insn_code = CODE_FOR_andpsi3;
3762 and_optab->handlers[(int) SImode].insn_code = CODE_FOR_andsi3;
3766 and_optab->handlers[(int) DImode].insn_code = CODE_FOR_anddi3;
3770 and_optab->handlers[(int) TImode].insn_code = CODE_FOR_andti3;
3772 init_integral_libfuncs (and_optab, "and", '3');
3776 ior_optab->handlers[(int) QImode].insn_code = CODE_FOR_iorqi3;
3780 ior_optab->handlers[(int) HImode].insn_code = CODE_FOR_iorhi3;
3784 ior_optab->handlers[(int) PSImode].insn_code = CODE_FOR_iorpsi3;
3788 ior_optab->handlers[(int) SImode].insn_code = CODE_FOR_iorsi3;
3792 ior_optab->handlers[(int) DImode].insn_code = CODE_FOR_iordi3;
3796 ior_optab->handlers[(int) TImode].insn_code = CODE_FOR_iorti3;
3798 init_integral_libfuncs (ior_optab, "ior", '3');
3802 xor_optab->handlers[(int) QImode].insn_code = CODE_FOR_xorqi3;
3806 xor_optab->handlers[(int) HImode].insn_code = CODE_FOR_xorhi3;
3810 xor_optab->handlers[(int) PSImode].insn_code = CODE_FOR_xorpsi3;
3814 xor_optab->handlers[(int) SImode].insn_code = CODE_FOR_xorsi3;
3818 xor_optab->handlers[(int) DImode].insn_code = CODE_FOR_xordi3;
3822 xor_optab->handlers[(int) TImode].insn_code = CODE_FOR_xorti3;
3824 init_integral_libfuncs (xor_optab, "xor", '3');
3828 ashl_optab->handlers[(int) QImode].insn_code = CODE_FOR_ashlqi3;
3832 ashl_optab->handlers[(int) HImode].insn_code = CODE_FOR_ashlhi3;
3834 #ifdef HAVE_ashlpsi3
3836 ashl_optab->handlers[(int) PSImode].insn_code = CODE_FOR_ashlpsi3;
3840 ashl_optab->handlers[(int) SImode].insn_code = CODE_FOR_ashlsi3;
3844 ashl_optab->handlers[(int) DImode].insn_code = CODE_FOR_ashldi3;
3848 ashl_optab->handlers[(int) TImode].insn_code = CODE_FOR_ashlti3;
3850 init_integral_libfuncs (ashl_optab, "ashl", '3');
3854 ashr_optab->handlers[(int) QImode].insn_code = CODE_FOR_ashrqi3;
3858 ashr_optab->handlers[(int) HImode].insn_code = CODE_FOR_ashrhi3;
3860 #ifdef HAVE_ashrpsi3
3862 ashr_optab->handlers[(int) PSImode].insn_code = CODE_FOR_ashrpsi3;
3866 ashr_optab->handlers[(int) SImode].insn_code = CODE_FOR_ashrsi3;
3870 ashr_optab->handlers[(int) DImode].insn_code = CODE_FOR_ashrdi3;
3874 ashr_optab->handlers[(int) TImode].insn_code = CODE_FOR_ashrti3;
3876 init_integral_libfuncs (ashr_optab, "ashr", '3');
3880 lshl_optab->handlers[(int) QImode].insn_code = CODE_FOR_lshlqi3;
3884 lshl_optab->handlers[(int) HImode].insn_code = CODE_FOR_lshlhi3;
3886 #ifdef HAVE_lshlpsi3
3888 lshl_optab->handlers[(int) PSImode].insn_code = CODE_FOR_lshlpsi3;
3892 lshl_optab->handlers[(int) SImode].insn_code = CODE_FOR_lshlsi3;
3896 lshl_optab->handlers[(int) DImode].insn_code = CODE_FOR_lshldi3;
3900 lshl_optab->handlers[(int) TImode].insn_code = CODE_FOR_lshlti3;
3902 init_integral_libfuncs (lshl_optab, "lshl", '3');
3906 lshr_optab->handlers[(int) QImode].insn_code = CODE_FOR_lshrqi3;
3910 lshr_optab->handlers[(int) HImode].insn_code = CODE_FOR_lshrhi3;
3912 #ifdef HAVE_lshrpsi3
3914 lshr_optab->handlers[(int) PSImode].insn_code = CODE_FOR_lshrpsi3;
3918 lshr_optab->handlers[(int) SImode].insn_code = CODE_FOR_lshrsi3;
3922 lshr_optab->handlers[(int) DImode].insn_code = CODE_FOR_lshrdi3;
3926 lshr_optab->handlers[(int) TImode].insn_code = CODE_FOR_lshrti3;
3928 init_integral_libfuncs (lshr_optab, "lshr", '3');
3932 rotl_optab->handlers[(int) QImode].insn_code = CODE_FOR_rotlqi3;
3936 rotl_optab->handlers[(int) HImode].insn_code = CODE_FOR_rotlhi3;
3938 #ifdef HAVE_rotlpsi3
3940 rotl_optab->handlers[(int) PSImode].insn_code = CODE_FOR_rotlpsi3;
3944 rotl_optab->handlers[(int) SImode].insn_code = CODE_FOR_rotlsi3;
3948 rotl_optab->handlers[(int) DImode].insn_code = CODE_FOR_rotldi3;
3952 rotl_optab->handlers[(int) TImode].insn_code = CODE_FOR_rotlti3;
3954 init_integral_libfuncs (rotl_optab, "rotl", '3');
3958 rotr_optab->handlers[(int) QImode].insn_code = CODE_FOR_rotrqi3;
3962 rotr_optab->handlers[(int) HImode].insn_code = CODE_FOR_rotrhi3;
3964 #ifdef HAVE_rotrpsi3
3966 rotr_optab->handlers[(int) PSImode].insn_code = CODE_FOR_rotrpsi3;
3970 rotr_optab->handlers[(int) SImode].insn_code = CODE_FOR_rotrsi3;
3974 rotr_optab->handlers[(int) DImode].insn_code = CODE_FOR_rotrdi3;
3978 rotr_optab->handlers[(int) TImode].insn_code = CODE_FOR_rotrti3;
3980 init_integral_libfuncs (rotr_optab, "rotr", '3');
3984 smin_optab->handlers[(int) QImode].insn_code = CODE_FOR_sminqi3;
3988 smin_optab->handlers[(int) HImode].insn_code = CODE_FOR_sminhi3;
3992 smin_optab->handlers[(int) SImode].insn_code = CODE_FOR_sminsi3;
3996 smin_optab->handlers[(int) DImode].insn_code = CODE_FOR_smindi3;
4000 smin_optab->handlers[(int) TImode].insn_code = CODE_FOR_sminti3;
4004 smin_optab->handlers[(int) SFmode].insn_code = CODE_FOR_minsf3;
4008 smin_optab->handlers[(int) DFmode].insn_code = CODE_FOR_mindf3;
4012 smin_optab->handlers[(int) XFmode].insn_code = CODE_FOR_minxf3;
4016 smin_optab->handlers[(int) TFmode].insn_code = CODE_FOR_mintf3;
4018 init_integral_libfuncs (smin_optab, "min", '3');
4019 init_floating_libfuncs (smin_optab, "min", '3');
4023 smax_optab->handlers[(int) QImode].insn_code = CODE_FOR_smaxqi3;
4027 smax_optab->handlers[(int) HImode].insn_code = CODE_FOR_smaxhi3;
4031 smax_optab->handlers[(int) SImode].insn_code = CODE_FOR_smaxsi3;
4035 smax_optab->handlers[(int) DImode].insn_code = CODE_FOR_smaxdi3;
4039 smax_optab->handlers[(int) TImode].insn_code = CODE_FOR_smaxti3;
4043 smax_optab->handlers[(int) SFmode].insn_code = CODE_FOR_maxsf3;
4047 smax_optab->handlers[(int) DFmode].insn_code = CODE_FOR_maxdf3;
4051 smax_optab->handlers[(int) XFmode].insn_code = CODE_FOR_maxxf3;
4055 smax_optab->handlers[(int) TFmode].insn_code = CODE_FOR_maxtf3;
4057 init_integral_libfuncs (smax_optab, "max", '3');
4058 init_floating_libfuncs (smax_optab, "max", '3');
4062 umin_optab->handlers[(int) QImode].insn_code = CODE_FOR_uminqi3;
4066 umin_optab->handlers[(int) HImode].insn_code = CODE_FOR_uminhi3;
4070 umin_optab->handlers[(int) SImode].insn_code = CODE_FOR_uminsi3;
4074 umin_optab->handlers[(int) DImode].insn_code = CODE_FOR_umindi3;
4078 umin_optab->handlers[(int) TImode].insn_code = CODE_FOR_uminti3;
4080 init_integral_libfuncs (umin_optab, "umin", '3');
4084 umax_optab->handlers[(int) QImode].insn_code = CODE_FOR_umaxqi3;
4088 umax_optab->handlers[(int) HImode].insn_code = CODE_FOR_umaxhi3;
4092 umax_optab->handlers[(int) SImode].insn_code = CODE_FOR_umaxsi3;
4096 umax_optab->handlers[(int) DImode].insn_code = CODE_FOR_umaxdi3;
4100 umax_optab->handlers[(int) TImode].insn_code = CODE_FOR_umaxti3;
4102 init_integral_libfuncs (umax_optab, "umax", '3');
4106 neg_optab->handlers[(int) QImode].insn_code = CODE_FOR_negqi2;
4110 neg_optab->handlers[(int) HImode].insn_code = CODE_FOR_neghi2;
4114 neg_optab->handlers[(int) PSImode].insn_code = CODE_FOR_negpsi2;
4118 neg_optab->handlers[(int) SImode].insn_code = CODE_FOR_negsi2;
4122 neg_optab->handlers[(int) DImode].insn_code = CODE_FOR_negdi2;
4126 neg_optab->handlers[(int) TImode].insn_code = CODE_FOR_negti2;
4130 neg_optab->handlers[(int) SFmode].insn_code = CODE_FOR_negsf2;
4134 neg_optab->handlers[(int) DFmode].insn_code = CODE_FOR_negdf2;
4138 neg_optab->handlers[(int) XFmode].insn_code = CODE_FOR_negxf2;
4142 neg_optab->handlers[(int) TFmode].insn_code = CODE_FOR_negtf2;
4144 init_integral_libfuncs (neg_optab, "neg", '2');
4145 init_floating_libfuncs (neg_optab, "neg", '2');
4149 abs_optab->handlers[(int) QImode].insn_code = CODE_FOR_absqi2;
4153 abs_optab->handlers[(int) HImode].insn_code = CODE_FOR_abshi2;
4157 abs_optab->handlers[(int) PSImode].insn_code = CODE_FOR_abspsi2;
4161 abs_optab->handlers[(int) SImode].insn_code = CODE_FOR_abssi2;
4165 abs_optab->handlers[(int) DImode].insn_code = CODE_FOR_absdi2;
4169 abs_optab->handlers[(int) TImode].insn_code = CODE_FOR_absti2;
4173 abs_optab->handlers[(int) SFmode].insn_code = CODE_FOR_abssf2;
4177 abs_optab->handlers[(int) DFmode].insn_code = CODE_FOR_absdf2;
4181 abs_optab->handlers[(int) XFmode].insn_code = CODE_FOR_absxf2;
4185 abs_optab->handlers[(int) TFmode].insn_code = CODE_FOR_abstf2;
4187 /* No library calls here! If there is no abs instruction,
4188 expand_expr will generate a conditional negation. */
4192 sqrt_optab->handlers[(int) QImode].insn_code = CODE_FOR_sqrtqi2;
4196 sqrt_optab->handlers[(int) HImode].insn_code = CODE_FOR_sqrthi2;
4198 #ifdef HAVE_sqrtpsi2
4200 sqrt_optab->handlers[(int) PSImode].insn_code = CODE_FOR_sqrtpsi2;
4204 sqrt_optab->handlers[(int) SImode].insn_code = CODE_FOR_sqrtsi2;
4208 sqrt_optab->handlers[(int) DImode].insn_code = CODE_FOR_sqrtdi2;
4212 sqrt_optab->handlers[(int) TImode].insn_code = CODE_FOR_sqrtti2;
4216 sqrt_optab->handlers[(int) SFmode].insn_code = CODE_FOR_sqrtsf2;
4220 sqrt_optab->handlers[(int) DFmode].insn_code = CODE_FOR_sqrtdf2;
4224 sqrt_optab->handlers[(int) TFmode].insn_code = CODE_FOR_sqrttf2;
4226 /* No library calls here! If there is no sqrt instruction expand_builtin
4227 should force the library call. */
4229 #ifdef HAVE_strlenqi
4231 strlen_optab->handlers[(int) QImode].insn_code = CODE_FOR_strlenqi;
4233 #ifdef HAVE_strlenhi
4235 strlen_optab->handlers[(int) HImode].insn_code = CODE_FOR_strlenhi;
4237 #ifdef HAVE_strlenpsi
4239 strlen_optab->handlers[(int) PSImode].insn_code = CODE_FOR_strlenpsi;
4241 #ifdef HAVE_strlensi
4243 strlen_optab->handlers[(int) SImode].insn_code = CODE_FOR_strlensi;
4245 #ifdef HAVE_strlendi
4247 strlen_optab->handlers[(int) DImode].insn_code = CODE_FOR_strlendi;
4249 #ifdef HAVE_strlenti
4251 strlen_optab->handlers[(int) TImode].insn_code = CODE_FOR_strlenti;
4253 /* No library calls here! If there is no strlen instruction expand_builtin
4254 should force the library call. */
4256 #ifdef HAVE_one_cmplqi2
4257 if (HAVE_one_cmplqi2)
4258 one_cmpl_optab->handlers[(int) QImode].insn_code = CODE_FOR_one_cmplqi2;
4260 #ifdef HAVE_one_cmplhi2
4261 if (HAVE_one_cmplhi2)
4262 one_cmpl_optab->handlers[(int) HImode].insn_code = CODE_FOR_one_cmplhi2;
4264 #ifdef HAVE_one_cmplpsi2
4265 if (HAVE_one_cmplpsi2)
4266 one_cmpl_optab->handlers[(int) PSImode].insn_code = CODE_FOR_one_cmplpsi2;
4268 #ifdef HAVE_one_cmplsi2
4269 if (HAVE_one_cmplsi2)
4270 one_cmpl_optab->handlers[(int) SImode].insn_code = CODE_FOR_one_cmplsi2;
4272 #ifdef HAVE_one_cmpldi2
4273 if (HAVE_one_cmpldi2)
4274 one_cmpl_optab->handlers[(int) DImode].insn_code = CODE_FOR_one_cmpldi2;
4276 #ifdef HAVE_one_cmplti2
4277 if (HAVE_one_cmplti2)
4278 one_cmpl_optab->handlers[(int) TImode].insn_code = CODE_FOR_one_cmplti2;
4280 init_integral_libfuncs (one_cmpl_optab, "one_cmpl", '2');
4284 ffs_optab->handlers[(int) QImode].insn_code = CODE_FOR_ffsqi2;
4288 ffs_optab->handlers[(int) HImode].insn_code = CODE_FOR_ffshi2;
4292 ffs_optab->handlers[(int) PSImode].insn_code = CODE_FOR_ffspsi2;
4296 ffs_optab->handlers[(int) SImode].insn_code = CODE_FOR_ffssi2;
4300 ffs_optab->handlers[(int) DImode].insn_code = CODE_FOR_ffsdi2;
4304 ffs_optab->handlers[(int) TImode].insn_code = CODE_FOR_ffsti2;
4306 init_integral_libfuncs (ffs_optab, "ffs", '2');
4310 mov_optab->handlers[(int) QImode].insn_code = CODE_FOR_movqi;
4314 mov_optab->handlers[(int) HImode].insn_code = CODE_FOR_movhi;
4318 mov_optab->handlers[(int) PSImode].insn_code = CODE_FOR_movpsi;
4322 mov_optab->handlers[(int) SImode].insn_code = CODE_FOR_movsi;
4326 mov_optab->handlers[(int) DImode].insn_code = CODE_FOR_movdi;
4330 mov_optab->handlers[(int) TImode].insn_code = CODE_FOR_movti;
4334 mov_optab->handlers[(int) SFmode].insn_code = CODE_FOR_movsf;
4338 mov_optab->handlers[(int) DFmode].insn_code = CODE_FOR_movdf;
4342 mov_optab->handlers[(int) XFmode].insn_code = CODE_FOR_movxf;
4346 mov_optab->handlers[(int) TFmode].insn_code = CODE_FOR_movtf;
4350 mov_optab->handlers[(int) CCmode].insn_code = CODE_FOR_movcc;
4353 #ifdef EXTRA_CC_MODES
4357 #ifdef HAVE_movstrictqi
4358 if (HAVE_movstrictqi)
4359 movstrict_optab->handlers[(int) QImode].insn_code = CODE_FOR_movstrictqi;
4361 #ifdef HAVE_movstricthi
4362 if (HAVE_movstricthi)
4363 movstrict_optab->handlers[(int) HImode].insn_code = CODE_FOR_movstricthi;
4365 #ifdef HAVE_movstrictpsi
4366 if (HAVE_movstrictpsi)
4367 movstrict_optab->handlers[(int) PSImode].insn_code = CODE_FOR_movstrictpsi;
4369 #ifdef HAVE_movstrictsi
4370 if (HAVE_movstrictsi)
4371 movstrict_optab->handlers[(int) SImode].insn_code = CODE_FOR_movstrictsi;
4373 #ifdef HAVE_movstrictdi
4374 if (HAVE_movstrictdi)
4375 movstrict_optab->handlers[(int) DImode].insn_code = CODE_FOR_movstrictdi;
4377 #ifdef HAVE_movstrictti
4378 if (HAVE_movstrictti)
4379 movstrict_optab->handlers[(int) TImode].insn_code = CODE_FOR_movstrictti;
4384 cmp_optab->handlers[(int) QImode].insn_code = CODE_FOR_cmpqi;
4388 cmp_optab->handlers[(int) HImode].insn_code = CODE_FOR_cmphi;
4392 cmp_optab->handlers[(int) PSImode].insn_code = CODE_FOR_cmppsi;
4396 cmp_optab->handlers[(int) SImode].insn_code = CODE_FOR_cmpsi;
4400 cmp_optab->handlers[(int) DImode].insn_code = CODE_FOR_cmpdi;
4404 cmp_optab->handlers[(int) TImode].insn_code = CODE_FOR_cmpti;
4408 cmp_optab->handlers[(int) SFmode].insn_code = CODE_FOR_cmpsf;
4412 cmp_optab->handlers[(int) DFmode].insn_code = CODE_FOR_cmpdf;
4416 cmp_optab->handlers[(int) XFmode].insn_code = CODE_FOR_cmpxf;
4420 cmp_optab->handlers[(int) TFmode].insn_code = CODE_FOR_cmptf;
4422 /* Comparison libcalls for integers MUST come in pairs, signed/unsigned. */
4423 init_integral_libfuncs (cmp_optab, "cmp", '2');
4424 init_integral_libfuncs (ucmp_optab, "ucmp", '2');
4425 init_floating_libfuncs (cmp_optab, "cmp", '2');
4429 tst_optab->handlers[(int) QImode].insn_code = CODE_FOR_tstqi;
4433 tst_optab->handlers[(int) HImode].insn_code = CODE_FOR_tsthi;
4437 tst_optab->handlers[(int) PSImode].insn_code = CODE_FOR_tstpsi;
4441 tst_optab->handlers[(int) SImode].insn_code = CODE_FOR_tstsi;
4445 tst_optab->handlers[(int) DImode].insn_code = CODE_FOR_tstdi;
4449 tst_optab->handlers[(int) TImode].insn_code = CODE_FOR_tstti;
4453 tst_optab->handlers[(int) SFmode].insn_code = CODE_FOR_tstsf;
4457 tst_optab->handlers[(int) DFmode].insn_code = CODE_FOR_tstdf;
4461 tst_optab->handlers[(int) XFmode].insn_code = CODE_FOR_tstxf;
4465 tst_optab->handlers[(int) TFmode].insn_code = CODE_FOR_tsttf;
4470 bcc_gen_fctn[(int) EQ] = gen_beq;
4474 bcc_gen_fctn[(int) NE] = gen_bne;
4478 bcc_gen_fctn[(int) GT] = gen_bgt;
4482 bcc_gen_fctn[(int) GE] = gen_bge;
4486 bcc_gen_fctn[(int) GTU] = gen_bgtu;
4490 bcc_gen_fctn[(int) GEU] = gen_bgeu;
4494 bcc_gen_fctn[(int) LT] = gen_blt;
4498 bcc_gen_fctn[(int) LE] = gen_ble;
4502 bcc_gen_fctn[(int) LTU] = gen_bltu;
4506 bcc_gen_fctn[(int) LEU] = gen_bleu;
4509 for (i = 0; i < NUM_RTX_CODE; i++)
4510 setcc_gen_code[i] = CODE_FOR_nothing;
4514 setcc_gen_code[(int) EQ] = CODE_FOR_seq;
4518 setcc_gen_code[(int) NE] = CODE_FOR_sne;
4522 setcc_gen_code[(int) GT] = CODE_FOR_sgt;
4526 setcc_gen_code[(int) GE] = CODE_FOR_sge;
4530 setcc_gen_code[(int) GTU] = CODE_FOR_sgtu;
4534 setcc_gen_code[(int) GEU] = CODE_FOR_sgeu;
4538 setcc_gen_code[(int) LT] = CODE_FOR_slt;
4542 setcc_gen_code[(int) LE] = CODE_FOR_sle;
4546 setcc_gen_code[(int) LTU] = CODE_FOR_sltu;
4550 setcc_gen_code[(int) LEU] = CODE_FOR_sleu;
4553 extendsfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extendsfdf2");
4554 extendsfxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extendsfxf2");
4555 extendsftf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extendsftf2");
4556 extenddfxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extenddfxf2");
4557 extenddftf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extenddftf2");
4559 truncdfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__truncdfsf2");
4560 truncxfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__truncxfsf2");
4561 trunctfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__trunctfsf2");
4562 truncxfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__truncxfdf2");
4563 trunctfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__trunctfdf2");
4565 memcpy_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memcpy");
4566 bcopy_libfunc = gen_rtx (SYMBOL_REF, Pmode, "bcopy");
4567 memcmp_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memcmp");
4568 bcmp_libfunc = gen_rtx (SYMBOL_REF, Pmode, "bcmp");
4569 memset_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memset");
4570 bzero_libfunc = gen_rtx (SYMBOL_REF, Pmode, "bzero");
4572 eqsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqsf2");
4573 nesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nesf2");
4574 gtsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtsf2");
4575 gesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gesf2");
4576 ltsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltsf2");
4577 lesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lesf2");
4579 eqdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqdf2");
4580 nedf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nedf2");
4581 gtdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtdf2");
4582 gedf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gedf2");
4583 ltdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltdf2");
4584 ledf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ledf2");
4586 eqxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqxf2");
4587 nexf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nexf2");
4588 gtxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtxf2");
4589 gexf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gexf2");
4590 ltxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltxf2");
4591 lexf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lexf2");
4593 eqtf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqtf2");
4594 netf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__netf2");
4595 gttf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gttf2");
4596 getf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__getf2");
4597 lttf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lttf2");
4598 letf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__letf2");
4600 floatsisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsisf");
4601 floatdisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatdisf");
4602 floattisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattisf");
4604 floatsidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsidf");
4605 floatdidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatdidf");
4606 floattidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattidf");
4608 floatsixf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsixf");
4609 floatdixf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatdixf");
4610 floattixf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattixf");
4612 floatsitf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsitf");
4613 floatditf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatditf");
4614 floattitf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattitf");
4616 fixsfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixsfsi");
4617 fixsfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixsfdi");
4618 fixsfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixsfti");
4620 fixdfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixdfsi");
4621 fixdfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixdfdi");
4622 fixdfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixdfti");
4624 fixxfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixxfsi");
4625 fixxfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixxfdi");
4626 fixxfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixxfti");
4628 fixtfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixtfsi");
4629 fixtfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixtfdi");
4630 fixtfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixtfti");
4632 fixunssfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunssfsi");
4633 fixunssfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunssfdi");
4634 fixunssfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunssfti");
4636 fixunsdfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsdfsi");
4637 fixunsdfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsdfdi");
4638 fixunsdfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsdfti");
4640 fixunsxfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsxfsi");
4641 fixunsxfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsxfdi");
4642 fixunsxfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsxfti");
4644 fixunstfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunstfsi");
4645 fixunstfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunstfdi");
4646 fixunstfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunstfti");
4651 /* SCO 3.2 apparently has a broken ldexp. */
4664 #endif /* BROKEN_LDEXP */