1 /* Expand the basic unary and binary arithmetic operations, for GNU compiler.
2 Copyright (C) 1987, 1988, 1992, 1993, 1994 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"
33 /* Each optab contains info on how this target machine
34 can perform a particular operation
35 for all sizes and kinds of operands.
37 The operation to be performed is often specified
38 by passing one of these optabs as an argument.
40 See expr.h for documentation of these optabs. */
45 optab smul_widen_optab;
46 optab umul_widen_optab;
69 optab movstrict_optab;
80 optab ucmp_optab; /* Used only for libcalls for unsigned comparisons. */
85 /* Tables of patterns for extending one integer mode to another. */
86 enum insn_code extendtab[MAX_MACHINE_MODE][MAX_MACHINE_MODE][2];
88 /* Tables of patterns for converting between fixed and floating point. */
89 enum insn_code fixtab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
90 enum insn_code fixtrunctab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
91 enum insn_code floattab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
93 /* Contains the optab used for each rtx code. */
94 optab code_to_optab[NUM_RTX_CODE + 1];
96 /* SYMBOL_REF rtx's for the library functions that are called
97 implicitly and not via optabs. */
99 rtx extendsfdf2_libfunc;
100 rtx extendsfxf2_libfunc;
101 rtx extendsftf2_libfunc;
102 rtx extenddfxf2_libfunc;
103 rtx extenddftf2_libfunc;
105 rtx truncdfsf2_libfunc;
106 rtx truncxfsf2_libfunc;
107 rtx trunctfsf2_libfunc;
108 rtx truncxfdf2_libfunc;
109 rtx trunctfdf2_libfunc;
146 rtx floatsisf_libfunc;
147 rtx floatdisf_libfunc;
148 rtx floattisf_libfunc;
150 rtx floatsidf_libfunc;
151 rtx floatdidf_libfunc;
152 rtx floattidf_libfunc;
154 rtx floatsixf_libfunc;
155 rtx floatdixf_libfunc;
156 rtx floattixf_libfunc;
158 rtx floatsitf_libfunc;
159 rtx floatditf_libfunc;
160 rtx floattitf_libfunc;
178 rtx fixunssfsi_libfunc;
179 rtx fixunssfdi_libfunc;
180 rtx fixunssfti_libfunc;
182 rtx fixunsdfsi_libfunc;
183 rtx fixunsdfdi_libfunc;
184 rtx fixunsdfti_libfunc;
186 rtx fixunsxfsi_libfunc;
187 rtx fixunsxfdi_libfunc;
188 rtx fixunsxfti_libfunc;
190 rtx fixunstfsi_libfunc;
191 rtx fixunstfdi_libfunc;
192 rtx fixunstfti_libfunc;
194 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
195 gives the gen_function to make a branch to test that condition. */
197 rtxfun bcc_gen_fctn[NUM_RTX_CODE];
199 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
200 gives the insn code to make a store-condition insn
201 to test that condition. */
203 enum insn_code setcc_gen_code[NUM_RTX_CODE];
205 static int add_equal_note PROTO((rtx, rtx, enum rtx_code, rtx, rtx));
206 static rtx widen_operand PROTO((rtx, enum machine_mode,
207 enum machine_mode, int, int));
208 static enum insn_code can_fix_p PROTO((enum machine_mode, enum machine_mode,
210 static enum insn_code can_float_p PROTO((enum machine_mode, enum machine_mode,
212 static rtx ftruncify PROTO((rtx));
213 static optab init_optab PROTO((enum rtx_code));
214 static void init_libfuncs PROTO((optab, int, int, char *, int));
215 static void init_integral_libfuncs PROTO((optab, char *, int));
216 static void init_floating_libfuncs PROTO((optab, char *, int));
217 static void init_complex_libfuncs PROTO((optab, char *, int));
219 /* Add a REG_EQUAL note to the last insn in SEQ. TARGET is being set to
220 the result of operation CODE applied to OP0 (and OP1 if it is a binary
223 If the last insn does not set TARGET, don't do anything, but return 1.
225 If a previous insn sets TARGET and TARGET is one of OP0 or OP1,
226 don't add the REG_EQUAL note but return 0. Our caller can then try
227 again, ensuring that TARGET is not one of the operands. */
230 add_equal_note (seq, target, code, op0, op1)
240 if ((GET_RTX_CLASS (code) != '1' && GET_RTX_CLASS (code) != '2'
241 && GET_RTX_CLASS (code) != 'c' && GET_RTX_CLASS (code) != '<')
242 || GET_CODE (seq) != SEQUENCE
243 || (set = single_set (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1))) == 0
244 || GET_CODE (target) == ZERO_EXTRACT
245 || (! rtx_equal_p (SET_DEST (set), target)
246 /* For a STRICT_LOW_PART, the REG_NOTE applies to what is inside the
248 && (GET_CODE (SET_DEST (set)) != STRICT_LOW_PART
249 || ! rtx_equal_p (SUBREG_REG (XEXP (SET_DEST (set), 0)),
253 /* If TARGET is in OP0 or OP1, check if anything in SEQ sets TARGET
254 besides the last insn. */
255 if (reg_overlap_mentioned_p (target, op0)
256 || (op1 && reg_overlap_mentioned_p (target, op1)))
257 for (i = XVECLEN (seq, 0) - 2; i >= 0; i--)
258 if (reg_set_p (target, XVECEXP (seq, 0, i)))
261 if (GET_RTX_CLASS (code) == '1')
262 note = gen_rtx (code, GET_MODE (target), copy_rtx (op0));
264 note = gen_rtx (code, GET_MODE (target), copy_rtx (op0), copy_rtx (op1));
266 REG_NOTES (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1))
267 = gen_rtx (EXPR_LIST, REG_EQUAL, note,
268 REG_NOTES (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1)));
273 /* Widen OP to MODE and return the rtx for the widened operand. UNSIGNEDP
274 says whether OP is signed or unsigned. NO_EXTEND is nonzero if we need
275 not actually do a sign-extend or zero-extend, but can leave the
276 higher-order bits of the result rtx undefined, for example, in the case
277 of logical operations, but not right shifts. */
280 widen_operand (op, mode, oldmode, unsignedp, no_extend)
282 enum machine_mode mode, oldmode;
288 /* If we must extend do so. If OP is either a constant or a SUBREG
289 for a promoted object, also extend since it will be more efficient to
292 || GET_MODE (op) == VOIDmode
293 || (GET_CODE (op) == SUBREG && SUBREG_PROMOTED_VAR_P (op)))
294 return convert_modes (mode, oldmode, op, unsignedp);
296 /* If MODE is no wider than a single word, we return a paradoxical
298 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
299 return gen_rtx (SUBREG, mode, force_reg (GET_MODE (op), op), 0);
301 /* Otherwise, get an object of MODE, clobber it, and set the low-order
304 result = gen_reg_rtx (mode);
305 emit_insn (gen_rtx (CLOBBER, VOIDmode, result));
306 emit_move_insn (gen_lowpart (GET_MODE (op), result), op);
310 /* Generate code to perform an operation specified by BINOPTAB
311 on operands OP0 and OP1, with result having machine-mode MODE.
313 UNSIGNEDP is for the case where we have to widen the operands
314 to perform the operation. It says to use zero-extension.
316 If TARGET is nonzero, the value
317 is generated there, if it is convenient to do so.
318 In all cases an rtx is returned for the locus of the value;
319 this may or may not be TARGET. */
322 expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods)
323 enum machine_mode mode;
328 enum optab_methods methods;
330 enum mode_class class;
331 enum machine_mode wider_mode;
333 int commutative_op = 0;
334 int shift_op = (binoptab->code == ASHIFT
335 || binoptab->code == ASHIFTRT
336 || binoptab->code == LSHIFTRT
337 || binoptab->code == ROTATE
338 || binoptab->code == ROTATERT);
339 rtx entry_last = get_last_insn ();
342 class = GET_MODE_CLASS (mode);
344 op0 = protect_from_queue (op0, 0);
345 op1 = protect_from_queue (op1, 0);
347 target = protect_from_queue (target, 1);
351 op0 = force_not_mem (op0);
352 op1 = force_not_mem (op1);
355 /* If subtracting an integer constant, convert this into an addition of
356 the negated constant. */
358 if (binoptab == sub_optab && GET_CODE (op1) == CONST_INT)
360 op1 = negate_rtx (mode, op1);
361 binoptab = add_optab;
364 /* If we are inside an appropriately-short loop and one operand is an
365 expensive constant, force it into a register. */
366 if (CONSTANT_P (op0) && preserve_subexpressions_p ()
367 && rtx_cost (op0, binoptab->code) > 2)
368 op0 = force_reg (mode, op0);
370 if (CONSTANT_P (op1) && preserve_subexpressions_p ()
371 && rtx_cost (op1, binoptab->code) > 2)
372 op1 = force_reg (shift_op ? word_mode : mode, op1);
374 /* Record where to delete back to if we backtrack. */
375 last = get_last_insn ();
377 /* If operation is commutative,
378 try to make the first operand a register.
379 Even better, try to make it the same as the target.
380 Also try to make the last operand a constant. */
381 if (GET_RTX_CLASS (binoptab->code) == 'c'
382 || binoptab == smul_widen_optab
383 || binoptab == umul_widen_optab)
387 if (((target == 0 || GET_CODE (target) == REG)
388 ? ((GET_CODE (op1) == REG
389 && GET_CODE (op0) != REG)
391 : rtx_equal_p (op1, target))
392 || GET_CODE (op0) == CONST_INT)
400 /* If we can do it with a three-operand insn, do so. */
402 if (methods != OPTAB_MUST_WIDEN
403 && binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
405 int icode = (int) binoptab->handlers[(int) mode].insn_code;
406 enum machine_mode mode0 = insn_operand_mode[icode][1];
407 enum machine_mode mode1 = insn_operand_mode[icode][2];
409 rtx xop0 = op0, xop1 = op1;
414 temp = gen_reg_rtx (mode);
416 /* If it is a commutative operator and the modes would match
417 if we would swap the operands, we can save the conversions. */
420 if (GET_MODE (op0) != mode0 && GET_MODE (op1) != mode1
421 && GET_MODE (op0) == mode1 && GET_MODE (op1) == mode0)
425 tmp = op0; op0 = op1; op1 = tmp;
426 tmp = xop0; xop0 = xop1; xop1 = tmp;
430 /* In case the insn wants input operands in modes different from
431 the result, convert the operands. */
433 if (GET_MODE (op0) != VOIDmode
434 && GET_MODE (op0) != mode0)
435 xop0 = convert_to_mode (mode0, xop0, unsignedp);
437 if (GET_MODE (xop1) != VOIDmode
438 && GET_MODE (xop1) != mode1)
439 xop1 = convert_to_mode (mode1, xop1, unsignedp);
441 /* Now, if insn's predicates don't allow our operands, put them into
444 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
445 xop0 = copy_to_mode_reg (mode0, xop0);
447 if (! (*insn_operand_predicate[icode][2]) (xop1, mode1))
448 xop1 = copy_to_mode_reg (mode1, xop1);
450 if (! (*insn_operand_predicate[icode][0]) (temp, mode))
451 temp = gen_reg_rtx (mode);
453 pat = GEN_FCN (icode) (temp, xop0, xop1);
456 /* If PAT is a multi-insn sequence, try to add an appropriate
457 REG_EQUAL note to it. If we can't because TEMP conflicts with an
458 operand, call ourselves again, this time without a target. */
459 if (GET_CODE (pat) == SEQUENCE
460 && ! add_equal_note (pat, temp, binoptab->code, xop0, xop1))
462 delete_insns_since (last);
463 return expand_binop (mode, binoptab, op0, op1, NULL_RTX,
471 delete_insns_since (last);
474 /* If this is a multiply, see if we can do a widening operation that
475 takes operands of this mode and makes a wider mode. */
477 if (binoptab == smul_optab && GET_MODE_WIDER_MODE (mode) != VOIDmode
478 && (((unsignedp ? umul_widen_optab : smul_widen_optab)
479 ->handlers[(int) GET_MODE_WIDER_MODE (mode)].insn_code)
480 != CODE_FOR_nothing))
482 temp = expand_binop (GET_MODE_WIDER_MODE (mode),
483 unsignedp ? umul_widen_optab : smul_widen_optab,
484 op0, op1, 0, unsignedp, OPTAB_DIRECT);
486 if (GET_MODE_CLASS (mode) == MODE_INT)
487 return gen_lowpart (mode, temp);
489 return convert_to_mode (mode, temp, unsignedp);
492 /* Look for a wider mode of the same class for which we think we
493 can open-code the operation. Check for a widening multiply at the
494 wider mode as well. */
496 if ((class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
497 && methods != OPTAB_DIRECT && methods != OPTAB_LIB)
498 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
499 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
501 if (binoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing
502 || (binoptab == smul_optab
503 && GET_MODE_WIDER_MODE (wider_mode) != VOIDmode
504 && (((unsignedp ? umul_widen_optab : smul_widen_optab)
505 ->handlers[(int) GET_MODE_WIDER_MODE (wider_mode)].insn_code)
506 != CODE_FOR_nothing)))
508 rtx xop0 = op0, xop1 = op1;
511 /* For certain integer operations, we need not actually extend
512 the narrow operands, as long as we will truncate
513 the results to the same narrowness. */
515 if ((binoptab == ior_optab || binoptab == and_optab
516 || binoptab == xor_optab
517 || binoptab == add_optab || binoptab == sub_optab
518 || binoptab == smul_optab || binoptab == ashl_optab)
519 && class == MODE_INT)
522 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp, no_extend);
524 /* The second operand of a shift must always be extended. */
525 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
526 no_extend && binoptab != ashl_optab);
528 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
529 unsignedp, OPTAB_DIRECT);
532 if (class != MODE_INT)
535 target = gen_reg_rtx (mode);
536 convert_move (target, temp, 0);
540 return gen_lowpart (mode, temp);
543 delete_insns_since (last);
547 /* These can be done a word at a time. */
548 if ((binoptab == and_optab || binoptab == ior_optab || binoptab == xor_optab)
550 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
551 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
557 /* If TARGET is the same as one of the operands, the REG_EQUAL note
558 won't be accurate, so use a new target. */
559 if (target == 0 || target == op0 || target == op1)
560 target = gen_reg_rtx (mode);
564 /* Do the actual arithmetic. */
565 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
567 rtx target_piece = operand_subword (target, i, 1, mode);
568 rtx x = expand_binop (word_mode, binoptab,
569 operand_subword_force (op0, i, mode),
570 operand_subword_force (op1, i, mode),
571 target_piece, unsignedp, methods);
572 if (target_piece != x)
573 emit_move_insn (target_piece, x);
576 insns = get_insns ();
579 if (binoptab->code != UNKNOWN)
581 = gen_rtx (binoptab->code, mode, copy_rtx (op0), copy_rtx (op1));
585 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
589 /* Synthesize double word shifts from single word shifts. */
590 if ((binoptab == lshr_optab || binoptab == ashl_optab
591 || binoptab == ashr_optab)
593 && GET_CODE (op1) == CONST_INT
594 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
595 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
596 && ashl_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
597 && lshr_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
599 rtx insns, equiv_value;
600 rtx into_target, outof_target;
601 rtx into_input, outof_input;
602 int shift_count, left_shift, outof_word;
604 /* If TARGET is the same as one of the operands, the REG_EQUAL note
605 won't be accurate, so use a new target. */
606 if (target == 0 || target == op0 || target == op1)
607 target = gen_reg_rtx (mode);
611 shift_count = INTVAL (op1);
613 /* OUTOF_* is the word we are shifting bits away from, and
614 INTO_* is the word that we are shifting bits towards, thus
615 they differ depending on the direction of the shift and
618 left_shift = binoptab == ashl_optab;
619 outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
621 outof_target = operand_subword (target, outof_word, 1, mode);
622 into_target = operand_subword (target, 1 - outof_word, 1, mode);
624 outof_input = operand_subword_force (op0, outof_word, mode);
625 into_input = operand_subword_force (op0, 1 - outof_word, mode);
627 if (shift_count >= BITS_PER_WORD)
629 emit_move_insn (into_target,
630 expand_binop (word_mode, binoptab,
632 GEN_INT (shift_count - BITS_PER_WORD),
633 into_target, unsignedp, methods));
635 /* For a signed right shift, we must fill the word we are shifting
636 out of with copies of the sign bit. Otherwise it is zeroed. */
637 if (binoptab != ashr_optab)
638 emit_move_insn (outof_target, CONST0_RTX (word_mode));
640 emit_move_insn (outof_target,
641 expand_binop (word_mode, binoptab,
643 GEN_INT (BITS_PER_WORD - 1),
644 outof_target, unsignedp, methods));
648 rtx carries, into_temp;
649 optab reverse_unsigned_shift, unsigned_shift;
651 /* For a shift of less then BITS_PER_WORD, to compute the carry,
652 we must do a logical shift in the opposite direction of the
655 reverse_unsigned_shift = (left_shift ? lshr_optab : ashl_optab);
657 /* For a shift of less than BITS_PER_WORD, to compute the word
658 shifted towards, we need to unsigned shift the orig value of
661 unsigned_shift = (left_shift ? ashl_optab : lshr_optab);
663 carries = expand_binop (word_mode, reverse_unsigned_shift,
665 GEN_INT (BITS_PER_WORD - shift_count),
666 0, unsignedp, methods);
668 emit_move_insn (outof_target,
669 expand_binop (word_mode, binoptab,
671 op1, outof_target, unsignedp, methods));
672 into_temp = expand_binop (word_mode, unsigned_shift,
674 op1, 0, unsignedp, methods);
676 emit_move_insn (into_target,
677 expand_binop (word_mode, ior_optab,
679 into_target, unsignedp, methods));
682 insns = get_insns ();
685 if (binoptab->code != UNKNOWN)
686 equiv_value = gen_rtx (binoptab->code, mode, op0, op1);
690 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
694 /* Synthesize double word rotates from single word shifts. */
695 if ((binoptab == rotl_optab || binoptab == rotr_optab)
697 && GET_CODE (op1) == CONST_INT
698 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
699 && ashl_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
700 && lshr_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
702 rtx insns, equiv_value;
703 rtx into_target, outof_target;
704 rtx into_input, outof_input;
705 int shift_count, left_shift, outof_word;
707 /* If TARGET is the same as one of the operands, the REG_EQUAL note
708 won't be accurate, so use a new target. */
709 if (target == 0 || target == op0 || target == op1)
710 target = gen_reg_rtx (mode);
714 shift_count = INTVAL (op1);
716 /* OUTOF_* is the word we are shifting bits away from, and
717 INTO_* is the word that we are shifting bits towards, thus
718 they differ depending on the direction of the shift and
721 left_shift = (binoptab == rotl_optab);
722 outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
724 outof_target = operand_subword (target, outof_word, 1, mode);
725 into_target = operand_subword (target, 1 - outof_word, 1, mode);
727 outof_input = operand_subword_force (op0, outof_word, mode);
728 into_input = operand_subword_force (op0, 1 - outof_word, mode);
730 if (shift_count == BITS_PER_WORD)
732 /* This is just a word swap. */
733 emit_move_insn (outof_target, into_input);
734 emit_move_insn (into_target, outof_input);
738 rtx into_temp1, into_temp2, outof_temp1, outof_temp2;
739 rtx first_shift_count, second_shift_count;
740 optab reverse_unsigned_shift, unsigned_shift;
742 reverse_unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
743 ? lshr_optab : ashl_optab);
745 unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
746 ? ashl_optab : lshr_optab);
748 if (shift_count > BITS_PER_WORD)
750 first_shift_count = GEN_INT (shift_count - BITS_PER_WORD);
751 second_shift_count = GEN_INT (2*BITS_PER_WORD - shift_count);
755 first_shift_count = GEN_INT (BITS_PER_WORD - shift_count);
756 second_shift_count = GEN_INT (shift_count);
759 into_temp1 = expand_binop (word_mode, unsigned_shift,
760 outof_input, first_shift_count,
761 0, unsignedp, methods);
762 into_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
763 into_input, second_shift_count,
764 into_target, unsignedp, methods);
765 emit_move_insn (into_target,
766 expand_binop (word_mode, ior_optab,
767 into_temp1, into_temp2,
768 into_target, unsignedp, methods));
770 outof_temp1 = expand_binop (word_mode, unsigned_shift,
771 into_input, first_shift_count,
772 0, unsignedp, methods);
773 outof_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
774 outof_input, second_shift_count,
775 outof_target, unsignedp, methods);
776 emit_move_insn (outof_target,
777 expand_binop (word_mode, ior_optab,
778 outof_temp1, outof_temp2,
779 outof_target, unsignedp, methods));
782 insns = get_insns ();
785 if (binoptab->code != UNKNOWN)
786 equiv_value = gen_rtx (binoptab->code, mode, op0, op1);
790 /* We can't make this a no conflict block if this is a word swap,
791 because the word swap case fails if the input and output values
792 are in the same register. */
793 if (shift_count != BITS_PER_WORD)
794 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
800 /* These can be done a word at a time by propagating carries. */
801 if ((binoptab == add_optab || binoptab == sub_optab)
803 && GET_MODE_SIZE (mode) >= 2 * UNITS_PER_WORD
804 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
807 rtx carry_tmp = gen_reg_rtx (word_mode);
808 optab otheroptab = binoptab == add_optab ? sub_optab : add_optab;
809 int nwords = GET_MODE_BITSIZE (mode) / BITS_PER_WORD;
810 rtx carry_in, carry_out;
813 /* We can handle either a 1 or -1 value for the carry. If STORE_FLAG
814 value is one of those, use it. Otherwise, use 1 since it is the
815 one easiest to get. */
816 #if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
817 int normalizep = STORE_FLAG_VALUE;
822 /* Prepare the operands. */
823 xop0 = force_reg (mode, op0);
824 xop1 = force_reg (mode, op1);
826 if (target == 0 || GET_CODE (target) != REG
827 || target == xop0 || target == xop1)
828 target = gen_reg_rtx (mode);
830 /* Indicate for flow that the entire target reg is being set. */
831 if (GET_CODE (target) == REG)
832 emit_insn (gen_rtx (CLOBBER, VOIDmode, target));
834 /* Do the actual arithmetic. */
835 for (i = 0; i < nwords; i++)
837 int index = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i);
838 rtx target_piece = operand_subword (target, index, 1, mode);
839 rtx op0_piece = operand_subword_force (xop0, index, mode);
840 rtx op1_piece = operand_subword_force (xop1, index, mode);
843 /* Main add/subtract of the input operands. */
844 x = expand_binop (word_mode, binoptab,
845 op0_piece, op1_piece,
846 target_piece, unsignedp, methods);
852 /* Store carry from main add/subtract. */
853 carry_out = gen_reg_rtx (word_mode);
854 carry_out = emit_store_flag (carry_out,
855 binoptab == add_optab ? LTU : GTU,
857 word_mode, 1, normalizep);
864 /* Add/subtract previous carry to main result. */
865 x = expand_binop (word_mode,
866 normalizep == 1 ? binoptab : otheroptab,
868 target_piece, 1, methods);
869 if (target_piece != x)
870 emit_move_insn (target_piece, x);
874 /* THIS CODE HAS NOT BEEN TESTED. */
875 /* Get out carry from adding/subtracting carry in. */
876 carry_tmp = emit_store_flag (carry_tmp,
877 binoptab == add_optab
880 word_mode, 1, normalizep);
881 /* Logical-ior the two poss. carry together. */
882 carry_out = expand_binop (word_mode, ior_optab,
883 carry_out, carry_tmp,
884 carry_out, 0, methods);
890 carry_in = carry_out;
893 if (i == GET_MODE_BITSIZE (mode) / BITS_PER_WORD)
897 temp = emit_move_insn (target, target);
898 REG_NOTES (temp) = gen_rtx (EXPR_LIST, REG_EQUAL,
899 gen_rtx (binoptab->code, mode,
906 delete_insns_since (last);
909 /* If we want to multiply two two-word values and have normal and widening
910 multiplies of single-word values, we can do this with three smaller
911 multiplications. Note that we do not make a REG_NO_CONFLICT block here
912 because we are not operating on one word at a time.
914 The multiplication proceeds as follows:
915 _______________________
916 [__op0_high_|__op0_low__]
917 _______________________
918 * [__op1_high_|__op1_low__]
919 _______________________________________________
920 _______________________
921 (1) [__op0_low__*__op1_low__]
922 _______________________
923 (2a) [__op0_low__*__op1_high_]
924 _______________________
925 (2b) [__op0_high_*__op1_low__]
926 _______________________
927 (3) [__op0_high_*__op1_high_]
930 This gives a 4-word result. Since we are only interested in the
931 lower 2 words, partial result (3) and the upper words of (2a) and
932 (2b) don't need to be calculated. Hence (2a) and (2b) can be
933 calculated using non-widening multiplication.
935 (1), however, needs to be calculated with an unsigned widening
936 multiplication. If this operation is not directly supported we
937 try using a signed widening multiplication and adjust the result.
938 This adjustment works as follows:
940 If both operands are positive then no adjustment is needed.
942 If the operands have different signs, for example op0_low < 0 and
943 op1_low >= 0, the instruction treats the most significant bit of
944 op0_low as a sign bit instead of a bit with significance
945 2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low
946 with 2**BITS_PER_WORD - op0_low, and two's complements the
947 result. Conclusion: We need to add op1_low * 2**BITS_PER_WORD to
950 Similarly, if both operands are negative, we need to add
951 (op0_low + op1_low) * 2**BITS_PER_WORD.
953 We use a trick to adjust quickly. We logically shift op0_low right
954 (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to
955 op0_high (op1_high) before it is used to calculate 2b (2a). If no
956 logical shift exists, we do an arithmetic right shift and subtract
959 if (binoptab == smul_optab
961 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
962 && smul_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
963 && add_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
964 && ((umul_widen_optab->handlers[(int) mode].insn_code
966 || (smul_widen_optab->handlers[(int) mode].insn_code
967 != CODE_FOR_nothing)))
969 int low = (WORDS_BIG_ENDIAN ? 1 : 0);
970 int high = (WORDS_BIG_ENDIAN ? 0 : 1);
971 rtx op0_high = operand_subword_force (op0, high, mode);
972 rtx op0_low = operand_subword_force (op0, low, mode);
973 rtx op1_high = operand_subword_force (op1, high, mode);
974 rtx op1_low = operand_subword_force (op1, low, mode);
979 /* If the target is the same as one of the inputs, don't use it. This
980 prevents problems with the REG_EQUAL note. */
981 if (target == op0 || target == op1)
984 /* Multiply the two lower words to get a double-word product.
985 If unsigned widening multiplication is available, use that;
986 otherwise use the signed form and compensate. */
988 if (umul_widen_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
990 product = expand_binop (mode, umul_widen_optab, op0_low, op1_low,
991 target, 1, OPTAB_DIRECT);
993 /* If we didn't succeed, delete everything we did so far. */
995 delete_insns_since (last);
997 op0_xhigh = op0_high, op1_xhigh = op1_high;
1001 && smul_widen_optab->handlers[(int) mode].insn_code
1002 != CODE_FOR_nothing)
1004 rtx wordm1 = GEN_INT (BITS_PER_WORD - 1);
1005 product = expand_binop (mode, smul_widen_optab, op0_low, op1_low,
1006 target, 1, OPTAB_DIRECT);
1007 op0_xhigh = expand_binop (word_mode, lshr_optab, op0_low, wordm1,
1008 NULL_RTX, 1, OPTAB_DIRECT);
1010 op0_xhigh = expand_binop (word_mode, add_optab, op0_high,
1011 op0_xhigh, op0_xhigh, 0, OPTAB_DIRECT);
1014 op0_xhigh = expand_binop (word_mode, ashr_optab, op0_low, wordm1,
1015 NULL_RTX, 0, OPTAB_DIRECT);
1017 op0_xhigh = expand_binop (word_mode, sub_optab, op0_high,
1018 op0_xhigh, op0_xhigh, 0,
1022 op1_xhigh = expand_binop (word_mode, lshr_optab, op1_low, wordm1,
1023 NULL_RTX, 1, OPTAB_DIRECT);
1025 op1_xhigh = expand_binop (word_mode, add_optab, op1_high,
1026 op1_xhigh, op1_xhigh, 0, OPTAB_DIRECT);
1029 op1_xhigh = expand_binop (word_mode, ashr_optab, op1_low, wordm1,
1030 NULL_RTX, 0, OPTAB_DIRECT);
1032 op1_xhigh = expand_binop (word_mode, sub_optab, op1_high,
1033 op1_xhigh, op1_xhigh, 0,
1038 /* If we have been able to directly compute the product of the
1039 low-order words of the operands and perform any required adjustments
1040 of the operands, we proceed by trying two more multiplications
1041 and then computing the appropriate sum.
1043 We have checked above that the required addition is provided.
1044 Full-word addition will normally always succeed, especially if
1045 it is provided at all, so we don't worry about its failure. The
1046 multiplication may well fail, however, so we do handle that. */
1048 if (product && op0_xhigh && op1_xhigh)
1051 rtx product_high = operand_subword (product, high, 1, mode);
1052 rtx temp = expand_binop (word_mode, binoptab, op0_low, op1_xhigh,
1053 NULL_RTX, 0, OPTAB_DIRECT);
1057 product_piece = expand_binop (word_mode, add_optab, temp,
1058 product_high, product_high,
1059 0, OPTAB_LIB_WIDEN);
1060 if (product_piece != product_high)
1061 emit_move_insn (product_high, product_piece);
1063 temp = expand_binop (word_mode, binoptab, op1_low, op0_xhigh,
1064 NULL_RTX, 0, OPTAB_DIRECT);
1066 product_piece = expand_binop (word_mode, add_optab, temp,
1067 product_high, product_high,
1068 0, OPTAB_LIB_WIDEN);
1069 if (product_piece != product_high)
1070 emit_move_insn (product_high, product_piece);
1072 temp = emit_move_insn (product, product);
1073 REG_NOTES (temp) = gen_rtx (EXPR_LIST, REG_EQUAL,
1074 gen_rtx (MULT, mode, copy_rtx (op0),
1082 /* If we get here, we couldn't do it for some reason even though we
1083 originally thought we could. Delete anything we've emitted in
1086 delete_insns_since (last);
1089 /* We need to open-code the complex type operations: '+, -, * and /' */
1091 /* At this point we allow operations between two similar complex
1092 numbers, and also if one of the operands is not a complex number
1093 but rather of MODE_FLOAT or MODE_INT. However, the caller
1094 must make sure that the MODE of the non-complex operand matches
1095 the SUBMODE of the complex operand. */
1097 if (class == MODE_COMPLEX_FLOAT || class == MODE_COMPLEX_INT)
1099 rtx real0 = (rtx) 0;
1100 rtx imag0 = (rtx) 0;
1101 rtx real1 = (rtx) 0;
1102 rtx imag1 = (rtx) 0;
1109 /* Find the correct mode for the real and imaginary parts */
1110 enum machine_mode submode
1111 = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
1112 class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
1115 if (submode == BLKmode)
1119 target = gen_reg_rtx (mode);
1123 realr = gen_realpart (submode, target);
1124 imagr = gen_imagpart (submode, target);
1126 if (GET_MODE (op0) == mode)
1128 real0 = gen_realpart (submode, op0);
1129 imag0 = gen_imagpart (submode, op0);
1134 if (GET_MODE (op1) == mode)
1136 real1 = gen_realpart (submode, op1);
1137 imag1 = gen_imagpart (submode, op1);
1142 if (! real0 || ! real1 || ! (imag0 || imag1))
1145 switch (binoptab->code)
1148 /* (a+ib) + (c+id) = (a+c) + i(b+d) */
1150 /* (a+ib) - (c+id) = (a-c) + i(b-d) */
1151 res = expand_binop (submode, binoptab, real0, real1,
1152 realr, unsignedp, methods);
1154 emit_move_insn (realr, res);
1157 res = expand_binop (submode, binoptab, imag0, imag1,
1158 imagr, unsignedp, methods);
1161 else if (binoptab->code == MINUS)
1162 res = expand_unop (submode, neg_optab, imag1, imagr, unsignedp);
1167 emit_move_insn (imagr, res);
1171 /* (a+ib) * (c+id) = (ac-bd) + i(ad+cb) */
1175 /* Don't fetch these from memory more than once. */
1176 real0 = force_reg (submode, real0);
1177 real1 = force_reg (submode, real1);
1178 imag0 = force_reg (submode, imag0);
1179 imag1 = force_reg (submode, imag1);
1181 res = expand_binop (submode, sub_optab,
1182 expand_binop (submode, binoptab, real0,
1183 real1, 0, unsignedp, methods),
1184 expand_binop (submode, binoptab, imag0,
1185 imag1, 0, unsignedp, methods),
1186 realr, unsignedp, methods);
1189 emit_move_insn (realr, res);
1191 res = expand_binop (submode, add_optab,
1192 expand_binop (submode, binoptab,
1194 0, unsignedp, methods),
1195 expand_binop (submode, binoptab,
1197 0, unsignedp, methods),
1198 imagr, unsignedp, methods);
1200 emit_move_insn (imagr, res);
1204 /* Don't fetch these from memory more than once. */
1205 real0 = force_reg (submode, real0);
1206 real1 = force_reg (submode, real1);
1208 res = expand_binop (submode, binoptab, real0, real1,
1209 realr, unsignedp, methods);
1211 emit_move_insn (realr, res);
1214 res = expand_binop (submode, binoptab,
1215 real1, imag0, imagr, unsignedp, methods);
1217 res = expand_binop (submode, binoptab,
1218 real0, imag1, imagr, unsignedp, methods);
1220 emit_move_insn (imagr, res);
1225 /* (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd)) */
1228 { /* (a+ib) / (c+i0) = (a/c) + i(b/c) */
1230 /* Don't fetch these from memory more than once. */
1231 real1 = force_reg (submode, real1);
1233 /* Simply divide the real and imaginary parts by `c' */
1234 if (class == MODE_COMPLEX_FLOAT)
1235 res = expand_binop (submode, binoptab, real0, real1,
1236 realr, unsignedp, methods);
1238 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
1239 real0, real1, realr, unsignedp);
1242 emit_move_insn (realr, res);
1244 if (class == MODE_COMPLEX_FLOAT)
1245 res = expand_binop (submode, binoptab, imag0, real1,
1246 imagr, unsignedp, methods);
1248 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
1249 imag0, real1, imagr, unsignedp);
1252 emit_move_insn (imagr, res);
1254 else /* Divisor is of complex type */
1262 /* Don't fetch these from memory more than once. */
1263 real0 = force_reg (submode, real0);
1264 real1 = force_reg (submode, real1);
1266 imag0 = force_reg (submode, imag0);
1267 imag1 = force_reg (submode, imag1);
1269 /* Divisor: c*c + d*d */
1270 divisor = expand_binop (submode, add_optab,
1271 expand_binop (submode, smul_optab,
1273 0, unsignedp, methods),
1274 expand_binop (submode, smul_optab,
1276 0, unsignedp, methods),
1277 0, unsignedp, methods);
1279 if (! imag0) /* ((a)(c-id))/divisor */
1280 { /* (a+i0) / (c+id) = (ac/(cc+dd)) + i(-ad/(cc+dd)) */
1281 /* Calculate the dividend */
1282 real_t = expand_binop (submode, smul_optab, real0, real1,
1283 0, unsignedp, methods);
1286 = expand_unop (submode, neg_optab,
1287 expand_binop (submode, smul_optab, real0,
1288 imag1, 0, unsignedp, methods),
1291 else /* ((a+ib)(c-id))/divider */
1293 /* Calculate the dividend */
1294 real_t = expand_binop (submode, add_optab,
1295 expand_binop (submode, smul_optab,
1297 0, unsignedp, methods),
1298 expand_binop (submode, smul_optab,
1300 0, unsignedp, methods),
1301 0, unsignedp, methods);
1303 imag_t = expand_binop (submode, sub_optab,
1304 expand_binop (submode, smul_optab,
1306 0, unsignedp, methods),
1307 expand_binop (submode, smul_optab,
1309 0, unsignedp, methods),
1310 0, unsignedp, methods);
1314 if (class == MODE_COMPLEX_FLOAT)
1315 res = expand_binop (submode, binoptab, real_t, divisor,
1316 realr, unsignedp, methods);
1318 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
1319 real_t, divisor, realr, unsignedp);
1322 emit_move_insn (realr, res);
1324 if (class == MODE_COMPLEX_FLOAT)
1325 res = expand_binop (submode, binoptab, imag_t, divisor,
1326 imagr, unsignedp, methods);
1328 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
1329 imag_t, divisor, imagr, unsignedp);
1332 emit_move_insn (imagr, res);
1343 if (binoptab->code != UNKNOWN)
1345 = gen_rtx (binoptab->code, mode, copy_rtx (op0), copy_rtx (op1));
1349 emit_no_conflict_block (seq, target, op0, op1, equiv_value);
1354 /* It can't be open-coded in this mode.
1355 Use a library call if one is available and caller says that's ok. */
1357 if (binoptab->handlers[(int) mode].libfunc
1358 && (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN))
1361 rtx funexp = binoptab->handlers[(int) mode].libfunc;
1363 enum machine_mode op1_mode = mode;
1370 op1_mode = word_mode;
1371 /* Specify unsigned here,
1372 since negative shift counts are meaningless. */
1373 op1x = convert_to_mode (word_mode, op1, 1);
1376 /* Pass 1 for NO_QUEUE so we don't lose any increments
1377 if the libcall is cse'd or moved. */
1378 value = emit_library_call_value (binoptab->handlers[(int) mode].libfunc,
1379 NULL_RTX, 1, mode, 2,
1380 op0, mode, op1x, op1_mode);
1382 insns = get_insns ();
1385 target = gen_reg_rtx (mode);
1386 emit_libcall_block (insns, target, value,
1387 gen_rtx (binoptab->code, mode, op0, op1));
1392 delete_insns_since (last);
1394 /* It can't be done in this mode. Can we do it in a wider mode? */
1396 if (! (methods == OPTAB_WIDEN || methods == OPTAB_LIB_WIDEN
1397 || methods == OPTAB_MUST_WIDEN))
1399 /* Caller says, don't even try. */
1400 delete_insns_since (entry_last);
1404 /* Compute the value of METHODS to pass to recursive calls.
1405 Don't allow widening to be tried recursively. */
1407 methods = (methods == OPTAB_LIB_WIDEN ? OPTAB_LIB : OPTAB_DIRECT);
1409 /* Look for a wider mode of the same class for which it appears we can do
1412 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1414 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1415 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1417 if ((binoptab->handlers[(int) wider_mode].insn_code
1418 != CODE_FOR_nothing)
1419 || (methods == OPTAB_LIB
1420 && binoptab->handlers[(int) wider_mode].libfunc))
1422 rtx xop0 = op0, xop1 = op1;
1425 /* For certain integer operations, we need not actually extend
1426 the narrow operands, as long as we will truncate
1427 the results to the same narrowness. */
1429 if ((binoptab == ior_optab || binoptab == and_optab
1430 || binoptab == xor_optab
1431 || binoptab == add_optab || binoptab == sub_optab
1432 || binoptab == smul_optab || binoptab == ashl_optab)
1433 && class == MODE_INT)
1436 xop0 = widen_operand (xop0, wider_mode, mode,
1437 unsignedp, no_extend);
1439 /* The second operand of a shift must always be extended. */
1440 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
1441 no_extend && binoptab != ashl_optab);
1443 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
1444 unsignedp, methods);
1447 if (class != MODE_INT)
1450 target = gen_reg_rtx (mode);
1451 convert_move (target, temp, 0);
1455 return gen_lowpart (mode, temp);
1458 delete_insns_since (last);
1463 delete_insns_since (entry_last);
1467 /* Expand a binary operator which has both signed and unsigned forms.
1468 UOPTAB is the optab for unsigned operations, and SOPTAB is for
1471 If we widen unsigned operands, we may use a signed wider operation instead
1472 of an unsigned wider operation, since the result would be the same. */
1475 sign_expand_binop (mode, uoptab, soptab, op0, op1, target, unsignedp, methods)
1476 enum machine_mode mode;
1477 optab uoptab, soptab;
1478 rtx op0, op1, target;
1480 enum optab_methods methods;
1483 optab direct_optab = unsignedp ? uoptab : soptab;
1484 struct optab wide_soptab;
1486 /* Do it without widening, if possible. */
1487 temp = expand_binop (mode, direct_optab, op0, op1, target,
1488 unsignedp, OPTAB_DIRECT);
1489 if (temp || methods == OPTAB_DIRECT)
1492 /* Try widening to a signed int. Make a fake signed optab that
1493 hides any signed insn for direct use. */
1494 wide_soptab = *soptab;
1495 wide_soptab.handlers[(int) mode].insn_code = CODE_FOR_nothing;
1496 wide_soptab.handlers[(int) mode].libfunc = 0;
1498 temp = expand_binop (mode, &wide_soptab, op0, op1, target,
1499 unsignedp, OPTAB_WIDEN);
1501 /* For unsigned operands, try widening to an unsigned int. */
1502 if (temp == 0 && unsignedp)
1503 temp = expand_binop (mode, uoptab, op0, op1, target,
1504 unsignedp, OPTAB_WIDEN);
1505 if (temp || methods == OPTAB_WIDEN)
1508 /* Use the right width lib call if that exists. */
1509 temp = expand_binop (mode, direct_optab, op0, op1, target, unsignedp, OPTAB_LIB);
1510 if (temp || methods == OPTAB_LIB)
1513 /* Must widen and use a lib call, use either signed or unsigned. */
1514 temp = expand_binop (mode, &wide_soptab, op0, op1, target,
1515 unsignedp, methods);
1519 return expand_binop (mode, uoptab, op0, op1, target,
1520 unsignedp, methods);
1524 /* Generate code to perform an operation specified by BINOPTAB
1525 on operands OP0 and OP1, with two results to TARG1 and TARG2.
1526 We assume that the order of the operands for the instruction
1527 is TARG0, OP0, OP1, TARG1, which would fit a pattern like
1528 [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
1530 Either TARG0 or TARG1 may be zero, but what that means is that
1531 that result is not actually wanted. We will generate it into
1532 a dummy pseudo-reg and discard it. They may not both be zero.
1534 Returns 1 if this operation can be performed; 0 if not. */
1537 expand_twoval_binop (binoptab, op0, op1, targ0, targ1, unsignedp)
1543 enum machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
1544 enum mode_class class;
1545 enum machine_mode wider_mode;
1546 rtx entry_last = get_last_insn ();
1549 class = GET_MODE_CLASS (mode);
1551 op0 = protect_from_queue (op0, 0);
1552 op1 = protect_from_queue (op1, 0);
1556 op0 = force_not_mem (op0);
1557 op1 = force_not_mem (op1);
1560 /* If we are inside an appropriately-short loop and one operand is an
1561 expensive constant, force it into a register. */
1562 if (CONSTANT_P (op0) && preserve_subexpressions_p ()
1563 && rtx_cost (op0, binoptab->code) > 2)
1564 op0 = force_reg (mode, op0);
1566 if (CONSTANT_P (op1) && preserve_subexpressions_p ()
1567 && rtx_cost (op1, binoptab->code) > 2)
1568 op1 = force_reg (mode, op1);
1571 targ0 = protect_from_queue (targ0, 1);
1573 targ0 = gen_reg_rtx (mode);
1575 targ1 = protect_from_queue (targ1, 1);
1577 targ1 = gen_reg_rtx (mode);
1579 /* Record where to go back to if we fail. */
1580 last = get_last_insn ();
1582 if (binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1584 int icode = (int) binoptab->handlers[(int) mode].insn_code;
1585 enum machine_mode mode0 = insn_operand_mode[icode][1];
1586 enum machine_mode mode1 = insn_operand_mode[icode][2];
1588 rtx xop0 = op0, xop1 = op1;
1590 /* In case this insn wants input operands in modes different from the
1591 result, convert the operands. */
1592 if (GET_MODE (op0) != VOIDmode && GET_MODE (op0) != mode0)
1593 xop0 = convert_to_mode (mode0, xop0, unsignedp);
1595 if (GET_MODE (op1) != VOIDmode && GET_MODE (op1) != mode1)
1596 xop1 = convert_to_mode (mode1, xop1, unsignedp);
1598 /* Now, if insn doesn't accept these operands, put them into pseudos. */
1599 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
1600 xop0 = copy_to_mode_reg (mode0, xop0);
1602 if (! (*insn_operand_predicate[icode][2]) (xop1, mode1))
1603 xop1 = copy_to_mode_reg (mode1, xop1);
1605 /* We could handle this, but we should always be called with a pseudo
1606 for our targets and all insns should take them as outputs. */
1607 if (! (*insn_operand_predicate[icode][0]) (targ0, mode)
1608 || ! (*insn_operand_predicate[icode][3]) (targ1, mode))
1611 pat = GEN_FCN (icode) (targ0, xop0, xop1, targ1);
1618 delete_insns_since (last);
1621 /* It can't be done in this mode. Can we do it in a wider mode? */
1623 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1625 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1626 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1628 if (binoptab->handlers[(int) wider_mode].insn_code
1629 != CODE_FOR_nothing)
1631 register rtx t0 = gen_reg_rtx (wider_mode);
1632 register rtx t1 = gen_reg_rtx (wider_mode);
1634 if (expand_twoval_binop (binoptab,
1635 convert_modes (wider_mode, mode, op0,
1637 convert_modes (wider_mode, mode, op1,
1641 convert_move (targ0, t0, unsignedp);
1642 convert_move (targ1, t1, unsignedp);
1646 delete_insns_since (last);
1651 delete_insns_since (entry_last);
1655 /* Generate code to perform an operation specified by UNOPTAB
1656 on operand OP0, with result having machine-mode MODE.
1658 UNSIGNEDP is for the case where we have to widen the operands
1659 to perform the operation. It says to use zero-extension.
1661 If TARGET is nonzero, the value
1662 is generated there, if it is convenient to do so.
1663 In all cases an rtx is returned for the locus of the value;
1664 this may or may not be TARGET. */
1667 expand_unop (mode, unoptab, op0, target, unsignedp)
1668 enum machine_mode mode;
1674 enum mode_class class;
1675 enum machine_mode wider_mode;
1677 rtx last = get_last_insn ();
1680 class = GET_MODE_CLASS (mode);
1682 op0 = protect_from_queue (op0, 0);
1686 op0 = force_not_mem (op0);
1690 target = protect_from_queue (target, 1);
1692 if (unoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1694 int icode = (int) unoptab->handlers[(int) mode].insn_code;
1695 enum machine_mode mode0 = insn_operand_mode[icode][1];
1701 temp = gen_reg_rtx (mode);
1703 if (GET_MODE (xop0) != VOIDmode
1704 && GET_MODE (xop0) != mode0)
1705 xop0 = convert_to_mode (mode0, xop0, unsignedp);
1707 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
1709 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
1710 xop0 = copy_to_mode_reg (mode0, xop0);
1712 if (! (*insn_operand_predicate[icode][0]) (temp, mode))
1713 temp = gen_reg_rtx (mode);
1715 pat = GEN_FCN (icode) (temp, xop0);
1718 if (GET_CODE (pat) == SEQUENCE
1719 && ! add_equal_note (pat, temp, unoptab->code, xop0, NULL_RTX))
1721 delete_insns_since (last);
1722 return expand_unop (mode, unoptab, op0, NULL_RTX, unsignedp);
1730 delete_insns_since (last);
1733 /* It can't be done in this mode. Can we open-code it in a wider mode? */
1735 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1736 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1737 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1739 if (unoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing)
1743 /* For certain operations, we need not actually extend
1744 the narrow operand, as long as we will truncate the
1745 results to the same narrowness. */
1747 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
1748 (unoptab == neg_optab
1749 || unoptab == one_cmpl_optab)
1750 && class == MODE_INT);
1752 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
1757 if (class != MODE_INT)
1760 target = gen_reg_rtx (mode);
1761 convert_move (target, temp, 0);
1765 return gen_lowpart (mode, temp);
1768 delete_insns_since (last);
1772 /* These can be done a word at a time. */
1773 if (unoptab == one_cmpl_optab
1774 && class == MODE_INT
1775 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
1776 && unoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
1781 if (target == 0 || target == op0)
1782 target = gen_reg_rtx (mode);
1786 /* Do the actual arithmetic. */
1787 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
1789 rtx target_piece = operand_subword (target, i, 1, mode);
1790 rtx x = expand_unop (word_mode, unoptab,
1791 operand_subword_force (op0, i, mode),
1792 target_piece, unsignedp);
1793 if (target_piece != x)
1794 emit_move_insn (target_piece, x);
1797 insns = get_insns ();
1800 emit_no_conflict_block (insns, target, op0, NULL_RTX,
1801 gen_rtx (unoptab->code, mode, copy_rtx (op0)));
1805 /* Open-code the complex negation operation. */
1806 else if (unoptab == neg_optab
1807 && (class == MODE_COMPLEX_FLOAT || class == MODE_COMPLEX_INT))
1813 /* Find the correct mode for the real and imaginary parts */
1814 enum machine_mode submode
1815 = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
1816 class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
1819 if (submode == BLKmode)
1823 target = gen_reg_rtx (mode);
1827 target_piece = gen_imagpart (submode, target);
1828 x = expand_unop (submode, unoptab,
1829 gen_imagpart (submode, op0),
1830 target_piece, unsignedp);
1831 if (target_piece != x)
1832 emit_move_insn (target_piece, x);
1834 target_piece = gen_realpart (submode, target);
1835 x = expand_unop (submode, unoptab,
1836 gen_realpart (submode, op0),
1837 target_piece, unsignedp);
1838 if (target_piece != x)
1839 emit_move_insn (target_piece, x);
1844 emit_no_conflict_block (seq, target, op0, 0,
1845 gen_rtx (unoptab->code, mode, copy_rtx (op0)));
1849 /* Now try a library call in this mode. */
1850 if (unoptab->handlers[(int) mode].libfunc)
1853 rtx funexp = unoptab->handlers[(int) mode].libfunc;
1858 /* Pass 1 for NO_QUEUE so we don't lose any increments
1859 if the libcall is cse'd or moved. */
1860 value = emit_library_call_value (unoptab->handlers[(int) mode].libfunc,
1861 NULL_RTX, 1, mode, 1, op0, mode);
1862 insns = get_insns ();
1865 target = gen_reg_rtx (mode);
1866 emit_libcall_block (insns, target, value,
1867 gen_rtx (unoptab->code, mode, op0));
1872 /* It can't be done in this mode. Can we do it in a wider mode? */
1874 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1876 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1877 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1879 if ((unoptab->handlers[(int) wider_mode].insn_code
1880 != CODE_FOR_nothing)
1881 || unoptab->handlers[(int) wider_mode].libfunc)
1885 /* For certain operations, we need not actually extend
1886 the narrow operand, as long as we will truncate the
1887 results to the same narrowness. */
1889 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
1890 (unoptab == neg_optab
1891 || unoptab == one_cmpl_optab)
1892 && class == MODE_INT);
1894 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
1899 if (class != MODE_INT)
1902 target = gen_reg_rtx (mode);
1903 convert_move (target, temp, 0);
1907 return gen_lowpart (mode, temp);
1910 delete_insns_since (last);
1918 /* Emit code to compute the absolute value of OP0, with result to
1919 TARGET if convenient. (TARGET may be 0.) The return value says
1920 where the result actually is to be found.
1922 MODE is the mode of the operand; the mode of the result is
1923 different but can be deduced from MODE.
1925 UNSIGNEDP is relevant for complex integer modes. */
1928 expand_complex_abs (mode, op0, target, unsignedp)
1929 enum machine_mode mode;
1934 enum mode_class class = GET_MODE_CLASS (mode);
1935 enum machine_mode wider_mode;
1937 rtx entry_last = get_last_insn ();
1941 /* Find the correct mode for the real and imaginary parts. */
1942 enum machine_mode submode
1943 = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
1944 class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
1947 if (submode == BLKmode)
1950 op0 = protect_from_queue (op0, 0);
1954 op0 = force_not_mem (op0);
1957 last = get_last_insn ();
1960 target = protect_from_queue (target, 1);
1962 if (abs_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1964 int icode = (int) abs_optab->handlers[(int) mode].insn_code;
1965 enum machine_mode mode0 = insn_operand_mode[icode][1];
1971 temp = gen_reg_rtx (submode);
1973 if (GET_MODE (xop0) != VOIDmode
1974 && GET_MODE (xop0) != mode0)
1975 xop0 = convert_to_mode (mode0, xop0, unsignedp);
1977 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
1979 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
1980 xop0 = copy_to_mode_reg (mode0, xop0);
1982 if (! (*insn_operand_predicate[icode][0]) (temp, submode))
1983 temp = gen_reg_rtx (submode);
1985 pat = GEN_FCN (icode) (temp, xop0);
1988 if (GET_CODE (pat) == SEQUENCE
1989 && ! add_equal_note (pat, temp, abs_optab->code, xop0, NULL_RTX))
1991 delete_insns_since (last);
1992 return expand_unop (mode, abs_optab, op0, NULL_RTX, unsignedp);
2000 delete_insns_since (last);
2003 /* It can't be done in this mode. Can we open-code it in a wider mode? */
2005 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2006 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2008 if (abs_optab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing)
2012 xop0 = convert_modes (wider_mode, mode, xop0, unsignedp);
2013 temp = expand_complex_abs (wider_mode, xop0, NULL_RTX, unsignedp);
2017 if (class != MODE_COMPLEX_INT)
2020 target = gen_reg_rtx (submode);
2021 convert_move (target, temp, 0);
2025 return gen_lowpart (submode, temp);
2028 delete_insns_since (last);
2032 /* Open-code the complex absolute-value operation
2033 if we can open-code sqrt. Otherwise it's not worth while. */
2034 if (sqrt_optab->handlers[(int) submode].insn_code != CODE_FOR_nothing)
2036 rtx real, imag, total;
2038 real = gen_realpart (submode, op0);
2039 imag = gen_imagpart (submode, op0);
2041 /* Square both parts. */
2042 real = expand_mult (submode, real, real, NULL_RTX, 0);
2043 imag = expand_mult (submode, imag, imag, NULL_RTX, 0);
2045 /* Sum the parts. */
2046 total = expand_binop (submode, add_optab, real, imag, 0,
2047 0, OPTAB_LIB_WIDEN);
2049 /* Get sqrt in TARGET. Set TARGET to where the result is. */
2050 target = expand_unop (submode, sqrt_optab, total, target, 0);
2052 delete_insns_since (last);
2057 /* Now try a library call in this mode. */
2058 if (abs_optab->handlers[(int) mode].libfunc)
2061 rtx funexp = abs_optab->handlers[(int) mode].libfunc;
2066 /* Pass 1 for NO_QUEUE so we don't lose any increments
2067 if the libcall is cse'd or moved. */
2068 value = emit_library_call_value (abs_optab->handlers[(int) mode].libfunc,
2069 NULL_RTX, 1, submode, 1, op0, mode);
2070 insns = get_insns ();
2073 target = gen_reg_rtx (submode);
2074 emit_libcall_block (insns, target, value,
2075 gen_rtx (abs_optab->code, mode, op0));
2080 /* It can't be done in this mode. Can we do it in a wider mode? */
2082 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2083 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2085 if ((abs_optab->handlers[(int) wider_mode].insn_code
2086 != CODE_FOR_nothing)
2087 || abs_optab->handlers[(int) wider_mode].libfunc)
2091 xop0 = convert_modes (wider_mode, mode, xop0, unsignedp);
2093 temp = expand_complex_abs (wider_mode, xop0, NULL_RTX, unsignedp);
2097 if (class != MODE_COMPLEX_INT)
2100 target = gen_reg_rtx (submode);
2101 convert_move (target, temp, 0);
2105 return gen_lowpart (submode, temp);
2108 delete_insns_since (last);
2112 delete_insns_since (entry_last);
2116 /* Generate an instruction whose insn-code is INSN_CODE,
2117 with two operands: an output TARGET and an input OP0.
2118 TARGET *must* be nonzero, and the output is always stored there.
2119 CODE is an rtx code such that (CODE OP0) is an rtx that describes
2120 the value that is stored into TARGET. */
2123 emit_unop_insn (icode, target, op0, code)
2130 enum machine_mode mode0 = insn_operand_mode[icode][1];
2133 temp = target = protect_from_queue (target, 1);
2135 op0 = protect_from_queue (op0, 0);
2138 op0 = force_not_mem (op0);
2140 /* Now, if insn does not accept our operands, put them into pseudos. */
2142 if (! (*insn_operand_predicate[icode][1]) (op0, mode0))
2143 op0 = copy_to_mode_reg (mode0, op0);
2145 if (! (*insn_operand_predicate[icode][0]) (temp, GET_MODE (temp))
2146 || (flag_force_mem && GET_CODE (temp) == MEM))
2147 temp = gen_reg_rtx (GET_MODE (temp));
2149 pat = GEN_FCN (icode) (temp, op0);
2151 if (GET_CODE (pat) == SEQUENCE && code != UNKNOWN)
2152 add_equal_note (pat, temp, code, op0, NULL_RTX);
2157 emit_move_insn (target, temp);
2160 /* Emit code to perform a series of operations on a multi-word quantity, one
2163 Such a block is preceded by a CLOBBER of the output, consists of multiple
2164 insns, each setting one word of the output, and followed by a SET copying
2165 the output to itself.
2167 Each of the insns setting words of the output receives a REG_NO_CONFLICT
2168 note indicating that it doesn't conflict with the (also multi-word)
2169 inputs. The entire block is surrounded by REG_LIBCALL and REG_RETVAL
2172 INSNS is a block of code generated to perform the operation, not including
2173 the CLOBBER and final copy. All insns that compute intermediate values
2174 are first emitted, followed by the block as described above. Only
2175 INSNs are allowed in the block; no library calls or jumps may be
2178 TARGET, OP0, and OP1 are the output and inputs of the operations,
2179 respectively. OP1 may be zero for a unary operation.
2181 EQUIV, if non-zero, is an expression to be placed into a REG_EQUAL note
2184 If TARGET is not a register, INSNS is simply emitted with no special
2187 The final insn emitted is returned. */
2190 emit_no_conflict_block (insns, target, op0, op1, equiv)
2196 rtx prev, next, first, last, insn;
2198 if (GET_CODE (target) != REG || reload_in_progress)
2199 return emit_insns (insns);
2201 /* First emit all insns that do not store into words of the output and remove
2202 these from the list. */
2203 for (insn = insns; insn; insn = next)
2208 next = NEXT_INSN (insn);
2210 if (GET_CODE (insn) != INSN)
2213 if (GET_CODE (PATTERN (insn)) == SET)
2214 set = PATTERN (insn);
2215 else if (GET_CODE (PATTERN (insn)) == PARALLEL)
2217 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
2218 if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET)
2220 set = XVECEXP (PATTERN (insn), 0, i);
2228 if (! reg_overlap_mentioned_p (target, SET_DEST (set)))
2230 if (PREV_INSN (insn))
2231 NEXT_INSN (PREV_INSN (insn)) = next;
2236 PREV_INSN (next) = PREV_INSN (insn);
2242 prev = get_last_insn ();
2244 /* Now write the CLOBBER of the output, followed by the setting of each
2245 of the words, followed by the final copy. */
2246 if (target != op0 && target != op1)
2247 emit_insn (gen_rtx (CLOBBER, VOIDmode, target));
2249 for (insn = insns; insn; insn = next)
2251 next = NEXT_INSN (insn);
2254 if (op1 && GET_CODE (op1) == REG)
2255 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_NO_CONFLICT, op1,
2258 if (op0 && GET_CODE (op0) == REG)
2259 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_NO_CONFLICT, op0,
2263 if (mov_optab->handlers[(int) GET_MODE (target)].insn_code
2264 != CODE_FOR_nothing)
2266 last = emit_move_insn (target, target);
2269 = gen_rtx (EXPR_LIST, REG_EQUAL, equiv, REG_NOTES (last));
2272 last = get_last_insn ();
2275 first = get_insns ();
2277 first = NEXT_INSN (prev);
2279 /* Encapsulate the block so it gets manipulated as a unit. */
2280 REG_NOTES (first) = gen_rtx (INSN_LIST, REG_LIBCALL, last,
2282 REG_NOTES (last) = gen_rtx (INSN_LIST, REG_RETVAL, first, REG_NOTES (last));
2287 /* Emit code to make a call to a constant function or a library call.
2289 INSNS is a list containing all insns emitted in the call.
2290 These insns leave the result in RESULT. Our block is to copy RESULT
2291 to TARGET, which is logically equivalent to EQUIV.
2293 We first emit any insns that set a pseudo on the assumption that these are
2294 loading constants into registers; doing so allows them to be safely cse'ed
2295 between blocks. Then we emit all the other insns in the block, followed by
2296 an insn to move RESULT to TARGET. This last insn will have a REQ_EQUAL
2297 note with an operand of EQUIV.
2299 Moving assignments to pseudos outside of the block is done to improve
2300 the generated code, but is not required to generate correct code,
2301 hence being unable to move an assignment is not grounds for not making
2302 a libcall block. There are two reasons why it is safe to leave these
2303 insns inside the block: First, we know that these pseudos cannot be
2304 used in generated RTL outside the block since they are created for
2305 temporary purposes within the block. Second, CSE will not record the
2306 values of anything set inside a libcall block, so we know they must
2307 be dead at the end of the block.
2309 Except for the first group of insns (the ones setting pseudos), the
2310 block is delimited by REG_RETVAL and REG_LIBCALL notes. */
2313 emit_libcall_block (insns, target, result, equiv)
2319 rtx prev, next, first, last, insn;
2321 /* First emit all insns that set pseudos. Remove them from the list as
2322 we go. Avoid insns that set pseudos which were referenced in previous
2323 insns. These can be generated by move_by_pieces, for example,
2324 to update an address. Similarly, avoid insns that reference things
2325 set in previous insns. */
2327 for (insn = insns; insn; insn = next)
2329 rtx set = single_set (insn);
2331 next = NEXT_INSN (insn);
2333 if (set != 0 && GET_CODE (SET_DEST (set)) == REG
2334 && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER
2336 || (! reg_mentioned_p (SET_DEST (set), PATTERN (insns))
2337 && ! reg_used_between_p (SET_DEST (set), insns, insn)
2338 && ! modified_in_p (SET_SRC (set), insns)
2339 && ! modified_between_p (SET_SRC (set), insns, insn))))
2341 if (PREV_INSN (insn))
2342 NEXT_INSN (PREV_INSN (insn)) = next;
2347 PREV_INSN (next) = PREV_INSN (insn);
2353 prev = get_last_insn ();
2355 /* Write the remaining insns followed by the final copy. */
2357 for (insn = insns; insn; insn = next)
2359 next = NEXT_INSN (insn);
2364 last = emit_move_insn (target, result);
2365 REG_NOTES (last) = gen_rtx (EXPR_LIST,
2366 REG_EQUAL, copy_rtx (equiv), REG_NOTES (last));
2369 first = get_insns ();
2371 first = NEXT_INSN (prev);
2373 /* Encapsulate the block so it gets manipulated as a unit. */
2374 REG_NOTES (first) = gen_rtx (INSN_LIST, REG_LIBCALL, last,
2376 REG_NOTES (last) = gen_rtx (INSN_LIST, REG_RETVAL, first, REG_NOTES (last));
2379 /* Generate code to store zero in X. */
2385 emit_move_insn (x, const0_rtx);
2388 /* Generate code to store 1 in X
2389 assuming it contains zero beforehand. */
2392 emit_0_to_1_insn (x)
2395 emit_move_insn (x, const1_rtx);
2398 /* Generate code to compare X with Y
2399 so that the condition codes are set.
2401 MODE is the mode of the inputs (in case they are const_int).
2402 UNSIGNEDP nonzero says that X and Y are unsigned;
2403 this matters if they need to be widened.
2405 If they have mode BLKmode, then SIZE specifies the size of both X and Y,
2406 and ALIGN specifies the known shared alignment of X and Y.
2408 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).
2409 It is ignored for fixed-point and block comparisons;
2410 it is used only for floating-point comparisons. */
2413 emit_cmp_insn (x, y, comparison, size, mode, unsignedp, align)
2415 enum rtx_code comparison;
2417 enum machine_mode mode;
2421 enum mode_class class;
2422 enum machine_mode wider_mode;
2424 class = GET_MODE_CLASS (mode);
2426 /* They could both be VOIDmode if both args are immediate constants,
2427 but we should fold that at an earlier stage.
2428 With no special code here, this will call abort,
2429 reminding the programmer to implement such folding. */
2431 if (mode != BLKmode && flag_force_mem)
2433 x = force_not_mem (x);
2434 y = force_not_mem (y);
2437 /* If we are inside an appropriately-short loop and one operand is an
2438 expensive constant, force it into a register. */
2439 if (CONSTANT_P (x) && preserve_subexpressions_p () && rtx_cost (x, COMPARE) > 2)
2440 x = force_reg (mode, x);
2442 if (CONSTANT_P (y) && preserve_subexpressions_p () && rtx_cost (y, COMPARE) > 2)
2443 y = force_reg (mode, y);
2445 /* Don't let both operands fail to indicate the mode. */
2446 if (GET_MODE (x) == VOIDmode && GET_MODE (y) == VOIDmode)
2447 x = force_reg (mode, x);
2449 /* Handle all BLKmode compares. */
2451 if (mode == BLKmode)
2454 x = protect_from_queue (x, 0);
2455 y = protect_from_queue (y, 0);
2459 #ifdef HAVE_cmpstrqi
2461 && GET_CODE (size) == CONST_INT
2462 && INTVAL (size) < (1 << GET_MODE_BITSIZE (QImode)))
2464 enum machine_mode result_mode
2465 = insn_operand_mode[(int) CODE_FOR_cmpstrqi][0];
2466 rtx result = gen_reg_rtx (result_mode);
2467 emit_insn (gen_cmpstrqi (result, x, y, size, GEN_INT (align)));
2468 emit_cmp_insn (result, const0_rtx, comparison, NULL_RTX,
2473 #ifdef HAVE_cmpstrhi
2475 && GET_CODE (size) == CONST_INT
2476 && INTVAL (size) < (1 << GET_MODE_BITSIZE (HImode)))
2478 enum machine_mode result_mode
2479 = insn_operand_mode[(int) CODE_FOR_cmpstrhi][0];
2480 rtx result = gen_reg_rtx (result_mode);
2481 emit_insn (gen_cmpstrhi (result, x, y, size, GEN_INT (align)));
2482 emit_cmp_insn (result, const0_rtx, comparison, NULL_RTX,
2487 #ifdef HAVE_cmpstrsi
2490 enum machine_mode result_mode
2491 = insn_operand_mode[(int) CODE_FOR_cmpstrsi][0];
2492 rtx result = gen_reg_rtx (result_mode);
2493 size = protect_from_queue (size, 0);
2494 emit_insn (gen_cmpstrsi (result, x, y,
2495 convert_to_mode (SImode, size, 1),
2497 emit_cmp_insn (result, const0_rtx, comparison, NULL_RTX,
2503 #ifdef TARGET_MEM_FUNCTIONS
2504 emit_library_call (memcmp_libfunc, 0,
2505 TYPE_MODE (integer_type_node), 3,
2506 XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
2509 emit_library_call (bcmp_libfunc, 0,
2510 TYPE_MODE (integer_type_node), 3,
2511 XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
2514 emit_cmp_insn (hard_libcall_value (TYPE_MODE (integer_type_node)),
2515 const0_rtx, comparison, NULL_RTX,
2516 TYPE_MODE (integer_type_node), 0, 0);
2521 /* Handle some compares against zero. */
2523 if (y == CONST0_RTX (mode)
2524 && tst_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2526 int icode = (int) tst_optab->handlers[(int) mode].insn_code;
2529 x = protect_from_queue (x, 0);
2530 y = protect_from_queue (y, 0);
2532 /* Now, if insn does accept these operands, put them into pseudos. */
2533 if (! (*insn_operand_predicate[icode][0])
2534 (x, insn_operand_mode[icode][0]))
2535 x = copy_to_mode_reg (insn_operand_mode[icode][0], x);
2537 emit_insn (GEN_FCN (icode) (x));
2541 /* Handle compares for which there is a directly suitable insn. */
2543 if (cmp_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2545 int icode = (int) cmp_optab->handlers[(int) mode].insn_code;
2548 x = protect_from_queue (x, 0);
2549 y = protect_from_queue (y, 0);
2551 /* Now, if insn doesn't accept these operands, put them into pseudos. */
2552 if (! (*insn_operand_predicate[icode][0])
2553 (x, insn_operand_mode[icode][0]))
2554 x = copy_to_mode_reg (insn_operand_mode[icode][0], x);
2556 if (! (*insn_operand_predicate[icode][1])
2557 (y, insn_operand_mode[icode][1]))
2558 y = copy_to_mode_reg (insn_operand_mode[icode][1], y);
2560 emit_insn (GEN_FCN (icode) (x, y));
2564 /* Try widening if we can find a direct insn that way. */
2566 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
2568 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2569 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2571 if (cmp_optab->handlers[(int) wider_mode].insn_code
2572 != CODE_FOR_nothing)
2574 x = protect_from_queue (x, 0);
2575 y = protect_from_queue (y, 0);
2576 x = convert_modes (wider_mode, mode, x, unsignedp);
2577 y = convert_modes (wider_mode, mode, y, unsignedp);
2578 emit_cmp_insn (x, y, comparison, NULL_RTX,
2579 wider_mode, unsignedp, align);
2585 /* Handle a lib call just for the mode we are using. */
2587 if (cmp_optab->handlers[(int) mode].libfunc
2588 && class != MODE_FLOAT)
2590 rtx libfunc = cmp_optab->handlers[(int) mode].libfunc;
2591 /* If we want unsigned, and this mode has a distinct unsigned
2592 comparison routine, use that. */
2593 if (unsignedp && ucmp_optab->handlers[(int) mode].libfunc)
2594 libfunc = ucmp_optab->handlers[(int) mode].libfunc;
2596 emit_library_call (libfunc, 1,
2597 word_mode, 2, x, mode, y, mode);
2599 /* Integer comparison returns a result that must be compared against 1,
2600 so that even if we do an unsigned compare afterward,
2601 there is still a value that can represent the result "less than". */
2603 emit_cmp_insn (hard_libcall_value (word_mode), const1_rtx,
2604 comparison, NULL_RTX, word_mode, unsignedp, 0);
2608 if (class == MODE_FLOAT)
2609 emit_float_lib_cmp (x, y, comparison);
2615 /* Nonzero if a compare of mode MODE can be done straightforwardly
2616 (without splitting it into pieces). */
2619 can_compare_p (mode)
2620 enum machine_mode mode;
2624 if (cmp_optab->handlers[(int)mode].insn_code != CODE_FOR_nothing)
2626 mode = GET_MODE_WIDER_MODE (mode);
2627 } while (mode != VOIDmode);
2632 /* Emit a library call comparison between floating point X and Y.
2633 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */
2636 emit_float_lib_cmp (x, y, comparison)
2638 enum rtx_code comparison;
2640 enum machine_mode mode = GET_MODE (x);
2647 libfunc = eqsf2_libfunc;
2651 libfunc = nesf2_libfunc;
2655 libfunc = gtsf2_libfunc;
2659 libfunc = gesf2_libfunc;
2663 libfunc = ltsf2_libfunc;
2667 libfunc = lesf2_libfunc;
2670 else if (mode == DFmode)
2674 libfunc = eqdf2_libfunc;
2678 libfunc = nedf2_libfunc;
2682 libfunc = gtdf2_libfunc;
2686 libfunc = gedf2_libfunc;
2690 libfunc = ltdf2_libfunc;
2694 libfunc = ledf2_libfunc;
2697 else if (mode == XFmode)
2701 libfunc = eqxf2_libfunc;
2705 libfunc = nexf2_libfunc;
2709 libfunc = gtxf2_libfunc;
2713 libfunc = gexf2_libfunc;
2717 libfunc = ltxf2_libfunc;
2721 libfunc = lexf2_libfunc;
2724 else if (mode == TFmode)
2728 libfunc = eqtf2_libfunc;
2732 libfunc = netf2_libfunc;
2736 libfunc = gttf2_libfunc;
2740 libfunc = getf2_libfunc;
2744 libfunc = lttf2_libfunc;
2748 libfunc = letf2_libfunc;
2753 enum machine_mode wider_mode;
2755 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2756 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2758 if ((cmp_optab->handlers[(int) wider_mode].insn_code
2759 != CODE_FOR_nothing)
2760 || (cmp_optab->handlers[(int) wider_mode].libfunc != 0))
2762 x = protect_from_queue (x, 0);
2763 y = protect_from_queue (y, 0);
2764 x = convert_to_mode (wider_mode, x, 0);
2765 y = convert_to_mode (wider_mode, y, 0);
2766 emit_float_lib_cmp (x, y, comparison);
2776 emit_library_call (libfunc, 1,
2777 word_mode, 2, x, mode, y, mode);
2779 emit_cmp_insn (hard_libcall_value (word_mode), const0_rtx, comparison,
2780 NULL_RTX, word_mode, 0, 0);
2783 /* Generate code to indirectly jump to a location given in the rtx LOC. */
2786 emit_indirect_jump (loc)
2789 if (! ((*insn_operand_predicate[(int)CODE_FOR_indirect_jump][0])
2791 loc = copy_to_mode_reg (Pmode, loc);
2793 emit_jump_insn (gen_indirect_jump (loc));
2797 /* These three functions generate an insn body and return it
2798 rather than emitting the insn.
2800 They do not protect from queued increments,
2801 because they may be used 1) in protect_from_queue itself
2802 and 2) in other passes where there is no queue. */
2804 /* Generate and return an insn body to add Y to X. */
2807 gen_add2_insn (x, y)
2810 int icode = (int) add_optab->handlers[(int) GET_MODE (x)].insn_code;
2812 if (! (*insn_operand_predicate[icode][0]) (x, insn_operand_mode[icode][0])
2813 || ! (*insn_operand_predicate[icode][1]) (x, insn_operand_mode[icode][1])
2814 || ! (*insn_operand_predicate[icode][2]) (y, insn_operand_mode[icode][2]))
2817 return (GEN_FCN (icode) (x, x, y));
2821 have_add2_insn (mode)
2822 enum machine_mode mode;
2824 return add_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
2827 /* Generate and return an insn body to subtract Y from X. */
2830 gen_sub2_insn (x, y)
2833 int icode = (int) sub_optab->handlers[(int) GET_MODE (x)].insn_code;
2835 if (! (*insn_operand_predicate[icode][0]) (x, insn_operand_mode[icode][0])
2836 || ! (*insn_operand_predicate[icode][1]) (x, insn_operand_mode[icode][1])
2837 || ! (*insn_operand_predicate[icode][2]) (y, insn_operand_mode[icode][2]))
2840 return (GEN_FCN (icode) (x, x, y));
2844 have_sub2_insn (mode)
2845 enum machine_mode mode;
2847 return sub_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
2850 /* Generate the body of an instruction to copy Y into X.
2851 It may be a SEQUENCE, if one insn isn't enough. */
2854 gen_move_insn (x, y)
2857 register enum machine_mode mode = GET_MODE (x);
2858 enum insn_code insn_code;
2861 if (mode == VOIDmode)
2862 mode = GET_MODE (y);
2864 insn_code = mov_optab->handlers[(int) mode].insn_code;
2866 /* Handle MODE_CC modes: If we don't have a special move insn for this mode,
2867 find a mode to do it in. If we have a movcc, use it. Otherwise,
2868 find the MODE_INT mode of the same width. */
2870 if (GET_MODE_CLASS (mode) == MODE_CC && insn_code == CODE_FOR_nothing)
2872 enum machine_mode tmode = VOIDmode;
2876 && mov_optab->handlers[(int) CCmode].insn_code != CODE_FOR_nothing)
2879 for (tmode = QImode; tmode != VOIDmode;
2880 tmode = GET_MODE_WIDER_MODE (tmode))
2881 if (GET_MODE_SIZE (tmode) == GET_MODE_SIZE (mode))
2884 if (tmode == VOIDmode)
2887 /* Get X and Y in TMODE. We can't use gen_lowpart here because it
2888 may call change_address which is not appropriate if we were
2889 called when a reload was in progress. We don't have to worry
2890 about changing the address since the size in bytes is supposed to
2891 be the same. Copy the MEM to change the mode and move any
2892 substitutions from the old MEM to the new one. */
2894 if (reload_in_progress)
2896 x = gen_lowpart_common (tmode, x1);
2897 if (x == 0 && GET_CODE (x1) == MEM)
2899 x = gen_rtx (MEM, tmode, XEXP (x1, 0));
2900 RTX_UNCHANGING_P (x) = RTX_UNCHANGING_P (x1);
2901 MEM_IN_STRUCT_P (x) = MEM_IN_STRUCT_P (x1);
2902 MEM_VOLATILE_P (x) = MEM_VOLATILE_P (x1);
2903 copy_replacements (x1, x);
2906 y = gen_lowpart_common (tmode, y1);
2907 if (y == 0 && GET_CODE (y1) == MEM)
2909 y = gen_rtx (MEM, tmode, XEXP (y1, 0));
2910 RTX_UNCHANGING_P (y) = RTX_UNCHANGING_P (y1);
2911 MEM_IN_STRUCT_P (y) = MEM_IN_STRUCT_P (y1);
2912 MEM_VOLATILE_P (y) = MEM_VOLATILE_P (y1);
2913 copy_replacements (y1, y);
2918 x = gen_lowpart (tmode, x);
2919 y = gen_lowpart (tmode, y);
2922 insn_code = mov_optab->handlers[(int) tmode].insn_code;
2923 return (GEN_FCN (insn_code) (x, y));
2927 emit_move_insn_1 (x, y);
2928 seq = gen_sequence ();
2933 /* Return the insn code used to extend FROM_MODE to TO_MODE.
2934 UNSIGNEDP specifies zero-extension instead of sign-extension. If
2935 no such operation exists, CODE_FOR_nothing will be returned. */
2938 can_extend_p (to_mode, from_mode, unsignedp)
2939 enum machine_mode to_mode, from_mode;
2942 return extendtab[(int) to_mode][(int) from_mode][unsignedp];
2945 /* Generate the body of an insn to extend Y (with mode MFROM)
2946 into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */
2949 gen_extend_insn (x, y, mto, mfrom, unsignedp)
2951 enum machine_mode mto, mfrom;
2954 return (GEN_FCN (extendtab[(int) mto][(int) mfrom][unsignedp]) (x, y));
2957 /* can_fix_p and can_float_p say whether the target machine
2958 can directly convert a given fixed point type to
2959 a given floating point type, or vice versa.
2960 The returned value is the CODE_FOR_... value to use,
2961 or CODE_FOR_nothing if these modes cannot be directly converted.
2963 *TRUNCP_PTR is set to 1 if it is necessary to output
2964 an explicit FTRUNC insn before the fix insn; otherwise 0. */
2966 static enum insn_code
2967 can_fix_p (fixmode, fltmode, unsignedp, truncp_ptr)
2968 enum machine_mode fltmode, fixmode;
2973 if (fixtrunctab[(int) fltmode][(int) fixmode][unsignedp] != CODE_FOR_nothing)
2974 return fixtrunctab[(int) fltmode][(int) fixmode][unsignedp];
2976 if (ftrunc_optab->handlers[(int) fltmode].insn_code != CODE_FOR_nothing)
2979 return fixtab[(int) fltmode][(int) fixmode][unsignedp];
2981 return CODE_FOR_nothing;
2984 static enum insn_code
2985 can_float_p (fltmode, fixmode, unsignedp)
2986 enum machine_mode fixmode, fltmode;
2989 return floattab[(int) fltmode][(int) fixmode][unsignedp];
2992 /* Generate code to convert FROM to floating point
2993 and store in TO. FROM must be fixed point and not VOIDmode.
2994 UNSIGNEDP nonzero means regard FROM as unsigned.
2995 Normally this is done by correcting the final value
2996 if it is negative. */
2999 expand_float (to, from, unsignedp)
3003 enum insn_code icode;
3004 register rtx target = to;
3005 enum machine_mode fmode, imode;
3007 /* Crash now, because we won't be able to decide which mode to use. */
3008 if (GET_MODE (from) == VOIDmode)
3011 /* Look for an insn to do the conversion. Do it in the specified
3012 modes if possible; otherwise convert either input, output or both to
3013 wider mode. If the integer mode is wider than the mode of FROM,
3014 we can do the conversion signed even if the input is unsigned. */
3016 for (imode = GET_MODE (from); imode != VOIDmode;
3017 imode = GET_MODE_WIDER_MODE (imode))
3018 for (fmode = GET_MODE (to); fmode != VOIDmode;
3019 fmode = GET_MODE_WIDER_MODE (fmode))
3021 int doing_unsigned = unsignedp;
3023 icode = can_float_p (fmode, imode, unsignedp);
3024 if (icode == CODE_FOR_nothing && imode != GET_MODE (from) && unsignedp)
3025 icode = can_float_p (fmode, imode, 0), doing_unsigned = 0;
3027 if (icode != CODE_FOR_nothing)
3029 to = protect_from_queue (to, 1);
3030 from = protect_from_queue (from, 0);
3032 if (imode != GET_MODE (from))
3033 from = convert_to_mode (imode, from, unsignedp);
3035 if (fmode != GET_MODE (to))
3036 target = gen_reg_rtx (fmode);
3038 emit_unop_insn (icode, target, from,
3039 doing_unsigned ? UNSIGNED_FLOAT : FLOAT);
3042 convert_move (to, target, 0);
3047 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
3049 /* Unsigned integer, and no way to convert directly.
3050 Convert as signed, then conditionally adjust the result. */
3053 rtx label = gen_label_rtx ();
3055 REAL_VALUE_TYPE offset;
3059 to = protect_from_queue (to, 1);
3060 from = protect_from_queue (from, 0);
3063 from = force_not_mem (from);
3065 /* Look for a usable floating mode FMODE wider than the source and at
3066 least as wide as the target. Using FMODE will avoid rounding woes
3067 with unsigned values greater than the signed maximum value. */
3068 for (fmode = GET_MODE (to); fmode != VOIDmode;
3069 fmode = GET_MODE_WIDER_MODE (fmode))
3070 if (GET_MODE_BITSIZE (GET_MODE (from)) < GET_MODE_BITSIZE (fmode)
3071 && can_float_p (fmode, GET_MODE (from), 0) != CODE_FOR_nothing)
3074 if (fmode == VOIDmode)
3076 /* There is no such mode. Pretend the target is wide enough. */
3077 fmode = GET_MODE (to);
3079 /* Avoid double-rounding when TO is narrower than FROM. */
3080 if ((significand_size (fmode) + 1)
3081 < GET_MODE_BITSIZE (GET_MODE (from)))
3084 rtx neglabel = gen_label_rtx ();
3086 imode = GET_MODE (from);
3087 do_pending_stack_adjust ();
3089 /* Test whether the sign bit is set. */
3090 emit_cmp_insn (from, const0_rtx, GE, NULL_RTX, imode, 0, 0);
3091 emit_jump_insn (gen_blt (neglabel));
3093 /* The sign bit is not set. Convert as signed. */
3094 expand_float (target, from, 0);
3095 emit_jump_insn (gen_jump (label));
3097 /* The sign bit is set.
3098 Convert to a usable (positive signed) value by shifting right
3099 one bit, while remembering if a nonzero bit was shifted
3100 out; i.e., compute (from & 1) | (from >> 1). */
3102 emit_label (neglabel);
3103 temp = expand_binop (imode, and_optab, from, const1_rtx,
3105 temp1 = expand_binop (imode, lshr_optab, from, const1_rtx,
3107 temp = expand_binop (imode, ior_optab, temp, temp1,
3109 expand_float (target, temp, 0);
3111 /* Multiply by 2 to undo the shift above. */
3112 target = expand_binop (fmode, add_optab, target, target,
3114 do_pending_stack_adjust ();
3120 /* If we are about to do some arithmetic to correct for an
3121 unsigned operand, do it in a pseudo-register. */
3123 if (GET_MODE (to) != fmode
3124 || GET_CODE (to) != REG || REGNO (to) <= LAST_VIRTUAL_REGISTER)
3125 target = gen_reg_rtx (fmode);
3127 /* Convert as signed integer to floating. */
3128 expand_float (target, from, 0);
3130 /* If FROM is negative (and therefore TO is negative),
3131 correct its value by 2**bitwidth. */
3133 do_pending_stack_adjust ();
3134 emit_cmp_insn (from, const0_rtx, GE, NULL_RTX, GET_MODE (from), 0, 0);
3135 emit_jump_insn (gen_bge (label));
3136 /* On SCO 3.2.1, ldexp rejects values outside [0.5, 1).
3137 Rather than setting up a dconst_dot_5, let's hope SCO
3139 offset = REAL_VALUE_LDEXP (dconst1, GET_MODE_BITSIZE (GET_MODE (from)));
3140 temp = expand_binop (fmode, add_optab, target,
3141 CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode),
3142 target, 0, OPTAB_LIB_WIDEN);
3144 emit_move_insn (target, temp);
3146 do_pending_stack_adjust ();
3152 /* No hardware instruction available; call a library rotine to convert from
3153 SImode, DImode, or TImode into SFmode, DFmode, XFmode, or TFmode. */
3159 to = protect_from_queue (to, 1);
3160 from = protect_from_queue (from, 0);
3162 if (GET_MODE_SIZE (GET_MODE (from)) < GET_MODE_SIZE (SImode))
3163 from = convert_to_mode (SImode, from, unsignedp);
3166 from = force_not_mem (from);
3168 if (GET_MODE (to) == SFmode)
3170 if (GET_MODE (from) == SImode)
3171 libfcn = floatsisf_libfunc;
3172 else if (GET_MODE (from) == DImode)
3173 libfcn = floatdisf_libfunc;
3174 else if (GET_MODE (from) == TImode)
3175 libfcn = floattisf_libfunc;
3179 else if (GET_MODE (to) == DFmode)
3181 if (GET_MODE (from) == SImode)
3182 libfcn = floatsidf_libfunc;
3183 else if (GET_MODE (from) == DImode)
3184 libfcn = floatdidf_libfunc;
3185 else if (GET_MODE (from) == TImode)
3186 libfcn = floattidf_libfunc;
3190 else if (GET_MODE (to) == XFmode)
3192 if (GET_MODE (from) == SImode)
3193 libfcn = floatsixf_libfunc;
3194 else if (GET_MODE (from) == DImode)
3195 libfcn = floatdixf_libfunc;
3196 else if (GET_MODE (from) == TImode)
3197 libfcn = floattixf_libfunc;
3201 else if (GET_MODE (to) == TFmode)
3203 if (GET_MODE (from) == SImode)
3204 libfcn = floatsitf_libfunc;
3205 else if (GET_MODE (from) == DImode)
3206 libfcn = floatditf_libfunc;
3207 else if (GET_MODE (from) == TImode)
3208 libfcn = floattitf_libfunc;
3217 value = emit_library_call_value (libfcn, NULL_RTX, 1,
3219 1, from, GET_MODE (from));
3220 insns = get_insns ();
3223 emit_libcall_block (insns, target, value,
3224 gen_rtx (FLOAT, GET_MODE (to), from));
3229 /* Copy result to requested destination
3230 if we have been computing in a temp location. */
3234 if (GET_MODE (target) == GET_MODE (to))
3235 emit_move_insn (to, target);
3237 convert_move (to, target, 0);
3241 /* expand_fix: generate code to convert FROM to fixed point
3242 and store in TO. FROM must be floating point. */
3248 rtx temp = gen_reg_rtx (GET_MODE (x));
3249 return expand_unop (GET_MODE (x), ftrunc_optab, x, temp, 0);
3253 expand_fix (to, from, unsignedp)
3254 register rtx to, from;
3257 enum insn_code icode;
3258 register rtx target = to;
3259 enum machine_mode fmode, imode;
3263 /* We first try to find a pair of modes, one real and one integer, at
3264 least as wide as FROM and TO, respectively, in which we can open-code
3265 this conversion. If the integer mode is wider than the mode of TO,
3266 we can do the conversion either signed or unsigned. */
3268 for (imode = GET_MODE (to); imode != VOIDmode;
3269 imode = GET_MODE_WIDER_MODE (imode))
3270 for (fmode = GET_MODE (from); fmode != VOIDmode;
3271 fmode = GET_MODE_WIDER_MODE (fmode))
3273 int doing_unsigned = unsignedp;
3275 icode = can_fix_p (imode, fmode, unsignedp, &must_trunc);
3276 if (icode == CODE_FOR_nothing && imode != GET_MODE (to) && unsignedp)
3277 icode = can_fix_p (imode, fmode, 0, &must_trunc), doing_unsigned = 0;
3279 if (icode != CODE_FOR_nothing)
3281 to = protect_from_queue (to, 1);
3282 from = protect_from_queue (from, 0);
3284 if (fmode != GET_MODE (from))
3285 from = convert_to_mode (fmode, from, 0);
3288 from = ftruncify (from);
3290 if (imode != GET_MODE (to))
3291 target = gen_reg_rtx (imode);
3293 emit_unop_insn (icode, target, from,
3294 doing_unsigned ? UNSIGNED_FIX : FIX);
3296 convert_move (to, target, unsignedp);
3301 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
3302 /* For an unsigned conversion, there is one more way to do it.
3303 If we have a signed conversion, we generate code that compares
3304 the real value to the largest representable positive number. If if
3305 is smaller, the conversion is done normally. Otherwise, subtract
3306 one plus the highest signed number, convert, and add it back.
3308 We only need to check all real modes, since we know we didn't find
3309 anything with a wider integer mode. */
3311 if (unsignedp && GET_MODE_BITSIZE (GET_MODE (to)) <= HOST_BITS_PER_WIDE_INT)
3312 for (fmode = GET_MODE (from); fmode != VOIDmode;
3313 fmode = GET_MODE_WIDER_MODE (fmode))
3314 /* Make sure we won't lose significant bits doing this. */
3315 if (GET_MODE_BITSIZE (fmode) > GET_MODE_BITSIZE (GET_MODE (to))
3316 && CODE_FOR_nothing != can_fix_p (GET_MODE (to), fmode, 0,
3320 REAL_VALUE_TYPE offset;
3321 rtx limit, lab1, lab2, insn;
3323 bitsize = GET_MODE_BITSIZE (GET_MODE (to));
3324 offset = REAL_VALUE_LDEXP (dconst1, bitsize - 1);
3325 limit = CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode);
3326 lab1 = gen_label_rtx ();
3327 lab2 = gen_label_rtx ();
3330 to = protect_from_queue (to, 1);
3331 from = protect_from_queue (from, 0);
3334 from = force_not_mem (from);
3336 if (fmode != GET_MODE (from))
3337 from = convert_to_mode (fmode, from, 0);
3339 /* See if we need to do the subtraction. */
3340 do_pending_stack_adjust ();
3341 emit_cmp_insn (from, limit, GE, NULL_RTX, GET_MODE (from), 0, 0);
3342 emit_jump_insn (gen_bge (lab1));
3344 /* If not, do the signed "fix" and branch around fixup code. */
3345 expand_fix (to, from, 0);
3346 emit_jump_insn (gen_jump (lab2));
3349 /* Otherwise, subtract 2**(N-1), convert to signed number,
3350 then add 2**(N-1). Do the addition using XOR since this
3351 will often generate better code. */
3353 target = expand_binop (GET_MODE (from), sub_optab, from, limit,
3354 NULL_RTX, 0, OPTAB_LIB_WIDEN);
3355 expand_fix (to, target, 0);
3356 target = expand_binop (GET_MODE (to), xor_optab, to,
3357 GEN_INT ((HOST_WIDE_INT) 1 << (bitsize - 1)),
3358 to, 1, OPTAB_LIB_WIDEN);
3361 emit_move_insn (to, target);
3365 /* Make a place for a REG_NOTE and add it. */
3366 insn = emit_move_insn (to, to);
3367 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL,
3368 gen_rtx (UNSIGNED_FIX, GET_MODE (to),
3376 /* We can't do it with an insn, so use a library call. But first ensure
3377 that the mode of TO is at least as wide as SImode, since those are the
3378 only library calls we know about. */
3380 if (GET_MODE_SIZE (GET_MODE (to)) < GET_MODE_SIZE (SImode))
3382 target = gen_reg_rtx (SImode);
3384 expand_fix (target, from, unsignedp);
3386 else if (GET_MODE (from) == SFmode)
3388 if (GET_MODE (to) == SImode)
3389 libfcn = unsignedp ? fixunssfsi_libfunc : fixsfsi_libfunc;
3390 else if (GET_MODE (to) == DImode)
3391 libfcn = unsignedp ? fixunssfdi_libfunc : fixsfdi_libfunc;
3392 else if (GET_MODE (to) == TImode)
3393 libfcn = unsignedp ? fixunssfti_libfunc : fixsfti_libfunc;
3397 else if (GET_MODE (from) == DFmode)
3399 if (GET_MODE (to) == SImode)
3400 libfcn = unsignedp ? fixunsdfsi_libfunc : fixdfsi_libfunc;
3401 else if (GET_MODE (to) == DImode)
3402 libfcn = unsignedp ? fixunsdfdi_libfunc : fixdfdi_libfunc;
3403 else if (GET_MODE (to) == TImode)
3404 libfcn = unsignedp ? fixunsdfti_libfunc : fixdfti_libfunc;
3408 else if (GET_MODE (from) == XFmode)
3410 if (GET_MODE (to) == SImode)
3411 libfcn = unsignedp ? fixunsxfsi_libfunc : fixxfsi_libfunc;
3412 else if (GET_MODE (to) == DImode)
3413 libfcn = unsignedp ? fixunsxfdi_libfunc : fixxfdi_libfunc;
3414 else if (GET_MODE (to) == TImode)
3415 libfcn = unsignedp ? fixunsxfti_libfunc : fixxfti_libfunc;
3419 else if (GET_MODE (from) == TFmode)
3421 if (GET_MODE (to) == SImode)
3422 libfcn = unsignedp ? fixunstfsi_libfunc : fixtfsi_libfunc;
3423 else if (GET_MODE (to) == DImode)
3424 libfcn = unsignedp ? fixunstfdi_libfunc : fixtfdi_libfunc;
3425 else if (GET_MODE (to) == TImode)
3426 libfcn = unsignedp ? fixunstfti_libfunc : fixtfti_libfunc;
3437 to = protect_from_queue (to, 1);
3438 from = protect_from_queue (from, 0);
3441 from = force_not_mem (from);
3445 emit_library_call (libfcn, 1, GET_MODE (to), 1, from, GET_MODE (from));
3446 insns = get_insns ();
3449 emit_libcall_block (insns, target, hard_libcall_value (GET_MODE (to)),
3450 gen_rtx (unsignedp ? FIX : UNSIGNED_FIX,
3451 GET_MODE (to), from));
3454 if (GET_MODE (to) == GET_MODE (target))
3455 emit_move_insn (to, target);
3457 convert_move (to, target, 0);
3465 optab op = (optab) xmalloc (sizeof (struct optab));
3467 for (i = 0; i < NUM_MACHINE_MODES; i++)
3469 op->handlers[i].insn_code = CODE_FOR_nothing;
3470 op->handlers[i].libfunc = 0;
3473 if (code != UNKNOWN)
3474 code_to_optab[(int) code] = op;
3479 /* Initialize the libfunc fields of an entire group of entries in some
3480 optab. Each entry is set equal to a string consisting of a leading
3481 pair of underscores followed by a generic operation name followed by
3482 a mode name (downshifted to lower case) followed by a single character
3483 representing the number of operands for the given operation (which is
3484 usually one of the characters '2', '3', or '4').
3486 OPTABLE is the table in which libfunc fields are to be initialized.
3487 FIRST_MODE is the first machine mode index in the given optab to
3489 LAST_MODE is the last machine mode index in the given optab to
3491 OPNAME is the generic (string) name of the operation.
3492 SUFFIX is the character which specifies the number of operands for
3493 the given generic operation.
3497 init_libfuncs (optable, first_mode, last_mode, opname, suffix)
3498 register optab optable;
3499 register int first_mode;
3500 register int last_mode;
3501 register char *opname;
3502 register char suffix;
3505 register unsigned opname_len = strlen (opname);
3507 for (mode = first_mode; (int) mode <= (int) last_mode;
3508 mode = (enum machine_mode) ((int) mode + 1))
3510 register char *mname = mode_name[(int) mode];
3511 register unsigned mname_len = strlen (mname);
3512 register char *libfunc_name
3513 = (char *) xmalloc (2 + opname_len + mname_len + 1 + 1);
3520 for (q = opname; *q; )
3522 for (q = mname; *q; q++)
3523 *p++ = tolower (*q);
3526 optable->handlers[(int) mode].libfunc
3527 = gen_rtx (SYMBOL_REF, Pmode, libfunc_name);
3531 /* Initialize the libfunc fields of an entire group of entries in some
3532 optab which correspond to all integer mode operations. The parameters
3533 have the same meaning as similarly named ones for the `init_libfuncs'
3534 routine. (See above). */
3537 init_integral_libfuncs (optable, opname, suffix)
3538 register optab optable;
3539 register char *opname;
3540 register char suffix;
3542 init_libfuncs (optable, SImode, TImode, opname, suffix);
3545 /* Initialize the libfunc fields of an entire group of entries in some
3546 optab which correspond to all real mode operations. The parameters
3547 have the same meaning as similarly named ones for the `init_libfuncs'
3548 routine. (See above). */
3551 init_floating_libfuncs (optable, opname, suffix)
3552 register optab optable;
3553 register char *opname;
3554 register char suffix;
3556 init_libfuncs (optable, SFmode, TFmode, opname, suffix);
3559 /* Initialize the libfunc fields of an entire group of entries in some
3560 optab which correspond to all complex floating modes. The parameters
3561 have the same meaning as similarly named ones for the `init_libfuncs'
3562 routine. (See above). */
3565 init_complex_libfuncs (optable, opname, suffix)
3566 register optab optable;
3567 register char *opname;
3568 register char suffix;
3570 init_libfuncs (optable, SCmode, TCmode, opname, suffix);
3573 /* Call this once to initialize the contents of the optabs
3574 appropriately for the current target machine. */
3582 /* Start by initializing all tables to contain CODE_FOR_nothing. */
3584 for (p = fixtab[0][0];
3585 p < fixtab[0][0] + sizeof fixtab / sizeof (fixtab[0][0][0]);
3587 *p = CODE_FOR_nothing;
3589 for (p = fixtrunctab[0][0];
3590 p < fixtrunctab[0][0] + sizeof fixtrunctab / sizeof (fixtrunctab[0][0][0]);
3592 *p = CODE_FOR_nothing;
3594 for (p = floattab[0][0];
3595 p < floattab[0][0] + sizeof floattab / sizeof (floattab[0][0][0]);
3597 *p = CODE_FOR_nothing;
3599 for (p = extendtab[0][0];
3600 p < extendtab[0][0] + sizeof extendtab / sizeof extendtab[0][0][0];
3602 *p = CODE_FOR_nothing;
3604 for (i = 0; i < NUM_RTX_CODE; i++)
3605 setcc_gen_code[i] = CODE_FOR_nothing;
3607 add_optab = init_optab (PLUS);
3608 sub_optab = init_optab (MINUS);
3609 smul_optab = init_optab (MULT);
3610 smul_widen_optab = init_optab (UNKNOWN);
3611 umul_widen_optab = init_optab (UNKNOWN);
3612 sdiv_optab = init_optab (DIV);
3613 sdivmod_optab = init_optab (UNKNOWN);
3614 udiv_optab = init_optab (UDIV);
3615 udivmod_optab = init_optab (UNKNOWN);
3616 smod_optab = init_optab (MOD);
3617 umod_optab = init_optab (UMOD);
3618 flodiv_optab = init_optab (DIV);
3619 ftrunc_optab = init_optab (UNKNOWN);
3620 and_optab = init_optab (AND);
3621 ior_optab = init_optab (IOR);
3622 xor_optab = init_optab (XOR);
3623 ashl_optab = init_optab (ASHIFT);
3624 ashr_optab = init_optab (ASHIFTRT);
3625 lshr_optab = init_optab (LSHIFTRT);
3626 rotl_optab = init_optab (ROTATE);
3627 rotr_optab = init_optab (ROTATERT);
3628 smin_optab = init_optab (SMIN);
3629 smax_optab = init_optab (SMAX);
3630 umin_optab = init_optab (UMIN);
3631 umax_optab = init_optab (UMAX);
3632 mov_optab = init_optab (UNKNOWN);
3633 movstrict_optab = init_optab (UNKNOWN);
3634 cmp_optab = init_optab (UNKNOWN);
3635 ucmp_optab = init_optab (UNKNOWN);
3636 tst_optab = init_optab (UNKNOWN);
3637 neg_optab = init_optab (NEG);
3638 abs_optab = init_optab (ABS);
3639 one_cmpl_optab = init_optab (NOT);
3640 ffs_optab = init_optab (FFS);
3641 sqrt_optab = init_optab (SQRT);
3642 sin_optab = init_optab (UNKNOWN);
3643 cos_optab = init_optab (UNKNOWN);
3644 strlen_optab = init_optab (UNKNOWN);
3646 for (i = 0; i < NUM_MACHINE_MODES; i++)
3648 movstr_optab[i] = CODE_FOR_nothing;
3650 #ifdef HAVE_SECONDARY_RELOADS
3651 reload_in_optab[i] = reload_out_optab[i] = CODE_FOR_nothing;
3655 /* Fill in the optabs with the insns we support. */
3658 #ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC
3659 /* This flag says the same insns that convert to a signed fixnum
3660 also convert validly to an unsigned one. */
3661 for (i = 0; i < NUM_MACHINE_MODES; i++)
3662 for (j = 0; j < NUM_MACHINE_MODES; j++)
3663 fixtrunctab[i][j][1] = fixtrunctab[i][j][0];
3666 #ifdef EXTRA_CC_MODES
3670 /* Initialize the optabs with the names of the library functions. */
3671 init_integral_libfuncs (add_optab, "add", '3');
3672 init_floating_libfuncs (add_optab, "add", '3');
3673 init_integral_libfuncs (sub_optab, "sub", '3');
3674 init_floating_libfuncs (sub_optab, "sub", '3');
3675 init_integral_libfuncs (smul_optab, "mul", '3');
3676 init_floating_libfuncs (smul_optab, "mul", '3');
3677 init_integral_libfuncs (sdiv_optab, "div", '3');
3678 init_integral_libfuncs (udiv_optab, "udiv", '3');
3679 init_integral_libfuncs (sdivmod_optab, "divmod", '4');
3680 init_integral_libfuncs (udivmod_optab, "udivmod", '4');
3681 init_integral_libfuncs (smod_optab, "mod", '3');
3682 init_integral_libfuncs (umod_optab, "umod", '3');
3683 init_floating_libfuncs (flodiv_optab, "div", '3');
3684 init_floating_libfuncs (ftrunc_optab, "ftrunc", '2');
3685 init_integral_libfuncs (and_optab, "and", '3');
3686 init_integral_libfuncs (ior_optab, "ior", '3');
3687 init_integral_libfuncs (xor_optab, "xor", '3');
3688 init_integral_libfuncs (ashl_optab, "ashl", '3');
3689 init_integral_libfuncs (ashr_optab, "ashr", '3');
3690 init_integral_libfuncs (lshr_optab, "lshr", '3');
3691 init_integral_libfuncs (rotl_optab, "rotl", '3');
3692 init_integral_libfuncs (rotr_optab, "rotr", '3');
3693 init_integral_libfuncs (smin_optab, "min", '3');
3694 init_floating_libfuncs (smin_optab, "min", '3');
3695 init_integral_libfuncs (smax_optab, "max", '3');
3696 init_floating_libfuncs (smax_optab, "max", '3');
3697 init_integral_libfuncs (umin_optab, "umin", '3');
3698 init_integral_libfuncs (umax_optab, "umax", '3');
3699 init_integral_libfuncs (neg_optab, "neg", '2');
3700 init_floating_libfuncs (neg_optab, "neg", '2');
3701 init_integral_libfuncs (one_cmpl_optab, "one_cmpl", '2');
3702 init_integral_libfuncs (ffs_optab, "ffs", '2');
3704 /* Comparison libcalls for integers MUST come in pairs, signed/unsigned. */
3705 init_integral_libfuncs (cmp_optab, "cmp", '2');
3706 init_integral_libfuncs (ucmp_optab, "ucmp", '2');
3707 init_floating_libfuncs (cmp_optab, "cmp", '2');
3709 #ifdef MULSI3_LIBCALL
3710 smul_optab->handlers[(int) SImode].libfunc
3711 = gen_rtx (SYMBOL_REF, Pmode, MULSI3_LIBCALL);
3713 #ifdef MULDI3_LIBCALL
3714 smul_optab->handlers[(int) DImode].libfunc
3715 = gen_rtx (SYMBOL_REF, Pmode, MULDI3_LIBCALL);
3717 #ifdef MULTI3_LIBCALL
3718 smul_optab->handlers[(int) TImode].libfunc
3719 = gen_rtx (SYMBOL_REF, Pmode, MULTI3_LIBCALL);
3722 #ifdef DIVSI3_LIBCALL
3723 sdiv_optab->handlers[(int) SImode].libfunc
3724 = gen_rtx (SYMBOL_REF, Pmode, DIVSI3_LIBCALL);
3726 #ifdef DIVDI3_LIBCALL
3727 sdiv_optab->handlers[(int) DImode].libfunc
3728 = gen_rtx (SYMBOL_REF, Pmode, DIVDI3_LIBCALL);
3730 #ifdef DIVTI3_LIBCALL
3731 sdiv_optab->handlers[(int) TImode].libfunc
3732 = gen_rtx (SYMBOL_REF, Pmode, DIVTI3_LIBCALL);
3735 #ifdef UDIVSI3_LIBCALL
3736 udiv_optab->handlers[(int) SImode].libfunc
3737 = gen_rtx (SYMBOL_REF, Pmode, UDIVSI3_LIBCALL);
3739 #ifdef UDIVDI3_LIBCALL
3740 udiv_optab->handlers[(int) DImode].libfunc
3741 = gen_rtx (SYMBOL_REF, Pmode, UDIVDI3_LIBCALL);
3743 #ifdef UDIVTI3_LIBCALL
3744 udiv_optab->handlers[(int) TImode].libfunc
3745 = gen_rtx (SYMBOL_REF, Pmode, UDIVTI3_LIBCALL);
3749 #ifdef MODSI3_LIBCALL
3750 smod_optab->handlers[(int) SImode].libfunc
3751 = gen_rtx (SYMBOL_REF, Pmode, MODSI3_LIBCALL);
3753 #ifdef MODDI3_LIBCALL
3754 smod_optab->handlers[(int) DImode].libfunc
3755 = gen_rtx (SYMBOL_REF, Pmode, MODDI3_LIBCALL);
3757 #ifdef MODTI3_LIBCALL
3758 smod_optab->handlers[(int) TImode].libfunc
3759 = gen_rtx (SYMBOL_REF, Pmode, MODTI3_LIBCALL);
3763 #ifdef UMODSI3_LIBCALL
3764 umod_optab->handlers[(int) SImode].libfunc
3765 = gen_rtx (SYMBOL_REF, Pmode, UMODSI3_LIBCALL);
3767 #ifdef UMODDI3_LIBCALL
3768 umod_optab->handlers[(int) DImode].libfunc
3769 = gen_rtx (SYMBOL_REF, Pmode, UMODDI3_LIBCALL);
3771 #ifdef UMODTI3_LIBCALL
3772 umod_optab->handlers[(int) TImode].libfunc
3773 = gen_rtx (SYMBOL_REF, Pmode, UMODTI3_LIBCALL);
3776 /* Define library calls for quad FP instructions */
3777 #ifdef ADDTF3_LIBCALL
3778 add_optab->handlers[(int) TFmode].libfunc
3779 = gen_rtx (SYMBOL_REF, Pmode, ADDTF3_LIBCALL);
3781 #ifdef SUBTF3_LIBCALL
3782 sub_optab->handlers[(int) TFmode].libfunc
3783 = gen_rtx (SYMBOL_REF, Pmode, SUBTF3_LIBCALL);
3785 #ifdef MULTF3_LIBCALL
3786 smul_optab->handlers[(int) TFmode].libfunc
3787 = gen_rtx (SYMBOL_REF, Pmode, MULTF3_LIBCALL);
3789 #ifdef DIVTF3_LIBCALL
3790 flodiv_optab->handlers[(int) TFmode].libfunc
3791 = gen_rtx (SYMBOL_REF, Pmode, DIVTF3_LIBCALL);
3793 #ifdef SQRTTF2_LIBCALL
3794 sqrt_optab->handlers[(int) TFmode].libfunc
3795 = gen_rtx (SYMBOL_REF, Pmode, SQRTTF2_LIBCALL);
3798 /* Use cabs for DC complex abs, since systems generally have cabs.
3799 Don't define any libcall for SCmode, so that cabs will be used. */
3800 abs_optab->handlers[(int) DCmode].libfunc
3801 = gen_rtx (SYMBOL_REF, Pmode, "cabs");
3803 /* The ffs function operates on `int'. */
3804 #ifndef INT_TYPE_SIZE
3805 #define INT_TYPE_SIZE BITS_PER_WORD
3807 ffs_optab->handlers[(int) mode_for_size (INT_TYPE_SIZE, MODE_INT, 0)] .libfunc
3808 = gen_rtx (SYMBOL_REF, Pmode, "ffs");
3810 extendsfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extendsfdf2");
3811 extendsfxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extendsfxf2");
3812 extendsftf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extendsftf2");
3813 extenddfxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extenddfxf2");
3814 extenddftf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extenddftf2");
3816 truncdfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__truncdfsf2");
3817 truncxfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__truncxfsf2");
3818 trunctfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__trunctfsf2");
3819 truncxfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__truncxfdf2");
3820 trunctfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__trunctfdf2");
3822 memcpy_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memcpy");
3823 bcopy_libfunc = gen_rtx (SYMBOL_REF, Pmode, "bcopy");
3824 memcmp_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memcmp");
3825 bcmp_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gcc_bcmp");
3826 memset_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memset");
3827 bzero_libfunc = gen_rtx (SYMBOL_REF, Pmode, "bzero");
3829 eqsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqsf2");
3830 nesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nesf2");
3831 gtsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtsf2");
3832 gesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gesf2");
3833 ltsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltsf2");
3834 lesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lesf2");
3836 eqdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqdf2");
3837 nedf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nedf2");
3838 gtdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtdf2");
3839 gedf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gedf2");
3840 ltdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltdf2");
3841 ledf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ledf2");
3843 eqxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqxf2");
3844 nexf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nexf2");
3845 gtxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtxf2");
3846 gexf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gexf2");
3847 ltxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltxf2");
3848 lexf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lexf2");
3850 eqtf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqtf2");
3851 netf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__netf2");
3852 gttf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gttf2");
3853 getf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__getf2");
3854 lttf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lttf2");
3855 letf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__letf2");
3857 /* Define library calls for quad FP instructions */
3858 #ifdef EQTF2_LIBCALL
3859 eqtf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, EQTF2_LIBCALL);
3861 #ifdef NETF2_LIBCALL
3862 netf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, NETF2_LIBCALL);
3864 #ifdef GTTF2_LIBCALL
3865 gttf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, GTTF2_LIBCALL);
3867 #ifdef GETF2_LIBCALL
3868 getf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, GETF2_LIBCALL);
3870 #ifdef LTTF2_LIBCALL
3871 lttf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, LTTF2_LIBCALL);
3873 #ifdef LETF2_LIBCALL
3874 letf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, LETF2_LIBCALL);
3877 floatsisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsisf");
3878 floatdisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatdisf");
3879 floattisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattisf");
3881 floatsidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsidf");
3882 floatdidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatdidf");
3883 floattidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattidf");
3885 floatsixf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsixf");
3886 floatdixf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatdixf");
3887 floattixf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattixf");
3889 floatsitf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsitf");
3890 floatditf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatditf");
3891 floattitf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattitf");
3893 fixsfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixsfsi");
3894 fixsfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixsfdi");
3895 fixsfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixsfti");
3897 fixdfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixdfsi");
3898 fixdfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixdfdi");
3899 fixdfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixdfti");
3901 fixxfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixxfsi");
3902 fixxfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixxfdi");
3903 fixxfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixxfti");
3905 fixtfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixtfsi");
3906 fixtfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixtfdi");
3907 fixtfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixtfti");
3909 fixunssfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunssfsi");
3910 fixunssfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunssfdi");
3911 fixunssfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunssfti");
3913 fixunsdfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsdfsi");
3914 fixunsdfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsdfdi");
3915 fixunsdfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsdfti");
3917 fixunsxfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsxfsi");
3918 fixunsxfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsxfdi");
3919 fixunsxfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsxfti");
3921 fixunstfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunstfsi");
3922 fixunstfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunstfdi");
3923 fixunstfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunstfti");
3925 /* Define library calls for quad FP instructions */
3926 #ifdef TRUNCTFSF2_LIBCALL
3927 trunctfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, TRUNCTFSF2_LIBCALL);
3929 #ifdef TRUNCTFDF2_LIBCALL
3930 trunctfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, TRUNCTFDF2_LIBCALL);
3932 #ifdef EXTENDSFTF2_LIBCALL
3933 extendsftf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, EXTENDSFTF2_LIBCALL);
3935 #ifdef EXTENDDFTF2_LIBCALL
3936 extenddftf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, EXTENDDFTF2_LIBCALL);
3938 #ifdef FLOATSITF2_LIBCALL
3939 floatsitf_libfunc = gen_rtx (SYMBOL_REF, Pmode, FLOATSITF2_LIBCALL);
3941 #ifdef FIX_TRUNCTFSI2_LIBCALL
3942 fixtfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, FIX_TRUNCTFSI2_LIBCALL);
3944 #ifdef FIXUNS_TRUNCTFSI2_LIBCALL
3945 fixunstfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, FIXUNS_TRUNCTFSI2_LIBCALL);
3951 /* SCO 3.2 apparently has a broken ldexp. */
3964 #endif /* BROKEN_LDEXP */