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"
31 /* Each optab contains info on how this target machine
32 can perform a particular operation
33 for all sizes and kinds of operands.
35 The operation to be performed is often specified
36 by passing one of these optabs as an argument.
38 See expr.h for documentation of these optabs. */
43 optab smul_widen_optab;
44 optab umul_widen_optab;
68 optab movstrict_optab;
77 optab ucmp_optab; /* Used only for libcalls for unsigned comparisons. */
82 /* SYMBOL_REF rtx's for the library functions that are called
83 implicitly and not via optabs. */
85 rtx extendsfdf2_libfunc;
86 rtx extendsfxf2_libfunc;
87 rtx extendsftf2_libfunc;
88 rtx extenddfxf2_libfunc;
89 rtx extenddftf2_libfunc;
91 rtx truncdfsf2_libfunc;
92 rtx truncxfsf2_libfunc;
93 rtx trunctfsf2_libfunc;
94 rtx truncxfdf2_libfunc;
95 rtx trunctfdf2_libfunc;
132 rtx floatsisf_libfunc;
133 rtx floatdisf_libfunc;
134 rtx floattisf_libfunc;
136 rtx floatsidf_libfunc;
137 rtx floatdidf_libfunc;
138 rtx floattidf_libfunc;
140 rtx floatsixf_libfunc;
141 rtx floatdixf_libfunc;
142 rtx floattixf_libfunc;
144 rtx floatsitf_libfunc;
145 rtx floatditf_libfunc;
146 rtx floattitf_libfunc;
164 rtx fixunssfsi_libfunc;
165 rtx fixunssfdi_libfunc;
166 rtx fixunssfti_libfunc;
168 rtx fixunsdfsi_libfunc;
169 rtx fixunsdfdi_libfunc;
170 rtx fixunsdfti_libfunc;
172 rtx fixunsxfsi_libfunc;
173 rtx fixunsxfdi_libfunc;
174 rtx fixunsxfti_libfunc;
176 rtx fixunstfsi_libfunc;
177 rtx fixunstfdi_libfunc;
178 rtx fixunstfti_libfunc;
180 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
181 gives the gen_function to make a branch to test that condition. */
183 rtxfun bcc_gen_fctn[NUM_RTX_CODE];
185 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
186 gives the insn code to make a store-condition insn
187 to test that condition. */
189 enum insn_code setcc_gen_code[NUM_RTX_CODE];
191 static void emit_float_lib_cmp ();
193 /* Add a REG_EQUAL note to the last insn in SEQ. TARGET is being set to
194 the result of operation CODE applied to OP0 (and OP1 if it is a binary
197 If the last insn does not set TARGET, don't do anything, but return 1.
199 If a previous insn sets TARGET and TARGET is one of OP0 or OP1,
200 don't add the REG_EQUAL note but return 0. Our caller can then try
201 again, ensuring that TARGET is not one of the operands. */
204 add_equal_note (seq, target, code, op0, op1)
214 if ((GET_RTX_CLASS (code) != '1' && GET_RTX_CLASS (code) != '2'
215 && GET_RTX_CLASS (code) != 'c' && GET_RTX_CLASS (code) != '<')
216 || GET_CODE (seq) != SEQUENCE
217 || (set = single_set (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1))) == 0
218 || GET_CODE (target) == ZERO_EXTRACT
219 || (! rtx_equal_p (SET_DEST (set), target)
220 /* For a STRICT_LOW_PART, the REG_NOTE applies to what is inside the
222 && (GET_CODE (SET_DEST (set)) != STRICT_LOW_PART
223 || ! rtx_equal_p (SUBREG_REG (XEXP (SET_DEST (set), 0)),
227 /* If TARGET is in OP0 or OP1, check if anything in SEQ sets TARGET
228 besides the last insn. */
229 if (reg_overlap_mentioned_p (target, op0)
230 || (op1 && reg_overlap_mentioned_p (target, op1)))
231 for (i = XVECLEN (seq, 0) - 2; i >= 0; i--)
232 if (reg_set_p (target, XVECEXP (seq, 0, i)))
235 if (GET_RTX_CLASS (code) == '1')
236 note = gen_rtx (code, GET_MODE (target), op0);
238 note = gen_rtx (code, GET_MODE (target), op0, op1);
240 REG_NOTES (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1))
241 = gen_rtx (EXPR_LIST, REG_EQUAL, note,
242 REG_NOTES (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1)));
247 /* Generate code to perform an operation specified by BINOPTAB
248 on operands OP0 and OP1, with result having machine-mode MODE.
250 UNSIGNEDP is for the case where we have to widen the operands
251 to perform the operation. It says to use zero-extension.
253 If TARGET is nonzero, the value
254 is generated there, if it is convenient to do so.
255 In all cases an rtx is returned for the locus of the value;
256 this may or may not be TARGET. */
259 expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods)
260 enum machine_mode mode;
265 enum optab_methods methods;
267 enum mode_class class;
268 enum machine_mode wider_mode;
270 int commutative_op = 0;
271 int shift_op = (binoptab->code == ASHIFT
272 || binoptab->code == ASHIFTRT
273 || binoptab->code == LSHIFT
274 || binoptab->code == LSHIFTRT
275 || binoptab->code == ROTATE
276 || binoptab->code == ROTATERT);
279 class = GET_MODE_CLASS (mode);
281 op0 = protect_from_queue (op0, 0);
282 op1 = protect_from_queue (op1, 0);
284 target = protect_from_queue (target, 1);
288 op0 = force_not_mem (op0);
289 op1 = force_not_mem (op1);
292 /* If we are inside an appropriately-short loop and one operand is an
293 expensive constant, force it into a register. */
294 if (CONSTANT_P (op0) && preserve_subexpressions_p ()
295 && rtx_cost (op0, binoptab->code) > 2)
296 op0 = force_reg (mode, op0);
298 if (CONSTANT_P (op1) && preserve_subexpressions_p ()
299 && rtx_cost (op1, binoptab->code) > 2)
300 op1 = force_reg (shift_op ? word_mode : mode, op1);
302 #if 0 /* Turned off because it seems to be a kludgy method. */
303 /* If subtracting integer from pointer, and the pointer has a special mode,
304 then change it to an add. We use the add insn of Pmode for combining
305 integers with pointers, and the sub insn to subtract two pointers. */
307 if (binoptab == sub_optab
308 && GET_MODE (op0) == Pmode && GET_MODE (op1) != Pmode)
310 op1 = negate_rtx (GET_MODE(op1), op1);
311 binoptab = add_optab;
315 /* Record where to delete back to if we backtrack. */
316 last = get_last_insn ();
318 /* If operation is commutative,
319 try to make the first operand a register.
320 Even better, try to make it the same as the target.
321 Also try to make the last operand a constant. */
322 if (GET_RTX_CLASS (binoptab->code) == 'c'
323 || binoptab == smul_widen_optab
324 || binoptab == umul_widen_optab)
328 if (((target == 0 || GET_CODE (target) == REG)
329 ? ((GET_CODE (op1) == REG
330 && GET_CODE (op0) != REG)
332 : rtx_equal_p (op1, target))
333 || GET_CODE (op0) == CONST_INT)
341 /* If we can do it with a three-operand insn, do so. */
343 if (methods != OPTAB_MUST_WIDEN
344 && binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
346 int icode = (int) binoptab->handlers[(int) mode].insn_code;
347 enum machine_mode mode0 = insn_operand_mode[icode][1];
348 enum machine_mode mode1 = insn_operand_mode[icode][2];
350 rtx xop0 = op0, xop1 = op1;
355 temp = gen_reg_rtx (mode);
357 /* If it is a commutative operator and the modes would match
358 if we would swap the operands, we can save the conversions. */
361 if (GET_MODE (op0) != mode0 && GET_MODE (op1) != mode1
362 && GET_MODE (op0) == mode1 && GET_MODE (op1) == mode0)
366 tmp = op0; op0 = op1; op1 = tmp;
367 tmp = xop0; xop0 = xop1; xop1 = tmp;
371 /* In case the insn wants input operands in modes different from
372 the result, convert the operands. */
374 if (GET_MODE (op0) != VOIDmode
375 && GET_MODE (op0) != mode0)
376 xop0 = convert_to_mode (mode0, xop0, unsignedp);
378 if (GET_MODE (xop1) != VOIDmode
379 && GET_MODE (xop1) != mode1)
380 xop1 = convert_to_mode (mode1, xop1, unsignedp);
382 /* Now, if insn's predicates don't allow our operands, put them into
385 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
386 xop0 = copy_to_mode_reg (mode0, xop0);
388 if (! (*insn_operand_predicate[icode][2]) (xop1, mode1))
389 xop1 = copy_to_mode_reg (mode1, xop1);
391 if (! (*insn_operand_predicate[icode][0]) (temp, mode))
392 temp = gen_reg_rtx (mode);
394 pat = GEN_FCN (icode) (temp, xop0, xop1);
397 /* If PAT is a multi-insn sequence, try to add an appropriate
398 REG_EQUAL note to it. If we can't because TEMP conflicts with an
399 operand, call ourselves again, this time without a target. */
400 if (GET_CODE (pat) == SEQUENCE
401 && ! add_equal_note (pat, temp, binoptab->code, xop0, xop1))
403 delete_insns_since (last);
404 return expand_binop (mode, binoptab, op0, op1, 0, unsignedp,
412 delete_insns_since (last);
415 /* These can be done a word at a time. */
416 if ((binoptab == and_optab || binoptab == ior_optab || binoptab == xor_optab)
418 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
419 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
425 /* If TARGET is the same as one of the operands, the REG_EQUAL note
426 won't be accurate, so use a new target. */
427 if (target == 0 || target == op0 || target == op1)
428 target = gen_reg_rtx (mode);
432 /* Do the actual arithmetic. */
433 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
435 rtx target_piece = operand_subword (target, i, 1, mode);
436 rtx x = expand_binop (word_mode, binoptab,
437 operand_subword_force (op0, i, mode),
438 operand_subword_force (op1, i, mode),
439 target_piece, unsignedp, methods);
440 if (target_piece != x)
441 emit_move_insn (target_piece, x);
444 insns = get_insns ();
447 if (binoptab->code != UNKNOWN)
448 equiv_value = gen_rtx (binoptab->code, mode, op0, op1);
452 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
456 /* These can be done a word at a time by propagating carries. */
457 if ((binoptab == add_optab || binoptab == sub_optab)
459 && GET_MODE_SIZE (mode) >= 2 * UNITS_PER_WORD
460 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
463 rtx carry_tmp = gen_reg_rtx (word_mode);
464 optab otheroptab = binoptab == add_optab ? sub_optab : add_optab;
465 int nwords = GET_MODE_BITSIZE (mode) / BITS_PER_WORD;
466 rtx carry_in, carry_out;
468 /* We can handle either a 1 or -1 value for the carry. If STORE_FLAG
469 value is one of those, use it. Otherwise, use 1 since it is the
470 one easiest to get. */
471 #if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
472 int normalizep = STORE_FLAG_VALUE;
477 /* Prepare the operands. */
478 op0 = force_reg (mode, op0);
479 op1 = force_reg (mode, op1);
481 if (target == 0 || GET_CODE (target) != REG
482 || target == op0 || target == op1)
483 target = gen_reg_rtx (mode);
485 /* Do the actual arithmetic. */
486 for (i = 0; i < nwords; i++)
488 int index = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i);
489 rtx target_piece = operand_subword (target, index, 1, mode);
490 rtx op0_piece = operand_subword_force (op0, index, mode);
491 rtx op1_piece = operand_subword_force (op1, index, mode);
494 /* Main add/subtract of the input operands. */
495 x = expand_binop (word_mode, binoptab,
496 op0_piece, op1_piece,
497 target_piece, unsignedp, methods);
503 /* Store carry from main add/subtract. */
504 carry_out = gen_reg_rtx (word_mode);
505 carry_out = emit_store_flag (carry_out,
506 binoptab == add_optab ? LTU : GTU,
508 word_mode, 1, normalizep);
515 /* Add/subtract previous carry to main result. */
516 x = expand_binop (word_mode,
517 normalizep == 1 ? binoptab : otheroptab,
519 target_piece, 1, methods);
520 if (target_piece != x)
521 emit_move_insn (target_piece, x);
525 /* THIS CODE HAS NOT BEEN TESTED. */
526 /* Get out carry from adding/subtracting carry in. */
527 carry_tmp = emit_store_flag (carry_tmp,
528 binoptab == add_optab
531 word_mode, 1, normalizep);
532 /* Logical-ior the two poss. carry together. */
533 carry_out = expand_binop (word_mode, ior_optab,
534 carry_out, carry_tmp,
535 carry_out, 0, methods);
541 carry_in = carry_out;
544 if (i == GET_MODE_BITSIZE (mode) / BITS_PER_WORD)
548 temp = emit_move_insn (target, target);
549 REG_NOTES (temp) = gen_rtx (EXPR_LIST, REG_EQUAL,
550 gen_rtx (binoptab->code, mode, op0, op1),
555 delete_insns_since (last);
558 /* If we want to multiply two two-word values and have normal and widening
559 multiplies of single-word values, we can do this with three smaller
560 multiplications. Note that we do not make a REG_NO_CONFLICT block here
561 because we are not operating on one word at a time.
563 The multiplication proceeds as follows:
564 _______________________
565 [__op0_high_|__op0_low__]
566 _______________________
567 * [__op1_high_|__op1_low__]
568 _______________________________________________
569 _______________________
570 (1) [__op0_low__*__op1_low__]
571 _______________________
572 (2a) [__op0_low__*__op1_high_]
573 _______________________
574 (2b) [__op0_high_*__op1_low__]
575 _______________________
576 (3) [__op0_high_*__op1_high_]
579 This gives a 4-word result. Since we are only interested in the
580 lower 2 words, partial result (3) and the upper words of (2a) and
581 (2b) don't need to be calculated. Hence (2a) and (2b) can be
582 calculated using non-widening multiplication.
584 (1), however, needs to be calculated with an unsigned widening
585 multiplication. If this operation is not directly supported we
586 try using a signed widening multiplication and adjust the result.
587 This adjustment works as follows:
589 If both operands are positive then no adjustment is needed.
591 If the operands have different signs, for example op0_low < 0 and
592 op1_low >= 0, the instruction treats the most significant bit of
593 op0_low as a sign bit instead of a bit with significance
594 2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low
595 with 2**BITS_PER_WORD - op0_low, and two's complements the
596 result. Conclusion: We need to add op1_low * 2**BITS_PER_WORD to
599 Similarly, if both operands are negative, we need to add
600 (op0_low + op1_low) * 2**BITS_PER_WORD.
602 We use a trick to adjust quickly. We logically shift op0_low right
603 (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to
604 op0_high (op1_high) before it is used to calculate 2b (2a). If no
605 logical shift exists, we do an arithmetic right shift and subtract
608 if (binoptab == smul_optab
610 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
611 && smul_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
612 && add_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
613 && ((umul_widen_optab->handlers[(int) mode].insn_code
615 || (smul_widen_optab->handlers[(int) mode].insn_code
616 != CODE_FOR_nothing)))
618 int low = (WORDS_BIG_ENDIAN ? 1 : 0);
619 int high = (WORDS_BIG_ENDIAN ? 0 : 1);
620 rtx op0_high = operand_subword_force (op0, high, mode);
621 rtx op0_low = operand_subword_force (op0, low, mode);
622 rtx op1_high = operand_subword_force (op1, high, mode);
623 rtx op1_low = operand_subword_force (op1, low, mode);
628 /* If the target is the same as one of the inputs, don't use it. This
629 prevents problems with the REG_EQUAL note. */
630 if (target == op0 || target == op1)
633 /* Multiply the two lower words to get a double-word product.
634 If unsigned widening multiplication is available, use that;
635 otherwise use the signed form and compensate. */
637 if (umul_widen_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
639 product = expand_binop (mode, umul_widen_optab, op0_low, op1_low,
640 target, 1, OPTAB_DIRECT);
642 /* If we didn't succeed, delete everything we did so far. */
644 delete_insns_since (last);
646 op0_xhigh = op0_high, op1_xhigh = op1_high;
650 && smul_widen_optab->handlers[(int) mode].insn_code
653 rtx wordm1 = gen_rtx (CONST_INT, VOIDmode, BITS_PER_WORD - 1);
654 product = expand_binop (mode, smul_widen_optab, op0_low, op1_low,
655 target, 1, OPTAB_DIRECT);
656 op0_xhigh = expand_binop (word_mode, lshr_optab, op0_low, wordm1,
659 op0_xhigh = expand_binop (word_mode, add_optab, op0_high,
660 op0_xhigh, op0_xhigh, 0, OPTAB_DIRECT);
663 op0_xhigh = expand_binop (word_mode, ashr_optab, op0_low, wordm1,
666 op0_xhigh = expand_binop (word_mode, sub_optab, op0_high,
667 op0_xhigh, op0_xhigh, 0,
671 op1_xhigh = expand_binop (word_mode, lshr_optab, op1_low, wordm1,
674 op1_xhigh = expand_binop (word_mode, add_optab, op1_high,
675 op1_xhigh, op1_xhigh, 0, OPTAB_DIRECT);
678 op1_xhigh = expand_binop (word_mode, ashr_optab, op1_low, wordm1,
681 op1_xhigh = expand_binop (word_mode, sub_optab, op1_high,
682 op1_xhigh, op1_xhigh, 0,
687 /* If we have been able to directly compute the product of the
688 low-order words of the operands and perform any required adjustments
689 of the operands, we proceed by trying two more multiplications
690 and then computing the appropriate sum.
692 We have checked above that the required addition is provided.
693 Full-word addition will normally always succeed, especially if
694 it is provided at all, so we don't worry about its failure. The
695 multiplication may well fail, however, so we do handle that. */
697 if (product && op0_xhigh && op1_xhigh)
700 rtx product_high = operand_subword (product, high, 1, mode);
701 rtx temp = expand_binop (word_mode, binoptab, op0_low, op1_xhigh, 0,
706 product_piece = expand_binop (word_mode, add_optab, temp,
707 product_high, product_high,
709 if (product_piece != product_high)
710 emit_move_insn (product_high, product_piece);
712 temp = expand_binop (word_mode, binoptab, op1_low, op0_xhigh, 0,
715 product_piece = expand_binop (word_mode, add_optab, temp,
716 product_high, product_high,
718 if (product_piece != product_high)
719 emit_move_insn (product_high, product_piece);
721 temp = emit_move_insn (product, product);
722 REG_NOTES (temp) = gen_rtx (EXPR_LIST, REG_EQUAL,
723 gen_rtx (MULT, mode, op0, op1),
730 /* If we get here, we couldn't do it for some reason even though we
731 originally thought we could. Delete anything we've emitted in
734 delete_insns_since (last);
737 /* It can't be open-coded in this mode.
738 Use a library call if one is available and caller says that's ok. */
740 if (binoptab->handlers[(int) mode].libfunc
741 && (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN))
744 rtx funexp = binoptab->handlers[(int) mode].libfunc;
748 /* Pass 1 for NO_QUEUE so we don't lose any increments
749 if the libcall is cse'd or moved. */
750 emit_library_call (binoptab->handlers[(int) mode].libfunc,
751 1, mode, 2, op0, mode, op1,
752 (shift_op ? word_mode : mode));
754 insns = get_insns ();
757 target = gen_reg_rtx (mode);
758 emit_libcall_block (insns, target, hard_libcall_value (mode),
759 gen_rtx (binoptab->code, mode, op0, op1));
764 delete_insns_since (last);
766 /* It can't be done in this mode. Can we do it in a wider mode? */
768 if (! (methods == OPTAB_WIDEN || methods == OPTAB_LIB_WIDEN
769 || methods == OPTAB_MUST_WIDEN))
770 return 0; /* Caller says, don't even try. */
772 /* Compute the value of METHODS to pass to recursive calls.
773 Don't allow widening to be tried recursively. */
775 methods = (methods == OPTAB_LIB_WIDEN ? OPTAB_LIB : OPTAB_DIRECT);
777 /* Look for a wider mode of the same class for which it appears we can do
780 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
782 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
783 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
785 if ((binoptab->handlers[(int) wider_mode].insn_code
787 || (methods == OPTAB_LIB
788 && binoptab->handlers[(int) wider_mode].libfunc))
790 rtx xop0 = op0, xop1 = op1;
793 /* For certain integer operations, we need not actually extend
794 the narrow operands, as long as we will truncate
795 the results to the same narrowness. */
797 if ((binoptab == ior_optab || binoptab == and_optab
798 || binoptab == xor_optab
799 || binoptab == add_optab || binoptab == sub_optab
800 || binoptab == smul_optab
801 || binoptab == ashl_optab || binoptab == lshl_optab)
802 && class == MODE_INT)
805 /* If an operand is a constant integer, we might as well
806 convert it since that is more efficient than using a SUBREG,
807 unlike the case for other operands. */
809 if (no_extend && GET_MODE (xop0) != VOIDmode)
810 xop0 = gen_rtx (SUBREG, wider_mode,
811 force_reg (GET_MODE (xop0), xop0), 0);
813 xop0 = convert_to_mode (wider_mode, xop0, unsignedp);
815 if (no_extend && GET_MODE (xop1) != VOIDmode)
816 xop1 = gen_rtx (SUBREG, wider_mode,
817 force_reg (GET_MODE (xop1), xop1), 0);
819 xop1 = convert_to_mode (wider_mode, xop1, unsignedp);
821 temp = expand_binop (wider_mode, binoptab, xop0, xop1, 0,
825 if (class != MODE_INT)
828 target = gen_reg_rtx (mode);
829 convert_move (target, temp, 0);
833 return gen_lowpart (mode, temp);
836 delete_insns_since (last);
844 /* Expand a binary operator which has both signed and unsigned forms.
845 UOPTAB is the optab for unsigned operations, and SOPTAB is for
848 If we widen unsigned operands, we may use a signed wider operation instead
849 of an unsigned wider operation, since the result would be the same. */
852 sign_expand_binop (mode, uoptab, soptab, op0, op1, target, unsignedp, methods)
853 enum machine_mode mode;
854 optab uoptab, soptab;
855 rtx op0, op1, target;
857 enum optab_methods methods;
860 optab direct_optab = unsignedp ? uoptab : soptab;
861 struct optab wide_soptab;
863 /* Do it without widening, if possible. */
864 temp = expand_binop (mode, direct_optab, op0, op1, target,
865 unsignedp, OPTAB_DIRECT);
866 if (temp || methods == OPTAB_DIRECT)
869 /* Try widening to a signed int. Make a fake signed optab that
870 hides any signed insn for direct use. */
871 wide_soptab = *soptab;
872 wide_soptab.handlers[(int) mode].insn_code = CODE_FOR_nothing;
873 wide_soptab.handlers[(int) mode].libfunc = 0;
875 temp = expand_binop (mode, &wide_soptab, op0, op1, target,
876 unsignedp, OPTAB_WIDEN);
878 /* For unsigned operands, try widening to an unsigned int. */
879 if (temp == 0 && unsignedp)
880 temp = expand_binop (mode, uoptab, op0, op1, target,
881 unsignedp, OPTAB_WIDEN);
882 if (temp || methods == OPTAB_WIDEN)
885 /* Use the right width lib call if that exists. */
886 temp = expand_binop (mode, direct_optab, op0, op1, target, unsignedp, OPTAB_LIB);
887 if (temp || methods == OPTAB_LIB)
890 /* Must widen and use a lib call, use either signed or unsigned. */
891 temp = expand_binop (mode, &wide_soptab, op0, op1, target,
896 return expand_binop (mode, uoptab, op0, op1, target,
901 /* Generate code to perform an operation specified by BINOPTAB
902 on operands OP0 and OP1, with two results to TARG1 and TARG2.
903 We assume that the order of the operands for the instruction
904 is TARG0, OP0, OP1, TARG1, which would fit a pattern like
905 [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
907 Either TARG0 or TARG1 may be zero, but what that means is that
908 that result is not actually wanted. We will generate it into
909 a dummy pseudo-reg and discard it. They may not both be zero.
911 Returns 1 if this operation can be performed; 0 if not. */
914 expand_twoval_binop (binoptab, op0, op1, targ0, targ1, unsignedp)
920 enum machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
921 enum mode_class class;
922 enum machine_mode wider_mode;
925 class = GET_MODE_CLASS (mode);
927 op0 = protect_from_queue (op0, 0);
928 op1 = protect_from_queue (op1, 0);
932 op0 = force_not_mem (op0);
933 op1 = force_not_mem (op1);
936 /* If we are inside an appropriately-short loop and one operand is an
937 expensive constant, force it into a register. */
938 if (CONSTANT_P (op0) && preserve_subexpressions_p ()
939 && rtx_cost (op0, binoptab->code) > 2)
940 op0 = force_reg (mode, op0);
942 if (CONSTANT_P (op1) && preserve_subexpressions_p ()
943 && rtx_cost (op1, binoptab->code) > 2)
944 op1 = force_reg (mode, op1);
947 targ0 = protect_from_queue (targ0, 1);
949 targ0 = gen_reg_rtx (mode);
951 targ1 = protect_from_queue (targ1, 1);
953 targ1 = gen_reg_rtx (mode);
955 /* Record where to go back to if we fail. */
956 last = get_last_insn ();
958 if (binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
960 int icode = (int) binoptab->handlers[(int) mode].insn_code;
961 enum machine_mode mode0 = insn_operand_mode[icode][1];
962 enum machine_mode mode1 = insn_operand_mode[icode][2];
964 rtx xop0 = op0, xop1 = op1;
966 /* In case this insn wants input operands in modes different from the
967 result, convert the operands. */
968 if (GET_MODE (op0) != VOIDmode && GET_MODE (op0) != mode0)
969 xop0 = convert_to_mode (mode0, xop0, unsignedp);
971 if (GET_MODE (op1) != VOIDmode && GET_MODE (op1) != mode1)
972 xop1 = convert_to_mode (mode1, xop1, unsignedp);
974 /* Now, if insn doesn't accept these operands, put them into pseudos. */
975 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
976 xop0 = copy_to_mode_reg (mode0, xop0);
978 if (! (*insn_operand_predicate[icode][2]) (xop1, mode1))
979 xop1 = copy_to_mode_reg (mode1, xop1);
981 /* We could handle this, but we should always be called with a pseudo
982 for our targets and all insns should take them as outputs. */
983 if (! (*insn_operand_predicate[icode][0]) (targ0, mode)
984 || ! (*insn_operand_predicate[icode][3]) (targ1, mode))
987 pat = GEN_FCN (icode) (targ0, xop0, xop1, targ1);
994 delete_insns_since (last);
997 /* It can't be done in this mode. Can we do it in a wider mode? */
999 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1001 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1002 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1004 if (binoptab->handlers[(int) wider_mode].insn_code
1005 != CODE_FOR_nothing)
1007 register rtx t0 = gen_reg_rtx (wider_mode);
1008 register rtx t1 = gen_reg_rtx (wider_mode);
1010 if (expand_twoval_binop (binoptab,
1011 convert_to_mode (wider_mode, op0,
1013 convert_to_mode (wider_mode, op1,
1017 convert_move (targ0, t0, unsignedp);
1018 convert_move (targ1, t1, unsignedp);
1022 delete_insns_since (last);
1030 /* Generate code to perform an operation specified by UNOPTAB
1031 on operand OP0, with result having machine-mode MODE.
1033 UNSIGNEDP is for the case where we have to widen the operands
1034 to perform the operation. It says to use zero-extension.
1036 If TARGET is nonzero, the value
1037 is generated there, if it is convenient to do so.
1038 In all cases an rtx is returned for the locus of the value;
1039 this may or may not be TARGET. */
1042 expand_unop (mode, unoptab, op0, target, unsignedp)
1043 enum machine_mode mode;
1049 enum mode_class class;
1050 enum machine_mode wider_mode;
1052 rtx last = get_last_insn ();
1055 class = GET_MODE_CLASS (mode);
1057 op0 = protect_from_queue (op0, 0);
1061 op0 = force_not_mem (op0);
1065 target = protect_from_queue (target, 1);
1067 if (unoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1069 int icode = (int) unoptab->handlers[(int) mode].insn_code;
1070 enum machine_mode mode0 = insn_operand_mode[icode][1];
1076 temp = gen_reg_rtx (mode);
1078 if (GET_MODE (xop0) != VOIDmode
1079 && GET_MODE (xop0) != mode0)
1080 xop0 = convert_to_mode (mode0, xop0, unsignedp);
1082 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
1084 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
1085 xop0 = copy_to_mode_reg (mode0, xop0);
1087 if (! (*insn_operand_predicate[icode][0]) (temp, mode))
1088 temp = gen_reg_rtx (mode);
1090 pat = GEN_FCN (icode) (temp, xop0);
1093 if (GET_CODE (pat) == SEQUENCE
1094 && ! add_equal_note (pat, temp, unoptab->code, xop0, 0))
1096 delete_insns_since (last);
1097 return expand_unop (mode, unoptab, op0, 0, unsignedp);
1105 delete_insns_since (last);
1108 /* These can be done a word at a time. */
1109 if (unoptab == one_cmpl_optab
1110 && class == MODE_INT
1111 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
1112 && unoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
1117 if (target == 0 || target == op0)
1118 target = gen_reg_rtx (mode);
1122 /* Do the actual arithmetic. */
1123 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
1125 rtx target_piece = operand_subword (target, i, 1, mode);
1126 rtx x = expand_unop (word_mode, unoptab,
1127 operand_subword_force (op0, i, mode),
1128 target_piece, unsignedp);
1129 if (target_piece != x)
1130 emit_move_insn (target_piece, x);
1133 insns = get_insns ();
1136 emit_no_conflict_block (insns, target, op0, 0,
1137 gen_rtx (unoptab->code, mode, op0));
1141 if (unoptab->handlers[(int) mode].libfunc)
1144 rtx funexp = unoptab->handlers[(int) mode].libfunc;
1148 /* Pass 1 for NO_QUEUE so we don't lose any increments
1149 if the libcall is cse'd or moved. */
1150 emit_library_call (unoptab->handlers[(int) mode].libfunc,
1151 1, mode, 1, op0, mode);
1152 insns = get_insns ();
1155 target = gen_reg_rtx (mode);
1156 emit_libcall_block (insns, target, hard_libcall_value (mode),
1157 gen_rtx (unoptab->code, mode, op0));
1162 /* It can't be done in this mode. Can we do it in a wider mode? */
1164 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1166 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1167 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1169 if ((unoptab->handlers[(int) wider_mode].insn_code
1170 != CODE_FOR_nothing)
1171 || unoptab->handlers[(int) wider_mode].libfunc)
1175 /* For certain operations, we need not actually extend
1176 the narrow operand, as long as we will truncate the
1177 results to the same narrowness. */
1179 if ((unoptab == neg_optab || unoptab == one_cmpl_optab)
1180 && class == MODE_INT)
1181 xop0 = gen_rtx (SUBREG, wider_mode, force_reg (mode, xop0), 0);
1183 xop0 = convert_to_mode (wider_mode, xop0, unsignedp);
1185 temp = expand_unop (wider_mode, unoptab, xop0, 0, unsignedp);
1189 if (class != MODE_INT)
1192 target = gen_reg_rtx (mode);
1193 convert_move (target, temp, 0);
1197 return gen_lowpart (mode, temp);
1200 delete_insns_since (last);
1208 /* Generate an instruction whose insn-code is INSN_CODE,
1209 with two operands: an output TARGET and an input OP0.
1210 TARGET *must* be nonzero, and the output is always stored there.
1211 CODE is an rtx code such that (CODE OP0) is an rtx that describes
1212 the value that is stored into TARGET. */
1215 emit_unop_insn (icode, target, op0, code)
1222 enum machine_mode mode0 = insn_operand_mode[icode][1];
1225 temp = target = protect_from_queue (target, 1);
1227 op0 = protect_from_queue (op0, 0);
1230 op0 = force_not_mem (op0);
1232 /* Now, if insn does not accept our operands, put them into pseudos. */
1234 if (! (*insn_operand_predicate[icode][1]) (op0, mode0))
1235 op0 = copy_to_mode_reg (mode0, op0);
1237 if (! (*insn_operand_predicate[icode][0]) (temp, GET_MODE (temp))
1238 || (flag_force_mem && GET_CODE (temp) == MEM))
1239 temp = gen_reg_rtx (GET_MODE (temp));
1241 pat = GEN_FCN (icode) (temp, op0);
1243 if (GET_CODE (pat) == SEQUENCE && code != UNKNOWN)
1244 add_equal_note (pat, temp, code, op0, 0);
1249 emit_move_insn (target, temp);
1252 /* Emit code to perform a series of operations on a multi-word quantity, one
1255 Such a block is preceded by a CLOBBER of the output, consists of multiple
1256 insns, each setting one word of the output, and followed by a SET copying
1257 the output to itself.
1259 Each of the insns setting words of the output receives a REG_NO_CONFLICT
1260 note indicating that it doesn't conflict with the (also multi-word)
1261 inputs. The entire block is surrounded by REG_LIBCALL and REG_RETVAL
1264 INSNS is a block of code generated to perform the operation, not including
1265 the CLOBBER and final copy. All insns that compute intermediate values
1266 are first emitted, followed by the block as described above. Only
1267 INSNs are allowed in the block; no library calls or jumps may be
1270 TARGET, OP0, and OP1 are the output and inputs of the operations,
1271 respectively. OP1 may be zero for a unary operation.
1273 EQUIV, if non-zero, is an expression to be placed into a REG_EQUAL note
1276 If TARGET is not a register, INSNS is simply emitted with no special
1279 The final insn emitted is returned. */
1282 emit_no_conflict_block (insns, target, op0, op1, equiv)
1288 rtx prev, next, first, last, insn;
1290 if (GET_CODE (target) != REG || reload_in_progress)
1291 return emit_insns (insns);
1293 /* First emit all insns that do not store into words of the output and remove
1294 these from the list. */
1295 for (insn = insns; insn; insn = next)
1300 next = NEXT_INSN (insn);
1302 if (GET_CODE (insn) != INSN)
1305 if (GET_CODE (PATTERN (insn)) == SET)
1306 set = PATTERN (insn);
1307 else if (GET_CODE (PATTERN (insn)) == PARALLEL)
1309 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
1310 if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET)
1312 set = XVECEXP (PATTERN (insn), 0, i);
1320 if (! reg_overlap_mentioned_p (target, SET_DEST (set)))
1322 if (PREV_INSN (insn))
1323 NEXT_INSN (PREV_INSN (insn)) = next;
1328 PREV_INSN (next) = PREV_INSN (insn);
1334 prev = get_last_insn ();
1336 /* Now write the CLOBBER of the output, followed by the setting of each
1337 of the words, followed by the final copy. */
1338 if (target != op0 && target != op1)
1339 emit_insn (gen_rtx (CLOBBER, VOIDmode, target));
1341 for (insn = insns; insn; insn = next)
1343 next = NEXT_INSN (insn);
1346 if (op1 && GET_CODE (op1) == REG)
1347 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_NO_CONFLICT, op1,
1350 if (op0 && GET_CODE (op0) == REG)
1351 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_NO_CONFLICT, op0,
1355 last = emit_move_insn (target, target);
1357 REG_NOTES (last) = gen_rtx (EXPR_LIST, REG_EQUAL, equiv, REG_NOTES (last));
1360 first = get_insns ();
1362 first = NEXT_INSN (prev);
1364 /* Encapsulate the block so it gets manipulated as a unit. */
1365 REG_NOTES (first) = gen_rtx (INSN_LIST, REG_LIBCALL, last,
1367 REG_NOTES (last) = gen_rtx (INSN_LIST, REG_RETVAL, first, REG_NOTES (last));
1372 /* Emit code to make a call to a constant function or a library call.
1374 INSNS is a list containing all insns emitted in the call.
1375 These insns leave the result in RESULT. Our block is to copy RESULT
1376 to TARGET, which is logically equivalent to EQUIV.
1378 We first emit any insns that set a pseudo on the assumption that these are
1379 loading constants into registers; doing so allows them to be safely cse'ed
1380 between blocks. Then we emit all the other insns in the block, followed by
1381 an insn to move RESULT to TARGET. This last insn will have a REQ_EQUAL
1382 note with an operand of EQUIV.
1384 Moving assignments to pseudos outside of the block is done to improve
1385 the generated code, but is not required to generate correct code,
1386 hence being unable to move an assignment is not grounds for not making
1387 a libcall block. There are two reasons why it is safe to leave these
1388 insns inside the block: First, we know that these pseudos cannot be
1389 used in generated RTL outside the block since they are created for
1390 temporary purposes within the block. Second, CSE will not record the
1391 values of anything set inside a libcall block, so we know they must
1392 be dead at the end of the block.
1394 Except for the first group of insns (the ones setting pseudos), the
1395 block is delimited by REG_RETVAL and REG_LIBCALL notes. */
1398 emit_libcall_block (insns, target, result, equiv)
1404 rtx prev, next, first, last, insn;
1406 /* First emit all insns that set pseudos. Remove them from the list as
1407 we go. Avoid insns that set pseudo which were referenced in previous
1408 insns. These can be generated by move_by_pieces, for example,
1409 to update an address. */
1411 for (insn = insns; insn; insn = next)
1413 rtx set = single_set (insn);
1415 next = NEXT_INSN (insn);
1417 if (set != 0 && GET_CODE (SET_DEST (set)) == REG
1418 && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER
1420 || (! reg_mentioned_p (SET_DEST (set), PATTERN (insns))
1421 && ! reg_used_between_p (SET_DEST (set), insns, insn))))
1423 if (PREV_INSN (insn))
1424 NEXT_INSN (PREV_INSN (insn)) = next;
1429 PREV_INSN (next) = PREV_INSN (insn);
1435 prev = get_last_insn ();
1437 /* Write the remaining insns followed by the final copy. */
1439 for (insn = insns; insn; insn = next)
1441 next = NEXT_INSN (insn);
1446 last = emit_move_insn (target, result);
1447 REG_NOTES (last) = gen_rtx (EXPR_LIST, REG_EQUAL, equiv, REG_NOTES (last));
1450 first = get_insns ();
1452 first = NEXT_INSN (prev);
1454 /* Encapsulate the block so it gets manipulated as a unit. */
1455 REG_NOTES (first) = gen_rtx (INSN_LIST, REG_LIBCALL, last,
1457 REG_NOTES (last) = gen_rtx (INSN_LIST, REG_RETVAL, first, REG_NOTES (last));
1460 /* Generate code to store zero in X. */
1466 emit_move_insn (x, const0_rtx);
1469 /* Generate code to store 1 in X
1470 assuming it contains zero beforehand. */
1473 emit_0_to_1_insn (x)
1476 emit_move_insn (x, const1_rtx);
1479 /* Generate code to compare X with Y
1480 so that the condition codes are set.
1482 MODE is the mode of the inputs (in case they are const_int).
1483 UNSIGNEDP nonzero says that X and Y are unsigned;
1484 this matters if they need to be widened.
1486 If they have mode BLKmode, then SIZE specifies the size of both X and Y,
1487 and ALIGN specifies the known shared alignment of X and Y.
1489 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).
1490 It is ignored for fixed-point and block comparisons;
1491 it is used only for floating-point comparisons. */
1494 emit_cmp_insn (x, y, comparison, size, mode, unsignedp, align)
1496 enum rtx_code comparison;
1498 enum machine_mode mode;
1502 enum mode_class class;
1503 enum machine_mode wider_mode;
1505 class = GET_MODE_CLASS (mode);
1507 /* They could both be VOIDmode if both args are immediate constants,
1508 but we should fold that at an earlier stage.
1509 With no special code here, this will call abort,
1510 reminding the programmer to implement such folding. */
1512 if (mode != BLKmode && flag_force_mem)
1514 x = force_not_mem (x);
1515 y = force_not_mem (y);
1518 /* If we are inside an appropriately-short loop and one operand is an
1519 expensive constant, force it into a register. */
1520 if (CONSTANT_P (x) && preserve_subexpressions_p () && rtx_cost (x, COMPARE) > 2)
1521 x = force_reg (mode, x);
1523 if (CONSTANT_P (y) && preserve_subexpressions_p () && rtx_cost (y, COMPARE) > 2)
1524 y = force_reg (mode, y);
1526 /* Don't let both operands fail to indicate the mode. */
1527 if (GET_MODE (x) == VOIDmode && GET_MODE (y) == VOIDmode)
1528 x = force_reg (mode, x);
1530 /* Handle all BLKmode compares. */
1532 if (mode == BLKmode)
1535 x = protect_from_queue (x, 0);
1536 y = protect_from_queue (y, 0);
1540 #ifdef HAVE_cmpstrqi
1542 && GET_CODE (size) == CONST_INT
1543 && INTVAL (size) < (1 << GET_MODE_BITSIZE (QImode)))
1545 enum machine_mode result_mode
1546 = insn_operand_mode[(int) CODE_FOR_cmpstrqi][0];
1547 rtx result = gen_reg_rtx (result_mode);
1548 emit_insn (gen_cmpstrqi (result, x, y, size,
1549 gen_rtx (CONST_INT, VOIDmode, align)));
1550 emit_cmp_insn (result, const0_rtx, comparison, 0, result_mode, 0, 0);
1554 #ifdef HAVE_cmpstrhi
1556 && GET_CODE (size) == CONST_INT
1557 && INTVAL (size) < (1 << GET_MODE_BITSIZE (HImode)))
1559 enum machine_mode result_mode
1560 = insn_operand_mode[(int) CODE_FOR_cmpstrhi][0];
1561 rtx result = gen_reg_rtx (result_mode);
1562 emit_insn (gen_cmpstrhi (result, x, y, size,
1563 gen_rtx (CONST_INT, VOIDmode, align)));
1564 emit_cmp_insn (result, const0_rtx, comparison, 0, result_mode, 0, 0);
1568 #ifdef HAVE_cmpstrsi
1571 enum machine_mode result_mode
1572 = insn_operand_mode[(int) CODE_FOR_cmpstrsi][0];
1573 rtx result = gen_reg_rtx (result_mode);
1574 emit_insn (gen_cmpstrsi (result, x, y,
1575 convert_to_mode (SImode, size, 1),
1576 gen_rtx (CONST_INT, VOIDmode, align)));
1577 emit_cmp_insn (result, const0_rtx, comparison, 0, result_mode, 0, 0);
1582 #ifdef TARGET_MEM_FUNCTIONS
1583 emit_library_call (memcmp_libfunc, 1,
1584 TYPE_MODE (integer_type_node), 3,
1585 XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
1588 emit_library_call (bcmp_libfunc, 1,
1589 TYPE_MODE (integer_type_node), 3,
1590 XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
1593 emit_cmp_insn (hard_libcall_value (TYPE_MODE (integer_type_node)),
1594 const0_rtx, comparison, 0,
1595 TYPE_MODE (integer_type_node), 0, 0);
1600 /* Handle some compares against zero. */
1602 if (y == CONST0_RTX (mode)
1603 && tst_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1605 int icode = (int) tst_optab->handlers[(int) mode].insn_code;
1608 x = protect_from_queue (x, 0);
1609 y = protect_from_queue (y, 0);
1611 /* Now, if insn does accept these operands, put them into pseudos. */
1612 if (! (*insn_operand_predicate[icode][0])
1613 (x, insn_operand_mode[icode][0]))
1614 x = copy_to_mode_reg (insn_operand_mode[icode][0], x);
1616 emit_insn (GEN_FCN (icode) (x));
1620 /* Handle compares for which there is a directly suitable insn. */
1622 if (cmp_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1624 int icode = (int) cmp_optab->handlers[(int) mode].insn_code;
1627 x = protect_from_queue (x, 0);
1628 y = protect_from_queue (y, 0);
1630 /* Now, if insn doesn't accept these operands, put them into pseudos. */
1631 if (! (*insn_operand_predicate[icode][0])
1632 (x, insn_operand_mode[icode][0]))
1633 x = copy_to_mode_reg (insn_operand_mode[icode][0], x);
1635 if (! (*insn_operand_predicate[icode][1])
1636 (y, insn_operand_mode[icode][1]))
1637 y = copy_to_mode_reg (insn_operand_mode[icode][1], y);
1639 emit_insn (GEN_FCN (icode) (x, y));
1643 /* Try widening if we can find a direct insn that way. */
1645 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1647 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1648 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1650 if (cmp_optab->handlers[(int) wider_mode].insn_code
1651 != CODE_FOR_nothing)
1653 x = convert_to_mode (wider_mode, x, unsignedp);
1654 y = convert_to_mode (wider_mode, y, unsignedp);
1655 emit_cmp_insn (x, y, comparison, 0,
1656 wider_mode, unsignedp, align);
1662 /* Handle a lib call just for the mode we are using. */
1664 if (cmp_optab->handlers[(int) mode].libfunc
1665 && class != MODE_FLOAT)
1667 rtx libfunc = cmp_optab->handlers[(int) mode].libfunc;
1668 /* If we want unsigned, and this mode has a distinct unsigned
1669 comparison routine, use that. */
1670 if (unsignedp && ucmp_optab->handlers[(int) mode].libfunc)
1671 libfunc = ucmp_optab->handlers[(int) mode].libfunc;
1673 emit_library_call (libfunc, 1,
1674 SImode, 2, x, mode, y, mode);
1676 /* Integer comparison returns a result that must be compared against 1,
1677 so that even if we do an unsigned compare afterward,
1678 there is still a value that can represent the result "less than". */
1680 emit_cmp_insn (hard_libcall_value (SImode), const1_rtx,
1681 comparison, 0, SImode, unsignedp, 0);
1685 if (class == MODE_FLOAT)
1686 emit_float_lib_cmp (x, y, comparison);
1692 /* Nonzero if a compare of mode MODE can be done straightforwardly
1693 (without splitting it into pieces). */
1696 can_compare_p (mode)
1697 enum machine_mode mode;
1701 if (cmp_optab->handlers[(int)mode].insn_code != CODE_FOR_nothing)
1703 mode = GET_MODE_WIDER_MODE (mode);
1704 } while (mode != VOIDmode);
1709 /* Emit a library call comparison between floating point X and Y.
1710 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */
1713 emit_float_lib_cmp (x, y, comparison)
1715 enum rtx_code comparison;
1717 enum machine_mode mode = GET_MODE (x);
1724 libfunc = eqsf2_libfunc;
1728 libfunc = nesf2_libfunc;
1732 libfunc = gtsf2_libfunc;
1736 libfunc = gesf2_libfunc;
1740 libfunc = ltsf2_libfunc;
1744 libfunc = lesf2_libfunc;
1747 else if (mode == DFmode)
1751 libfunc = eqdf2_libfunc;
1755 libfunc = nedf2_libfunc;
1759 libfunc = gtdf2_libfunc;
1763 libfunc = gedf2_libfunc;
1767 libfunc = ltdf2_libfunc;
1771 libfunc = ledf2_libfunc;
1774 else if (mode == XFmode)
1778 libfunc = eqxf2_libfunc;
1782 libfunc = nexf2_libfunc;
1786 libfunc = gtxf2_libfunc;
1790 libfunc = gexf2_libfunc;
1794 libfunc = ltxf2_libfunc;
1798 libfunc = lexf2_libfunc;
1801 else if (mode == TFmode)
1805 libfunc = eqtf2_libfunc;
1809 libfunc = netf2_libfunc;
1813 libfunc = gttf2_libfunc;
1817 libfunc = getf2_libfunc;
1821 libfunc = lttf2_libfunc;
1825 libfunc = letf2_libfunc;
1830 enum machine_mode wider_mode;
1832 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1833 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1835 if ((cmp_optab->handlers[(int) wider_mode].insn_code
1836 != CODE_FOR_nothing)
1837 || (cmp_optab->handlers[(int) wider_mode].libfunc != 0))
1839 x = convert_to_mode (wider_mode, x, 0);
1840 y = convert_to_mode (wider_mode, y, 0);
1841 emit_float_lib_cmp (x, y, comparison);
1848 emit_library_call (libfunc, 1,
1849 SImode, 2, x, mode, y, mode);
1851 emit_cmp_insn (hard_libcall_value (SImode), const0_rtx, comparison,
1855 /* Generate code to indirectly jump to a location given in the rtx LOC. */
1858 emit_indirect_jump (loc)
1861 if (! ((*insn_operand_predicate[(int)CODE_FOR_indirect_jump][0])
1863 loc = copy_to_mode_reg (insn_operand_mode[(int)CODE_FOR_indirect_jump][0],
1866 emit_jump_insn (gen_indirect_jump (loc));
1870 /* These three functions generate an insn body and return it
1871 rather than emitting the insn.
1873 They do not protect from queued increments,
1874 because they may be used 1) in protect_from_queue itself
1875 and 2) in other passes where there is no queue. */
1877 /* Generate and return an insn body to add Y to X. */
1880 gen_add2_insn (x, y)
1883 int icode = (int) add_optab->handlers[(int) GET_MODE (x)].insn_code;
1885 if (! (*insn_operand_predicate[icode][0]) (x, insn_operand_mode[icode][0])
1886 || ! (*insn_operand_predicate[icode][1]) (x, insn_operand_mode[icode][1])
1887 || ! (*insn_operand_predicate[icode][2]) (y, insn_operand_mode[icode][2]))
1890 return (GEN_FCN (icode) (x, x, y));
1894 have_add2_insn (mode)
1895 enum machine_mode mode;
1897 return add_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
1900 /* Generate and return an insn body to subtract Y from X. */
1903 gen_sub2_insn (x, y)
1906 int icode = (int) sub_optab->handlers[(int) GET_MODE (x)].insn_code;
1908 if (! (*insn_operand_predicate[icode][0]) (x, insn_operand_mode[icode][0])
1909 || ! (*insn_operand_predicate[icode][1]) (x, insn_operand_mode[icode][1])
1910 || ! (*insn_operand_predicate[icode][2]) (y, insn_operand_mode[icode][2]))
1913 return (GEN_FCN (icode) (x, x, y));
1917 have_sub2_insn (mode)
1918 enum machine_mode mode;
1920 return sub_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
1923 /* Generate the body of an instruction to copy Y into X. */
1926 gen_move_insn (x, y)
1929 register enum machine_mode mode = GET_MODE (x);
1930 enum insn_code insn_code;
1932 if (mode == VOIDmode)
1933 mode = GET_MODE (y);
1935 insn_code = mov_optab->handlers[(int) mode].insn_code;
1937 /* Handle MODE_CC modes: If we don't have a special move insn for this mode,
1938 find a mode to do it in. If we have a movcc, use it. Otherwise,
1939 find the MODE_INT mode of the same width. */
1941 if (insn_code == CODE_FOR_nothing)
1943 enum machine_mode tmode = VOIDmode;
1946 if (GET_MODE_CLASS (mode) == MODE_CC && mode != CCmode
1947 && mov_optab->handlers[(int) CCmode].insn_code != CODE_FOR_nothing)
1949 else if (GET_MODE_CLASS (mode) == MODE_CC)
1950 for (tmode = QImode; tmode != VOIDmode;
1951 tmode = GET_MODE_WIDER_MODE (tmode))
1952 if (GET_MODE_SIZE (tmode) == GET_MODE_SIZE (mode))
1955 if (tmode == VOIDmode)
1958 /* Get X and Y in TMODE. We can't use gen_lowpart here because it
1959 may call change_address which is not appropriate if we were
1960 called when a reload was in progress. We don't have to worry
1961 about changing the address since the size in bytes is supposed to
1962 be the same. Copy the MEM to change the mode and move any
1963 substitutions from the old MEM to the new one. */
1965 if (reload_in_progress)
1967 x = gen_lowpart_common (tmode, x1);
1968 if (x == 0 && GET_CODE (x1) == MEM)
1970 x = gen_rtx (MEM, tmode, XEXP (x1, 0));
1971 RTX_UNCHANGING_P (x) = RTX_UNCHANGING_P (x1);
1972 MEM_IN_STRUCT_P (x) = MEM_IN_STRUCT_P (x1);
1973 MEM_VOLATILE_P (x) = MEM_VOLATILE_P (x1);
1974 copy_replacements (x1, x);
1977 y = gen_lowpart_common (tmode, y1);
1978 if (y == 0 && GET_CODE (y1) == MEM)
1980 y = gen_rtx (MEM, tmode, XEXP (y1, 0));
1981 RTX_UNCHANGING_P (y) = RTX_UNCHANGING_P (y1);
1982 MEM_IN_STRUCT_P (y) = MEM_IN_STRUCT_P (y1);
1983 MEM_VOLATILE_P (y) = MEM_VOLATILE_P (y1);
1984 copy_replacements (y1, y);
1989 x = gen_lowpart (tmode, x);
1990 y = gen_lowpart (tmode, y);
1993 insn_code = mov_optab->handlers[(int) tmode].insn_code;
1996 return (GEN_FCN (insn_code) (x, y));
1999 /* Tables of patterns for extending one integer mode to another. */
2000 static enum insn_code extendtab[MAX_MACHINE_MODE][MAX_MACHINE_MODE][2];
2002 /* Return the insn code used to extend FROM_MODE to TO_MODE.
2003 UNSIGNEDP specifies zero-extension instead of sign-extension. If
2004 no such operation exists, CODE_FOR_nothing will be returned. */
2007 can_extend_p (to_mode, from_mode, unsignedp)
2008 enum machine_mode to_mode, from_mode;
2011 return extendtab[(int) to_mode][(int) from_mode][unsignedp];
2014 /* Generate the body of an insn to extend Y (with mode MFROM)
2015 into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */
2018 gen_extend_insn (x, y, mto, mfrom, unsignedp)
2020 enum machine_mode mto, mfrom;
2023 return (GEN_FCN (extendtab[(int) mto][(int) mfrom][unsignedp]) (x, y));
2031 for (p = extendtab[0][0];
2032 p < extendtab[0][0] + sizeof extendtab / sizeof extendtab[0][0][0];
2034 *p = CODE_FOR_nothing;
2036 #ifdef HAVE_extendditi2
2037 if (HAVE_extendditi2)
2038 extendtab[(int) TImode][(int) DImode][0] = CODE_FOR_extendditi2;
2040 #ifdef HAVE_extendsiti2
2041 if (HAVE_extendsiti2)
2042 extendtab[(int) TImode][(int) SImode][0] = CODE_FOR_extendsiti2;
2044 #ifdef HAVE_extendhiti2
2045 if (HAVE_extendhiti2)
2046 extendtab[(int) TImode][(int) HImode][0] = CODE_FOR_extendhiti2;
2048 #ifdef HAVE_extendqiti2
2049 if (HAVE_extendqiti2)
2050 extendtab[(int) TImode][(int) QImode][0] = CODE_FOR_extendqiti2;
2052 #ifdef HAVE_extendsidi2
2053 if (HAVE_extendsidi2)
2054 extendtab[(int) DImode][(int) SImode][0] = CODE_FOR_extendsidi2;
2056 #ifdef HAVE_extendhidi2
2057 if (HAVE_extendhidi2)
2058 extendtab[(int) DImode][(int) HImode][0] = CODE_FOR_extendhidi2;
2060 #ifdef HAVE_extendqidi2
2061 if (HAVE_extendqidi2)
2062 extendtab[(int) DImode][(int) QImode][0] = CODE_FOR_extendqidi2;
2064 #ifdef HAVE_extendhisi2
2065 if (HAVE_extendhisi2)
2066 extendtab[(int) SImode][(int) HImode][0] = CODE_FOR_extendhisi2;
2068 #ifdef HAVE_extendqisi2
2069 if (HAVE_extendqisi2)
2070 extendtab[(int) SImode][(int) QImode][0] = CODE_FOR_extendqisi2;
2072 #ifdef HAVE_extendqihi2
2073 if (HAVE_extendqihi2)
2074 extendtab[(int) HImode][(int) QImode][0] = CODE_FOR_extendqihi2;
2077 #ifdef HAVE_zero_extendditi2
2078 if (HAVE_zero_extendsiti2)
2079 extendtab[(int) TImode][(int) DImode][1] = CODE_FOR_zero_extendditi2;
2081 #ifdef HAVE_zero_extendsiti2
2082 if (HAVE_zero_extendsiti2)
2083 extendtab[(int) TImode][(int) SImode][1] = CODE_FOR_zero_extendsiti2;
2085 #ifdef HAVE_zero_extendhiti2
2086 if (HAVE_zero_extendhiti2)
2087 extendtab[(int) TImode][(int) HImode][1] = CODE_FOR_zero_extendhiti2;
2089 #ifdef HAVE_zero_extendqiti2
2090 if (HAVE_zero_extendqiti2)
2091 extendtab[(int) TImode][(int) QImode][1] = CODE_FOR_zero_extendqiti2;
2093 #ifdef HAVE_zero_extendsidi2
2094 if (HAVE_zero_extendsidi2)
2095 extendtab[(int) DImode][(int) SImode][1] = CODE_FOR_zero_extendsidi2;
2097 #ifdef HAVE_zero_extendhidi2
2098 if (HAVE_zero_extendhidi2)
2099 extendtab[(int) DImode][(int) HImode][1] = CODE_FOR_zero_extendhidi2;
2101 #ifdef HAVE_zero_extendqidi2
2102 if (HAVE_zero_extendqidi2)
2103 extendtab[(int) DImode][(int) QImode][1] = CODE_FOR_zero_extendqidi2;
2105 #ifdef HAVE_zero_extendhisi2
2106 if (HAVE_zero_extendhisi2)
2107 extendtab[(int) SImode][(int) HImode][1] = CODE_FOR_zero_extendhisi2;
2109 #ifdef HAVE_zero_extendqisi2
2110 if (HAVE_zero_extendqisi2)
2111 extendtab[(int) SImode][(int) QImode][1] = CODE_FOR_zero_extendqisi2;
2113 #ifdef HAVE_zero_extendqihi2
2114 if (HAVE_zero_extendqihi2)
2115 extendtab[(int) HImode][(int) QImode][1] = CODE_FOR_zero_extendqihi2;
2119 /* can_fix_p and can_float_p say whether the target machine
2120 can directly convert a given fixed point type to
2121 a given floating point type, or vice versa.
2122 The returned value is the CODE_FOR_... value to use,
2123 or CODE_FOR_nothing if these modes cannot be directly converted. */
2125 static enum insn_code fixtab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
2126 static enum insn_code fixtrunctab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
2127 static enum insn_code floattab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
2129 /* *TRUNCP_PTR is set to 1 if it is necessary to output
2130 an explicit FTRUNC insn before the fix insn; otherwise 0. */
2132 static enum insn_code
2133 can_fix_p (fixmode, fltmode, unsignedp, truncp_ptr)
2134 enum machine_mode fltmode, fixmode;
2139 if (fixtrunctab[(int) fltmode][(int) fixmode][unsignedp] != CODE_FOR_nothing)
2140 return fixtrunctab[(int) fltmode][(int) fixmode][unsignedp];
2142 if (ftrunc_optab->handlers[(int) fltmode].insn_code != CODE_FOR_nothing)
2145 return fixtab[(int) fltmode][(int) fixmode][unsignedp];
2147 return CODE_FOR_nothing;
2150 static enum insn_code
2151 can_float_p (fltmode, fixmode, unsignedp)
2152 enum machine_mode fixmode, fltmode;
2155 return floattab[(int) fltmode][(int) fixmode][unsignedp];
2162 for (p = fixtab[0][0];
2163 p < fixtab[0][0] + sizeof fixtab / sizeof (fixtab[0][0][0]);
2165 *p = CODE_FOR_nothing;
2166 for (p = fixtrunctab[0][0];
2167 p < fixtrunctab[0][0] + sizeof fixtrunctab / sizeof (fixtrunctab[0][0][0]);
2169 *p = CODE_FOR_nothing;
2171 #ifdef HAVE_fixsfqi2
2173 fixtab[(int) SFmode][(int) QImode][0] = CODE_FOR_fixsfqi2;
2175 #ifdef HAVE_fixsfhi2
2177 fixtab[(int) SFmode][(int) HImode][0] = CODE_FOR_fixsfhi2;
2179 #ifdef HAVE_fixsfsi2
2181 fixtab[(int) SFmode][(int) SImode][0] = CODE_FOR_fixsfsi2;
2183 #ifdef HAVE_fixsfdi2
2185 fixtab[(int) SFmode][(int) DImode][0] = CODE_FOR_fixsfdi2;
2188 #ifdef HAVE_fixdfqi2
2190 fixtab[(int) DFmode][(int) QImode][0] = CODE_FOR_fixdfqi2;
2192 #ifdef HAVE_fixdfhi2
2194 fixtab[(int) DFmode][(int) HImode][0] = CODE_FOR_fixdfhi2;
2196 #ifdef HAVE_fixdfsi2
2198 fixtab[(int) DFmode][(int) SImode][0] = CODE_FOR_fixdfsi2;
2200 #ifdef HAVE_fixdfdi2
2202 fixtab[(int) DFmode][(int) DImode][0] = CODE_FOR_fixdfdi2;
2204 #ifdef HAVE_fixdfti2
2206 fixtab[(int) DFmode][(int) TImode][0] = CODE_FOR_fixdfti2;
2209 #ifdef HAVE_fixxfqi2
2211 fixtab[(int) XFmode][(int) QImode][0] = CODE_FOR_fixxfqi2;
2213 #ifdef HAVE_fixxfhi2
2215 fixtab[(int) XFmode][(int) HImode][0] = CODE_FOR_fixxfhi2;
2217 #ifdef HAVE_fixxfsi2
2219 fixtab[(int) XFmode][(int) SImode][0] = CODE_FOR_fixxfsi2;
2221 #ifdef HAVE_fixxfdi2
2223 fixtab[(int) XFmode][(int) DImode][0] = CODE_FOR_fixxfdi2;
2225 #ifdef HAVE_fixxfti2
2227 fixtab[(int) XFmode][(int) TImode][0] = CODE_FOR_fixxfti2;
2230 #ifdef HAVE_fixtfqi2
2232 fixtab[(int) TFmode][(int) QImode][0] = CODE_FOR_fixtfqi2;
2234 #ifdef HAVE_fixtfhi2
2236 fixtab[(int) TFmode][(int) HImode][0] = CODE_FOR_fixtfhi2;
2238 #ifdef HAVE_fixtfsi2
2240 fixtab[(int) TFmode][(int) SImode][0] = CODE_FOR_fixtfsi2;
2242 #ifdef HAVE_fixtfdi2
2244 fixtab[(int) TFmode][(int) DImode][0] = CODE_FOR_fixtfdi2;
2246 #ifdef HAVE_fixtfti2
2248 fixtab[(int) TFmode][(int) TImode][0] = CODE_FOR_fixtfti2;
2251 #ifdef HAVE_fixunssfqi2
2252 if (HAVE_fixunssfqi2)
2253 fixtab[(int) SFmode][(int) QImode][1] = CODE_FOR_fixunssfqi2;
2255 #ifdef HAVE_fixunssfhi2
2256 if (HAVE_fixunssfhi2)
2257 fixtab[(int) SFmode][(int) HImode][1] = CODE_FOR_fixunssfhi2;
2259 #ifdef HAVE_fixunssfsi2
2260 if (HAVE_fixunssfsi2)
2261 fixtab[(int) SFmode][(int) SImode][1] = CODE_FOR_fixunssfsi2;
2263 #ifdef HAVE_fixunssfdi2
2264 if (HAVE_fixunssfdi2)
2265 fixtab[(int) SFmode][(int) DImode][1] = CODE_FOR_fixunssfdi2;
2268 #ifdef HAVE_fixunsdfqi2
2269 if (HAVE_fixunsdfqi2)
2270 fixtab[(int) DFmode][(int) QImode][1] = CODE_FOR_fixunsdfqi2;
2272 #ifdef HAVE_fixunsdfhi2
2273 if (HAVE_fixunsdfhi2)
2274 fixtab[(int) DFmode][(int) HImode][1] = CODE_FOR_fixunsdfhi2;
2276 #ifdef HAVE_fixunsdfsi2
2277 if (HAVE_fixunsdfsi2)
2278 fixtab[(int) DFmode][(int) SImode][1] = CODE_FOR_fixunsdfsi2;
2280 #ifdef HAVE_fixunsdfdi2
2281 if (HAVE_fixunsdfdi2)
2282 fixtab[(int) DFmode][(int) DImode][1] = CODE_FOR_fixunsdfdi2;
2284 #ifdef HAVE_fixunsdfti2
2285 if (HAVE_fixunsdfti2)
2286 fixtab[(int) DFmode][(int) TImode][1] = CODE_FOR_fixunsdfti2;
2289 #ifdef HAVE_fixunsxfqi2
2290 if (HAVE_fixunsxfqi2)
2291 fixtab[(int) XFmode][(int) QImode][1] = CODE_FOR_fixunsxfqi2;
2293 #ifdef HAVE_fixunsxfhi2
2294 if (HAVE_fixunsxfhi2)
2295 fixtab[(int) XFmode][(int) HImode][1] = CODE_FOR_fixunsxfhi2;
2297 #ifdef HAVE_fixunsxfsi2
2298 if (HAVE_fixunsxfsi2)
2299 fixtab[(int) XFmode][(int) SImode][1] = CODE_FOR_fixunsxfsi2;
2301 #ifdef HAVE_fixunsxfdi2
2302 if (HAVE_fixunsxfdi2)
2303 fixtab[(int) XFmode][(int) DImode][1] = CODE_FOR_fixunsxfdi2;
2305 #ifdef HAVE_fixunsxfti2
2306 if (HAVE_fixunsxfti2)
2307 fixtab[(int) XFmode][(int) TImode][1] = CODE_FOR_fixunsxfti2;
2310 #ifdef HAVE_fixunstfqi2
2311 if (HAVE_fixunstfqi2)
2312 fixtab[(int) TFmode][(int) QImode][1] = CODE_FOR_fixunstfqi2;
2314 #ifdef HAVE_fixunstfhi2
2315 if (HAVE_fixunstfhi2)
2316 fixtab[(int) TFmode][(int) HImode][1] = CODE_FOR_fixunstfhi2;
2318 #ifdef HAVE_fixunstfsi2
2319 if (HAVE_fixunstfsi2)
2320 fixtab[(int) TFmode][(int) SImode][1] = CODE_FOR_fixunstfsi2;
2322 #ifdef HAVE_fixunstfdi2
2323 if (HAVE_fixunstfdi2)
2324 fixtab[(int) TFmode][(int) DImode][1] = CODE_FOR_fixunstfdi2;
2326 #ifdef HAVE_fixunstfti2
2327 if (HAVE_fixunstfti2)
2328 fixtab[(int) TFmode][(int) TImode][1] = CODE_FOR_fixunstfti2;
2331 #ifdef HAVE_fix_truncsfqi2
2332 if (HAVE_fix_truncsfqi2)
2333 fixtrunctab[(int) SFmode][(int) QImode][0] = CODE_FOR_fix_truncsfqi2;
2335 #ifdef HAVE_fix_truncsfhi2
2336 if (HAVE_fix_truncsfhi2)
2337 fixtrunctab[(int) SFmode][(int) HImode][0] = CODE_FOR_fix_truncsfhi2;
2339 #ifdef HAVE_fix_truncsfsi2
2340 if (HAVE_fix_truncsfsi2)
2341 fixtrunctab[(int) SFmode][(int) SImode][0] = CODE_FOR_fix_truncsfsi2;
2343 #ifdef HAVE_fix_truncsfdi2
2344 if (HAVE_fix_truncsfdi2)
2345 fixtrunctab[(int) SFmode][(int) DImode][0] = CODE_FOR_fix_truncsfdi2;
2348 #ifdef HAVE_fix_truncdfqi2
2349 if (HAVE_fix_truncdfsi2)
2350 fixtrunctab[(int) DFmode][(int) QImode][0] = CODE_FOR_fix_truncdfqi2;
2352 #ifdef HAVE_fix_truncdfhi2
2353 if (HAVE_fix_truncdfhi2)
2354 fixtrunctab[(int) DFmode][(int) HImode][0] = CODE_FOR_fix_truncdfhi2;
2356 #ifdef HAVE_fix_truncdfsi2
2357 if (HAVE_fix_truncdfsi2)
2358 fixtrunctab[(int) DFmode][(int) SImode][0] = CODE_FOR_fix_truncdfsi2;
2360 #ifdef HAVE_fix_truncdfdi2
2361 if (HAVE_fix_truncdfdi2)
2362 fixtrunctab[(int) DFmode][(int) DImode][0] = CODE_FOR_fix_truncdfdi2;
2364 #ifdef HAVE_fix_truncdfti2
2365 if (HAVE_fix_truncdfti2)
2366 fixtrunctab[(int) DFmode][(int) TImode][0] = CODE_FOR_fix_truncdfti2;
2369 #ifdef HAVE_fix_truncxfqi2
2370 if (HAVE_fix_truncxfqi2)
2371 fixtrunctab[(int) XFmode][(int) QImode][0] = CODE_FOR_fix_truncxfqi2;
2373 #ifdef HAVE_fix_truncxfhi2
2374 if (HAVE_fix_truncxfhi2)
2375 fixtrunctab[(int) XFmode][(int) HImode][0] = CODE_FOR_fix_truncxfhi2;
2377 #ifdef HAVE_fix_truncxfsi2
2378 if (HAVE_fix_truncxfsi2)
2379 fixtrunctab[(int) XFmode][(int) SImode][0] = CODE_FOR_fix_truncxfsi2;
2381 #ifdef HAVE_fix_truncxfdi2
2382 if (HAVE_fix_truncxfdi2)
2383 fixtrunctab[(int) XFmode][(int) DImode][0] = CODE_FOR_fix_truncxfdi2;
2385 #ifdef HAVE_fix_truncxfti2
2386 if (HAVE_fix_truncxfti2)
2387 fixtrunctab[(int) XFmode][(int) TImode][0] = CODE_FOR_fix_truncxfti2;
2390 #ifdef HAVE_fix_trunctfqi2
2391 if (HAVE_fix_trunctfqi2)
2392 fixtrunctab[(int) TFmode][(int) QImode][0] = CODE_FOR_fix_trunctfqi2;
2394 #ifdef HAVE_fix_trunctfhi2
2395 if (HAVE_fix_trunctfhi2)
2396 fixtrunctab[(int) TFmode][(int) HImode][0] = CODE_FOR_fix_trunctfhi2;
2398 #ifdef HAVE_fix_trunctfsi2
2399 if (HAVE_fix_trunctfsi2)
2400 fixtrunctab[(int) TFmode][(int) SImode][0] = CODE_FOR_fix_trunctfsi2;
2402 #ifdef HAVE_fix_trunctfdi2
2403 if (HAVE_fix_trunctfdi2)
2404 fixtrunctab[(int) TFmode][(int) DImode][0] = CODE_FOR_fix_trunctfdi2;
2406 #ifdef HAVE_fix_trunctfti2
2407 if (HAVE_fix_trunctfti2)
2408 fixtrunctab[(int) TFmode][(int) TImode][0] = CODE_FOR_fix_trunctfti2;
2411 #ifdef HAVE_fixuns_truncsfqi2
2412 if (HAVE_fixuns_truncsfqi2)
2413 fixtrunctab[(int) SFmode][(int) QImode][1] = CODE_FOR_fixuns_truncsfqi2;
2415 #ifdef HAVE_fixuns_truncsfhi2
2416 if (HAVE_fixuns_truncsfhi2)
2417 fixtrunctab[(int) SFmode][(int) HImode][1] = CODE_FOR_fixuns_truncsfhi2;
2419 #ifdef HAVE_fixuns_truncsfsi2
2420 if (HAVE_fixuns_truncsfsi2)
2421 fixtrunctab[(int) SFmode][(int) SImode][1] = CODE_FOR_fixuns_truncsfsi2;
2423 #ifdef HAVE_fixuns_truncsfdi2
2424 if (HAVE_fixuns_truncsfdi2)
2425 fixtrunctab[(int) SFmode][(int) DImode][1] = CODE_FOR_fixuns_truncsfdi2;
2428 #ifdef HAVE_fixuns_truncdfqi2
2429 if (HAVE_fixuns_truncdfqi2)
2430 fixtrunctab[(int) DFmode][(int) QImode][1] = CODE_FOR_fixuns_truncdfqi2;
2432 #ifdef HAVE_fixuns_truncdfhi2
2433 if (HAVE_fixuns_truncdfhi2)
2434 fixtrunctab[(int) DFmode][(int) HImode][1] = CODE_FOR_fixuns_truncdfhi2;
2436 #ifdef HAVE_fixuns_truncdfsi2
2437 if (HAVE_fixuns_truncdfsi2)
2438 fixtrunctab[(int) DFmode][(int) SImode][1] = CODE_FOR_fixuns_truncdfsi2;
2440 #ifdef HAVE_fixuns_truncdfdi2
2441 if (HAVE_fixuns_truncdfdi2)
2442 fixtrunctab[(int) DFmode][(int) DImode][1] = CODE_FOR_fixuns_truncdfdi2;
2444 #ifdef HAVE_fixuns_truncdfti2
2445 if (HAVE_fixuns_truncdfti2)
2446 fixtrunctab[(int) DFmode][(int) TImode][1] = CODE_FOR_fixuns_truncdfti2;
2449 #ifdef HAVE_fixuns_truncxfqi2
2450 if (HAVE_fixuns_truncxfqi2)
2451 fixtrunctab[(int) XFmode][(int) QImode][1] = CODE_FOR_fixuns_truncxfqi2;
2453 #ifdef HAVE_fixuns_truncxfhi2
2454 if (HAVE_fixuns_truncxfhi2)
2455 fixtrunctab[(int) XFmode][(int) HImode][1] = CODE_FOR_fixuns_truncxfhi2;
2457 #ifdef HAVE_fixuns_truncxfsi2
2458 if (HAVE_fixuns_truncxfsi2)
2459 fixtrunctab[(int) XFmode][(int) SImode][1] = CODE_FOR_fixuns_truncxfsi2;
2461 #ifdef HAVE_fixuns_truncxfdi2
2462 if (HAVE_fixuns_truncxfdi2)
2463 fixtrunctab[(int) XFmode][(int) DImode][1] = CODE_FOR_fixuns_truncxfdi2;
2465 #ifdef HAVE_fixuns_truncxfti2
2466 if (HAVE_fixuns_truncxfti2)
2467 fixtrunctab[(int) XFmode][(int) TImode][1] = CODE_FOR_fixuns_truncxfti2;
2470 #ifdef HAVE_fixuns_trunctfqi2
2471 if (HAVE_fixuns_trunctfqi2)
2472 fixtrunctab[(int) TFmode][(int) QImode][1] = CODE_FOR_fixuns_trunctfqi2;
2474 #ifdef HAVE_fixuns_trunctfhi2
2475 if (HAVE_fixuns_trunctfhi2)
2476 fixtrunctab[(int) TFmode][(int) HImode][1] = CODE_FOR_fixuns_trunctfhi2;
2478 #ifdef HAVE_fixuns_trunctfsi2
2479 if (HAVE_fixuns_trunctfsi2)
2480 fixtrunctab[(int) TFmode][(int) SImode][1] = CODE_FOR_fixuns_trunctfsi2;
2482 #ifdef HAVE_fixuns_trunctfdi2
2483 if (HAVE_fixuns_trunctfdi2)
2484 fixtrunctab[(int) TFmode][(int) DImode][1] = CODE_FOR_fixuns_trunctfdi2;
2486 #ifdef HAVE_fixuns_trunctfti2
2487 if (HAVE_fixuns_trunctfti2)
2488 fixtrunctab[(int) TFmode][(int) TImode][1] = CODE_FOR_fixuns_trunctfti2;
2491 #ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC
2492 /* This flag says the same insns that convert to a signed fixnum
2493 also convert validly to an unsigned one. */
2497 for (i = 0; i < NUM_MACHINE_MODES; i++)
2498 for (j = 0; j < NUM_MACHINE_MODES; j++)
2499 fixtrunctab[i][j][1] = fixtrunctab[i][j][0];
2508 for (p = floattab[0][0];
2509 p < floattab[0][0] + sizeof floattab / sizeof (floattab[0][0][0]);
2511 *p = CODE_FOR_nothing;
2513 #ifdef HAVE_floatqisf2
2514 if (HAVE_floatqisf2)
2515 floattab[(int) SFmode][(int) QImode][0] = CODE_FOR_floatqisf2;
2517 #ifdef HAVE_floathisf2
2518 if (HAVE_floathisf2)
2519 floattab[(int) SFmode][(int) HImode][0] = CODE_FOR_floathisf2;
2521 #ifdef HAVE_floatsisf2
2522 if (HAVE_floatsisf2)
2523 floattab[(int) SFmode][(int) SImode][0] = CODE_FOR_floatsisf2;
2525 #ifdef HAVE_floatdisf2
2526 if (HAVE_floatdisf2)
2527 floattab[(int) SFmode][(int) DImode][0] = CODE_FOR_floatdisf2;
2529 #ifdef HAVE_floattisf2
2530 if (HAVE_floattisf2)
2531 floattab[(int) SFmode][(int) TImode][0] = CODE_FOR_floattisf2;
2534 #ifdef HAVE_floatqidf2
2535 if (HAVE_floatqidf2)
2536 floattab[(int) DFmode][(int) QImode][0] = CODE_FOR_floatqidf2;
2538 #ifdef HAVE_floathidf2
2539 if (HAVE_floathidf2)
2540 floattab[(int) DFmode][(int) HImode][0] = CODE_FOR_floathidf2;
2542 #ifdef HAVE_floatsidf2
2543 if (HAVE_floatsidf2)
2544 floattab[(int) DFmode][(int) SImode][0] = CODE_FOR_floatsidf2;
2546 #ifdef HAVE_floatdidf2
2547 if (HAVE_floatdidf2)
2548 floattab[(int) DFmode][(int) DImode][0] = CODE_FOR_floatdidf2;
2550 #ifdef HAVE_floattidf2
2551 if (HAVE_floattidf2)
2552 floattab[(int) DFmode][(int) TImode][0] = CODE_FOR_floattidf2;
2555 #ifdef HAVE_floatqixf2
2556 if (HAVE_floatqixf2)
2557 floattab[(int) XFmode][(int) QImode][0] = CODE_FOR_floatqixf2;
2559 #ifdef HAVE_floathixf2
2560 if (HAVE_floathixf2)
2561 floattab[(int) XFmode][(int) HImode][0] = CODE_FOR_floathixf2;
2563 #ifdef HAVE_floatsixf2
2564 if (HAVE_floatsixf2)
2565 floattab[(int) XFmode][(int) SImode][0] = CODE_FOR_floatsixf2;
2567 #ifdef HAVE_floatdixf2
2568 if (HAVE_floatdixf2)
2569 floattab[(int) XFmode][(int) DImode][0] = CODE_FOR_floatdixf2;
2571 #ifdef HAVE_floattixf2
2572 if (HAVE_floattixf2)
2573 floattab[(int) XFmode][(int) TImode][0] = CODE_FOR_floattixf2;
2576 #ifdef HAVE_floatqitf2
2577 if (HAVE_floatqitf2)
2578 floattab[(int) TFmode][(int) QImode][0] = CODE_FOR_floatqitf2;
2580 #ifdef HAVE_floathitf2
2581 if (HAVE_floathitf2)
2582 floattab[(int) TFmode][(int) HImode][0] = CODE_FOR_floathitf2;
2584 #ifdef HAVE_floatsitf2
2585 if (HAVE_floatsitf2)
2586 floattab[(int) TFmode][(int) SImode][0] = CODE_FOR_floatsitf2;
2588 #ifdef HAVE_floatditf2
2589 if (HAVE_floatditf2)
2590 floattab[(int) TFmode][(int) DImode][0] = CODE_FOR_floatditf2;
2592 #ifdef HAVE_floattitf2
2593 if (HAVE_floattitf2)
2594 floattab[(int) TFmode][(int) TImode][0] = CODE_FOR_floattitf2;
2597 #ifdef HAVE_floatunsqisf2
2598 if (HAVE_floatunsqisf2)
2599 floattab[(int) SFmode][(int) QImode][1] = CODE_FOR_floatunsqisf2;
2601 #ifdef HAVE_floatunshisf2
2602 if (HAVE_floatunshisf2)
2603 floattab[(int) SFmode][(int) HImode][1] = CODE_FOR_floatunshisf2;
2605 #ifdef HAVE_floatunssisf2
2606 if (HAVE_floatunssisf2)
2607 floattab[(int) SFmode][(int) SImode][1] = CODE_FOR_floatunssisf2;
2609 #ifdef HAVE_floatunsdisf2
2610 if (HAVE_floatunsdisf2)
2611 floattab[(int) SFmode][(int) DImode][1] = CODE_FOR_floatunsdisf2;
2613 #ifdef HAVE_floatunstisf2
2614 if (HAVE_floatunstisf2)
2615 floattab[(int) SFmode][(int) TImode][1] = CODE_FOR_floatunstisf2;
2618 #ifdef HAVE_floatunsqidf2
2619 if (HAVE_floatunsqidf2)
2620 floattab[(int) DFmode][(int) QImode][1] = CODE_FOR_floatunsqidf2;
2622 #ifdef HAVE_floatunshidf2
2623 if (HAVE_floatunshidf2)
2624 floattab[(int) DFmode][(int) HImode][1] = CODE_FOR_floatunshidf2;
2626 #ifdef HAVE_floatunssidf2
2627 if (HAVE_floatunssidf2)
2628 floattab[(int) DFmode][(int) SImode][1] = CODE_FOR_floatunssidf2;
2630 #ifdef HAVE_floatunsdidf2
2631 if (HAVE_floatunsdidf2)
2632 floattab[(int) DFmode][(int) DImode][1] = CODE_FOR_floatunsdidf2;
2634 #ifdef HAVE_floatunstidf2
2635 if (HAVE_floatunstidf2)
2636 floattab[(int) DFmode][(int) TImode][1] = CODE_FOR_floatunstidf2;
2639 #ifdef HAVE_floatunsqixf2
2640 if (HAVE_floatunsqixf2)
2641 floattab[(int) XFmode][(int) QImode][1] = CODE_FOR_floatunsqixf2;
2643 #ifdef HAVE_floatunshixf2
2644 if (HAVE_floatunshixf2)
2645 floattab[(int) XFmode][(int) HImode][1] = CODE_FOR_floatunshixf2;
2647 #ifdef HAVE_floatunssixf2
2648 if (HAVE_floatunssixf2)
2649 floattab[(int) XFmode][(int) SImode][1] = CODE_FOR_floatunssixf2;
2651 #ifdef HAVE_floatunsdixf2
2652 if (HAVE_floatunsdixf2)
2653 floattab[(int) XFmode][(int) DImode][1] = CODE_FOR_floatunsdixf2;
2655 #ifdef HAVE_floatunstixf2
2656 if (HAVE_floatunstixf2)
2657 floattab[(int) XFmode][(int) TImode][1] = CODE_FOR_floatunstixf2;
2660 #ifdef HAVE_floatunsqitf2
2661 if (HAVE_floatunsqitf2)
2662 floattab[(int) TFmode][(int) QImode][1] = CODE_FOR_floatunsqitf2;
2664 #ifdef HAVE_floatunshitf2
2665 if (HAVE_floatunshitf2)
2666 floattab[(int) TFmode][(int) HImode][1] = CODE_FOR_floatunshitf2;
2668 #ifdef HAVE_floatunssitf2
2669 if (HAVE_floatunssitf2)
2670 floattab[(int) TFmode][(int) SImode][1] = CODE_FOR_floatunssitf2;
2672 #ifdef HAVE_floatunsditf2
2673 if (HAVE_floatunsditf2)
2674 floattab[(int) TFmode][(int) DImode][1] = CODE_FOR_floatunsditf2;
2676 #ifdef HAVE_floatunstitf2
2677 if (HAVE_floatunstitf2)
2678 floattab[(int) TFmode][(int) TImode][1] = CODE_FOR_floatunstitf2;
2682 /* Generate code to convert FROM to floating point
2683 and store in TO. FROM must be fixed point and not VOIDmode.
2684 UNSIGNEDP nonzero means regard FROM as unsigned.
2685 Normally this is done by correcting the final value
2686 if it is negative. */
2689 expand_float (to, from, unsignedp)
2693 enum insn_code icode;
2694 register rtx target = to;
2695 enum machine_mode fmode, imode;
2697 /* Crash now, because we won't be able to decide which mode to use. */
2698 if (GET_MODE (from) == VOIDmode)
2701 /* Look for an insn to do the conversion. Do it in the specified
2702 modes if possible; otherwise convert either input, output or both to
2703 wider mode. If the integer mode is wider than the mode of FROM,
2704 we can do the conversion signed even if the input is unsigned. */
2706 for (imode = GET_MODE (from); imode != VOIDmode;
2707 imode = GET_MODE_WIDER_MODE (imode))
2708 for (fmode = GET_MODE (to); fmode != VOIDmode;
2709 fmode = GET_MODE_WIDER_MODE (fmode))
2711 int doing_unsigned = unsignedp;
2713 icode = can_float_p (fmode, imode, unsignedp);
2714 if (icode == CODE_FOR_nothing && imode != GET_MODE (from) && unsignedp)
2715 icode = can_float_p (fmode, imode, 0), doing_unsigned = 0;
2717 if (icode != CODE_FOR_nothing)
2719 to = protect_from_queue (to, 1);
2721 if (imode != GET_MODE (from))
2722 from = convert_to_mode (imode, from, unsignedp);
2724 from = protect_from_queue (from, 0);
2726 if (fmode != GET_MODE (to))
2727 target = gen_reg_rtx (fmode);
2729 emit_unop_insn (icode, target, from,
2730 doing_unsigned ? UNSIGNED_FLOAT : FLOAT);
2733 convert_move (to, target, 0);
2738 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
2740 /* Unsigned integer, and no way to convert directly.
2741 Convert as signed, then conditionally adjust the result. */
2744 rtx label = gen_label_rtx ();
2746 REAL_VALUE_TYPE offset;
2750 to = protect_from_queue (to, 1);
2751 from = protect_from_queue (from, 0);
2754 from = force_not_mem (from);
2756 /* If we are about to do some arithmetic to correct for an
2757 unsigned operand, do it in a pseudo-register. */
2759 if (GET_CODE (to) != REG || REGNO (to) <= LAST_VIRTUAL_REGISTER)
2760 target = gen_reg_rtx (GET_MODE (to));
2762 /* Convert as signed integer to floating. */
2763 expand_float (target, from, 0);
2765 /* If FROM is negative (and therefore TO is negative),
2766 correct its value by 2**bitwidth. */
2768 do_pending_stack_adjust ();
2769 emit_cmp_insn (from, const0_rtx, GE, 0, GET_MODE (from), 0, 0);
2770 emit_jump_insn (gen_bge (label));
2771 /* On SCO 3.2.1, ldexp rejects values outside [0.5, 1).
2772 Rather than setting up a dconst_dot_5, let's hope SCO
2774 offset = REAL_VALUE_LDEXP (dconst1, GET_MODE_BITSIZE (GET_MODE (from)));
2775 temp = expand_binop (GET_MODE (to), add_optab, target,
2776 immed_real_const_1 (offset, GET_MODE (to)),
2777 target, 0, OPTAB_LIB_WIDEN);
2779 emit_move_insn (target, temp);
2780 do_pending_stack_adjust ();
2786 /* No hardware instruction available; call a library rotine to convert from
2787 SImode, DImode, or TImode into SFmode, DFmode, XFmode, or TFmode. */
2792 to = protect_from_queue (to, 1);
2794 if (GET_MODE_SIZE (GET_MODE (from)) < GET_MODE_SIZE (SImode))
2795 from = convert_to_mode (SImode, from, unsignedp);
2797 from = protect_from_queue (from, 0);
2800 from = force_not_mem (from);
2802 if (GET_MODE (to) == SFmode)
2804 if (GET_MODE (from) == SImode)
2805 libfcn = floatsisf_libfunc;
2806 else if (GET_MODE (from) == DImode)
2807 libfcn = floatdisf_libfunc;
2808 else if (GET_MODE (from) == TImode)
2809 libfcn = floattisf_libfunc;
2813 else if (GET_MODE (to) == DFmode)
2815 if (GET_MODE (from) == SImode)
2816 libfcn = floatsidf_libfunc;
2817 else if (GET_MODE (from) == DImode)
2818 libfcn = floatdidf_libfunc;
2819 else if (GET_MODE (from) == TImode)
2820 libfcn = floattidf_libfunc;
2824 else if (GET_MODE (to) == XFmode)
2826 if (GET_MODE (from) == SImode)
2827 libfcn = floatsixf_libfunc;
2828 else if (GET_MODE (from) == DImode)
2829 libfcn = floatdixf_libfunc;
2830 else if (GET_MODE (from) == TImode)
2831 libfcn = floattixf_libfunc;
2835 else if (GET_MODE (to) == TFmode)
2837 if (GET_MODE (from) == SImode)
2838 libfcn = floatsitf_libfunc;
2839 else if (GET_MODE (from) == DImode)
2840 libfcn = floatditf_libfunc;
2841 else if (GET_MODE (from) == TImode)
2842 libfcn = floattitf_libfunc;
2851 emit_library_call (libfcn, 1, GET_MODE (to), 1, from, GET_MODE (from));
2852 insns = get_insns ();
2855 emit_libcall_block (insns, target, hard_libcall_value (GET_MODE (to)),
2856 gen_rtx (FLOAT, GET_MODE (to), from));
2859 /* Copy result to requested destination
2860 if we have been computing in a temp location. */
2864 if (GET_MODE (target) == GET_MODE (to))
2865 emit_move_insn (to, target);
2867 convert_move (to, target, 0);
2871 /* expand_fix: generate code to convert FROM to fixed point
2872 and store in TO. FROM must be floating point. */
2878 rtx temp = gen_reg_rtx (GET_MODE (x));
2879 return expand_unop (GET_MODE (x), ftrunc_optab, x, temp, 0);
2883 expand_fix (to, from, unsignedp)
2884 register rtx to, from;
2887 enum insn_code icode;
2888 register rtx target = to;
2889 enum machine_mode fmode, imode;
2893 /* We first try to find a pair of modes, one real and one integer, at
2894 least as wide as FROM and TO, respectively, in which we can open-code
2895 this conversion. If the integer mode is wider than the mode of TO,
2896 we can do the conversion either signed or unsigned. */
2898 for (imode = GET_MODE (to); imode != VOIDmode;
2899 imode = GET_MODE_WIDER_MODE (imode))
2900 for (fmode = GET_MODE (from); fmode != VOIDmode;
2901 fmode = GET_MODE_WIDER_MODE (fmode))
2903 int doing_unsigned = unsignedp;
2905 icode = can_fix_p (imode, fmode, unsignedp, &must_trunc);
2906 if (icode == CODE_FOR_nothing && imode != GET_MODE (to) && unsignedp)
2907 icode = can_fix_p (imode, fmode, 0, &must_trunc), doing_unsigned = 0;
2909 if (icode != CODE_FOR_nothing)
2911 to = protect_from_queue (to, 1);
2913 if (fmode != GET_MODE (from))
2914 from = convert_to_mode (fmode, from, 0);
2916 from = protect_from_queue (from, 0);
2919 from = ftruncify (from);
2921 if (imode != GET_MODE (to))
2922 target = gen_reg_rtx (imode);
2924 emit_unop_insn (icode, target, from,
2925 doing_unsigned ? UNSIGNED_FIX : FIX);
2927 convert_move (to, target, unsignedp);
2932 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
2933 /* For an unsigned conversion, there is one more way to do it.
2934 If we have a signed conversion, we generate code that compares
2935 the real value to the largest representable positive number. If if
2936 is smaller, the conversion is done normally. Otherwise, subtract
2937 one plus the highest signed number, convert, and add it back.
2939 We only need to check all real modes, since we know we didn't find
2940 anything with a wider integer mode. */
2942 if (unsignedp && GET_MODE_BITSIZE (GET_MODE (to)) <= HOST_BITS_PER_INT)
2943 for (fmode = GET_MODE (from); fmode != VOIDmode;
2944 fmode = GET_MODE_WIDER_MODE (fmode))
2945 /* Make sure we won't lose significant bits doing this. */
2946 if (GET_MODE_BITSIZE (fmode) > GET_MODE_BITSIZE (GET_MODE (to))
2947 && CODE_FOR_nothing != can_fix_p (GET_MODE (to), fmode, 0,
2950 int bitsize = GET_MODE_BITSIZE (GET_MODE (to));
2951 REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (dconst1, bitsize - 1);
2952 rtx limit = immed_real_const_1 (offset, fmode);
2953 rtx lab1 = gen_label_rtx ();
2954 rtx lab2 = gen_label_rtx ();
2958 to = protect_from_queue (to, 1);
2959 from = protect_from_queue (from, 0);
2962 from = force_not_mem (from);
2964 if (fmode != GET_MODE (from))
2965 from = convert_to_mode (fmode, from, 0);
2967 /* See if we need to do the subtraction. */
2968 do_pending_stack_adjust ();
2969 emit_cmp_insn (from, limit, GE, 0, GET_MODE (from), 0, 0);
2970 emit_jump_insn (gen_bge (lab1));
2972 /* If not, do the signed "fix" and branch around fixup code. */
2973 expand_fix (to, from, 0);
2974 emit_jump_insn (gen_jump (lab2));
2977 /* Otherwise, subtract 2**(N-1), convert to signed number,
2978 then add 2**(N-1). Do the addition using XOR since this
2979 will often generate better code. */
2981 target = expand_binop (GET_MODE (from), sub_optab, from, limit,
2982 0, 0, OPTAB_LIB_WIDEN);
2983 expand_fix (to, target, 0);
2984 target = expand_binop (GET_MODE (to), xor_optab, to,
2985 gen_rtx (CONST_INT, VOIDmode,
2986 1 << (bitsize - 1)),
2987 to, 1, OPTAB_LIB_WIDEN);
2990 emit_move_insn (to, target);
2994 /* Make a place for a REG_NOTE and add it. */
2995 insn = emit_move_insn (to, to);
2996 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL,
2997 gen_rtx (UNSIGNED_FIX, GET_MODE (to),
2998 from), REG_NOTES (insn));
3004 /* We can't do it with an insn, so use a library call. But first ensure
3005 that the mode of TO is at least as wide as SImode, since those are the
3006 only library calls we know about. */
3008 if (GET_MODE_SIZE (GET_MODE (to)) < GET_MODE_SIZE (SImode))
3010 target = gen_reg_rtx (SImode);
3012 expand_fix (target, from, unsignedp);
3014 else if (GET_MODE (from) == SFmode)
3016 if (GET_MODE (to) == SImode)
3017 libfcn = unsignedp ? fixunssfsi_libfunc : fixsfsi_libfunc;
3018 else if (GET_MODE (to) == DImode)
3019 libfcn = unsignedp ? fixunssfdi_libfunc : fixsfdi_libfunc;
3020 else if (GET_MODE (to) == TImode)
3021 libfcn = unsignedp ? fixunssfti_libfunc : fixsfti_libfunc;
3025 else if (GET_MODE (from) == DFmode)
3027 if (GET_MODE (to) == SImode)
3028 libfcn = unsignedp ? fixunsdfsi_libfunc : fixdfsi_libfunc;
3029 else if (GET_MODE (to) == DImode)
3030 libfcn = unsignedp ? fixunsdfdi_libfunc : fixdfdi_libfunc;
3031 else if (GET_MODE (to) == TImode)
3032 libfcn = unsignedp ? fixunsdfti_libfunc : fixdfti_libfunc;
3036 else if (GET_MODE (from) == XFmode)
3038 if (GET_MODE (to) == SImode)
3039 libfcn = unsignedp ? fixunsxfsi_libfunc : fixxfsi_libfunc;
3040 else if (GET_MODE (to) == DImode)
3041 libfcn = unsignedp ? fixunsxfdi_libfunc : fixxfdi_libfunc;
3042 else if (GET_MODE (to) == TImode)
3043 libfcn = unsignedp ? fixunsxfti_libfunc : fixxfti_libfunc;
3047 else if (GET_MODE (from) == TFmode)
3049 if (GET_MODE (to) == SImode)
3050 libfcn = unsignedp ? fixunstfsi_libfunc : fixtfsi_libfunc;
3051 else if (GET_MODE (to) == DImode)
3052 libfcn = unsignedp ? fixunstfdi_libfunc : fixtfdi_libfunc;
3053 else if (GET_MODE (to) == TImode)
3054 libfcn = unsignedp ? fixunstfti_libfunc : fixtfti_libfunc;
3065 to = protect_from_queue (to, 1);
3066 from = protect_from_queue (from, 0);
3069 from = force_not_mem (from);
3073 emit_library_call (libfcn, 1, GET_MODE (to), 1, from, GET_MODE (from));
3074 insns = get_insns ();
3077 emit_libcall_block (insns, target, hard_libcall_value (GET_MODE (to)),
3078 gen_rtx (unsignedp ? FIX : UNSIGNED_FIX,
3079 GET_MODE (to), from));
3082 if (GET_MODE (to) == GET_MODE (target))
3083 emit_move_insn (to, target);
3085 convert_move (to, target, 0);
3093 optab op = (optab) xmalloc (sizeof (struct optab));
3095 for (i = 0; i < NUM_MACHINE_MODES; i++)
3097 op->handlers[i].insn_code = CODE_FOR_nothing;
3098 op->handlers[i].libfunc = 0;
3103 /* Initialize the libfunc fields of an entire group of entries in some
3104 optab. Each entry is set equal to a string consisting of a leading
3105 pair of underscores followed by a generic operation name followed by
3106 a mode name (downshifted to lower case) followed by a single character
3107 representing the number of operands for the given operation (which is
3108 usually one of the characters '2', '3', or '4').
3110 OPTABLE is the table in which libfunc fields are to be initialized.
3111 FIRST_MODE is the first machine mode index in the given optab to
3113 LAST_MODE is the last machine mode index in the given optab to
3115 OPNAME is the generic (string) name of the operation.
3116 SUFFIX is the character which specifies the number of operands for
3117 the given generic operation.
3121 init_libfuncs (optable, first_mode, last_mode, opname, suffix)
3122 register optab optable;
3123 register char *opname;
3124 register enum machine_mode first_mode;
3125 register enum machine_mode last_mode;
3126 register char suffix;
3128 register enum machine_mode mode;
3129 register unsigned opname_len = strlen (opname);
3131 for (mode = first_mode; mode <= last_mode; mode++)
3133 register char *mname = mode_name[(int) mode];
3134 register unsigned mname_len = strlen (mname);
3135 register char *libfunc_name
3136 = (char *) xmalloc (2 + opname_len + mname_len + 1 + 1);
3143 for (q = opname; *q; )
3145 for (q = mname; *q; q++)
3146 *p++ = tolower (*q);
3149 optable->handlers[(int) mode].libfunc
3150 = gen_rtx (SYMBOL_REF, Pmode, libfunc_name);
3154 /* Initialize the libfunc fields of an entire group of entries in some
3155 optab which correspond to all integer mode operations. The parameters
3156 have the same meaning as similarly named ones for the `init_libfuncs'
3157 routine. (See above). */
3160 init_integral_libfuncs (optable, opname, suffix)
3161 register optab optable;
3162 register char *opname;
3163 register char suffix;
3165 init_libfuncs (optable, SImode, TImode, opname, suffix);
3168 /* Initialize the libfunc fields of an entire group of entries in some
3169 optab which correspond to all real mode operations. The parameters
3170 have the same meaning as similarly named ones for the `init_libfuncs'
3171 routine. (See above). */
3174 init_floating_libfuncs (optable, opname, suffix)
3175 register optab optable;
3176 register char *opname;
3177 register char suffix;
3179 init_libfuncs (optable, SFmode, TFmode, opname, suffix);
3182 /* Call this once to initialize the contents of the optabs
3183 appropriately for the current target machine. */
3194 add_optab = init_optab (PLUS);
3195 sub_optab = init_optab (MINUS);
3196 smul_optab = init_optab (MULT);
3197 smul_widen_optab = init_optab (UNKNOWN);
3198 umul_widen_optab = init_optab (UNKNOWN);
3199 sdiv_optab = init_optab (DIV);
3200 sdivmod_optab = init_optab (UNKNOWN);
3201 udiv_optab = init_optab (UDIV);
3202 udivmod_optab = init_optab (UNKNOWN);
3203 smod_optab = init_optab (MOD);
3204 umod_optab = init_optab (UMOD);
3205 flodiv_optab = init_optab (DIV);
3206 ftrunc_optab = init_optab (UNKNOWN);
3207 and_optab = init_optab (AND);
3208 ior_optab = init_optab (IOR);
3209 xor_optab = init_optab (XOR);
3210 ashl_optab = init_optab (ASHIFT);
3211 ashr_optab = init_optab (ASHIFTRT);
3212 lshl_optab = init_optab (LSHIFT);
3213 lshr_optab = init_optab (LSHIFTRT);
3214 rotl_optab = init_optab (ROTATE);
3215 rotr_optab = init_optab (ROTATERT);
3216 smin_optab = init_optab (SMIN);
3217 smax_optab = init_optab (SMAX);
3218 umin_optab = init_optab (UMIN);
3219 umax_optab = init_optab (UMAX);
3220 mov_optab = init_optab (UNKNOWN);
3221 movstrict_optab = init_optab (UNKNOWN);
3222 cmp_optab = init_optab (UNKNOWN);
3223 ucmp_optab = init_optab (UNKNOWN);
3224 tst_optab = init_optab (UNKNOWN);
3225 neg_optab = init_optab (NEG);
3226 abs_optab = init_optab (ABS);
3227 one_cmpl_optab = init_optab (NOT);
3228 ffs_optab = init_optab (FFS);
3229 sqrt_optab = init_optab (SQRT);
3230 strlen_optab = init_optab (UNKNOWN);
3234 add_optab->handlers[(int) QImode].insn_code = CODE_FOR_addqi3;
3238 add_optab->handlers[(int) HImode].insn_code = CODE_FOR_addhi3;
3242 add_optab->handlers[(int) PSImode].insn_code = CODE_FOR_addpsi3;
3246 add_optab->handlers[(int) SImode].insn_code = CODE_FOR_addsi3;
3250 add_optab->handlers[(int) DImode].insn_code = CODE_FOR_adddi3;
3254 add_optab->handlers[(int) TImode].insn_code = CODE_FOR_addti3;
3258 add_optab->handlers[(int) SFmode].insn_code = CODE_FOR_addsf3;
3262 add_optab->handlers[(int) DFmode].insn_code = CODE_FOR_adddf3;
3266 add_optab->handlers[(int) XFmode].insn_code = CODE_FOR_addxf3;
3270 add_optab->handlers[(int) TFmode].insn_code = CODE_FOR_addtf3;
3272 init_integral_libfuncs (add_optab, "add", '3');
3273 init_floating_libfuncs (add_optab, "add", '3');
3277 sub_optab->handlers[(int) QImode].insn_code = CODE_FOR_subqi3;
3281 sub_optab->handlers[(int) HImode].insn_code = CODE_FOR_subhi3;
3285 sub_optab->handlers[(int) PSImode].insn_code = CODE_FOR_subpsi3;
3289 sub_optab->handlers[(int) SImode].insn_code = CODE_FOR_subsi3;
3293 sub_optab->handlers[(int) DImode].insn_code = CODE_FOR_subdi3;
3297 sub_optab->handlers[(int) TImode].insn_code = CODE_FOR_subti3;
3301 sub_optab->handlers[(int) SFmode].insn_code = CODE_FOR_subsf3;
3305 sub_optab->handlers[(int) DFmode].insn_code = CODE_FOR_subdf3;
3309 sub_optab->handlers[(int) XFmode].insn_code = CODE_FOR_subxf3;
3313 sub_optab->handlers[(int) TFmode].insn_code = CODE_FOR_subtf3;
3315 init_integral_libfuncs (sub_optab, "sub", '3');
3316 init_floating_libfuncs (sub_optab, "sub", '3');
3320 smul_optab->handlers[(int) QImode].insn_code = CODE_FOR_mulqi3;
3324 smul_optab->handlers[(int) HImode].insn_code = CODE_FOR_mulhi3;
3328 smul_optab->handlers[(int) PSImode].insn_code = CODE_FOR_mulpsi3;
3332 smul_optab->handlers[(int) SImode].insn_code = CODE_FOR_mulsi3;
3336 smul_optab->handlers[(int) DImode].insn_code = CODE_FOR_muldi3;
3340 smul_optab->handlers[(int) TImode].insn_code = CODE_FOR_multi3;
3344 smul_optab->handlers[(int) SFmode].insn_code = CODE_FOR_mulsf3;
3348 smul_optab->handlers[(int) DFmode].insn_code = CODE_FOR_muldf3;
3352 smul_optab->handlers[(int) XFmode].insn_code = CODE_FOR_mulxf3;
3356 smul_optab->handlers[(int) TFmode].insn_code = CODE_FOR_multf3;
3358 init_integral_libfuncs (smul_optab, "mul", '3');
3359 init_floating_libfuncs (smul_optab, "mul", '3');
3361 #ifdef MULSI3_LIBCALL
3362 smul_optab->handlers[(int) SImode].libfunc
3363 = gen_rtx (SYMBOL_REF, Pmode, MULSI3_LIBCALL);
3365 #ifdef MULDI3_LIBCALL
3366 smul_optab->handlers[(int) DImode].libfunc
3367 = gen_rtx (SYMBOL_REF, Pmode, MULDI3_LIBCALL);
3369 #ifdef MULTI3_LIBCALL
3370 smul_optab->handlers[(int) TImode].libfunc
3371 = gen_rtx (SYMBOL_REF, Pmode, MULTI3_LIBCALL);
3374 #ifdef HAVE_mulqihi3
3376 smul_widen_optab->handlers[(int) HImode].insn_code = CODE_FOR_mulqihi3;
3378 #ifdef HAVE_mulhisi3
3380 smul_widen_optab->handlers[(int) SImode].insn_code = CODE_FOR_mulhisi3;
3382 #ifdef HAVE_mulsidi3
3384 smul_widen_optab->handlers[(int) DImode].insn_code = CODE_FOR_mulsidi3;
3386 #ifdef HAVE_mulditi3
3388 smul_widen_optab->handlers[(int) TImode].insn_code = CODE_FOR_mulditi3;
3391 #ifdef HAVE_umulqihi3
3393 umul_widen_optab->handlers[(int) HImode].insn_code = CODE_FOR_umulqihi3;
3395 #ifdef HAVE_umulhisi3
3397 umul_widen_optab->handlers[(int) SImode].insn_code = CODE_FOR_umulhisi3;
3399 #ifdef HAVE_umulsidi3
3401 umul_widen_optab->handlers[(int) DImode].insn_code = CODE_FOR_umulsidi3;
3403 #ifdef HAVE_umulditi3
3405 umul_widen_optab->handlers[(int) TImode].insn_code = CODE_FOR_umulditi3;
3410 sdiv_optab->handlers[(int) QImode].insn_code = CODE_FOR_divqi3;
3414 sdiv_optab->handlers[(int) HImode].insn_code = CODE_FOR_divhi3;
3418 sdiv_optab->handlers[(int) PSImode].insn_code = CODE_FOR_divpsi3;
3422 sdiv_optab->handlers[(int) SImode].insn_code = CODE_FOR_divsi3;
3426 sdiv_optab->handlers[(int) DImode].insn_code = CODE_FOR_divdi3;
3430 sdiv_optab->handlers[(int) TImode].insn_code = CODE_FOR_divti3;
3432 init_integral_libfuncs (sdiv_optab, "div", '3');
3434 #ifdef DIVSI3_LIBCALL
3435 sdiv_optab->handlers[(int) SImode].libfunc
3436 = gen_rtx (SYMBOL_REF, Pmode, DIVSI3_LIBCALL);
3438 #ifdef DIVDI3_LIBCALL
3439 sdiv_optab->handlers[(int) DImode].libfunc
3440 = gen_rtx (SYMBOL_REF, Pmode, DIVDI3_LIBCALL);
3442 #ifdef DIVTI3_LIBCALL
3443 sdiv_optab->handlers[(int) TImode].libfunc
3444 = gen_rtx (SYMBOL_REF, Pmode, DIVTI3_LIBCALL);
3449 udiv_optab->handlers[(int) QImode].insn_code = CODE_FOR_udivqi3;
3453 udiv_optab->handlers[(int) HImode].insn_code = CODE_FOR_udivhi3;
3455 #ifdef HAVE_udivpsi3
3457 udiv_optab->handlers[(int) PSImode].insn_code = CODE_FOR_udivpsi3;
3461 udiv_optab->handlers[(int) SImode].insn_code = CODE_FOR_udivsi3;
3465 udiv_optab->handlers[(int) DImode].insn_code = CODE_FOR_udivdi3;
3469 udiv_optab->handlers[(int) TImode].insn_code = CODE_FOR_udivti3;
3471 init_integral_libfuncs (udiv_optab, "udiv", '3');
3473 #ifdef UDIVSI3_LIBCALL
3474 udiv_optab->handlers[(int) SImode].libfunc
3475 = gen_rtx (SYMBOL_REF, Pmode, UDIVSI3_LIBCALL);
3477 #ifdef UDIVDI3_LIBCALL
3478 udiv_optab->handlers[(int) DImode].libfunc
3479 = gen_rtx (SYMBOL_REF, Pmode, UDIVDI3_LIBCALL);
3481 #ifdef UDIVTI3_LIBCALL
3482 udiv_optab->handlers[(int) TImode].libfunc
3483 = gen_rtx (SYMBOL_REF, Pmode, UDIVTI3_LIBCALL);
3486 #ifdef HAVE_divmodqi4
3488 sdivmod_optab->handlers[(int) QImode].insn_code = CODE_FOR_divmodqi4;
3490 #ifdef HAVE_divmodhi4
3492 sdivmod_optab->handlers[(int) HImode].insn_code = CODE_FOR_divmodhi4;
3494 #ifdef HAVE_divmodsi4
3496 sdivmod_optab->handlers[(int) SImode].insn_code = CODE_FOR_divmodsi4;
3498 #ifdef HAVE_divmoddi4
3500 sdivmod_optab->handlers[(int) DImode].insn_code = CODE_FOR_divmoddi4;
3502 #ifdef HAVE_divmodti4
3504 sdivmod_optab->handlers[(int) TImode].insn_code = CODE_FOR_divmodti4;
3506 init_integral_libfuncs (sdivmod_optab, "divmod", '4');
3508 #ifdef HAVE_udivmodqi4
3509 if (HAVE_udivmodqi4)
3510 udivmod_optab->handlers[(int) QImode].insn_code = CODE_FOR_udivmodqi4;
3512 #ifdef HAVE_udivmodhi4
3513 if (HAVE_udivmodhi4)
3514 udivmod_optab->handlers[(int) HImode].insn_code = CODE_FOR_udivmodhi4;
3516 #ifdef HAVE_udivmodsi4
3517 if (HAVE_udivmodsi4)
3518 udivmod_optab->handlers[(int) SImode].insn_code = CODE_FOR_udivmodsi4;
3520 #ifdef HAVE_udivmoddi4
3521 if (HAVE_udivmoddi4)
3522 udivmod_optab->handlers[(int) DImode].insn_code = CODE_FOR_udivmoddi4;
3524 #ifdef HAVE_udivmodti4
3525 if (HAVE_udivmodti4)
3526 udivmod_optab->handlers[(int) TImode].insn_code = CODE_FOR_udivmodti4;
3528 init_integral_libfuncs (udivmod_optab, "udivmod", '4');
3532 smod_optab->handlers[(int) QImode].insn_code = CODE_FOR_modqi3;
3536 smod_optab->handlers[(int) HImode].insn_code = CODE_FOR_modhi3;
3540 smod_optab->handlers[(int) PSImode].insn_code = CODE_FOR_modpsi3;
3544 smod_optab->handlers[(int) SImode].insn_code = CODE_FOR_modsi3;
3548 smod_optab->handlers[(int) DImode].insn_code = CODE_FOR_moddi3;
3552 smod_optab->handlers[(int) TImode].insn_code = CODE_FOR_modti3;
3554 init_integral_libfuncs (smod_optab, "mod", '3');
3556 #ifdef MODSI3_LIBCALL
3557 smod_optab->handlers[(int) SImode].libfunc
3558 = gen_rtx (SYMBOL_REF, Pmode, MODSI3_LIBCALL);
3560 #ifdef MODDI3_LIBCALL
3561 smod_optab->handlers[(int) DImode].libfunc
3562 = gen_rtx (SYMBOL_REF, Pmode, MODDI3_LIBCALL);
3564 #ifdef MODTI3_LIBCALL
3565 smod_optab->handlers[(int) TImode].libfunc
3566 = gen_rtx (SYMBOL_REF, Pmode, MODTI3_LIBCALL);
3571 umod_optab->handlers[(int) QImode].insn_code = CODE_FOR_umodqi3;
3575 umod_optab->handlers[(int) HImode].insn_code = CODE_FOR_umodhi3;
3577 #ifdef HAVE_umodpsi3
3579 umod_optab->handlers[(int) PSImode].insn_code = CODE_FOR_umodpsi3;
3583 umod_optab->handlers[(int) SImode].insn_code = CODE_FOR_umodsi3;
3587 umod_optab->handlers[(int) DImode].insn_code = CODE_FOR_umoddi3;
3591 umod_optab->handlers[(int) TImode].insn_code = CODE_FOR_umodti3;
3593 init_integral_libfuncs (umod_optab, "umod", '3');
3595 #ifdef UMODSI3_LIBCALL
3596 umod_optab->handlers[(int) SImode].libfunc
3597 = gen_rtx (SYMBOL_REF, Pmode, UMODSI3_LIBCALL);
3599 #ifdef UMODDI3_LIBCALL
3600 umod_optab->handlers[(int) DImode].libfunc
3601 = gen_rtx (SYMBOL_REF, Pmode, UMODDI3_LIBCALL);
3603 #ifdef UMODTI3_LIBCALL
3604 umod_optab->handlers[(int) TImode].libfunc
3605 = gen_rtx (SYMBOL_REF, Pmode, UMODTI3_LIBCALL);
3610 flodiv_optab->handlers[(int) SFmode].insn_code = CODE_FOR_divsf3;
3614 flodiv_optab->handlers[(int) DFmode].insn_code = CODE_FOR_divdf3;
3618 flodiv_optab->handlers[(int) XFmode].insn_code = CODE_FOR_divxf3;
3622 flodiv_optab->handlers[(int) TFmode].insn_code = CODE_FOR_divtf3;
3624 init_floating_libfuncs (flodiv_optab, "div", '3');
3626 #ifdef HAVE_ftruncsf2
3628 ftrunc_optab->handlers[(int) SFmode].insn_code = CODE_FOR_ftruncsf2;
3630 #ifdef HAVE_ftruncdf2
3632 ftrunc_optab->handlers[(int) DFmode].insn_code = CODE_FOR_ftruncdf2;
3634 #ifdef HAVE_ftruncxf2
3636 ftrunc_optab->handlers[(int) XFmode].insn_code = CODE_FOR_ftruncxf2;
3638 #ifdef HAVE_ftrunctf2
3640 ftrunc_optab->handlers[(int) TFmode].insn_code = CODE_FOR_ftrunctf2;
3642 init_floating_libfuncs (ftrunc_optab, "ftrunc", '2');
3646 and_optab->handlers[(int) QImode].insn_code = CODE_FOR_andqi3;
3650 and_optab->handlers[(int) HImode].insn_code = CODE_FOR_andhi3;
3654 and_optab->handlers[(int) PSImode].insn_code = CODE_FOR_andpsi3;
3658 and_optab->handlers[(int) SImode].insn_code = CODE_FOR_andsi3;
3662 and_optab->handlers[(int) DImode].insn_code = CODE_FOR_anddi3;
3666 and_optab->handlers[(int) TImode].insn_code = CODE_FOR_andti3;
3668 init_integral_libfuncs (and_optab, "and", '3');
3672 ior_optab->handlers[(int) QImode].insn_code = CODE_FOR_iorqi3;
3676 ior_optab->handlers[(int) HImode].insn_code = CODE_FOR_iorhi3;
3680 ior_optab->handlers[(int) PSImode].insn_code = CODE_FOR_iorpsi3;
3684 ior_optab->handlers[(int) SImode].insn_code = CODE_FOR_iorsi3;
3688 ior_optab->handlers[(int) DImode].insn_code = CODE_FOR_iordi3;
3692 ior_optab->handlers[(int) TImode].insn_code = CODE_FOR_iorti3;
3694 init_integral_libfuncs (ior_optab, "ior", '3');
3698 xor_optab->handlers[(int) QImode].insn_code = CODE_FOR_xorqi3;
3702 xor_optab->handlers[(int) HImode].insn_code = CODE_FOR_xorhi3;
3706 xor_optab->handlers[(int) PSImode].insn_code = CODE_FOR_xorpsi3;
3710 xor_optab->handlers[(int) SImode].insn_code = CODE_FOR_xorsi3;
3714 xor_optab->handlers[(int) DImode].insn_code = CODE_FOR_xordi3;
3718 xor_optab->handlers[(int) TImode].insn_code = CODE_FOR_xorti3;
3720 init_integral_libfuncs (xor_optab, "xor", '3');
3724 ashl_optab->handlers[(int) QImode].insn_code = CODE_FOR_ashlqi3;
3728 ashl_optab->handlers[(int) HImode].insn_code = CODE_FOR_ashlhi3;
3730 #ifdef HAVE_ashlpsi3
3732 ashl_optab->handlers[(int) PSImode].insn_code = CODE_FOR_ashlpsi3;
3736 ashl_optab->handlers[(int) SImode].insn_code = CODE_FOR_ashlsi3;
3740 ashl_optab->handlers[(int) DImode].insn_code = CODE_FOR_ashldi3;
3744 ashl_optab->handlers[(int) TImode].insn_code = CODE_FOR_ashlti3;
3746 init_integral_libfuncs (ashl_optab, "ashl", '3');
3750 ashr_optab->handlers[(int) QImode].insn_code = CODE_FOR_ashrqi3;
3754 ashr_optab->handlers[(int) HImode].insn_code = CODE_FOR_ashrhi3;
3756 #ifdef HAVE_ashrpsi3
3758 ashr_optab->handlers[(int) PSImode].insn_code = CODE_FOR_ashrpsi3;
3762 ashr_optab->handlers[(int) SImode].insn_code = CODE_FOR_ashrsi3;
3766 ashr_optab->handlers[(int) DImode].insn_code = CODE_FOR_ashrdi3;
3770 ashr_optab->handlers[(int) TImode].insn_code = CODE_FOR_ashrti3;
3772 init_integral_libfuncs (ashr_optab, "ashr", '3');
3776 lshl_optab->handlers[(int) QImode].insn_code = CODE_FOR_lshlqi3;
3780 lshl_optab->handlers[(int) HImode].insn_code = CODE_FOR_lshlhi3;
3782 #ifdef HAVE_lshlpsi3
3784 lshl_optab->handlers[(int) PSImode].insn_code = CODE_FOR_lshlpsi3;
3788 lshl_optab->handlers[(int) SImode].insn_code = CODE_FOR_lshlsi3;
3792 lshl_optab->handlers[(int) DImode].insn_code = CODE_FOR_lshldi3;
3796 lshl_optab->handlers[(int) TImode].insn_code = CODE_FOR_lshlti3;
3798 init_integral_libfuncs (lshl_optab, "lshl", '3');
3802 lshr_optab->handlers[(int) QImode].insn_code = CODE_FOR_lshrqi3;
3806 lshr_optab->handlers[(int) HImode].insn_code = CODE_FOR_lshrhi3;
3808 #ifdef HAVE_lshrpsi3
3810 lshr_optab->handlers[(int) PSImode].insn_code = CODE_FOR_lshrpsi3;
3814 lshr_optab->handlers[(int) SImode].insn_code = CODE_FOR_lshrsi3;
3818 lshr_optab->handlers[(int) DImode].insn_code = CODE_FOR_lshrdi3;
3822 lshr_optab->handlers[(int) TImode].insn_code = CODE_FOR_lshrti3;
3824 init_integral_libfuncs (lshr_optab, "lshr", '3');
3828 rotl_optab->handlers[(int) QImode].insn_code = CODE_FOR_rotlqi3;
3832 rotl_optab->handlers[(int) HImode].insn_code = CODE_FOR_rotlhi3;
3834 #ifdef HAVE_rotlpsi3
3836 rotl_optab->handlers[(int) PSImode].insn_code = CODE_FOR_rotlpsi3;
3840 rotl_optab->handlers[(int) SImode].insn_code = CODE_FOR_rotlsi3;
3844 rotl_optab->handlers[(int) DImode].insn_code = CODE_FOR_rotldi3;
3848 rotl_optab->handlers[(int) TImode].insn_code = CODE_FOR_rotlti3;
3850 init_integral_libfuncs (rotl_optab, "rotl", '3');
3854 rotr_optab->handlers[(int) QImode].insn_code = CODE_FOR_rotrqi3;
3858 rotr_optab->handlers[(int) HImode].insn_code = CODE_FOR_rotrhi3;
3860 #ifdef HAVE_rotrpsi3
3862 rotr_optab->handlers[(int) PSImode].insn_code = CODE_FOR_rotrpsi3;
3866 rotr_optab->handlers[(int) SImode].insn_code = CODE_FOR_rotrsi3;
3870 rotr_optab->handlers[(int) DImode].insn_code = CODE_FOR_rotrdi3;
3874 rotr_optab->handlers[(int) TImode].insn_code = CODE_FOR_rotrti3;
3876 init_integral_libfuncs (rotr_optab, "rotr", '3');
3880 smin_optab->handlers[(int) QImode].insn_code = CODE_FOR_sminqi3;
3884 smin_optab->handlers[(int) HImode].insn_code = CODE_FOR_sminhi3;
3888 smin_optab->handlers[(int) SImode].insn_code = CODE_FOR_sminsi3;
3892 smin_optab->handlers[(int) DImode].insn_code = CODE_FOR_smindi3;
3896 smin_optab->handlers[(int) TImode].insn_code = CODE_FOR_sminti3;
3900 smin_optab->handlers[(int) SFmode].insn_code = CODE_FOR_minsf3;
3904 smin_optab->handlers[(int) DFmode].insn_code = CODE_FOR_mindf3;
3908 smin_optab->handlers[(int) XFmode].insn_code = CODE_FOR_minxf3;
3912 smin_optab->handlers[(int) TFmode].insn_code = CODE_FOR_mintf3;
3914 init_integral_libfuncs (smin_optab, "min", '3');
3915 init_floating_libfuncs (smin_optab, "min", '3');
3919 smax_optab->handlers[(int) QImode].insn_code = CODE_FOR_smaxqi3;
3923 smax_optab->handlers[(int) HImode].insn_code = CODE_FOR_smaxhi3;
3927 smax_optab->handlers[(int) SImode].insn_code = CODE_FOR_smaxsi3;
3931 smax_optab->handlers[(int) DImode].insn_code = CODE_FOR_smaxdi3;
3935 smax_optab->handlers[(int) TImode].insn_code = CODE_FOR_smaxti3;
3939 smax_optab->handlers[(int) SFmode].insn_code = CODE_FOR_maxsf3;
3943 smax_optab->handlers[(int) DFmode].insn_code = CODE_FOR_maxdf3;
3947 smax_optab->handlers[(int) XFmode].insn_code = CODE_FOR_maxxf3;
3951 smax_optab->handlers[(int) TFmode].insn_code = CODE_FOR_maxtf3;
3953 init_integral_libfuncs (smax_optab, "max", '3');
3954 init_floating_libfuncs (smax_optab, "max", '3');
3958 umin_optab->handlers[(int) QImode].insn_code = CODE_FOR_uminqi3;
3962 umin_optab->handlers[(int) HImode].insn_code = CODE_FOR_uminhi3;
3966 umin_optab->handlers[(int) SImode].insn_code = CODE_FOR_uminsi3;
3970 umin_optab->handlers[(int) DImode].insn_code = CODE_FOR_umindi3;
3974 umin_optab->handlers[(int) TImode].insn_code = CODE_FOR_uminti3;
3976 init_integral_libfuncs (umin_optab, "umin", '3');
3980 umax_optab->handlers[(int) QImode].insn_code = CODE_FOR_umaxqi3;
3984 umax_optab->handlers[(int) HImode].insn_code = CODE_FOR_umaxhi3;
3988 umax_optab->handlers[(int) SImode].insn_code = CODE_FOR_umaxsi3;
3992 umax_optab->handlers[(int) DImode].insn_code = CODE_FOR_umaxdi3;
3996 umax_optab->handlers[(int) TImode].insn_code = CODE_FOR_umaxti3;
3998 init_integral_libfuncs (umax_optab, "umax", '3');
4002 neg_optab->handlers[(int) QImode].insn_code = CODE_FOR_negqi2;
4006 neg_optab->handlers[(int) HImode].insn_code = CODE_FOR_neghi2;
4010 neg_optab->handlers[(int) PSImode].insn_code = CODE_FOR_negpsi2;
4014 neg_optab->handlers[(int) SImode].insn_code = CODE_FOR_negsi2;
4018 neg_optab->handlers[(int) DImode].insn_code = CODE_FOR_negdi2;
4022 neg_optab->handlers[(int) TImode].insn_code = CODE_FOR_negti2;
4026 neg_optab->handlers[(int) SFmode].insn_code = CODE_FOR_negsf2;
4030 neg_optab->handlers[(int) DFmode].insn_code = CODE_FOR_negdf2;
4034 neg_optab->handlers[(int) XFmode].insn_code = CODE_FOR_negxf2;
4038 neg_optab->handlers[(int) TFmode].insn_code = CODE_FOR_negtf2;
4040 init_integral_libfuncs (neg_optab, "neg", '2');
4041 init_floating_libfuncs (neg_optab, "neg", '2');
4045 abs_optab->handlers[(int) QImode].insn_code = CODE_FOR_absqi2;
4049 abs_optab->handlers[(int) HImode].insn_code = CODE_FOR_abshi2;
4053 abs_optab->handlers[(int) PSImode].insn_code = CODE_FOR_abspsi2;
4057 abs_optab->handlers[(int) SImode].insn_code = CODE_FOR_abssi2;
4061 abs_optab->handlers[(int) DImode].insn_code = CODE_FOR_absdi2;
4065 abs_optab->handlers[(int) TImode].insn_code = CODE_FOR_absti2;
4069 abs_optab->handlers[(int) SFmode].insn_code = CODE_FOR_abssf2;
4073 abs_optab->handlers[(int) DFmode].insn_code = CODE_FOR_absdf2;
4077 abs_optab->handlers[(int) XFmode].insn_code = CODE_FOR_absxf2;
4081 abs_optab->handlers[(int) TFmode].insn_code = CODE_FOR_abstf2;
4083 /* No library calls here! If there is no abs instruction,
4084 expand_expr will generate a conditional negation. */
4088 sqrt_optab->handlers[(int) QImode].insn_code = CODE_FOR_sqrtqi2;
4092 sqrt_optab->handlers[(int) HImode].insn_code = CODE_FOR_sqrthi2;
4094 #ifdef HAVE_sqrtpsi2
4096 sqrt_optab->handlers[(int) PSImode].insn_code = CODE_FOR_sqrtpsi2;
4100 sqrt_optab->handlers[(int) SImode].insn_code = CODE_FOR_sqrtsi2;
4104 sqrt_optab->handlers[(int) DImode].insn_code = CODE_FOR_sqrtdi2;
4108 sqrt_optab->handlers[(int) TImode].insn_code = CODE_FOR_sqrtti2;
4112 sqrt_optab->handlers[(int) SFmode].insn_code = CODE_FOR_sqrtsf2;
4116 sqrt_optab->handlers[(int) DFmode].insn_code = CODE_FOR_sqrtdf2;
4120 sqrt_optab->handlers[(int) TFmode].insn_code = CODE_FOR_sqrttf2;
4122 /* No library calls here! If there is no sqrt instruction expand_builtin
4123 should force the library call. */
4125 #ifdef HAVE_strlenqi
4127 strlen_optab->handlers[(int) QImode].insn_code = CODE_FOR_strlenqi;
4129 #ifdef HAVE_strlenhi
4131 strlen_optab->handlers[(int) HImode].insn_code = CODE_FOR_strlenhi;
4133 #ifdef HAVE_strlenpsi
4135 strlen_optab->handlers[(int) PSImode].insn_code = CODE_FOR_strlenpsi;
4137 #ifdef HAVE_strlensi
4139 strlen_optab->handlers[(int) SImode].insn_code = CODE_FOR_strlensi;
4141 #ifdef HAVE_strlendi
4143 strlen_optab->handlers[(int) DImode].insn_code = CODE_FOR_strlendi;
4145 #ifdef HAVE_strlenti
4147 strlen_optab->handlers[(int) TImode].insn_code = CODE_FOR_strlenti;
4149 /* No library calls here! If there is no strlen instruction expand_builtin
4150 should force the library call. */
4152 #ifdef HAVE_one_cmplqi2
4153 if (HAVE_one_cmplqi2)
4154 one_cmpl_optab->handlers[(int) QImode].insn_code = CODE_FOR_one_cmplqi2;
4156 #ifdef HAVE_one_cmplhi2
4157 if (HAVE_one_cmplhi2)
4158 one_cmpl_optab->handlers[(int) HImode].insn_code = CODE_FOR_one_cmplhi2;
4160 #ifdef HAVE_one_cmplpsi2
4161 if (HAVE_one_cmplpsi2)
4162 one_cmpl_optab->handlers[(int) PSImode].insn_code = CODE_FOR_one_cmplpsi2;
4164 #ifdef HAVE_one_cmplsi2
4165 if (HAVE_one_cmplsi2)
4166 one_cmpl_optab->handlers[(int) SImode].insn_code = CODE_FOR_one_cmplsi2;
4168 #ifdef HAVE_one_cmpldi2
4169 if (HAVE_one_cmpldi2)
4170 one_cmpl_optab->handlers[(int) DImode].insn_code = CODE_FOR_one_cmpldi2;
4172 #ifdef HAVE_one_cmplti2
4173 if (HAVE_one_cmplti2)
4174 one_cmpl_optab->handlers[(int) TImode].insn_code = CODE_FOR_one_cmplti2;
4176 init_integral_libfuncs (one_cmpl_optab, "one_cmpl", '2');
4180 ffs_optab->handlers[(int) QImode].insn_code = CODE_FOR_ffsqi2;
4184 ffs_optab->handlers[(int) HImode].insn_code = CODE_FOR_ffshi2;
4188 ffs_optab->handlers[(int) PSImode].insn_code = CODE_FOR_ffspsi2;
4192 ffs_optab->handlers[(int) SImode].insn_code = CODE_FOR_ffssi2;
4196 ffs_optab->handlers[(int) DImode].insn_code = CODE_FOR_ffsdi2;
4200 ffs_optab->handlers[(int) TImode].insn_code = CODE_FOR_ffsti2;
4202 init_integral_libfuncs (ffs_optab, "ffs", '2');
4206 mov_optab->handlers[(int) QImode].insn_code = CODE_FOR_movqi;
4210 mov_optab->handlers[(int) HImode].insn_code = CODE_FOR_movhi;
4214 mov_optab->handlers[(int) PSImode].insn_code = CODE_FOR_movpsi;
4218 mov_optab->handlers[(int) SImode].insn_code = CODE_FOR_movsi;
4222 mov_optab->handlers[(int) DImode].insn_code = CODE_FOR_movdi;
4226 mov_optab->handlers[(int) TImode].insn_code = CODE_FOR_movti;
4230 mov_optab->handlers[(int) SFmode].insn_code = CODE_FOR_movsf;
4234 mov_optab->handlers[(int) DFmode].insn_code = CODE_FOR_movdf;
4238 mov_optab->handlers[(int) XFmode].insn_code = CODE_FOR_movxf;
4242 mov_optab->handlers[(int) TFmode].insn_code = CODE_FOR_movtf;
4246 mov_optab->handlers[(int) CCmode].insn_code = CODE_FOR_movcc;
4249 #ifdef EXTRA_CC_MODES
4253 #ifdef HAVE_movstrictqi
4254 if (HAVE_movstrictqi)
4255 movstrict_optab->handlers[(int) QImode].insn_code = CODE_FOR_movstrictqi;
4257 #ifdef HAVE_movstricthi
4258 if (HAVE_movstricthi)
4259 movstrict_optab->handlers[(int) HImode].insn_code = CODE_FOR_movstricthi;
4261 #ifdef HAVE_movstrictpsi
4262 if (HAVE_movstrictpsi)
4263 movstrict_optab->handlers[(int) PSImode].insn_code = CODE_FOR_movstrictpsi;
4265 #ifdef HAVE_movstrictsi
4266 if (HAVE_movstrictsi)
4267 movstrict_optab->handlers[(int) SImode].insn_code = CODE_FOR_movstrictsi;
4269 #ifdef HAVE_movstrictdi
4270 if (HAVE_movstrictdi)
4271 movstrict_optab->handlers[(int) DImode].insn_code = CODE_FOR_movstrictdi;
4273 #ifdef HAVE_movstrictti
4274 if (HAVE_movstrictti)
4275 movstrict_optab->handlers[(int) TImode].insn_code = CODE_FOR_movstrictti;
4280 cmp_optab->handlers[(int) QImode].insn_code = CODE_FOR_cmpqi;
4284 cmp_optab->handlers[(int) HImode].insn_code = CODE_FOR_cmphi;
4288 cmp_optab->handlers[(int) PSImode].insn_code = CODE_FOR_cmppsi;
4292 cmp_optab->handlers[(int) SImode].insn_code = CODE_FOR_cmpsi;
4296 cmp_optab->handlers[(int) DImode].insn_code = CODE_FOR_cmpdi;
4300 cmp_optab->handlers[(int) TImode].insn_code = CODE_FOR_cmpti;
4304 cmp_optab->handlers[(int) SFmode].insn_code = CODE_FOR_cmpsf;
4308 cmp_optab->handlers[(int) DFmode].insn_code = CODE_FOR_cmpdf;
4312 cmp_optab->handlers[(int) XFmode].insn_code = CODE_FOR_cmpxf;
4316 cmp_optab->handlers[(int) TFmode].insn_code = CODE_FOR_cmptf;
4318 /* Comparison libcalls for integers MUST come in pairs, signed/unsigned. */
4319 init_integral_libfuncs (cmp_optab, "cmp", '2');
4320 init_integral_libfuncs (ucmp_optab, "ucmp", '2');
4321 init_floating_libfuncs (cmp_optab, "cmp", '2');
4325 tst_optab->handlers[(int) QImode].insn_code = CODE_FOR_tstqi;
4329 tst_optab->handlers[(int) HImode].insn_code = CODE_FOR_tsthi;
4333 tst_optab->handlers[(int) PSImode].insn_code = CODE_FOR_tstpsi;
4337 tst_optab->handlers[(int) SImode].insn_code = CODE_FOR_tstsi;
4341 tst_optab->handlers[(int) DImode].insn_code = CODE_FOR_tstdi;
4345 tst_optab->handlers[(int) TImode].insn_code = CODE_FOR_tstti;
4349 tst_optab->handlers[(int) SFmode].insn_code = CODE_FOR_tstsf;
4353 tst_optab->handlers[(int) DFmode].insn_code = CODE_FOR_tstdf;
4357 tst_optab->handlers[(int) XFmode].insn_code = CODE_FOR_tstxf;
4361 tst_optab->handlers[(int) TFmode].insn_code = CODE_FOR_tsttf;
4366 bcc_gen_fctn[(int) EQ] = gen_beq;
4370 bcc_gen_fctn[(int) NE] = gen_bne;
4374 bcc_gen_fctn[(int) GT] = gen_bgt;
4378 bcc_gen_fctn[(int) GE] = gen_bge;
4382 bcc_gen_fctn[(int) GTU] = gen_bgtu;
4386 bcc_gen_fctn[(int) GEU] = gen_bgeu;
4390 bcc_gen_fctn[(int) LT] = gen_blt;
4394 bcc_gen_fctn[(int) LE] = gen_ble;
4398 bcc_gen_fctn[(int) LTU] = gen_bltu;
4402 bcc_gen_fctn[(int) LEU] = gen_bleu;
4405 for (i = 0; i < NUM_RTX_CODE; i++)
4406 setcc_gen_code[i] = CODE_FOR_nothing;
4410 setcc_gen_code[(int) EQ] = CODE_FOR_seq;
4414 setcc_gen_code[(int) NE] = CODE_FOR_sne;
4418 setcc_gen_code[(int) GT] = CODE_FOR_sgt;
4422 setcc_gen_code[(int) GE] = CODE_FOR_sge;
4426 setcc_gen_code[(int) GTU] = CODE_FOR_sgtu;
4430 setcc_gen_code[(int) GEU] = CODE_FOR_sgeu;
4434 setcc_gen_code[(int) LT] = CODE_FOR_slt;
4438 setcc_gen_code[(int) LE] = CODE_FOR_sle;
4442 setcc_gen_code[(int) LTU] = CODE_FOR_sltu;
4446 setcc_gen_code[(int) LEU] = CODE_FOR_sleu;
4449 extendsfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extendsfdf2");
4450 extendsfxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extendsfxf2");
4451 extendsftf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extendsftf2");
4452 extenddfxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extenddfxf2");
4453 extenddftf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extenddftf2");
4455 truncdfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__truncdfsf2");
4456 truncxfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__truncxfsf2");
4457 trunctfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__trunctfsf2");
4458 truncxfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__truncxfdf2");
4459 trunctfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__trunctfdf2");
4461 memcpy_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memcpy");
4462 bcopy_libfunc = gen_rtx (SYMBOL_REF, Pmode, "bcopy");
4463 memcmp_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memcmp");
4464 bcmp_libfunc = gen_rtx (SYMBOL_REF, Pmode, "bcmp");
4465 memset_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memset");
4466 bzero_libfunc = gen_rtx (SYMBOL_REF, Pmode, "bzero");
4468 eqsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqsf2");
4469 nesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nesf2");
4470 gtsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtsf2");
4471 gesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gesf2");
4472 ltsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltsf2");
4473 lesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lesf2");
4475 eqdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqdf2");
4476 nedf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nedf2");
4477 gtdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtdf2");
4478 gedf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gedf2");
4479 ltdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltdf2");
4480 ledf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ledf2");
4482 eqxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqxf2");
4483 nexf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nexf2");
4484 gtxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtxf2");
4485 gexf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gexf2");
4486 ltxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltxf2");
4487 lexf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lexf2");
4489 eqtf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqtf2");
4490 netf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__netf2");
4491 gttf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gttf2");
4492 getf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__getf2");
4493 lttf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lttf2");
4494 letf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__letf2");
4496 floatsisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsisf");
4497 floatdisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatdisf");
4498 floattisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattisf");
4500 floatsidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsidf");
4501 floatdidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatdidf");
4502 floattidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattidf");
4504 floatsixf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsixf");
4505 floatdixf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatdixf");
4506 floattixf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattixf");
4508 floatsitf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsitf");
4509 floatditf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatditf");
4510 floattitf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattitf");
4512 fixsfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixsfsi");
4513 fixsfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixsfdi");
4514 fixsfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixsfti");
4516 fixdfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixdfsi");
4517 fixdfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixdfdi");
4518 fixdfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixdfti");
4520 fixxfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixxfsi");
4521 fixxfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixxfdi");
4522 fixxfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixxfti");
4524 fixtfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixtfsi");
4525 fixtfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixtfdi");
4526 fixtfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixtfti");
4528 fixunssfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunssfsi");
4529 fixunssfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunssfdi");
4530 fixunssfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunssfti");
4532 fixunsdfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsdfsi");
4533 fixunsdfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsdfdi");
4534 fixunsdfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsdfti");
4536 fixunsxfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsxfsi");
4537 fixunsxfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsxfdi");
4538 fixunsxfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsxfti");
4540 fixunstfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunstfsi");
4541 fixunstfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunstfdi");
4542 fixunstfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunstfti");
4547 /* SCO 3.2 apparently has a broken ldexp. */
4560 #endif /* BROKEN_LDEXP */