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, NULL_RTX, 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 NULL_RTX, 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 NULL_RTX, 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, NULL_RTX, unsignedp,
1185 expand_binop (submode, binoptab, imag0,
1186 imag1, NULL_RTX, unsignedp,
1188 realr, unsignedp, methods);
1191 emit_move_insn (realr, res);
1193 res = expand_binop (submode, add_optab,
1194 expand_binop (submode, binoptab,
1196 NULL_RTX, unsignedp, methods),
1197 expand_binop (submode, binoptab,
1199 NULL_RTX, unsignedp, methods),
1200 imagr, unsignedp, methods);
1202 emit_move_insn (imagr, res);
1206 /* Don't fetch these from memory more than once. */
1207 real0 = force_reg (submode, real0);
1208 real1 = force_reg (submode, real1);
1210 res = expand_binop (submode, binoptab, real0, real1,
1211 realr, unsignedp, methods);
1213 emit_move_insn (realr, res);
1216 res = expand_binop (submode, binoptab,
1217 real1, imag0, imagr, unsignedp, methods);
1219 res = expand_binop (submode, binoptab,
1220 real0, imag1, imagr, unsignedp, methods);
1222 emit_move_insn (imagr, res);
1227 /* (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd)) */
1230 { /* (a+ib) / (c+i0) = (a/c) + i(b/c) */
1232 /* Don't fetch these from memory more than once. */
1233 real1 = force_reg (submode, real1);
1235 /* Simply divide the real and imaginary parts by `c' */
1236 if (class == MODE_COMPLEX_FLOAT)
1237 res = expand_binop (submode, binoptab, real0, real1,
1238 realr, unsignedp, methods);
1240 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
1241 real0, real1, realr, unsignedp);
1244 emit_move_insn (realr, res);
1246 if (class == MODE_COMPLEX_FLOAT)
1247 res = expand_binop (submode, binoptab, imag0, real1,
1248 imagr, unsignedp, methods);
1250 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
1251 imag0, real1, imagr, unsignedp);
1254 emit_move_insn (imagr, res);
1256 else /* Divisor is of complex type */
1264 /* Don't fetch these from memory more than once. */
1265 real0 = force_reg (submode, real0);
1266 real1 = force_reg (submode, real1);
1268 imag0 = force_reg (submode, imag0);
1269 imag1 = force_reg (submode, imag1);
1271 /* Divisor: c*c + d*d */
1272 divisor = expand_binop (submode, add_optab,
1273 expand_binop (submode, smul_optab,
1274 real1, real1, NULL_RTX,
1275 unsignedp, methods),
1276 expand_binop (submode, smul_optab,
1277 imag1, imag1, NULL_RTX,
1278 unsignedp, methods),
1279 NULL_RTX, unsignedp, methods);
1281 if (! imag0) /* ((a)(c-id))/divisor */
1282 { /* (a+i0) / (c+id) = (ac/(cc+dd)) + i(-ad/(cc+dd)) */
1283 /* Calculate the dividend */
1284 real_t = expand_binop (submode, smul_optab, real0, real1,
1285 NULL_RTX, unsignedp, methods);
1288 = expand_unop (submode, neg_optab,
1289 expand_binop (submode, smul_optab, real0,
1290 imag1, NULL_RTX, unsignedp,
1292 NULL_RTX, unsignedp);
1294 else /* ((a+ib)(c-id))/divider */
1296 /* Calculate the dividend */
1297 real_t = expand_binop (submode, add_optab,
1298 expand_binop (submode, smul_optab,
1299 real0, real1, NULL_RTX,
1300 unsignedp, methods),
1301 expand_binop (submode, smul_optab,
1302 imag0, imag1, NULL_RTX,
1303 unsignedp, methods),
1304 NULL_RTX, unsignedp, methods);
1306 imag_t = expand_binop (submode, sub_optab,
1307 expand_binop (submode, smul_optab,
1308 imag0, real1, NULL_RTX,
1309 unsignedp, methods),
1310 expand_binop (submode, smul_optab,
1311 real0, imag1, NULL_RTX,
1312 unsignedp, methods),
1313 NULL_RTX, unsignedp, methods);
1317 if (class == MODE_COMPLEX_FLOAT)
1318 res = expand_binop (submode, binoptab, real_t, divisor,
1319 realr, unsignedp, methods);
1321 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
1322 real_t, divisor, realr, unsignedp);
1325 emit_move_insn (realr, res);
1327 if (class == MODE_COMPLEX_FLOAT)
1328 res = expand_binop (submode, binoptab, imag_t, divisor,
1329 imagr, unsignedp, methods);
1331 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
1332 imag_t, divisor, imagr, unsignedp);
1335 emit_move_insn (imagr, res);
1346 if (binoptab->code != UNKNOWN)
1348 = gen_rtx (binoptab->code, mode, copy_rtx (op0), copy_rtx (op1));
1352 emit_no_conflict_block (seq, target, op0, op1, equiv_value);
1357 /* It can't be open-coded in this mode.
1358 Use a library call if one is available and caller says that's ok. */
1360 if (binoptab->handlers[(int) mode].libfunc
1361 && (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN))
1364 rtx funexp = binoptab->handlers[(int) mode].libfunc;
1366 enum machine_mode op1_mode = mode;
1373 op1_mode = word_mode;
1374 /* Specify unsigned here,
1375 since negative shift counts are meaningless. */
1376 op1x = convert_to_mode (word_mode, op1, 1);
1379 /* Pass 1 for NO_QUEUE so we don't lose any increments
1380 if the libcall is cse'd or moved. */
1381 value = emit_library_call_value (binoptab->handlers[(int) mode].libfunc,
1382 NULL_RTX, 1, mode, 2,
1383 op0, mode, op1x, op1_mode);
1385 insns = get_insns ();
1388 target = gen_reg_rtx (mode);
1389 emit_libcall_block (insns, target, value,
1390 gen_rtx (binoptab->code, mode, op0, op1));
1395 delete_insns_since (last);
1397 /* It can't be done in this mode. Can we do it in a wider mode? */
1399 if (! (methods == OPTAB_WIDEN || methods == OPTAB_LIB_WIDEN
1400 || methods == OPTAB_MUST_WIDEN))
1402 /* Caller says, don't even try. */
1403 delete_insns_since (entry_last);
1407 /* Compute the value of METHODS to pass to recursive calls.
1408 Don't allow widening to be tried recursively. */
1410 methods = (methods == OPTAB_LIB_WIDEN ? OPTAB_LIB : OPTAB_DIRECT);
1412 /* Look for a wider mode of the same class for which it appears we can do
1415 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1417 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1418 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1420 if ((binoptab->handlers[(int) wider_mode].insn_code
1421 != CODE_FOR_nothing)
1422 || (methods == OPTAB_LIB
1423 && binoptab->handlers[(int) wider_mode].libfunc))
1425 rtx xop0 = op0, xop1 = op1;
1428 /* For certain integer operations, we need not actually extend
1429 the narrow operands, as long as we will truncate
1430 the results to the same narrowness. */
1432 if ((binoptab == ior_optab || binoptab == and_optab
1433 || binoptab == xor_optab
1434 || binoptab == add_optab || binoptab == sub_optab
1435 || binoptab == smul_optab || binoptab == ashl_optab)
1436 && class == MODE_INT)
1439 xop0 = widen_operand (xop0, wider_mode, mode,
1440 unsignedp, no_extend);
1442 /* The second operand of a shift must always be extended. */
1443 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
1444 no_extend && binoptab != ashl_optab);
1446 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
1447 unsignedp, methods);
1450 if (class != MODE_INT)
1453 target = gen_reg_rtx (mode);
1454 convert_move (target, temp, 0);
1458 return gen_lowpart (mode, temp);
1461 delete_insns_since (last);
1466 delete_insns_since (entry_last);
1470 /* Expand a binary operator which has both signed and unsigned forms.
1471 UOPTAB is the optab for unsigned operations, and SOPTAB is for
1474 If we widen unsigned operands, we may use a signed wider operation instead
1475 of an unsigned wider operation, since the result would be the same. */
1478 sign_expand_binop (mode, uoptab, soptab, op0, op1, target, unsignedp, methods)
1479 enum machine_mode mode;
1480 optab uoptab, soptab;
1481 rtx op0, op1, target;
1483 enum optab_methods methods;
1486 optab direct_optab = unsignedp ? uoptab : soptab;
1487 struct optab wide_soptab;
1489 /* Do it without widening, if possible. */
1490 temp = expand_binop (mode, direct_optab, op0, op1, target,
1491 unsignedp, OPTAB_DIRECT);
1492 if (temp || methods == OPTAB_DIRECT)
1495 /* Try widening to a signed int. Make a fake signed optab that
1496 hides any signed insn for direct use. */
1497 wide_soptab = *soptab;
1498 wide_soptab.handlers[(int) mode].insn_code = CODE_FOR_nothing;
1499 wide_soptab.handlers[(int) mode].libfunc = 0;
1501 temp = expand_binop (mode, &wide_soptab, op0, op1, target,
1502 unsignedp, OPTAB_WIDEN);
1504 /* For unsigned operands, try widening to an unsigned int. */
1505 if (temp == 0 && unsignedp)
1506 temp = expand_binop (mode, uoptab, op0, op1, target,
1507 unsignedp, OPTAB_WIDEN);
1508 if (temp || methods == OPTAB_WIDEN)
1511 /* Use the right width lib call if that exists. */
1512 temp = expand_binop (mode, direct_optab, op0, op1, target, unsignedp, OPTAB_LIB);
1513 if (temp || methods == OPTAB_LIB)
1516 /* Must widen and use a lib call, use either signed or unsigned. */
1517 temp = expand_binop (mode, &wide_soptab, op0, op1, target,
1518 unsignedp, methods);
1522 return expand_binop (mode, uoptab, op0, op1, target,
1523 unsignedp, methods);
1527 /* Generate code to perform an operation specified by BINOPTAB
1528 on operands OP0 and OP1, with two results to TARG1 and TARG2.
1529 We assume that the order of the operands for the instruction
1530 is TARG0, OP0, OP1, TARG1, which would fit a pattern like
1531 [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
1533 Either TARG0 or TARG1 may be zero, but what that means is that
1534 that result is not actually wanted. We will generate it into
1535 a dummy pseudo-reg and discard it. They may not both be zero.
1537 Returns 1 if this operation can be performed; 0 if not. */
1540 expand_twoval_binop (binoptab, op0, op1, targ0, targ1, unsignedp)
1546 enum machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
1547 enum mode_class class;
1548 enum machine_mode wider_mode;
1549 rtx entry_last = get_last_insn ();
1552 class = GET_MODE_CLASS (mode);
1554 op0 = protect_from_queue (op0, 0);
1555 op1 = protect_from_queue (op1, 0);
1559 op0 = force_not_mem (op0);
1560 op1 = force_not_mem (op1);
1563 /* If we are inside an appropriately-short loop and one operand is an
1564 expensive constant, force it into a register. */
1565 if (CONSTANT_P (op0) && preserve_subexpressions_p ()
1566 && rtx_cost (op0, binoptab->code) > 2)
1567 op0 = force_reg (mode, op0);
1569 if (CONSTANT_P (op1) && preserve_subexpressions_p ()
1570 && rtx_cost (op1, binoptab->code) > 2)
1571 op1 = force_reg (mode, op1);
1574 targ0 = protect_from_queue (targ0, 1);
1576 targ0 = gen_reg_rtx (mode);
1578 targ1 = protect_from_queue (targ1, 1);
1580 targ1 = gen_reg_rtx (mode);
1582 /* Record where to go back to if we fail. */
1583 last = get_last_insn ();
1585 if (binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1587 int icode = (int) binoptab->handlers[(int) mode].insn_code;
1588 enum machine_mode mode0 = insn_operand_mode[icode][1];
1589 enum machine_mode mode1 = insn_operand_mode[icode][2];
1591 rtx xop0 = op0, xop1 = op1;
1593 /* In case this insn wants input operands in modes different from the
1594 result, convert the operands. */
1595 if (GET_MODE (op0) != VOIDmode && GET_MODE (op0) != mode0)
1596 xop0 = convert_to_mode (mode0, xop0, unsignedp);
1598 if (GET_MODE (op1) != VOIDmode && GET_MODE (op1) != mode1)
1599 xop1 = convert_to_mode (mode1, xop1, unsignedp);
1601 /* Now, if insn doesn't accept these operands, put them into pseudos. */
1602 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
1603 xop0 = copy_to_mode_reg (mode0, xop0);
1605 if (! (*insn_operand_predicate[icode][2]) (xop1, mode1))
1606 xop1 = copy_to_mode_reg (mode1, xop1);
1608 /* We could handle this, but we should always be called with a pseudo
1609 for our targets and all insns should take them as outputs. */
1610 if (! (*insn_operand_predicate[icode][0]) (targ0, mode)
1611 || ! (*insn_operand_predicate[icode][3]) (targ1, mode))
1614 pat = GEN_FCN (icode) (targ0, xop0, xop1, targ1);
1621 delete_insns_since (last);
1624 /* It can't be done in this mode. Can we do it in a wider mode? */
1626 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1628 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1629 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1631 if (binoptab->handlers[(int) wider_mode].insn_code
1632 != CODE_FOR_nothing)
1634 register rtx t0 = gen_reg_rtx (wider_mode);
1635 register rtx t1 = gen_reg_rtx (wider_mode);
1637 if (expand_twoval_binop (binoptab,
1638 convert_modes (wider_mode, mode, op0,
1640 convert_modes (wider_mode, mode, op1,
1644 convert_move (targ0, t0, unsignedp);
1645 convert_move (targ1, t1, unsignedp);
1649 delete_insns_since (last);
1654 delete_insns_since (entry_last);
1658 /* Generate code to perform an operation specified by UNOPTAB
1659 on operand OP0, with result having machine-mode MODE.
1661 UNSIGNEDP is for the case where we have to widen the operands
1662 to perform the operation. It says to use zero-extension.
1664 If TARGET is nonzero, the value
1665 is generated there, if it is convenient to do so.
1666 In all cases an rtx is returned for the locus of the value;
1667 this may or may not be TARGET. */
1670 expand_unop (mode, unoptab, op0, target, unsignedp)
1671 enum machine_mode mode;
1677 enum mode_class class;
1678 enum machine_mode wider_mode;
1680 rtx last = get_last_insn ();
1683 class = GET_MODE_CLASS (mode);
1685 op0 = protect_from_queue (op0, 0);
1689 op0 = force_not_mem (op0);
1693 target = protect_from_queue (target, 1);
1695 if (unoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1697 int icode = (int) unoptab->handlers[(int) mode].insn_code;
1698 enum machine_mode mode0 = insn_operand_mode[icode][1];
1704 temp = gen_reg_rtx (mode);
1706 if (GET_MODE (xop0) != VOIDmode
1707 && GET_MODE (xop0) != mode0)
1708 xop0 = convert_to_mode (mode0, xop0, unsignedp);
1710 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
1712 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
1713 xop0 = copy_to_mode_reg (mode0, xop0);
1715 if (! (*insn_operand_predicate[icode][0]) (temp, mode))
1716 temp = gen_reg_rtx (mode);
1718 pat = GEN_FCN (icode) (temp, xop0);
1721 if (GET_CODE (pat) == SEQUENCE
1722 && ! add_equal_note (pat, temp, unoptab->code, xop0, NULL_RTX))
1724 delete_insns_since (last);
1725 return expand_unop (mode, unoptab, op0, NULL_RTX, unsignedp);
1733 delete_insns_since (last);
1736 /* It can't be done in this mode. Can we open-code it in a wider mode? */
1738 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1739 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1740 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1742 if (unoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing)
1746 /* For certain operations, we need not actually extend
1747 the narrow operand, as long as we will truncate the
1748 results to the same narrowness. */
1750 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
1751 (unoptab == neg_optab
1752 || unoptab == one_cmpl_optab)
1753 && class == MODE_INT);
1755 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
1760 if (class != MODE_INT)
1763 target = gen_reg_rtx (mode);
1764 convert_move (target, temp, 0);
1768 return gen_lowpart (mode, temp);
1771 delete_insns_since (last);
1775 /* These can be done a word at a time. */
1776 if (unoptab == one_cmpl_optab
1777 && class == MODE_INT
1778 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
1779 && unoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
1784 if (target == 0 || target == op0)
1785 target = gen_reg_rtx (mode);
1789 /* Do the actual arithmetic. */
1790 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
1792 rtx target_piece = operand_subword (target, i, 1, mode);
1793 rtx x = expand_unop (word_mode, unoptab,
1794 operand_subword_force (op0, i, mode),
1795 target_piece, unsignedp);
1796 if (target_piece != x)
1797 emit_move_insn (target_piece, x);
1800 insns = get_insns ();
1803 emit_no_conflict_block (insns, target, op0, NULL_RTX,
1804 gen_rtx (unoptab->code, mode, copy_rtx (op0)));
1808 /* Open-code the complex negation operation. */
1809 else if (unoptab == neg_optab
1810 && (class == MODE_COMPLEX_FLOAT || class == MODE_COMPLEX_INT))
1816 /* Find the correct mode for the real and imaginary parts */
1817 enum machine_mode submode
1818 = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
1819 class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
1822 if (submode == BLKmode)
1826 target = gen_reg_rtx (mode);
1830 target_piece = gen_imagpart (submode, target);
1831 x = expand_unop (submode, unoptab,
1832 gen_imagpart (submode, op0),
1833 target_piece, unsignedp);
1834 if (target_piece != x)
1835 emit_move_insn (target_piece, x);
1837 target_piece = gen_realpart (submode, target);
1838 x = expand_unop (submode, unoptab,
1839 gen_realpart (submode, op0),
1840 target_piece, unsignedp);
1841 if (target_piece != x)
1842 emit_move_insn (target_piece, x);
1847 emit_no_conflict_block (seq, target, op0, 0,
1848 gen_rtx (unoptab->code, mode, copy_rtx (op0)));
1852 /* Now try a library call in this mode. */
1853 if (unoptab->handlers[(int) mode].libfunc)
1856 rtx funexp = unoptab->handlers[(int) mode].libfunc;
1861 /* Pass 1 for NO_QUEUE so we don't lose any increments
1862 if the libcall is cse'd or moved. */
1863 value = emit_library_call_value (unoptab->handlers[(int) mode].libfunc,
1864 NULL_RTX, 1, mode, 1, op0, mode);
1865 insns = get_insns ();
1868 target = gen_reg_rtx (mode);
1869 emit_libcall_block (insns, target, value,
1870 gen_rtx (unoptab->code, mode, op0));
1875 /* It can't be done in this mode. Can we do it in a wider mode? */
1877 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1879 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1880 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1882 if ((unoptab->handlers[(int) wider_mode].insn_code
1883 != CODE_FOR_nothing)
1884 || unoptab->handlers[(int) wider_mode].libfunc)
1888 /* For certain operations, we need not actually extend
1889 the narrow operand, as long as we will truncate the
1890 results to the same narrowness. */
1892 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
1893 (unoptab == neg_optab
1894 || unoptab == one_cmpl_optab)
1895 && class == MODE_INT);
1897 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
1902 if (class != MODE_INT)
1905 target = gen_reg_rtx (mode);
1906 convert_move (target, temp, 0);
1910 return gen_lowpart (mode, temp);
1913 delete_insns_since (last);
1921 /* Emit code to compute the absolute value of OP0, with result to
1922 TARGET if convenient. (TARGET may be 0.) The return value says
1923 where the result actually is to be found.
1925 MODE is the mode of the operand; the mode of the result is
1926 different but can be deduced from MODE.
1928 UNSIGNEDP is relevant for complex integer modes. */
1931 expand_complex_abs (mode, op0, target, unsignedp)
1932 enum machine_mode mode;
1937 enum mode_class class = GET_MODE_CLASS (mode);
1938 enum machine_mode wider_mode;
1940 rtx entry_last = get_last_insn ();
1944 /* Find the correct mode for the real and imaginary parts. */
1945 enum machine_mode submode
1946 = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
1947 class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
1950 if (submode == BLKmode)
1953 op0 = protect_from_queue (op0, 0);
1957 op0 = force_not_mem (op0);
1960 last = get_last_insn ();
1963 target = protect_from_queue (target, 1);
1965 if (abs_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1967 int icode = (int) abs_optab->handlers[(int) mode].insn_code;
1968 enum machine_mode mode0 = insn_operand_mode[icode][1];
1974 temp = gen_reg_rtx (submode);
1976 if (GET_MODE (xop0) != VOIDmode
1977 && GET_MODE (xop0) != mode0)
1978 xop0 = convert_to_mode (mode0, xop0, unsignedp);
1980 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
1982 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
1983 xop0 = copy_to_mode_reg (mode0, xop0);
1985 if (! (*insn_operand_predicate[icode][0]) (temp, submode))
1986 temp = gen_reg_rtx (submode);
1988 pat = GEN_FCN (icode) (temp, xop0);
1991 if (GET_CODE (pat) == SEQUENCE
1992 && ! add_equal_note (pat, temp, abs_optab->code, xop0, NULL_RTX))
1994 delete_insns_since (last);
1995 return expand_unop (mode, abs_optab, op0, NULL_RTX, unsignedp);
2003 delete_insns_since (last);
2006 /* It can't be done in this mode. Can we open-code it in a wider mode? */
2008 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2009 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2011 if (abs_optab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing)
2015 xop0 = convert_modes (wider_mode, mode, xop0, unsignedp);
2016 temp = expand_complex_abs (wider_mode, xop0, NULL_RTX, unsignedp);
2020 if (class != MODE_COMPLEX_INT)
2023 target = gen_reg_rtx (submode);
2024 convert_move (target, temp, 0);
2028 return gen_lowpart (submode, temp);
2031 delete_insns_since (last);
2035 /* Open-code the complex absolute-value operation
2036 if we can open-code sqrt. Otherwise it's not worth while. */
2037 if (sqrt_optab->handlers[(int) submode].insn_code != CODE_FOR_nothing)
2039 rtx real, imag, total;
2041 real = gen_realpart (submode, op0);
2042 imag = gen_imagpart (submode, op0);
2044 /* Square both parts. */
2045 real = expand_mult (submode, real, real, NULL_RTX, 0);
2046 imag = expand_mult (submode, imag, imag, NULL_RTX, 0);
2048 /* Sum the parts. */
2049 total = expand_binop (submode, add_optab, real, imag, NULL_RTX,
2050 0, OPTAB_LIB_WIDEN);
2052 /* Get sqrt in TARGET. Set TARGET to where the result is. */
2053 target = expand_unop (submode, sqrt_optab, total, target, 0);
2055 delete_insns_since (last);
2060 /* Now try a library call in this mode. */
2061 if (abs_optab->handlers[(int) mode].libfunc)
2064 rtx funexp = abs_optab->handlers[(int) mode].libfunc;
2069 /* Pass 1 for NO_QUEUE so we don't lose any increments
2070 if the libcall is cse'd or moved. */
2071 value = emit_library_call_value (abs_optab->handlers[(int) mode].libfunc,
2072 NULL_RTX, 1, submode, 1, op0, mode);
2073 insns = get_insns ();
2076 target = gen_reg_rtx (submode);
2077 emit_libcall_block (insns, target, value,
2078 gen_rtx (abs_optab->code, mode, op0));
2083 /* It can't be done in this mode. Can we do it in a wider mode? */
2085 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2086 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2088 if ((abs_optab->handlers[(int) wider_mode].insn_code
2089 != CODE_FOR_nothing)
2090 || abs_optab->handlers[(int) wider_mode].libfunc)
2094 xop0 = convert_modes (wider_mode, mode, xop0, unsignedp);
2096 temp = expand_complex_abs (wider_mode, xop0, NULL_RTX, unsignedp);
2100 if (class != MODE_COMPLEX_INT)
2103 target = gen_reg_rtx (submode);
2104 convert_move (target, temp, 0);
2108 return gen_lowpart (submode, temp);
2111 delete_insns_since (last);
2115 delete_insns_since (entry_last);
2119 /* Generate an instruction whose insn-code is INSN_CODE,
2120 with two operands: an output TARGET and an input OP0.
2121 TARGET *must* be nonzero, and the output is always stored there.
2122 CODE is an rtx code such that (CODE OP0) is an rtx that describes
2123 the value that is stored into TARGET. */
2126 emit_unop_insn (icode, target, op0, code)
2133 enum machine_mode mode0 = insn_operand_mode[icode][1];
2136 temp = target = protect_from_queue (target, 1);
2138 op0 = protect_from_queue (op0, 0);
2141 op0 = force_not_mem (op0);
2143 /* Now, if insn does not accept our operands, put them into pseudos. */
2145 if (! (*insn_operand_predicate[icode][1]) (op0, mode0))
2146 op0 = copy_to_mode_reg (mode0, op0);
2148 if (! (*insn_operand_predicate[icode][0]) (temp, GET_MODE (temp))
2149 || (flag_force_mem && GET_CODE (temp) == MEM))
2150 temp = gen_reg_rtx (GET_MODE (temp));
2152 pat = GEN_FCN (icode) (temp, op0);
2154 if (GET_CODE (pat) == SEQUENCE && code != UNKNOWN)
2155 add_equal_note (pat, temp, code, op0, NULL_RTX);
2160 emit_move_insn (target, temp);
2163 /* Emit code to perform a series of operations on a multi-word quantity, one
2166 Such a block is preceded by a CLOBBER of the output, consists of multiple
2167 insns, each setting one word of the output, and followed by a SET copying
2168 the output to itself.
2170 Each of the insns setting words of the output receives a REG_NO_CONFLICT
2171 note indicating that it doesn't conflict with the (also multi-word)
2172 inputs. The entire block is surrounded by REG_LIBCALL and REG_RETVAL
2175 INSNS is a block of code generated to perform the operation, not including
2176 the CLOBBER and final copy. All insns that compute intermediate values
2177 are first emitted, followed by the block as described above. Only
2178 INSNs are allowed in the block; no library calls or jumps may be
2181 TARGET, OP0, and OP1 are the output and inputs of the operations,
2182 respectively. OP1 may be zero for a unary operation.
2184 EQUIV, if non-zero, is an expression to be placed into a REG_EQUAL note
2187 If TARGET is not a register, INSNS is simply emitted with no special
2190 The final insn emitted is returned. */
2193 emit_no_conflict_block (insns, target, op0, op1, equiv)
2199 rtx prev, next, first, last, insn;
2201 if (GET_CODE (target) != REG || reload_in_progress)
2202 return emit_insns (insns);
2204 /* First emit all insns that do not store into words of the output and remove
2205 these from the list. */
2206 for (insn = insns; insn; insn = next)
2211 next = NEXT_INSN (insn);
2213 if (GET_CODE (insn) != INSN)
2216 if (GET_CODE (PATTERN (insn)) == SET)
2217 set = PATTERN (insn);
2218 else if (GET_CODE (PATTERN (insn)) == PARALLEL)
2220 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
2221 if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET)
2223 set = XVECEXP (PATTERN (insn), 0, i);
2231 if (! reg_overlap_mentioned_p (target, SET_DEST (set)))
2233 if (PREV_INSN (insn))
2234 NEXT_INSN (PREV_INSN (insn)) = next;
2239 PREV_INSN (next) = PREV_INSN (insn);
2245 prev = get_last_insn ();
2247 /* Now write the CLOBBER of the output, followed by the setting of each
2248 of the words, followed by the final copy. */
2249 if (target != op0 && target != op1)
2250 emit_insn (gen_rtx (CLOBBER, VOIDmode, target));
2252 for (insn = insns; insn; insn = next)
2254 next = NEXT_INSN (insn);
2257 if (op1 && GET_CODE (op1) == REG)
2258 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_NO_CONFLICT, op1,
2261 if (op0 && GET_CODE (op0) == REG)
2262 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_NO_CONFLICT, op0,
2266 if (mov_optab->handlers[(int) GET_MODE (target)].insn_code
2267 != CODE_FOR_nothing)
2269 last = emit_move_insn (target, target);
2272 = gen_rtx (EXPR_LIST, REG_EQUAL, equiv, REG_NOTES (last));
2275 last = get_last_insn ();
2278 first = get_insns ();
2280 first = NEXT_INSN (prev);
2282 /* Encapsulate the block so it gets manipulated as a unit. */
2283 REG_NOTES (first) = gen_rtx (INSN_LIST, REG_LIBCALL, last,
2285 REG_NOTES (last) = gen_rtx (INSN_LIST, REG_RETVAL, first, REG_NOTES (last));
2290 /* Emit code to make a call to a constant function or a library call.
2292 INSNS is a list containing all insns emitted in the call.
2293 These insns leave the result in RESULT. Our block is to copy RESULT
2294 to TARGET, which is logically equivalent to EQUIV.
2296 We first emit any insns that set a pseudo on the assumption that these are
2297 loading constants into registers; doing so allows them to be safely cse'ed
2298 between blocks. Then we emit all the other insns in the block, followed by
2299 an insn to move RESULT to TARGET. This last insn will have a REQ_EQUAL
2300 note with an operand of EQUIV.
2302 Moving assignments to pseudos outside of the block is done to improve
2303 the generated code, but is not required to generate correct code,
2304 hence being unable to move an assignment is not grounds for not making
2305 a libcall block. There are two reasons why it is safe to leave these
2306 insns inside the block: First, we know that these pseudos cannot be
2307 used in generated RTL outside the block since they are created for
2308 temporary purposes within the block. Second, CSE will not record the
2309 values of anything set inside a libcall block, so we know they must
2310 be dead at the end of the block.
2312 Except for the first group of insns (the ones setting pseudos), the
2313 block is delimited by REG_RETVAL and REG_LIBCALL notes. */
2316 emit_libcall_block (insns, target, result, equiv)
2322 rtx prev, next, first, last, insn;
2324 /* First emit all insns that set pseudos. Remove them from the list as
2325 we go. Avoid insns that set pseudos which were referenced in previous
2326 insns. These can be generated by move_by_pieces, for example,
2327 to update an address. Similarly, avoid insns that reference things
2328 set in previous insns. */
2330 for (insn = insns; insn; insn = next)
2332 rtx set = single_set (insn);
2334 next = NEXT_INSN (insn);
2336 if (set != 0 && GET_CODE (SET_DEST (set)) == REG
2337 && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER
2339 || (! reg_mentioned_p (SET_DEST (set), PATTERN (insns))
2340 && ! reg_used_between_p (SET_DEST (set), insns, insn)
2341 && ! modified_in_p (SET_SRC (set), insns)
2342 && ! modified_between_p (SET_SRC (set), insns, insn))))
2344 if (PREV_INSN (insn))
2345 NEXT_INSN (PREV_INSN (insn)) = next;
2350 PREV_INSN (next) = PREV_INSN (insn);
2356 prev = get_last_insn ();
2358 /* Write the remaining insns followed by the final copy. */
2360 for (insn = insns; insn; insn = next)
2362 next = NEXT_INSN (insn);
2367 last = emit_move_insn (target, result);
2368 REG_NOTES (last) = gen_rtx (EXPR_LIST,
2369 REG_EQUAL, copy_rtx (equiv), REG_NOTES (last));
2372 first = get_insns ();
2374 first = NEXT_INSN (prev);
2376 /* Encapsulate the block so it gets manipulated as a unit. */
2377 REG_NOTES (first) = gen_rtx (INSN_LIST, REG_LIBCALL, last,
2379 REG_NOTES (last) = gen_rtx (INSN_LIST, REG_RETVAL, first, REG_NOTES (last));
2382 /* Generate code to store zero in X. */
2388 emit_move_insn (x, const0_rtx);
2391 /* Generate code to store 1 in X
2392 assuming it contains zero beforehand. */
2395 emit_0_to_1_insn (x)
2398 emit_move_insn (x, const1_rtx);
2401 /* Generate code to compare X with Y
2402 so that the condition codes are set.
2404 MODE is the mode of the inputs (in case they are const_int).
2405 UNSIGNEDP nonzero says that X and Y are unsigned;
2406 this matters if they need to be widened.
2408 If they have mode BLKmode, then SIZE specifies the size of both X and Y,
2409 and ALIGN specifies the known shared alignment of X and Y.
2411 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).
2412 It is ignored for fixed-point and block comparisons;
2413 it is used only for floating-point comparisons. */
2416 emit_cmp_insn (x, y, comparison, size, mode, unsignedp, align)
2418 enum rtx_code comparison;
2420 enum machine_mode mode;
2424 enum mode_class class;
2425 enum machine_mode wider_mode;
2427 class = GET_MODE_CLASS (mode);
2429 /* They could both be VOIDmode if both args are immediate constants,
2430 but we should fold that at an earlier stage.
2431 With no special code here, this will call abort,
2432 reminding the programmer to implement such folding. */
2434 if (mode != BLKmode && flag_force_mem)
2436 x = force_not_mem (x);
2437 y = force_not_mem (y);
2440 /* If we are inside an appropriately-short loop and one operand is an
2441 expensive constant, force it into a register. */
2442 if (CONSTANT_P (x) && preserve_subexpressions_p () && rtx_cost (x, COMPARE) > 2)
2443 x = force_reg (mode, x);
2445 if (CONSTANT_P (y) && preserve_subexpressions_p () && rtx_cost (y, COMPARE) > 2)
2446 y = force_reg (mode, y);
2448 /* Don't let both operands fail to indicate the mode. */
2449 if (GET_MODE (x) == VOIDmode && GET_MODE (y) == VOIDmode)
2450 x = force_reg (mode, x);
2452 /* Handle all BLKmode compares. */
2454 if (mode == BLKmode)
2457 x = protect_from_queue (x, 0);
2458 y = protect_from_queue (y, 0);
2462 #ifdef HAVE_cmpstrqi
2464 && GET_CODE (size) == CONST_INT
2465 && INTVAL (size) < (1 << GET_MODE_BITSIZE (QImode)))
2467 enum machine_mode result_mode
2468 = insn_operand_mode[(int) CODE_FOR_cmpstrqi][0];
2469 rtx result = gen_reg_rtx (result_mode);
2470 emit_insn (gen_cmpstrqi (result, x, y, size, GEN_INT (align)));
2471 emit_cmp_insn (result, const0_rtx, comparison, NULL_RTX,
2476 #ifdef HAVE_cmpstrhi
2478 && GET_CODE (size) == CONST_INT
2479 && INTVAL (size) < (1 << GET_MODE_BITSIZE (HImode)))
2481 enum machine_mode result_mode
2482 = insn_operand_mode[(int) CODE_FOR_cmpstrhi][0];
2483 rtx result = gen_reg_rtx (result_mode);
2484 emit_insn (gen_cmpstrhi (result, x, y, size, GEN_INT (align)));
2485 emit_cmp_insn (result, const0_rtx, comparison, NULL_RTX,
2490 #ifdef HAVE_cmpstrsi
2493 enum machine_mode result_mode
2494 = insn_operand_mode[(int) CODE_FOR_cmpstrsi][0];
2495 rtx result = gen_reg_rtx (result_mode);
2496 size = protect_from_queue (size, 0);
2497 emit_insn (gen_cmpstrsi (result, x, y,
2498 convert_to_mode (SImode, size, 1),
2500 emit_cmp_insn (result, const0_rtx, comparison, NULL_RTX,
2506 #ifdef TARGET_MEM_FUNCTIONS
2507 emit_library_call (memcmp_libfunc, 0,
2508 TYPE_MODE (integer_type_node), 3,
2509 XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
2512 emit_library_call (bcmp_libfunc, 0,
2513 TYPE_MODE (integer_type_node), 3,
2514 XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
2517 emit_cmp_insn (hard_libcall_value (TYPE_MODE (integer_type_node)),
2518 const0_rtx, comparison, NULL_RTX,
2519 TYPE_MODE (integer_type_node), 0, 0);
2524 /* Handle some compares against zero. */
2526 if (y == CONST0_RTX (mode)
2527 && tst_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2529 int icode = (int) tst_optab->handlers[(int) mode].insn_code;
2532 x = protect_from_queue (x, 0);
2533 y = protect_from_queue (y, 0);
2535 /* Now, if insn does accept these operands, put them into pseudos. */
2536 if (! (*insn_operand_predicate[icode][0])
2537 (x, insn_operand_mode[icode][0]))
2538 x = copy_to_mode_reg (insn_operand_mode[icode][0], x);
2540 emit_insn (GEN_FCN (icode) (x));
2544 /* Handle compares for which there is a directly suitable insn. */
2546 if (cmp_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2548 int icode = (int) cmp_optab->handlers[(int) mode].insn_code;
2551 x = protect_from_queue (x, 0);
2552 y = protect_from_queue (y, 0);
2554 /* Now, if insn doesn't accept these operands, put them into pseudos. */
2555 if (! (*insn_operand_predicate[icode][0])
2556 (x, insn_operand_mode[icode][0]))
2557 x = copy_to_mode_reg (insn_operand_mode[icode][0], x);
2559 if (! (*insn_operand_predicate[icode][1])
2560 (y, insn_operand_mode[icode][1]))
2561 y = copy_to_mode_reg (insn_operand_mode[icode][1], y);
2563 emit_insn (GEN_FCN (icode) (x, y));
2567 /* Try widening if we can find a direct insn that way. */
2569 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
2571 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2572 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2574 if (cmp_optab->handlers[(int) wider_mode].insn_code
2575 != CODE_FOR_nothing)
2577 x = protect_from_queue (x, 0);
2578 y = protect_from_queue (y, 0);
2579 x = convert_modes (wider_mode, mode, x, unsignedp);
2580 y = convert_modes (wider_mode, mode, y, unsignedp);
2581 emit_cmp_insn (x, y, comparison, NULL_RTX,
2582 wider_mode, unsignedp, align);
2588 /* Handle a lib call just for the mode we are using. */
2590 if (cmp_optab->handlers[(int) mode].libfunc
2591 && class != MODE_FLOAT)
2593 rtx libfunc = cmp_optab->handlers[(int) mode].libfunc;
2594 /* If we want unsigned, and this mode has a distinct unsigned
2595 comparison routine, use that. */
2596 if (unsignedp && ucmp_optab->handlers[(int) mode].libfunc)
2597 libfunc = ucmp_optab->handlers[(int) mode].libfunc;
2599 emit_library_call (libfunc, 1,
2600 word_mode, 2, x, mode, y, mode);
2602 /* Integer comparison returns a result that must be compared against 1,
2603 so that even if we do an unsigned compare afterward,
2604 there is still a value that can represent the result "less than". */
2606 emit_cmp_insn (hard_libcall_value (word_mode), const1_rtx,
2607 comparison, NULL_RTX, word_mode, unsignedp, 0);
2611 if (class == MODE_FLOAT)
2612 emit_float_lib_cmp (x, y, comparison);
2618 /* Nonzero if a compare of mode MODE can be done straightforwardly
2619 (without splitting it into pieces). */
2622 can_compare_p (mode)
2623 enum machine_mode mode;
2627 if (cmp_optab->handlers[(int)mode].insn_code != CODE_FOR_nothing)
2629 mode = GET_MODE_WIDER_MODE (mode);
2630 } while (mode != VOIDmode);
2635 /* Emit a library call comparison between floating point X and Y.
2636 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */
2639 emit_float_lib_cmp (x, y, comparison)
2641 enum rtx_code comparison;
2643 enum machine_mode mode = GET_MODE (x);
2650 libfunc = eqsf2_libfunc;
2654 libfunc = nesf2_libfunc;
2658 libfunc = gtsf2_libfunc;
2662 libfunc = gesf2_libfunc;
2666 libfunc = ltsf2_libfunc;
2670 libfunc = lesf2_libfunc;
2673 else if (mode == DFmode)
2677 libfunc = eqdf2_libfunc;
2681 libfunc = nedf2_libfunc;
2685 libfunc = gtdf2_libfunc;
2689 libfunc = gedf2_libfunc;
2693 libfunc = ltdf2_libfunc;
2697 libfunc = ledf2_libfunc;
2700 else if (mode == XFmode)
2704 libfunc = eqxf2_libfunc;
2708 libfunc = nexf2_libfunc;
2712 libfunc = gtxf2_libfunc;
2716 libfunc = gexf2_libfunc;
2720 libfunc = ltxf2_libfunc;
2724 libfunc = lexf2_libfunc;
2727 else if (mode == TFmode)
2731 libfunc = eqtf2_libfunc;
2735 libfunc = netf2_libfunc;
2739 libfunc = gttf2_libfunc;
2743 libfunc = getf2_libfunc;
2747 libfunc = lttf2_libfunc;
2751 libfunc = letf2_libfunc;
2756 enum machine_mode wider_mode;
2758 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2759 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2761 if ((cmp_optab->handlers[(int) wider_mode].insn_code
2762 != CODE_FOR_nothing)
2763 || (cmp_optab->handlers[(int) wider_mode].libfunc != 0))
2765 x = protect_from_queue (x, 0);
2766 y = protect_from_queue (y, 0);
2767 x = convert_to_mode (wider_mode, x, 0);
2768 y = convert_to_mode (wider_mode, y, 0);
2769 emit_float_lib_cmp (x, y, comparison);
2779 emit_library_call (libfunc, 1,
2780 word_mode, 2, x, mode, y, mode);
2782 emit_cmp_insn (hard_libcall_value (word_mode), const0_rtx, comparison,
2783 NULL_RTX, word_mode, 0, 0);
2786 /* Generate code to indirectly jump to a location given in the rtx LOC. */
2789 emit_indirect_jump (loc)
2792 if (! ((*insn_operand_predicate[(int)CODE_FOR_indirect_jump][0])
2794 loc = copy_to_mode_reg (Pmode, loc);
2796 emit_jump_insn (gen_indirect_jump (loc));
2800 /* These three functions generate an insn body and return it
2801 rather than emitting the insn.
2803 They do not protect from queued increments,
2804 because they may be used 1) in protect_from_queue itself
2805 and 2) in other passes where there is no queue. */
2807 /* Generate and return an insn body to add Y to X. */
2810 gen_add2_insn (x, y)
2813 int icode = (int) add_optab->handlers[(int) GET_MODE (x)].insn_code;
2815 if (! (*insn_operand_predicate[icode][0]) (x, insn_operand_mode[icode][0])
2816 || ! (*insn_operand_predicate[icode][1]) (x, insn_operand_mode[icode][1])
2817 || ! (*insn_operand_predicate[icode][2]) (y, insn_operand_mode[icode][2]))
2820 return (GEN_FCN (icode) (x, x, y));
2824 have_add2_insn (mode)
2825 enum machine_mode mode;
2827 return add_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
2830 /* Generate and return an insn body to subtract Y from X. */
2833 gen_sub2_insn (x, y)
2836 int icode = (int) sub_optab->handlers[(int) GET_MODE (x)].insn_code;
2838 if (! (*insn_operand_predicate[icode][0]) (x, insn_operand_mode[icode][0])
2839 || ! (*insn_operand_predicate[icode][1]) (x, insn_operand_mode[icode][1])
2840 || ! (*insn_operand_predicate[icode][2]) (y, insn_operand_mode[icode][2]))
2843 return (GEN_FCN (icode) (x, x, y));
2847 have_sub2_insn (mode)
2848 enum machine_mode mode;
2850 return sub_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
2853 /* Generate the body of an instruction to copy Y into X.
2854 It may be a SEQUENCE, if one insn isn't enough. */
2857 gen_move_insn (x, y)
2860 register enum machine_mode mode = GET_MODE (x);
2861 enum insn_code insn_code;
2864 if (mode == VOIDmode)
2865 mode = GET_MODE (y);
2867 insn_code = mov_optab->handlers[(int) mode].insn_code;
2869 /* Handle MODE_CC modes: If we don't have a special move insn for this mode,
2870 find a mode to do it in. If we have a movcc, use it. Otherwise,
2871 find the MODE_INT mode of the same width. */
2873 if (GET_MODE_CLASS (mode) == MODE_CC && insn_code == CODE_FOR_nothing)
2875 enum machine_mode tmode = VOIDmode;
2879 && mov_optab->handlers[(int) CCmode].insn_code != CODE_FOR_nothing)
2882 for (tmode = QImode; tmode != VOIDmode;
2883 tmode = GET_MODE_WIDER_MODE (tmode))
2884 if (GET_MODE_SIZE (tmode) == GET_MODE_SIZE (mode))
2887 if (tmode == VOIDmode)
2890 /* Get X and Y in TMODE. We can't use gen_lowpart here because it
2891 may call change_address which is not appropriate if we were
2892 called when a reload was in progress. We don't have to worry
2893 about changing the address since the size in bytes is supposed to
2894 be the same. Copy the MEM to change the mode and move any
2895 substitutions from the old MEM to the new one. */
2897 if (reload_in_progress)
2899 x = gen_lowpart_common (tmode, x1);
2900 if (x == 0 && GET_CODE (x1) == MEM)
2902 x = gen_rtx (MEM, tmode, XEXP (x1, 0));
2903 RTX_UNCHANGING_P (x) = RTX_UNCHANGING_P (x1);
2904 MEM_IN_STRUCT_P (x) = MEM_IN_STRUCT_P (x1);
2905 MEM_VOLATILE_P (x) = MEM_VOLATILE_P (x1);
2906 copy_replacements (x1, x);
2909 y = gen_lowpart_common (tmode, y1);
2910 if (y == 0 && GET_CODE (y1) == MEM)
2912 y = gen_rtx (MEM, tmode, XEXP (y1, 0));
2913 RTX_UNCHANGING_P (y) = RTX_UNCHANGING_P (y1);
2914 MEM_IN_STRUCT_P (y) = MEM_IN_STRUCT_P (y1);
2915 MEM_VOLATILE_P (y) = MEM_VOLATILE_P (y1);
2916 copy_replacements (y1, y);
2921 x = gen_lowpart (tmode, x);
2922 y = gen_lowpart (tmode, y);
2925 insn_code = mov_optab->handlers[(int) tmode].insn_code;
2926 return (GEN_FCN (insn_code) (x, y));
2930 emit_move_insn_1 (x, y);
2931 seq = gen_sequence ();
2936 /* Return the insn code used to extend FROM_MODE to TO_MODE.
2937 UNSIGNEDP specifies zero-extension instead of sign-extension. If
2938 no such operation exists, CODE_FOR_nothing will be returned. */
2941 can_extend_p (to_mode, from_mode, unsignedp)
2942 enum machine_mode to_mode, from_mode;
2945 return extendtab[(int) to_mode][(int) from_mode][unsignedp];
2948 /* Generate the body of an insn to extend Y (with mode MFROM)
2949 into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */
2952 gen_extend_insn (x, y, mto, mfrom, unsignedp)
2954 enum machine_mode mto, mfrom;
2957 return (GEN_FCN (extendtab[(int) mto][(int) mfrom][unsignedp]) (x, y));
2960 /* can_fix_p and can_float_p say whether the target machine
2961 can directly convert a given fixed point type to
2962 a given floating point type, or vice versa.
2963 The returned value is the CODE_FOR_... value to use,
2964 or CODE_FOR_nothing if these modes cannot be directly converted.
2966 *TRUNCP_PTR is set to 1 if it is necessary to output
2967 an explicit FTRUNC insn before the fix insn; otherwise 0. */
2969 static enum insn_code
2970 can_fix_p (fixmode, fltmode, unsignedp, truncp_ptr)
2971 enum machine_mode fltmode, fixmode;
2976 if (fixtrunctab[(int) fltmode][(int) fixmode][unsignedp] != CODE_FOR_nothing)
2977 return fixtrunctab[(int) fltmode][(int) fixmode][unsignedp];
2979 if (ftrunc_optab->handlers[(int) fltmode].insn_code != CODE_FOR_nothing)
2982 return fixtab[(int) fltmode][(int) fixmode][unsignedp];
2984 return CODE_FOR_nothing;
2987 static enum insn_code
2988 can_float_p (fltmode, fixmode, unsignedp)
2989 enum machine_mode fixmode, fltmode;
2992 return floattab[(int) fltmode][(int) fixmode][unsignedp];
2995 /* Generate code to convert FROM to floating point
2996 and store in TO. FROM must be fixed point and not VOIDmode.
2997 UNSIGNEDP nonzero means regard FROM as unsigned.
2998 Normally this is done by correcting the final value
2999 if it is negative. */
3002 expand_float (to, from, unsignedp)
3006 enum insn_code icode;
3007 register rtx target = to;
3008 enum machine_mode fmode, imode;
3010 /* Crash now, because we won't be able to decide which mode to use. */
3011 if (GET_MODE (from) == VOIDmode)
3014 /* Look for an insn to do the conversion. Do it in the specified
3015 modes if possible; otherwise convert either input, output or both to
3016 wider mode. If the integer mode is wider than the mode of FROM,
3017 we can do the conversion signed even if the input is unsigned. */
3019 for (imode = GET_MODE (from); imode != VOIDmode;
3020 imode = GET_MODE_WIDER_MODE (imode))
3021 for (fmode = GET_MODE (to); fmode != VOIDmode;
3022 fmode = GET_MODE_WIDER_MODE (fmode))
3024 int doing_unsigned = unsignedp;
3026 icode = can_float_p (fmode, imode, unsignedp);
3027 if (icode == CODE_FOR_nothing && imode != GET_MODE (from) && unsignedp)
3028 icode = can_float_p (fmode, imode, 0), doing_unsigned = 0;
3030 if (icode != CODE_FOR_nothing)
3032 to = protect_from_queue (to, 1);
3033 from = protect_from_queue (from, 0);
3035 if (imode != GET_MODE (from))
3036 from = convert_to_mode (imode, from, unsignedp);
3038 if (fmode != GET_MODE (to))
3039 target = gen_reg_rtx (fmode);
3041 emit_unop_insn (icode, target, from,
3042 doing_unsigned ? UNSIGNED_FLOAT : FLOAT);
3045 convert_move (to, target, 0);
3050 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
3052 /* Unsigned integer, and no way to convert directly.
3053 Convert as signed, then conditionally adjust the result. */
3056 rtx label = gen_label_rtx ();
3058 REAL_VALUE_TYPE offset;
3062 to = protect_from_queue (to, 1);
3063 from = protect_from_queue (from, 0);
3066 from = force_not_mem (from);
3068 /* Look for a usable floating mode FMODE wider than the source and at
3069 least as wide as the target. Using FMODE will avoid rounding woes
3070 with unsigned values greater than the signed maximum value. */
3071 for (fmode = GET_MODE (to); fmode != VOIDmode;
3072 fmode = GET_MODE_WIDER_MODE (fmode))
3073 if (GET_MODE_BITSIZE (GET_MODE (from)) < GET_MODE_BITSIZE (fmode)
3074 && can_float_p (fmode, GET_MODE (from), 0) != CODE_FOR_nothing)
3077 if (fmode == VOIDmode)
3079 /* There is no such mode. Pretend the target is wide enough. */
3080 fmode = GET_MODE (to);
3082 /* Avoid double-rounding when TO is narrower than FROM. */
3083 if ((significand_size (fmode) + 1)
3084 < GET_MODE_BITSIZE (GET_MODE (from)))
3087 rtx neglabel = gen_label_rtx ();
3089 /* Don't use TARGET if it isn't a register or is a
3091 if (GET_CODE (target) != REG
3092 || REGNO (target) < FIRST_PSEUDO_REGISTER)
3093 target = gen_reg_rtx (fmode);
3095 imode = GET_MODE (from);
3096 do_pending_stack_adjust ();
3098 /* Test whether the sign bit is set. */
3099 emit_cmp_insn (from, const0_rtx, GE, NULL_RTX, imode, 0, 0);
3100 emit_jump_insn (gen_blt (neglabel));
3102 /* The sign bit is not set. Convert as signed. */
3103 expand_float (target, from, 0);
3104 emit_jump_insn (gen_jump (label));
3106 /* The sign bit is set.
3107 Convert to a usable (positive signed) value by shifting right
3108 one bit, while remembering if a nonzero bit was shifted
3109 out; i.e., compute (from & 1) | (from >> 1). */
3111 emit_label (neglabel);
3112 temp = expand_binop (imode, and_optab, from, const1_rtx,
3114 temp1 = expand_shift (RSHIFT_EXPR, imode, from, integer_one_node,
3116 temp = expand_binop (imode, ior_optab, temp, temp1, temp, 1, 0);
3117 expand_float (target, temp, 0);
3119 /* Multiply by 2 to undo the shift above. */
3120 target = expand_binop (fmode, add_optab, target, target,
3122 do_pending_stack_adjust ();
3128 /* If we are about to do some arithmetic to correct for an
3129 unsigned operand, do it in a pseudo-register. */
3131 if (GET_MODE (to) != fmode
3132 || GET_CODE (to) != REG || REGNO (to) <= LAST_VIRTUAL_REGISTER)
3133 target = gen_reg_rtx (fmode);
3135 /* Convert as signed integer to floating. */
3136 expand_float (target, from, 0);
3138 /* If FROM is negative (and therefore TO is negative),
3139 correct its value by 2**bitwidth. */
3141 do_pending_stack_adjust ();
3142 emit_cmp_insn (from, const0_rtx, GE, NULL_RTX, GET_MODE (from), 0, 0);
3143 emit_jump_insn (gen_bge (label));
3144 /* On SCO 3.2.1, ldexp rejects values outside [0.5, 1).
3145 Rather than setting up a dconst_dot_5, let's hope SCO
3147 offset = REAL_VALUE_LDEXP (dconst1, GET_MODE_BITSIZE (GET_MODE (from)));
3148 temp = expand_binop (fmode, add_optab, target,
3149 CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode),
3150 target, 0, OPTAB_LIB_WIDEN);
3152 emit_move_insn (target, temp);
3154 do_pending_stack_adjust ();
3160 /* No hardware instruction available; call a library rotine to convert from
3161 SImode, DImode, or TImode into SFmode, DFmode, XFmode, or TFmode. */
3167 to = protect_from_queue (to, 1);
3168 from = protect_from_queue (from, 0);
3170 if (GET_MODE_SIZE (GET_MODE (from)) < GET_MODE_SIZE (SImode))
3171 from = convert_to_mode (SImode, from, unsignedp);
3174 from = force_not_mem (from);
3176 if (GET_MODE (to) == SFmode)
3178 if (GET_MODE (from) == SImode)
3179 libfcn = floatsisf_libfunc;
3180 else if (GET_MODE (from) == DImode)
3181 libfcn = floatdisf_libfunc;
3182 else if (GET_MODE (from) == TImode)
3183 libfcn = floattisf_libfunc;
3187 else if (GET_MODE (to) == DFmode)
3189 if (GET_MODE (from) == SImode)
3190 libfcn = floatsidf_libfunc;
3191 else if (GET_MODE (from) == DImode)
3192 libfcn = floatdidf_libfunc;
3193 else if (GET_MODE (from) == TImode)
3194 libfcn = floattidf_libfunc;
3198 else if (GET_MODE (to) == XFmode)
3200 if (GET_MODE (from) == SImode)
3201 libfcn = floatsixf_libfunc;
3202 else if (GET_MODE (from) == DImode)
3203 libfcn = floatdixf_libfunc;
3204 else if (GET_MODE (from) == TImode)
3205 libfcn = floattixf_libfunc;
3209 else if (GET_MODE (to) == TFmode)
3211 if (GET_MODE (from) == SImode)
3212 libfcn = floatsitf_libfunc;
3213 else if (GET_MODE (from) == DImode)
3214 libfcn = floatditf_libfunc;
3215 else if (GET_MODE (from) == TImode)
3216 libfcn = floattitf_libfunc;
3225 value = emit_library_call_value (libfcn, NULL_RTX, 1,
3227 1, from, GET_MODE (from));
3228 insns = get_insns ();
3231 emit_libcall_block (insns, target, value,
3232 gen_rtx (FLOAT, GET_MODE (to), from));
3237 /* Copy result to requested destination
3238 if we have been computing in a temp location. */
3242 if (GET_MODE (target) == GET_MODE (to))
3243 emit_move_insn (to, target);
3245 convert_move (to, target, 0);
3249 /* expand_fix: generate code to convert FROM to fixed point
3250 and store in TO. FROM must be floating point. */
3256 rtx temp = gen_reg_rtx (GET_MODE (x));
3257 return expand_unop (GET_MODE (x), ftrunc_optab, x, temp, 0);
3261 expand_fix (to, from, unsignedp)
3262 register rtx to, from;
3265 enum insn_code icode;
3266 register rtx target = to;
3267 enum machine_mode fmode, imode;
3271 /* We first try to find a pair of modes, one real and one integer, at
3272 least as wide as FROM and TO, respectively, in which we can open-code
3273 this conversion. If the integer mode is wider than the mode of TO,
3274 we can do the conversion either signed or unsigned. */
3276 for (imode = GET_MODE (to); imode != VOIDmode;
3277 imode = GET_MODE_WIDER_MODE (imode))
3278 for (fmode = GET_MODE (from); fmode != VOIDmode;
3279 fmode = GET_MODE_WIDER_MODE (fmode))
3281 int doing_unsigned = unsignedp;
3283 icode = can_fix_p (imode, fmode, unsignedp, &must_trunc);
3284 if (icode == CODE_FOR_nothing && imode != GET_MODE (to) && unsignedp)
3285 icode = can_fix_p (imode, fmode, 0, &must_trunc), doing_unsigned = 0;
3287 if (icode != CODE_FOR_nothing)
3289 to = protect_from_queue (to, 1);
3290 from = protect_from_queue (from, 0);
3292 if (fmode != GET_MODE (from))
3293 from = convert_to_mode (fmode, from, 0);
3296 from = ftruncify (from);
3298 if (imode != GET_MODE (to))
3299 target = gen_reg_rtx (imode);
3301 emit_unop_insn (icode, target, from,
3302 doing_unsigned ? UNSIGNED_FIX : FIX);
3304 convert_move (to, target, unsignedp);
3309 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
3310 /* For an unsigned conversion, there is one more way to do it.
3311 If we have a signed conversion, we generate code that compares
3312 the real value to the largest representable positive number. If if
3313 is smaller, the conversion is done normally. Otherwise, subtract
3314 one plus the highest signed number, convert, and add it back.
3316 We only need to check all real modes, since we know we didn't find
3317 anything with a wider integer mode. */
3319 if (unsignedp && GET_MODE_BITSIZE (GET_MODE (to)) <= HOST_BITS_PER_WIDE_INT)
3320 for (fmode = GET_MODE (from); fmode != VOIDmode;
3321 fmode = GET_MODE_WIDER_MODE (fmode))
3322 /* Make sure we won't lose significant bits doing this. */
3323 if (GET_MODE_BITSIZE (fmode) > GET_MODE_BITSIZE (GET_MODE (to))
3324 && CODE_FOR_nothing != can_fix_p (GET_MODE (to), fmode, 0,
3328 REAL_VALUE_TYPE offset;
3329 rtx limit, lab1, lab2, insn;
3331 bitsize = GET_MODE_BITSIZE (GET_MODE (to));
3332 offset = REAL_VALUE_LDEXP (dconst1, bitsize - 1);
3333 limit = CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode);
3334 lab1 = gen_label_rtx ();
3335 lab2 = gen_label_rtx ();
3338 to = protect_from_queue (to, 1);
3339 from = protect_from_queue (from, 0);
3342 from = force_not_mem (from);
3344 if (fmode != GET_MODE (from))
3345 from = convert_to_mode (fmode, from, 0);
3347 /* See if we need to do the subtraction. */
3348 do_pending_stack_adjust ();
3349 emit_cmp_insn (from, limit, GE, NULL_RTX, GET_MODE (from), 0, 0);
3350 emit_jump_insn (gen_bge (lab1));
3352 /* If not, do the signed "fix" and branch around fixup code. */
3353 expand_fix (to, from, 0);
3354 emit_jump_insn (gen_jump (lab2));
3357 /* Otherwise, subtract 2**(N-1), convert to signed number,
3358 then add 2**(N-1). Do the addition using XOR since this
3359 will often generate better code. */
3361 target = expand_binop (GET_MODE (from), sub_optab, from, limit,
3362 NULL_RTX, 0, OPTAB_LIB_WIDEN);
3363 expand_fix (to, target, 0);
3364 target = expand_binop (GET_MODE (to), xor_optab, to,
3365 GEN_INT ((HOST_WIDE_INT) 1 << (bitsize - 1)),
3366 to, 1, OPTAB_LIB_WIDEN);
3369 emit_move_insn (to, target);
3373 /* Make a place for a REG_NOTE and add it. */
3374 insn = emit_move_insn (to, to);
3375 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL,
3376 gen_rtx (UNSIGNED_FIX, GET_MODE (to),
3384 /* We can't do it with an insn, so use a library call. But first ensure
3385 that the mode of TO is at least as wide as SImode, since those are the
3386 only library calls we know about. */
3388 if (GET_MODE_SIZE (GET_MODE (to)) < GET_MODE_SIZE (SImode))
3390 target = gen_reg_rtx (SImode);
3392 expand_fix (target, from, unsignedp);
3394 else if (GET_MODE (from) == SFmode)
3396 if (GET_MODE (to) == SImode)
3397 libfcn = unsignedp ? fixunssfsi_libfunc : fixsfsi_libfunc;
3398 else if (GET_MODE (to) == DImode)
3399 libfcn = unsignedp ? fixunssfdi_libfunc : fixsfdi_libfunc;
3400 else if (GET_MODE (to) == TImode)
3401 libfcn = unsignedp ? fixunssfti_libfunc : fixsfti_libfunc;
3405 else if (GET_MODE (from) == DFmode)
3407 if (GET_MODE (to) == SImode)
3408 libfcn = unsignedp ? fixunsdfsi_libfunc : fixdfsi_libfunc;
3409 else if (GET_MODE (to) == DImode)
3410 libfcn = unsignedp ? fixunsdfdi_libfunc : fixdfdi_libfunc;
3411 else if (GET_MODE (to) == TImode)
3412 libfcn = unsignedp ? fixunsdfti_libfunc : fixdfti_libfunc;
3416 else if (GET_MODE (from) == XFmode)
3418 if (GET_MODE (to) == SImode)
3419 libfcn = unsignedp ? fixunsxfsi_libfunc : fixxfsi_libfunc;
3420 else if (GET_MODE (to) == DImode)
3421 libfcn = unsignedp ? fixunsxfdi_libfunc : fixxfdi_libfunc;
3422 else if (GET_MODE (to) == TImode)
3423 libfcn = unsignedp ? fixunsxfti_libfunc : fixxfti_libfunc;
3427 else if (GET_MODE (from) == TFmode)
3429 if (GET_MODE (to) == SImode)
3430 libfcn = unsignedp ? fixunstfsi_libfunc : fixtfsi_libfunc;
3431 else if (GET_MODE (to) == DImode)
3432 libfcn = unsignedp ? fixunstfdi_libfunc : fixtfdi_libfunc;
3433 else if (GET_MODE (to) == TImode)
3434 libfcn = unsignedp ? fixunstfti_libfunc : fixtfti_libfunc;
3445 to = protect_from_queue (to, 1);
3446 from = protect_from_queue (from, 0);
3449 from = force_not_mem (from);
3453 emit_library_call (libfcn, 1, GET_MODE (to), 1, from, GET_MODE (from));
3454 insns = get_insns ();
3457 emit_libcall_block (insns, target, hard_libcall_value (GET_MODE (to)),
3458 gen_rtx (unsignedp ? FIX : UNSIGNED_FIX,
3459 GET_MODE (to), from));
3462 if (GET_MODE (to) == GET_MODE (target))
3463 emit_move_insn (to, target);
3465 convert_move (to, target, 0);
3473 optab op = (optab) xmalloc (sizeof (struct optab));
3475 for (i = 0; i < NUM_MACHINE_MODES; i++)
3477 op->handlers[i].insn_code = CODE_FOR_nothing;
3478 op->handlers[i].libfunc = 0;
3481 if (code != UNKNOWN)
3482 code_to_optab[(int) code] = op;
3487 /* Initialize the libfunc fields of an entire group of entries in some
3488 optab. Each entry is set equal to a string consisting of a leading
3489 pair of underscores followed by a generic operation name followed by
3490 a mode name (downshifted to lower case) followed by a single character
3491 representing the number of operands for the given operation (which is
3492 usually one of the characters '2', '3', or '4').
3494 OPTABLE is the table in which libfunc fields are to be initialized.
3495 FIRST_MODE is the first machine mode index in the given optab to
3497 LAST_MODE is the last machine mode index in the given optab to
3499 OPNAME is the generic (string) name of the operation.
3500 SUFFIX is the character which specifies the number of operands for
3501 the given generic operation.
3505 init_libfuncs (optable, first_mode, last_mode, opname, suffix)
3506 register optab optable;
3507 register int first_mode;
3508 register int last_mode;
3509 register char *opname;
3510 register char suffix;
3513 register unsigned opname_len = strlen (opname);
3515 for (mode = first_mode; (int) mode <= (int) last_mode;
3516 mode = (enum machine_mode) ((int) mode + 1))
3518 register char *mname = mode_name[(int) mode];
3519 register unsigned mname_len = strlen (mname);
3520 register char *libfunc_name
3521 = (char *) xmalloc (2 + opname_len + mname_len + 1 + 1);
3528 for (q = opname; *q; )
3530 for (q = mname; *q; q++)
3531 *p++ = tolower (*q);
3534 optable->handlers[(int) mode].libfunc
3535 = gen_rtx (SYMBOL_REF, Pmode, libfunc_name);
3539 /* Initialize the libfunc fields of an entire group of entries in some
3540 optab which correspond to all integer mode operations. The parameters
3541 have the same meaning as similarly named ones for the `init_libfuncs'
3542 routine. (See above). */
3545 init_integral_libfuncs (optable, opname, suffix)
3546 register optab optable;
3547 register char *opname;
3548 register char suffix;
3550 init_libfuncs (optable, SImode, TImode, opname, suffix);
3553 /* Initialize the libfunc fields of an entire group of entries in some
3554 optab which correspond to all real mode operations. The parameters
3555 have the same meaning as similarly named ones for the `init_libfuncs'
3556 routine. (See above). */
3559 init_floating_libfuncs (optable, opname, suffix)
3560 register optab optable;
3561 register char *opname;
3562 register char suffix;
3564 init_libfuncs (optable, SFmode, TFmode, opname, suffix);
3567 /* Initialize the libfunc fields of an entire group of entries in some
3568 optab which correspond to all complex floating modes. The parameters
3569 have the same meaning as similarly named ones for the `init_libfuncs'
3570 routine. (See above). */
3573 init_complex_libfuncs (optable, opname, suffix)
3574 register optab optable;
3575 register char *opname;
3576 register char suffix;
3578 init_libfuncs (optable, SCmode, TCmode, opname, suffix);
3581 /* Call this once to initialize the contents of the optabs
3582 appropriately for the current target machine. */
3590 /* Start by initializing all tables to contain CODE_FOR_nothing. */
3592 for (p = fixtab[0][0];
3593 p < fixtab[0][0] + sizeof fixtab / sizeof (fixtab[0][0][0]);
3595 *p = CODE_FOR_nothing;
3597 for (p = fixtrunctab[0][0];
3598 p < fixtrunctab[0][0] + sizeof fixtrunctab / sizeof (fixtrunctab[0][0][0]);
3600 *p = CODE_FOR_nothing;
3602 for (p = floattab[0][0];
3603 p < floattab[0][0] + sizeof floattab / sizeof (floattab[0][0][0]);
3605 *p = CODE_FOR_nothing;
3607 for (p = extendtab[0][0];
3608 p < extendtab[0][0] + sizeof extendtab / sizeof extendtab[0][0][0];
3610 *p = CODE_FOR_nothing;
3612 for (i = 0; i < NUM_RTX_CODE; i++)
3613 setcc_gen_code[i] = CODE_FOR_nothing;
3615 add_optab = init_optab (PLUS);
3616 sub_optab = init_optab (MINUS);
3617 smul_optab = init_optab (MULT);
3618 smul_widen_optab = init_optab (UNKNOWN);
3619 umul_widen_optab = init_optab (UNKNOWN);
3620 sdiv_optab = init_optab (DIV);
3621 sdivmod_optab = init_optab (UNKNOWN);
3622 udiv_optab = init_optab (UDIV);
3623 udivmod_optab = init_optab (UNKNOWN);
3624 smod_optab = init_optab (MOD);
3625 umod_optab = init_optab (UMOD);
3626 flodiv_optab = init_optab (DIV);
3627 ftrunc_optab = init_optab (UNKNOWN);
3628 and_optab = init_optab (AND);
3629 ior_optab = init_optab (IOR);
3630 xor_optab = init_optab (XOR);
3631 ashl_optab = init_optab (ASHIFT);
3632 ashr_optab = init_optab (ASHIFTRT);
3633 lshr_optab = init_optab (LSHIFTRT);
3634 rotl_optab = init_optab (ROTATE);
3635 rotr_optab = init_optab (ROTATERT);
3636 smin_optab = init_optab (SMIN);
3637 smax_optab = init_optab (SMAX);
3638 umin_optab = init_optab (UMIN);
3639 umax_optab = init_optab (UMAX);
3640 mov_optab = init_optab (UNKNOWN);
3641 movstrict_optab = init_optab (UNKNOWN);
3642 cmp_optab = init_optab (UNKNOWN);
3643 ucmp_optab = init_optab (UNKNOWN);
3644 tst_optab = init_optab (UNKNOWN);
3645 neg_optab = init_optab (NEG);
3646 abs_optab = init_optab (ABS);
3647 one_cmpl_optab = init_optab (NOT);
3648 ffs_optab = init_optab (FFS);
3649 sqrt_optab = init_optab (SQRT);
3650 sin_optab = init_optab (UNKNOWN);
3651 cos_optab = init_optab (UNKNOWN);
3652 strlen_optab = init_optab (UNKNOWN);
3654 for (i = 0; i < NUM_MACHINE_MODES; i++)
3656 movstr_optab[i] = CODE_FOR_nothing;
3658 #ifdef HAVE_SECONDARY_RELOADS
3659 reload_in_optab[i] = reload_out_optab[i] = CODE_FOR_nothing;
3663 /* Fill in the optabs with the insns we support. */
3666 #ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC
3667 /* This flag says the same insns that convert to a signed fixnum
3668 also convert validly to an unsigned one. */
3669 for (i = 0; i < NUM_MACHINE_MODES; i++)
3670 for (j = 0; j < NUM_MACHINE_MODES; j++)
3671 fixtrunctab[i][j][1] = fixtrunctab[i][j][0];
3674 #ifdef EXTRA_CC_MODES
3678 /* Initialize the optabs with the names of the library functions. */
3679 init_integral_libfuncs (add_optab, "add", '3');
3680 init_floating_libfuncs (add_optab, "add", '3');
3681 init_integral_libfuncs (sub_optab, "sub", '3');
3682 init_floating_libfuncs (sub_optab, "sub", '3');
3683 init_integral_libfuncs (smul_optab, "mul", '3');
3684 init_floating_libfuncs (smul_optab, "mul", '3');
3685 init_integral_libfuncs (sdiv_optab, "div", '3');
3686 init_integral_libfuncs (udiv_optab, "udiv", '3');
3687 init_integral_libfuncs (sdivmod_optab, "divmod", '4');
3688 init_integral_libfuncs (udivmod_optab, "udivmod", '4');
3689 init_integral_libfuncs (smod_optab, "mod", '3');
3690 init_integral_libfuncs (umod_optab, "umod", '3');
3691 init_floating_libfuncs (flodiv_optab, "div", '3');
3692 init_floating_libfuncs (ftrunc_optab, "ftrunc", '2');
3693 init_integral_libfuncs (and_optab, "and", '3');
3694 init_integral_libfuncs (ior_optab, "ior", '3');
3695 init_integral_libfuncs (xor_optab, "xor", '3');
3696 init_integral_libfuncs (ashl_optab, "ashl", '3');
3697 init_integral_libfuncs (ashr_optab, "ashr", '3');
3698 init_integral_libfuncs (lshr_optab, "lshr", '3');
3699 init_integral_libfuncs (rotl_optab, "rotl", '3');
3700 init_integral_libfuncs (rotr_optab, "rotr", '3');
3701 init_integral_libfuncs (smin_optab, "min", '3');
3702 init_floating_libfuncs (smin_optab, "min", '3');
3703 init_integral_libfuncs (smax_optab, "max", '3');
3704 init_floating_libfuncs (smax_optab, "max", '3');
3705 init_integral_libfuncs (umin_optab, "umin", '3');
3706 init_integral_libfuncs (umax_optab, "umax", '3');
3707 init_integral_libfuncs (neg_optab, "neg", '2');
3708 init_floating_libfuncs (neg_optab, "neg", '2');
3709 init_integral_libfuncs (one_cmpl_optab, "one_cmpl", '2');
3710 init_integral_libfuncs (ffs_optab, "ffs", '2');
3712 /* Comparison libcalls for integers MUST come in pairs, signed/unsigned. */
3713 init_integral_libfuncs (cmp_optab, "cmp", '2');
3714 init_integral_libfuncs (ucmp_optab, "ucmp", '2');
3715 init_floating_libfuncs (cmp_optab, "cmp", '2');
3717 #ifdef MULSI3_LIBCALL
3718 smul_optab->handlers[(int) SImode].libfunc
3719 = gen_rtx (SYMBOL_REF, Pmode, MULSI3_LIBCALL);
3721 #ifdef MULDI3_LIBCALL
3722 smul_optab->handlers[(int) DImode].libfunc
3723 = gen_rtx (SYMBOL_REF, Pmode, MULDI3_LIBCALL);
3725 #ifdef MULTI3_LIBCALL
3726 smul_optab->handlers[(int) TImode].libfunc
3727 = gen_rtx (SYMBOL_REF, Pmode, MULTI3_LIBCALL);
3730 #ifdef DIVSI3_LIBCALL
3731 sdiv_optab->handlers[(int) SImode].libfunc
3732 = gen_rtx (SYMBOL_REF, Pmode, DIVSI3_LIBCALL);
3734 #ifdef DIVDI3_LIBCALL
3735 sdiv_optab->handlers[(int) DImode].libfunc
3736 = gen_rtx (SYMBOL_REF, Pmode, DIVDI3_LIBCALL);
3738 #ifdef DIVTI3_LIBCALL
3739 sdiv_optab->handlers[(int) TImode].libfunc
3740 = gen_rtx (SYMBOL_REF, Pmode, DIVTI3_LIBCALL);
3743 #ifdef UDIVSI3_LIBCALL
3744 udiv_optab->handlers[(int) SImode].libfunc
3745 = gen_rtx (SYMBOL_REF, Pmode, UDIVSI3_LIBCALL);
3747 #ifdef UDIVDI3_LIBCALL
3748 udiv_optab->handlers[(int) DImode].libfunc
3749 = gen_rtx (SYMBOL_REF, Pmode, UDIVDI3_LIBCALL);
3751 #ifdef UDIVTI3_LIBCALL
3752 udiv_optab->handlers[(int) TImode].libfunc
3753 = gen_rtx (SYMBOL_REF, Pmode, UDIVTI3_LIBCALL);
3757 #ifdef MODSI3_LIBCALL
3758 smod_optab->handlers[(int) SImode].libfunc
3759 = gen_rtx (SYMBOL_REF, Pmode, MODSI3_LIBCALL);
3761 #ifdef MODDI3_LIBCALL
3762 smod_optab->handlers[(int) DImode].libfunc
3763 = gen_rtx (SYMBOL_REF, Pmode, MODDI3_LIBCALL);
3765 #ifdef MODTI3_LIBCALL
3766 smod_optab->handlers[(int) TImode].libfunc
3767 = gen_rtx (SYMBOL_REF, Pmode, MODTI3_LIBCALL);
3771 #ifdef UMODSI3_LIBCALL
3772 umod_optab->handlers[(int) SImode].libfunc
3773 = gen_rtx (SYMBOL_REF, Pmode, UMODSI3_LIBCALL);
3775 #ifdef UMODDI3_LIBCALL
3776 umod_optab->handlers[(int) DImode].libfunc
3777 = gen_rtx (SYMBOL_REF, Pmode, UMODDI3_LIBCALL);
3779 #ifdef UMODTI3_LIBCALL
3780 umod_optab->handlers[(int) TImode].libfunc
3781 = gen_rtx (SYMBOL_REF, Pmode, UMODTI3_LIBCALL);
3784 /* Define library calls for quad FP instructions */
3785 #ifdef ADDTF3_LIBCALL
3786 add_optab->handlers[(int) TFmode].libfunc
3787 = gen_rtx (SYMBOL_REF, Pmode, ADDTF3_LIBCALL);
3789 #ifdef SUBTF3_LIBCALL
3790 sub_optab->handlers[(int) TFmode].libfunc
3791 = gen_rtx (SYMBOL_REF, Pmode, SUBTF3_LIBCALL);
3793 #ifdef MULTF3_LIBCALL
3794 smul_optab->handlers[(int) TFmode].libfunc
3795 = gen_rtx (SYMBOL_REF, Pmode, MULTF3_LIBCALL);
3797 #ifdef DIVTF3_LIBCALL
3798 flodiv_optab->handlers[(int) TFmode].libfunc
3799 = gen_rtx (SYMBOL_REF, Pmode, DIVTF3_LIBCALL);
3801 #ifdef SQRTTF2_LIBCALL
3802 sqrt_optab->handlers[(int) TFmode].libfunc
3803 = gen_rtx (SYMBOL_REF, Pmode, SQRTTF2_LIBCALL);
3806 /* Use cabs for DC complex abs, since systems generally have cabs.
3807 Don't define any libcall for SCmode, so that cabs will be used. */
3808 abs_optab->handlers[(int) DCmode].libfunc
3809 = gen_rtx (SYMBOL_REF, Pmode, "cabs");
3811 /* The ffs function operates on `int'. */
3812 #ifndef INT_TYPE_SIZE
3813 #define INT_TYPE_SIZE BITS_PER_WORD
3815 ffs_optab->handlers[(int) mode_for_size (INT_TYPE_SIZE, MODE_INT, 0)] .libfunc
3816 = gen_rtx (SYMBOL_REF, Pmode, "ffs");
3818 extendsfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extendsfdf2");
3819 extendsfxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extendsfxf2");
3820 extendsftf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extendsftf2");
3821 extenddfxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extenddfxf2");
3822 extenddftf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extenddftf2");
3824 truncdfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__truncdfsf2");
3825 truncxfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__truncxfsf2");
3826 trunctfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__trunctfsf2");
3827 truncxfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__truncxfdf2");
3828 trunctfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__trunctfdf2");
3830 memcpy_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memcpy");
3831 bcopy_libfunc = gen_rtx (SYMBOL_REF, Pmode, "bcopy");
3832 memcmp_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memcmp");
3833 bcmp_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gcc_bcmp");
3834 memset_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memset");
3835 bzero_libfunc = gen_rtx (SYMBOL_REF, Pmode, "bzero");
3837 eqsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqsf2");
3838 nesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nesf2");
3839 gtsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtsf2");
3840 gesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gesf2");
3841 ltsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltsf2");
3842 lesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lesf2");
3844 eqdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqdf2");
3845 nedf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nedf2");
3846 gtdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtdf2");
3847 gedf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gedf2");
3848 ltdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltdf2");
3849 ledf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ledf2");
3851 eqxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqxf2");
3852 nexf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nexf2");
3853 gtxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtxf2");
3854 gexf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gexf2");
3855 ltxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltxf2");
3856 lexf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lexf2");
3858 eqtf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqtf2");
3859 netf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__netf2");
3860 gttf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gttf2");
3861 getf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__getf2");
3862 lttf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lttf2");
3863 letf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__letf2");
3865 /* Define library calls for quad FP instructions */
3866 #ifdef EQTF2_LIBCALL
3867 eqtf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, EQTF2_LIBCALL);
3869 #ifdef NETF2_LIBCALL
3870 netf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, NETF2_LIBCALL);
3872 #ifdef GTTF2_LIBCALL
3873 gttf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, GTTF2_LIBCALL);
3875 #ifdef GETF2_LIBCALL
3876 getf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, GETF2_LIBCALL);
3878 #ifdef LTTF2_LIBCALL
3879 lttf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, LTTF2_LIBCALL);
3881 #ifdef LETF2_LIBCALL
3882 letf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, LETF2_LIBCALL);
3885 floatsisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsisf");
3886 floatdisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatdisf");
3887 floattisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattisf");
3889 floatsidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsidf");
3890 floatdidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatdidf");
3891 floattidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattidf");
3893 floatsixf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsixf");
3894 floatdixf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatdixf");
3895 floattixf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattixf");
3897 floatsitf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsitf");
3898 floatditf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatditf");
3899 floattitf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattitf");
3901 fixsfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixsfsi");
3902 fixsfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixsfdi");
3903 fixsfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixsfti");
3905 fixdfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixdfsi");
3906 fixdfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixdfdi");
3907 fixdfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixdfti");
3909 fixxfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixxfsi");
3910 fixxfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixxfdi");
3911 fixxfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixxfti");
3913 fixtfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixtfsi");
3914 fixtfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixtfdi");
3915 fixtfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixtfti");
3917 fixunssfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunssfsi");
3918 fixunssfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunssfdi");
3919 fixunssfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunssfti");
3921 fixunsdfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsdfsi");
3922 fixunsdfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsdfdi");
3923 fixunsdfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsdfti");
3925 fixunsxfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsxfsi");
3926 fixunsxfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsxfdi");
3927 fixunsxfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsxfti");
3929 fixunstfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunstfsi");
3930 fixunstfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunstfdi");
3931 fixunstfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunstfti");
3933 /* Define library calls for quad FP instructions */
3934 #ifdef TRUNCTFSF2_LIBCALL
3935 trunctfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, TRUNCTFSF2_LIBCALL);
3937 #ifdef TRUNCTFDF2_LIBCALL
3938 trunctfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, TRUNCTFDF2_LIBCALL);
3940 #ifdef EXTENDSFTF2_LIBCALL
3941 extendsftf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, EXTENDSFTF2_LIBCALL);
3943 #ifdef EXTENDDFTF2_LIBCALL
3944 extenddftf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, EXTENDDFTF2_LIBCALL);
3946 #ifdef FLOATSITF2_LIBCALL
3947 floatsitf_libfunc = gen_rtx (SYMBOL_REF, Pmode, FLOATSITF2_LIBCALL);
3949 #ifdef FIX_TRUNCTFSI2_LIBCALL
3950 fixtfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, FIX_TRUNCTFSI2_LIBCALL);
3952 #ifdef FIXUNS_TRUNCTFSI2_LIBCALL
3953 fixunstfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, FIXUNS_TRUNCTFSI2_LIBCALL);
3959 /* SCO 3.2 apparently has a broken ldexp. */
3972 #endif /* BROKEN_LDEXP */