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;
70 optab movstrict_optab;
81 optab ucmp_optab; /* Used only for libcalls for unsigned comparisons. */
86 /* Tables of patterns for extending one integer mode to another. */
87 enum insn_code extendtab[MAX_MACHINE_MODE][MAX_MACHINE_MODE][2];
89 /* Tables of patterns for converting between fixed and floating point. */
90 enum insn_code fixtab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
91 enum insn_code fixtrunctab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
92 enum insn_code floattab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
94 /* Contains the optab used for each rtx code. */
95 optab code_to_optab[NUM_RTX_CODE + 1];
97 /* SYMBOL_REF rtx's for the library functions that are called
98 implicitly and not via optabs. */
100 rtx extendsfdf2_libfunc;
101 rtx extendsfxf2_libfunc;
102 rtx extendsftf2_libfunc;
103 rtx extenddfxf2_libfunc;
104 rtx extenddftf2_libfunc;
106 rtx truncdfsf2_libfunc;
107 rtx truncxfsf2_libfunc;
108 rtx trunctfsf2_libfunc;
109 rtx truncxfdf2_libfunc;
110 rtx trunctfdf2_libfunc;
147 rtx floatsisf_libfunc;
148 rtx floatdisf_libfunc;
149 rtx floattisf_libfunc;
151 rtx floatsidf_libfunc;
152 rtx floatdidf_libfunc;
153 rtx floattidf_libfunc;
155 rtx floatsixf_libfunc;
156 rtx floatdixf_libfunc;
157 rtx floattixf_libfunc;
159 rtx floatsitf_libfunc;
160 rtx floatditf_libfunc;
161 rtx floattitf_libfunc;
179 rtx fixunssfsi_libfunc;
180 rtx fixunssfdi_libfunc;
181 rtx fixunssfti_libfunc;
183 rtx fixunsdfsi_libfunc;
184 rtx fixunsdfdi_libfunc;
185 rtx fixunsdfti_libfunc;
187 rtx fixunsxfsi_libfunc;
188 rtx fixunsxfdi_libfunc;
189 rtx fixunsxfti_libfunc;
191 rtx fixunstfsi_libfunc;
192 rtx fixunstfdi_libfunc;
193 rtx fixunstfti_libfunc;
195 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
196 gives the gen_function to make a branch to test that condition. */
198 rtxfun bcc_gen_fctn[NUM_RTX_CODE];
200 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
201 gives the insn code to make a store-condition insn
202 to test that condition. */
204 enum insn_code setcc_gen_code[NUM_RTX_CODE];
206 static int add_equal_note PROTO((rtx, rtx, enum rtx_code, rtx, rtx));
207 static rtx widen_operand PROTO((rtx, enum machine_mode,
208 enum machine_mode, int, int));
209 static enum insn_code can_fix_p PROTO((enum machine_mode, enum machine_mode,
211 static enum insn_code can_float_p PROTO((enum machine_mode, enum machine_mode,
213 static rtx ftruncify PROTO((rtx));
214 static optab init_optab PROTO((enum rtx_code));
215 static void init_libfuncs PROTO((optab, int, int, char *, int));
216 static void init_integral_libfuncs PROTO((optab, char *, int));
217 static void init_floating_libfuncs PROTO((optab, char *, int));
218 static void init_complex_libfuncs PROTO((optab, char *, int));
220 /* Add a REG_EQUAL note to the last insn in SEQ. TARGET is being set to
221 the result of operation CODE applied to OP0 (and OP1 if it is a binary
224 If the last insn does not set TARGET, don't do anything, but return 1.
226 If a previous insn sets TARGET and TARGET is one of OP0 or OP1,
227 don't add the REG_EQUAL note but return 0. Our caller can then try
228 again, ensuring that TARGET is not one of the operands. */
231 add_equal_note (seq, target, code, op0, op1)
241 if ((GET_RTX_CLASS (code) != '1' && GET_RTX_CLASS (code) != '2'
242 && GET_RTX_CLASS (code) != 'c' && GET_RTX_CLASS (code) != '<')
243 || GET_CODE (seq) != SEQUENCE
244 || (set = single_set (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1))) == 0
245 || GET_CODE (target) == ZERO_EXTRACT
246 || (! rtx_equal_p (SET_DEST (set), target)
247 /* For a STRICT_LOW_PART, the REG_NOTE applies to what is inside the
249 && (GET_CODE (SET_DEST (set)) != STRICT_LOW_PART
250 || ! rtx_equal_p (SUBREG_REG (XEXP (SET_DEST (set), 0)),
254 /* If TARGET is in OP0 or OP1, check if anything in SEQ sets TARGET
255 besides the last insn. */
256 if (reg_overlap_mentioned_p (target, op0)
257 || (op1 && reg_overlap_mentioned_p (target, op1)))
258 for (i = XVECLEN (seq, 0) - 2; i >= 0; i--)
259 if (reg_set_p (target, XVECEXP (seq, 0, i)))
262 if (GET_RTX_CLASS (code) == '1')
263 note = gen_rtx (code, GET_MODE (target), copy_rtx (op0));
265 note = gen_rtx (code, GET_MODE (target), copy_rtx (op0), copy_rtx (op1));
267 REG_NOTES (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1))
268 = gen_rtx (EXPR_LIST, REG_EQUAL, note,
269 REG_NOTES (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1)));
274 /* Widen OP to MODE and return the rtx for the widened operand. UNSIGNEDP
275 says whether OP is signed or unsigned. NO_EXTEND is nonzero if we need
276 not actually do a sign-extend or zero-extend, but can leave the
277 higher-order bits of the result rtx undefined, for example, in the case
278 of logical operations, but not right shifts. */
281 widen_operand (op, mode, oldmode, unsignedp, no_extend)
283 enum machine_mode mode, oldmode;
289 /* If we must extend do so. If OP is either a constant or a SUBREG
290 for a promoted object, also extend since it will be more efficient to
293 || GET_MODE (op) == VOIDmode
294 || (GET_CODE (op) == SUBREG && SUBREG_PROMOTED_VAR_P (op)))
295 return convert_modes (mode, oldmode, op, unsignedp);
297 /* If MODE is no wider than a single word, we return a paradoxical
299 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
300 return gen_rtx (SUBREG, mode, force_reg (GET_MODE (op), op), 0);
302 /* Otherwise, get an object of MODE, clobber it, and set the low-order
305 result = gen_reg_rtx (mode);
306 emit_insn (gen_rtx (CLOBBER, VOIDmode, result));
307 emit_move_insn (gen_lowpart (GET_MODE (op), result), op);
311 /* Generate code to perform an operation specified by BINOPTAB
312 on operands OP0 and OP1, with result having machine-mode MODE.
314 UNSIGNEDP is for the case where we have to widen the operands
315 to perform the operation. It says to use zero-extension.
317 If TARGET is nonzero, the value
318 is generated there, if it is convenient to do so.
319 In all cases an rtx is returned for the locus of the value;
320 this may or may not be TARGET. */
323 expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods)
324 enum machine_mode mode;
329 enum optab_methods methods;
331 enum mode_class class;
332 enum machine_mode wider_mode;
334 int commutative_op = 0;
335 int shift_op = (binoptab->code == ASHIFT
336 || binoptab->code == ASHIFTRT
337 || binoptab->code == LSHIFT
338 || binoptab->code == LSHIFTRT
339 || binoptab->code == ROTATE
340 || binoptab->code == ROTATERT);
341 rtx entry_last = get_last_insn ();
344 class = GET_MODE_CLASS (mode);
346 op0 = protect_from_queue (op0, 0);
347 op1 = protect_from_queue (op1, 0);
349 target = protect_from_queue (target, 1);
353 op0 = force_not_mem (op0);
354 op1 = force_not_mem (op1);
357 /* If subtracting an integer constant, convert this into an addition of
358 the negated constant. */
360 if (binoptab == sub_optab && GET_CODE (op1) == CONST_INT)
362 op1 = negate_rtx (mode, op1);
363 binoptab = add_optab;
366 /* If we are inside an appropriately-short loop and one operand is an
367 expensive constant, force it into a register. */
368 if (CONSTANT_P (op0) && preserve_subexpressions_p ()
369 && rtx_cost (op0, binoptab->code) > 2)
370 op0 = force_reg (mode, op0);
372 if (CONSTANT_P (op1) && preserve_subexpressions_p ()
373 && rtx_cost (op1, binoptab->code) > 2)
374 op1 = force_reg (shift_op ? word_mode : mode, op1);
376 /* Record where to delete back to if we backtrack. */
377 last = get_last_insn ();
379 /* If operation is commutative,
380 try to make the first operand a register.
381 Even better, try to make it the same as the target.
382 Also try to make the last operand a constant. */
383 if (GET_RTX_CLASS (binoptab->code) == 'c'
384 || binoptab == smul_widen_optab
385 || binoptab == umul_widen_optab)
389 if (((target == 0 || GET_CODE (target) == REG)
390 ? ((GET_CODE (op1) == REG
391 && GET_CODE (op0) != REG)
393 : rtx_equal_p (op1, target))
394 || GET_CODE (op0) == CONST_INT)
402 /* If we can do it with a three-operand insn, do so. */
404 if (methods != OPTAB_MUST_WIDEN
405 && binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
407 int icode = (int) binoptab->handlers[(int) mode].insn_code;
408 enum machine_mode mode0 = insn_operand_mode[icode][1];
409 enum machine_mode mode1 = insn_operand_mode[icode][2];
411 rtx xop0 = op0, xop1 = op1;
416 temp = gen_reg_rtx (mode);
418 /* If it is a commutative operator and the modes would match
419 if we would swap the operands, we can save the conversions. */
422 if (GET_MODE (op0) != mode0 && GET_MODE (op1) != mode1
423 && GET_MODE (op0) == mode1 && GET_MODE (op1) == mode0)
427 tmp = op0; op0 = op1; op1 = tmp;
428 tmp = xop0; xop0 = xop1; xop1 = tmp;
432 /* In case the insn wants input operands in modes different from
433 the result, convert the operands. */
435 if (GET_MODE (op0) != VOIDmode
436 && GET_MODE (op0) != mode0)
437 xop0 = convert_to_mode (mode0, xop0, unsignedp);
439 if (GET_MODE (xop1) != VOIDmode
440 && GET_MODE (xop1) != mode1)
441 xop1 = convert_to_mode (mode1, xop1, unsignedp);
443 /* Now, if insn's predicates don't allow our operands, put them into
446 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
447 xop0 = copy_to_mode_reg (mode0, xop0);
449 if (! (*insn_operand_predicate[icode][2]) (xop1, mode1))
450 xop1 = copy_to_mode_reg (mode1, xop1);
452 if (! (*insn_operand_predicate[icode][0]) (temp, mode))
453 temp = gen_reg_rtx (mode);
455 pat = GEN_FCN (icode) (temp, xop0, xop1);
458 /* If PAT is a multi-insn sequence, try to add an appropriate
459 REG_EQUAL note to it. If we can't because TEMP conflicts with an
460 operand, call ourselves again, this time without a target. */
461 if (GET_CODE (pat) == SEQUENCE
462 && ! add_equal_note (pat, temp, binoptab->code, xop0, xop1))
464 delete_insns_since (last);
465 return expand_binop (mode, binoptab, op0, op1, NULL_RTX,
473 delete_insns_since (last);
476 /* If this is a multiply, see if we can do a widening operation that
477 takes operands of this mode and makes a wider mode. */
479 if (binoptab == smul_optab && GET_MODE_WIDER_MODE (mode) != VOIDmode
480 && (((unsignedp ? umul_widen_optab : smul_widen_optab)
481 ->handlers[(int) GET_MODE_WIDER_MODE (mode)].insn_code)
482 != CODE_FOR_nothing))
484 temp = expand_binop (GET_MODE_WIDER_MODE (mode),
485 unsignedp ? umul_widen_optab : smul_widen_optab,
486 op0, op1, 0, unsignedp, OPTAB_DIRECT);
488 if (GET_MODE_CLASS (mode) == MODE_INT)
489 return gen_lowpart (mode, temp);
491 return convert_to_mode (mode, temp, unsignedp);
494 /* Look for a wider mode of the same class for which we think we
495 can open-code the operation. Check for a widening multiply at the
496 wider mode as well. */
498 if ((class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
499 && methods != OPTAB_DIRECT && methods != OPTAB_LIB)
500 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
501 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
503 if (binoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing
504 || (binoptab == smul_optab
505 && GET_MODE_WIDER_MODE (wider_mode) != VOIDmode
506 && (((unsignedp ? umul_widen_optab : smul_widen_optab)
507 ->handlers[(int) GET_MODE_WIDER_MODE (wider_mode)].insn_code)
508 != CODE_FOR_nothing)))
510 rtx xop0 = op0, xop1 = op1;
513 /* For certain integer operations, we need not actually extend
514 the narrow operands, as long as we will truncate
515 the results to the same narrowness. */
517 if ((binoptab == ior_optab || binoptab == and_optab
518 || binoptab == xor_optab
519 || binoptab == add_optab || binoptab == sub_optab
520 || binoptab == smul_optab
521 || binoptab == ashl_optab || binoptab == lshl_optab)
522 && class == MODE_INT)
525 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp, no_extend);
527 /* The second operand of a shift must always be extended. */
528 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
529 no_extend && binoptab != ashl_optab
530 && binoptab != lshl_optab);
532 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
533 unsignedp, OPTAB_DIRECT);
536 if (class != MODE_INT)
539 target = gen_reg_rtx (mode);
540 convert_move (target, temp, 0);
544 return gen_lowpart (mode, temp);
547 delete_insns_since (last);
551 /* These can be done a word at a time. */
552 if ((binoptab == and_optab || binoptab == ior_optab || binoptab == xor_optab)
554 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
555 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
561 /* If TARGET is the same as one of the operands, the REG_EQUAL note
562 won't be accurate, so use a new target. */
563 if (target == 0 || target == op0 || target == op1)
564 target = gen_reg_rtx (mode);
568 /* Do the actual arithmetic. */
569 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
571 rtx target_piece = operand_subword (target, i, 1, mode);
572 rtx x = expand_binop (word_mode, binoptab,
573 operand_subword_force (op0, i, mode),
574 operand_subword_force (op1, i, mode),
575 target_piece, unsignedp, methods);
576 if (target_piece != x)
577 emit_move_insn (target_piece, x);
580 insns = get_insns ();
583 if (binoptab->code != UNKNOWN)
585 = gen_rtx (binoptab->code, mode, copy_rtx (op0), copy_rtx (op1));
589 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
593 /* Synthesize double word shifts from single word shifts. */
594 if ((binoptab == lshl_optab || binoptab == lshr_optab
595 || binoptab == ashl_optab || binoptab == ashr_optab)
597 && GET_CODE (op1) == CONST_INT
598 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
599 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
600 && ashl_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
601 && lshr_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
603 rtx insns, equiv_value;
604 rtx into_target, outof_target;
605 rtx into_input, outof_input;
606 int shift_count, left_shift, outof_word;
608 /* If TARGET is the same as one of the operands, the REG_EQUAL note
609 won't be accurate, so use a new target. */
610 if (target == 0 || target == op0 || target == op1)
611 target = gen_reg_rtx (mode);
615 shift_count = INTVAL (op1);
617 /* OUTOF_* is the word we are shifting bits away from, and
618 INTO_* is the word that we are shifting bits towards, thus
619 they differ depending on the direction of the shift and
622 left_shift = (binoptab == ashl_optab || binoptab == lshl_optab);
623 outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
625 outof_target = operand_subword (target, outof_word, 1, mode);
626 into_target = operand_subword (target, 1 - outof_word, 1, mode);
628 outof_input = operand_subword_force (op0, outof_word, mode);
629 into_input = operand_subword_force (op0, 1 - outof_word, mode);
631 if (shift_count >= BITS_PER_WORD)
633 emit_move_insn (into_target,
634 expand_binop (word_mode, binoptab,
636 GEN_INT (shift_count - BITS_PER_WORD),
637 into_target, unsignedp, methods));
639 /* For a signed right shift, we must fill the word we are shifting
640 out of with copies of the sign bit. Otherwise it is zeroed. */
641 if (binoptab != ashr_optab)
642 emit_move_insn (outof_target, CONST0_RTX (word_mode));
644 emit_move_insn (outof_target,
645 expand_binop (word_mode, binoptab,
647 GEN_INT (BITS_PER_WORD - 1),
648 outof_target, unsignedp, methods));
652 rtx carries, into_temp;
653 optab reverse_unsigned_shift, unsigned_shift;
655 /* For a shift of less then BITS_PER_WORD, to compute the carry,
656 we must do a logical shift in the opposite direction of the
659 /* We use ashl_optab instead of lshl_optab, because ashl is
660 guaranteed to exist, but lshl may or may not exist. */
662 reverse_unsigned_shift = (left_shift ? lshr_optab : ashl_optab);
664 /* For a shift of less than BITS_PER_WORD, to compute the word
665 shifted towards, we need to unsigned shift the orig value of
668 unsigned_shift = (left_shift ? ashl_optab : lshr_optab);
670 carries = expand_binop (word_mode, reverse_unsigned_shift,
672 GEN_INT (BITS_PER_WORD - shift_count),
673 0, unsignedp, methods);
675 emit_move_insn (outof_target,
676 expand_binop (word_mode, binoptab,
678 op1, outof_target, unsignedp, methods));
679 into_temp = expand_binop (word_mode, unsigned_shift,
681 op1, 0, unsignedp, methods);
683 emit_move_insn (into_target,
684 expand_binop (word_mode, ior_optab,
686 into_target, unsignedp, methods));
689 insns = get_insns ();
692 if (binoptab->code != UNKNOWN)
693 equiv_value = gen_rtx (binoptab->code, mode, op0, op1);
697 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
701 /* Synthesize double word rotates from single word shifts. */
702 if ((binoptab == rotl_optab || binoptab == rotr_optab)
704 && GET_CODE (op1) == CONST_INT
705 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
706 && ashl_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
707 && lshr_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
709 rtx insns, equiv_value;
710 rtx into_target, outof_target;
711 rtx into_input, outof_input;
712 int shift_count, left_shift, outof_word;
714 /* If TARGET is the same as one of the operands, the REG_EQUAL note
715 won't be accurate, so use a new target. */
716 if (target == 0 || target == op0 || target == op1)
717 target = gen_reg_rtx (mode);
721 shift_count = INTVAL (op1);
723 /* OUTOF_* is the word we are shifting bits away from, and
724 INTO_* is the word that we are shifting bits towards, thus
725 they differ depending on the direction of the shift and
728 left_shift = (binoptab == rotl_optab);
729 outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
731 outof_target = operand_subword (target, outof_word, 1, mode);
732 into_target = operand_subword (target, 1 - outof_word, 1, mode);
734 outof_input = operand_subword_force (op0, outof_word, mode);
735 into_input = operand_subword_force (op0, 1 - outof_word, mode);
737 if (shift_count == BITS_PER_WORD)
739 /* This is just a word swap. */
740 emit_move_insn (outof_target, into_input);
741 emit_move_insn (into_target, outof_input);
745 rtx into_temp1, into_temp2, outof_temp1, outof_temp2;
746 rtx first_shift_count, second_shift_count;
747 optab reverse_unsigned_shift, unsigned_shift;
749 reverse_unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
750 ? lshr_optab : ashl_optab);
752 unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
753 ? ashl_optab : lshr_optab);
755 if (shift_count > BITS_PER_WORD)
757 first_shift_count = GEN_INT (shift_count - BITS_PER_WORD);
758 second_shift_count = GEN_INT (2*BITS_PER_WORD - shift_count);
762 first_shift_count = GEN_INT (BITS_PER_WORD - shift_count);
763 second_shift_count = GEN_INT (shift_count);
766 into_temp1 = expand_binop (word_mode, unsigned_shift,
767 outof_input, first_shift_count,
768 0, unsignedp, methods);
769 into_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
770 into_input, second_shift_count,
771 into_target, unsignedp, methods);
772 emit_move_insn (into_target,
773 expand_binop (word_mode, ior_optab,
774 into_temp1, into_temp2,
775 into_target, unsignedp, methods));
777 outof_temp1 = expand_binop (word_mode, unsigned_shift,
778 into_input, first_shift_count,
779 0, unsignedp, methods);
780 outof_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
781 outof_input, second_shift_count,
782 outof_target, unsignedp, methods);
783 emit_move_insn (outof_target,
784 expand_binop (word_mode, ior_optab,
785 outof_temp1, outof_temp2,
786 outof_target, unsignedp, methods));
789 insns = get_insns ();
792 if (binoptab->code != UNKNOWN)
793 equiv_value = gen_rtx (binoptab->code, mode, op0, op1);
797 /* We can't make this a no conflict block if this is a word swap,
798 because the word swap case fails if the input and output values
799 are in the same register. */
800 if (shift_count != BITS_PER_WORD)
801 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
807 /* These can be done a word at a time by propagating carries. */
808 if ((binoptab == add_optab || binoptab == sub_optab)
810 && GET_MODE_SIZE (mode) >= 2 * UNITS_PER_WORD
811 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
814 rtx carry_tmp = gen_reg_rtx (word_mode);
815 optab otheroptab = binoptab == add_optab ? sub_optab : add_optab;
816 int nwords = GET_MODE_BITSIZE (mode) / BITS_PER_WORD;
817 rtx carry_in, carry_out;
820 /* We can handle either a 1 or -1 value for the carry. If STORE_FLAG
821 value is one of those, use it. Otherwise, use 1 since it is the
822 one easiest to get. */
823 #if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
824 int normalizep = STORE_FLAG_VALUE;
829 /* Prepare the operands. */
830 xop0 = force_reg (mode, op0);
831 xop1 = force_reg (mode, op1);
833 if (target == 0 || GET_CODE (target) != REG
834 || target == xop0 || target == xop1)
835 target = gen_reg_rtx (mode);
837 /* Indicate for flow that the entire target reg is being set. */
838 if (GET_CODE (target) == REG)
839 emit_insn (gen_rtx (CLOBBER, VOIDmode, target));
841 /* Do the actual arithmetic. */
842 for (i = 0; i < nwords; i++)
844 int index = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i);
845 rtx target_piece = operand_subword (target, index, 1, mode);
846 rtx op0_piece = operand_subword_force (xop0, index, mode);
847 rtx op1_piece = operand_subword_force (xop1, index, mode);
850 /* Main add/subtract of the input operands. */
851 x = expand_binop (word_mode, binoptab,
852 op0_piece, op1_piece,
853 target_piece, unsignedp, methods);
859 /* Store carry from main add/subtract. */
860 carry_out = gen_reg_rtx (word_mode);
861 carry_out = emit_store_flag (carry_out,
862 binoptab == add_optab ? LTU : GTU,
864 word_mode, 1, normalizep);
871 /* Add/subtract previous carry to main result. */
872 x = expand_binop (word_mode,
873 normalizep == 1 ? binoptab : otheroptab,
875 target_piece, 1, methods);
876 if (target_piece != x)
877 emit_move_insn (target_piece, x);
881 /* THIS CODE HAS NOT BEEN TESTED. */
882 /* Get out carry from adding/subtracting carry in. */
883 carry_tmp = emit_store_flag (carry_tmp,
884 binoptab == add_optab
887 word_mode, 1, normalizep);
888 /* Logical-ior the two poss. carry together. */
889 carry_out = expand_binop (word_mode, ior_optab,
890 carry_out, carry_tmp,
891 carry_out, 0, methods);
897 carry_in = carry_out;
900 if (i == GET_MODE_BITSIZE (mode) / BITS_PER_WORD)
904 temp = emit_move_insn (target, target);
905 REG_NOTES (temp) = gen_rtx (EXPR_LIST, REG_EQUAL,
906 gen_rtx (binoptab->code, mode,
913 delete_insns_since (last);
916 /* If we want to multiply two two-word values and have normal and widening
917 multiplies of single-word values, we can do this with three smaller
918 multiplications. Note that we do not make a REG_NO_CONFLICT block here
919 because we are not operating on one word at a time.
921 The multiplication proceeds as follows:
922 _______________________
923 [__op0_high_|__op0_low__]
924 _______________________
925 * [__op1_high_|__op1_low__]
926 _______________________________________________
927 _______________________
928 (1) [__op0_low__*__op1_low__]
929 _______________________
930 (2a) [__op0_low__*__op1_high_]
931 _______________________
932 (2b) [__op0_high_*__op1_low__]
933 _______________________
934 (3) [__op0_high_*__op1_high_]
937 This gives a 4-word result. Since we are only interested in the
938 lower 2 words, partial result (3) and the upper words of (2a) and
939 (2b) don't need to be calculated. Hence (2a) and (2b) can be
940 calculated using non-widening multiplication.
942 (1), however, needs to be calculated with an unsigned widening
943 multiplication. If this operation is not directly supported we
944 try using a signed widening multiplication and adjust the result.
945 This adjustment works as follows:
947 If both operands are positive then no adjustment is needed.
949 If the operands have different signs, for example op0_low < 0 and
950 op1_low >= 0, the instruction treats the most significant bit of
951 op0_low as a sign bit instead of a bit with significance
952 2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low
953 with 2**BITS_PER_WORD - op0_low, and two's complements the
954 result. Conclusion: We need to add op1_low * 2**BITS_PER_WORD to
957 Similarly, if both operands are negative, we need to add
958 (op0_low + op1_low) * 2**BITS_PER_WORD.
960 We use a trick to adjust quickly. We logically shift op0_low right
961 (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to
962 op0_high (op1_high) before it is used to calculate 2b (2a). If no
963 logical shift exists, we do an arithmetic right shift and subtract
966 if (binoptab == smul_optab
968 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
969 && smul_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
970 && add_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
971 && ((umul_widen_optab->handlers[(int) mode].insn_code
973 || (smul_widen_optab->handlers[(int) mode].insn_code
974 != CODE_FOR_nothing)))
976 int low = (WORDS_BIG_ENDIAN ? 1 : 0);
977 int high = (WORDS_BIG_ENDIAN ? 0 : 1);
978 rtx op0_high = operand_subword_force (op0, high, mode);
979 rtx op0_low = operand_subword_force (op0, low, mode);
980 rtx op1_high = operand_subword_force (op1, high, mode);
981 rtx op1_low = operand_subword_force (op1, low, mode);
986 /* If the target is the same as one of the inputs, don't use it. This
987 prevents problems with the REG_EQUAL note. */
988 if (target == op0 || target == op1)
991 /* Multiply the two lower words to get a double-word product.
992 If unsigned widening multiplication is available, use that;
993 otherwise use the signed form and compensate. */
995 if (umul_widen_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
997 product = expand_binop (mode, umul_widen_optab, op0_low, op1_low,
998 target, 1, OPTAB_DIRECT);
1000 /* If we didn't succeed, delete everything we did so far. */
1002 delete_insns_since (last);
1004 op0_xhigh = op0_high, op1_xhigh = op1_high;
1008 && smul_widen_optab->handlers[(int) mode].insn_code
1009 != CODE_FOR_nothing)
1011 rtx wordm1 = GEN_INT (BITS_PER_WORD - 1);
1012 product = expand_binop (mode, smul_widen_optab, op0_low, op1_low,
1013 target, 1, OPTAB_DIRECT);
1014 op0_xhigh = expand_binop (word_mode, lshr_optab, op0_low, wordm1,
1015 NULL_RTX, 1, OPTAB_DIRECT);
1017 op0_xhigh = expand_binop (word_mode, add_optab, op0_high,
1018 op0_xhigh, op0_xhigh, 0, OPTAB_DIRECT);
1021 op0_xhigh = expand_binop (word_mode, ashr_optab, op0_low, wordm1,
1022 NULL_RTX, 0, OPTAB_DIRECT);
1024 op0_xhigh = expand_binop (word_mode, sub_optab, op0_high,
1025 op0_xhigh, op0_xhigh, 0,
1029 op1_xhigh = expand_binop (word_mode, lshr_optab, op1_low, wordm1,
1030 NULL_RTX, 1, OPTAB_DIRECT);
1032 op1_xhigh = expand_binop (word_mode, add_optab, op1_high,
1033 op1_xhigh, op1_xhigh, 0, OPTAB_DIRECT);
1036 op1_xhigh = expand_binop (word_mode, ashr_optab, op1_low, wordm1,
1037 NULL_RTX, 0, OPTAB_DIRECT);
1039 op1_xhigh = expand_binop (word_mode, sub_optab, op1_high,
1040 op1_xhigh, op1_xhigh, 0,
1045 /* If we have been able to directly compute the product of the
1046 low-order words of the operands and perform any required adjustments
1047 of the operands, we proceed by trying two more multiplications
1048 and then computing the appropriate sum.
1050 We have checked above that the required addition is provided.
1051 Full-word addition will normally always succeed, especially if
1052 it is provided at all, so we don't worry about its failure. The
1053 multiplication may well fail, however, so we do handle that. */
1055 if (product && op0_xhigh && op1_xhigh)
1058 rtx product_high = operand_subword (product, high, 1, mode);
1059 rtx temp = expand_binop (word_mode, binoptab, op0_low, op1_xhigh,
1060 NULL_RTX, 0, OPTAB_DIRECT);
1064 product_piece = expand_binop (word_mode, add_optab, temp,
1065 product_high, product_high,
1066 0, OPTAB_LIB_WIDEN);
1067 if (product_piece != product_high)
1068 emit_move_insn (product_high, product_piece);
1070 temp = expand_binop (word_mode, binoptab, op1_low, op0_xhigh,
1071 NULL_RTX, 0, OPTAB_DIRECT);
1073 product_piece = expand_binop (word_mode, add_optab, temp,
1074 product_high, product_high,
1075 0, OPTAB_LIB_WIDEN);
1076 if (product_piece != product_high)
1077 emit_move_insn (product_high, product_piece);
1079 temp = emit_move_insn (product, product);
1080 REG_NOTES (temp) = gen_rtx (EXPR_LIST, REG_EQUAL,
1081 gen_rtx (MULT, mode, copy_rtx (op0),
1089 /* If we get here, we couldn't do it for some reason even though we
1090 originally thought we could. Delete anything we've emitted in
1093 delete_insns_since (last);
1096 /* We need to open-code the complex type operations: '+, -, * and /' */
1098 /* At this point we allow operations between two similar complex
1099 numbers, and also if one of the operands is not a complex number
1100 but rather of MODE_FLOAT or MODE_INT. However, the caller
1101 must make sure that the MODE of the non-complex operand matches
1102 the SUBMODE of the complex operand. */
1104 if (class == MODE_COMPLEX_FLOAT || class == MODE_COMPLEX_INT)
1106 rtx real0 = (rtx) 0;
1107 rtx imag0 = (rtx) 0;
1108 rtx real1 = (rtx) 0;
1109 rtx imag1 = (rtx) 0;
1116 /* Find the correct mode for the real and imaginary parts */
1117 enum machine_mode submode
1118 = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
1119 class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
1122 if (submode == BLKmode)
1126 target = gen_reg_rtx (mode);
1130 realr = gen_realpart (submode, target);
1131 imagr = gen_imagpart (submode, target);
1133 if (GET_MODE (op0) == mode)
1135 real0 = gen_realpart (submode, op0);
1136 imag0 = gen_imagpart (submode, op0);
1141 if (GET_MODE (op1) == mode)
1143 real1 = gen_realpart (submode, op1);
1144 imag1 = gen_imagpart (submode, op1);
1149 if (! real0 || ! real1 || ! (imag0 || imag1))
1152 switch (binoptab->code)
1155 /* (a+ib) + (c+id) = (a+c) + i(b+d) */
1157 /* (a+ib) - (c+id) = (a-c) + i(b-d) */
1158 res = expand_binop (submode, binoptab, real0, real1,
1159 realr, unsignedp, methods);
1161 emit_move_insn (realr, res);
1164 res = expand_binop (submode, binoptab, imag0, imag1,
1165 imagr, unsignedp, methods);
1168 else if (binoptab->code == MINUS)
1169 res = expand_unop (submode, neg_optab, imag1, imagr, unsignedp);
1174 emit_move_insn (imagr, res);
1178 /* (a+ib) * (c+id) = (ac-bd) + i(ad+cb) */
1182 /* Don't fetch these from memory more than once. */
1183 real0 = force_reg (submode, real0);
1184 real1 = force_reg (submode, real1);
1185 imag0 = force_reg (submode, imag0);
1186 imag1 = force_reg (submode, imag1);
1188 res = expand_binop (submode, sub_optab,
1189 expand_binop (submode, binoptab, real0,
1190 real1, 0, unsignedp, methods),
1191 expand_binop (submode, binoptab, imag0,
1192 imag1, 0, unsignedp, methods),
1193 realr, unsignedp, methods);
1196 emit_move_insn (realr, res);
1198 res = expand_binop (submode, add_optab,
1199 expand_binop (submode, binoptab,
1201 0, unsignedp, methods),
1202 expand_binop (submode, binoptab,
1204 0, unsignedp, methods),
1205 imagr, unsignedp, methods);
1207 emit_move_insn (imagr, res);
1211 /* Don't fetch these from memory more than once. */
1212 real0 = force_reg (submode, real0);
1213 real1 = force_reg (submode, real1);
1215 res = expand_binop (submode, binoptab, real0, real1,
1216 realr, unsignedp, methods);
1218 emit_move_insn (realr, res);
1221 res = expand_binop (submode, binoptab,
1222 real1, imag0, imagr, unsignedp, methods);
1224 res = expand_binop (submode, binoptab,
1225 real0, imag1, imagr, unsignedp, methods);
1227 emit_move_insn (imagr, res);
1232 /* (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd)) */
1235 { /* (a+ib) / (c+i0) = (a/c) + i(b/c) */
1237 /* Don't fetch these from memory more than once. */
1238 real1 = force_reg (submode, real1);
1240 /* Simply divide the real and imaginary parts by `c' */
1241 if (class == MODE_COMPLEX_FLOAT)
1242 res = expand_binop (submode, binoptab, real0, real1,
1243 realr, unsignedp, methods);
1245 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
1246 real0, real1, realr, unsignedp);
1249 emit_move_insn (realr, res);
1251 if (class == MODE_COMPLEX_FLOAT)
1252 res = expand_binop (submode, binoptab, imag0, real1,
1253 imagr, unsignedp, methods);
1255 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
1256 imag0, real1, imagr, unsignedp);
1259 emit_move_insn (imagr, res);
1261 else /* Divisor is of complex type */
1269 /* Don't fetch these from memory more than once. */
1270 real0 = force_reg (submode, real0);
1271 real1 = force_reg (submode, real1);
1273 imag0 = force_reg (submode, imag0);
1274 imag1 = force_reg (submode, imag1);
1276 /* Divisor: c*c + d*d */
1277 divisor = expand_binop (submode, add_optab,
1278 expand_binop (submode, smul_optab,
1280 0, unsignedp, methods),
1281 expand_binop (submode, smul_optab,
1283 0, unsignedp, methods),
1284 0, unsignedp, methods);
1286 if (! imag0) /* ((a)(c-id))/divisor */
1287 { /* (a+i0) / (c+id) = (ac/(cc+dd)) + i(-ad/(cc+dd)) */
1288 /* Calculate the dividend */
1289 real_t = expand_binop (submode, smul_optab, real0, real1,
1290 0, unsignedp, methods);
1293 = expand_unop (submode, neg_optab,
1294 expand_binop (submode, smul_optab, real0,
1295 imag1, 0, unsignedp, methods),
1298 else /* ((a+ib)(c-id))/divider */
1300 /* Calculate the dividend */
1301 real_t = expand_binop (submode, add_optab,
1302 expand_binop (submode, smul_optab,
1304 0, unsignedp, methods),
1305 expand_binop (submode, smul_optab,
1307 0, unsignedp, methods),
1308 0, unsignedp, methods);
1310 imag_t = expand_binop (submode, sub_optab,
1311 expand_binop (submode, smul_optab,
1313 0, unsignedp, methods),
1314 expand_binop (submode, smul_optab,
1316 0, unsignedp, methods),
1317 0, unsignedp, methods);
1321 if (class == MODE_COMPLEX_FLOAT)
1322 res = expand_binop (submode, binoptab, real_t, divisor,
1323 realr, unsignedp, methods);
1325 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
1326 real_t, divisor, realr, unsignedp);
1329 emit_move_insn (realr, res);
1331 if (class == MODE_COMPLEX_FLOAT)
1332 res = expand_binop (submode, binoptab, imag_t, divisor,
1333 imagr, unsignedp, methods);
1335 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
1336 imag_t, divisor, imagr, unsignedp);
1339 emit_move_insn (imagr, res);
1350 if (binoptab->code != UNKNOWN)
1352 = gen_rtx (binoptab->code, mode, copy_rtx (op0), copy_rtx (op1));
1356 emit_no_conflict_block (seq, target, op0, op1, equiv_value);
1361 /* It can't be open-coded in this mode.
1362 Use a library call if one is available and caller says that's ok. */
1364 if (binoptab->handlers[(int) mode].libfunc
1365 && (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN))
1368 rtx funexp = binoptab->handlers[(int) mode].libfunc;
1370 enum machine_mode op1_mode = mode;
1377 op1_mode = word_mode;
1378 /* Specify unsigned here,
1379 since negative shift counts are meaningless. */
1380 op1x = convert_to_mode (word_mode, op1, 1);
1383 /* Pass 1 for NO_QUEUE so we don't lose any increments
1384 if the libcall is cse'd or moved. */
1385 value = emit_library_call_value (binoptab->handlers[(int) mode].libfunc,
1386 NULL_RTX, 1, mode, 2,
1387 op0, mode, op1x, op1_mode);
1389 insns = get_insns ();
1392 target = gen_reg_rtx (mode);
1393 emit_libcall_block (insns, target, value,
1394 gen_rtx (binoptab->code, mode, op0, op1));
1399 delete_insns_since (last);
1401 /* It can't be done in this mode. Can we do it in a wider mode? */
1403 if (! (methods == OPTAB_WIDEN || methods == OPTAB_LIB_WIDEN
1404 || methods == OPTAB_MUST_WIDEN))
1406 /* Caller says, don't even try. */
1407 delete_insns_since (entry_last);
1411 /* Compute the value of METHODS to pass to recursive calls.
1412 Don't allow widening to be tried recursively. */
1414 methods = (methods == OPTAB_LIB_WIDEN ? OPTAB_LIB : OPTAB_DIRECT);
1416 /* Look for a wider mode of the same class for which it appears we can do
1419 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1421 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1422 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1424 if ((binoptab->handlers[(int) wider_mode].insn_code
1425 != CODE_FOR_nothing)
1426 || (methods == OPTAB_LIB
1427 && binoptab->handlers[(int) wider_mode].libfunc))
1429 rtx xop0 = op0, xop1 = op1;
1432 /* For certain integer operations, we need not actually extend
1433 the narrow operands, as long as we will truncate
1434 the results to the same narrowness. */
1436 if ((binoptab == ior_optab || binoptab == and_optab
1437 || binoptab == xor_optab
1438 || binoptab == add_optab || binoptab == sub_optab
1439 || binoptab == smul_optab
1440 || binoptab == ashl_optab || binoptab == lshl_optab)
1441 && class == MODE_INT)
1444 xop0 = widen_operand (xop0, wider_mode, mode,
1445 unsignedp, no_extend);
1447 /* The second operand of a shift must always be extended. */
1448 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
1449 no_extend && binoptab != ashl_optab
1450 && binoptab != lshl_optab);
1452 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
1453 unsignedp, methods);
1456 if (class != MODE_INT)
1459 target = gen_reg_rtx (mode);
1460 convert_move (target, temp, 0);
1464 return gen_lowpart (mode, temp);
1467 delete_insns_since (last);
1472 delete_insns_since (entry_last);
1476 /* Expand a binary operator which has both signed and unsigned forms.
1477 UOPTAB is the optab for unsigned operations, and SOPTAB is for
1480 If we widen unsigned operands, we may use a signed wider operation instead
1481 of an unsigned wider operation, since the result would be the same. */
1484 sign_expand_binop (mode, uoptab, soptab, op0, op1, target, unsignedp, methods)
1485 enum machine_mode mode;
1486 optab uoptab, soptab;
1487 rtx op0, op1, target;
1489 enum optab_methods methods;
1492 optab direct_optab = unsignedp ? uoptab : soptab;
1493 struct optab wide_soptab;
1495 /* Do it without widening, if possible. */
1496 temp = expand_binop (mode, direct_optab, op0, op1, target,
1497 unsignedp, OPTAB_DIRECT);
1498 if (temp || methods == OPTAB_DIRECT)
1501 /* Try widening to a signed int. Make a fake signed optab that
1502 hides any signed insn for direct use. */
1503 wide_soptab = *soptab;
1504 wide_soptab.handlers[(int) mode].insn_code = CODE_FOR_nothing;
1505 wide_soptab.handlers[(int) mode].libfunc = 0;
1507 temp = expand_binop (mode, &wide_soptab, op0, op1, target,
1508 unsignedp, OPTAB_WIDEN);
1510 /* For unsigned operands, try widening to an unsigned int. */
1511 if (temp == 0 && unsignedp)
1512 temp = expand_binop (mode, uoptab, op0, op1, target,
1513 unsignedp, OPTAB_WIDEN);
1514 if (temp || methods == OPTAB_WIDEN)
1517 /* Use the right width lib call if that exists. */
1518 temp = expand_binop (mode, direct_optab, op0, op1, target, unsignedp, OPTAB_LIB);
1519 if (temp || methods == OPTAB_LIB)
1522 /* Must widen and use a lib call, use either signed or unsigned. */
1523 temp = expand_binop (mode, &wide_soptab, op0, op1, target,
1524 unsignedp, methods);
1528 return expand_binop (mode, uoptab, op0, op1, target,
1529 unsignedp, methods);
1533 /* Generate code to perform an operation specified by BINOPTAB
1534 on operands OP0 and OP1, with two results to TARG1 and TARG2.
1535 We assume that the order of the operands for the instruction
1536 is TARG0, OP0, OP1, TARG1, which would fit a pattern like
1537 [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
1539 Either TARG0 or TARG1 may be zero, but what that means is that
1540 that result is not actually wanted. We will generate it into
1541 a dummy pseudo-reg and discard it. They may not both be zero.
1543 Returns 1 if this operation can be performed; 0 if not. */
1546 expand_twoval_binop (binoptab, op0, op1, targ0, targ1, unsignedp)
1552 enum machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
1553 enum mode_class class;
1554 enum machine_mode wider_mode;
1555 rtx entry_last = get_last_insn ();
1558 class = GET_MODE_CLASS (mode);
1560 op0 = protect_from_queue (op0, 0);
1561 op1 = protect_from_queue (op1, 0);
1565 op0 = force_not_mem (op0);
1566 op1 = force_not_mem (op1);
1569 /* If we are inside an appropriately-short loop and one operand is an
1570 expensive constant, force it into a register. */
1571 if (CONSTANT_P (op0) && preserve_subexpressions_p ()
1572 && rtx_cost (op0, binoptab->code) > 2)
1573 op0 = force_reg (mode, op0);
1575 if (CONSTANT_P (op1) && preserve_subexpressions_p ()
1576 && rtx_cost (op1, binoptab->code) > 2)
1577 op1 = force_reg (mode, op1);
1580 targ0 = protect_from_queue (targ0, 1);
1582 targ0 = gen_reg_rtx (mode);
1584 targ1 = protect_from_queue (targ1, 1);
1586 targ1 = gen_reg_rtx (mode);
1588 /* Record where to go back to if we fail. */
1589 last = get_last_insn ();
1591 if (binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1593 int icode = (int) binoptab->handlers[(int) mode].insn_code;
1594 enum machine_mode mode0 = insn_operand_mode[icode][1];
1595 enum machine_mode mode1 = insn_operand_mode[icode][2];
1597 rtx xop0 = op0, xop1 = op1;
1599 /* In case this insn wants input operands in modes different from the
1600 result, convert the operands. */
1601 if (GET_MODE (op0) != VOIDmode && GET_MODE (op0) != mode0)
1602 xop0 = convert_to_mode (mode0, xop0, unsignedp);
1604 if (GET_MODE (op1) != VOIDmode && GET_MODE (op1) != mode1)
1605 xop1 = convert_to_mode (mode1, xop1, unsignedp);
1607 /* Now, if insn doesn't accept these operands, put them into pseudos. */
1608 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
1609 xop0 = copy_to_mode_reg (mode0, xop0);
1611 if (! (*insn_operand_predicate[icode][2]) (xop1, mode1))
1612 xop1 = copy_to_mode_reg (mode1, xop1);
1614 /* We could handle this, but we should always be called with a pseudo
1615 for our targets and all insns should take them as outputs. */
1616 if (! (*insn_operand_predicate[icode][0]) (targ0, mode)
1617 || ! (*insn_operand_predicate[icode][3]) (targ1, mode))
1620 pat = GEN_FCN (icode) (targ0, xop0, xop1, targ1);
1627 delete_insns_since (last);
1630 /* It can't be done in this mode. Can we do it in a wider mode? */
1632 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1634 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1635 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1637 if (binoptab->handlers[(int) wider_mode].insn_code
1638 != CODE_FOR_nothing)
1640 register rtx t0 = gen_reg_rtx (wider_mode);
1641 register rtx t1 = gen_reg_rtx (wider_mode);
1643 if (expand_twoval_binop (binoptab,
1644 convert_modes (wider_mode, mode, op0,
1646 convert_modes (wider_mode, mode, op1,
1650 convert_move (targ0, t0, unsignedp);
1651 convert_move (targ1, t1, unsignedp);
1655 delete_insns_since (last);
1660 delete_insns_since (entry_last);
1664 /* Generate code to perform an operation specified by UNOPTAB
1665 on operand OP0, with result having machine-mode MODE.
1667 UNSIGNEDP is for the case where we have to widen the operands
1668 to perform the operation. It says to use zero-extension.
1670 If TARGET is nonzero, the value
1671 is generated there, if it is convenient to do so.
1672 In all cases an rtx is returned for the locus of the value;
1673 this may or may not be TARGET. */
1676 expand_unop (mode, unoptab, op0, target, unsignedp)
1677 enum machine_mode mode;
1683 enum mode_class class;
1684 enum machine_mode wider_mode;
1686 rtx last = get_last_insn ();
1689 class = GET_MODE_CLASS (mode);
1691 op0 = protect_from_queue (op0, 0);
1695 op0 = force_not_mem (op0);
1699 target = protect_from_queue (target, 1);
1701 if (unoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1703 int icode = (int) unoptab->handlers[(int) mode].insn_code;
1704 enum machine_mode mode0 = insn_operand_mode[icode][1];
1710 temp = gen_reg_rtx (mode);
1712 if (GET_MODE (xop0) != VOIDmode
1713 && GET_MODE (xop0) != mode0)
1714 xop0 = convert_to_mode (mode0, xop0, unsignedp);
1716 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
1718 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
1719 xop0 = copy_to_mode_reg (mode0, xop0);
1721 if (! (*insn_operand_predicate[icode][0]) (temp, mode))
1722 temp = gen_reg_rtx (mode);
1724 pat = GEN_FCN (icode) (temp, xop0);
1727 if (GET_CODE (pat) == SEQUENCE
1728 && ! add_equal_note (pat, temp, unoptab->code, xop0, NULL_RTX))
1730 delete_insns_since (last);
1731 return expand_unop (mode, unoptab, op0, NULL_RTX, unsignedp);
1739 delete_insns_since (last);
1742 /* It can't be done in this mode. Can we open-code it in a wider mode? */
1744 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1745 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1746 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1748 if (unoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing)
1752 /* For certain operations, we need not actually extend
1753 the narrow operand, as long as we will truncate the
1754 results to the same narrowness. */
1756 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
1757 (unoptab == neg_optab
1758 || unoptab == one_cmpl_optab)
1759 && class == MODE_INT);
1761 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
1766 if (class != MODE_INT)
1769 target = gen_reg_rtx (mode);
1770 convert_move (target, temp, 0);
1774 return gen_lowpart (mode, temp);
1777 delete_insns_since (last);
1781 /* These can be done a word at a time. */
1782 if (unoptab == one_cmpl_optab
1783 && class == MODE_INT
1784 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
1785 && unoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
1790 if (target == 0 || target == op0)
1791 target = gen_reg_rtx (mode);
1795 /* Do the actual arithmetic. */
1796 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
1798 rtx target_piece = operand_subword (target, i, 1, mode);
1799 rtx x = expand_unop (word_mode, unoptab,
1800 operand_subword_force (op0, i, mode),
1801 target_piece, unsignedp);
1802 if (target_piece != x)
1803 emit_move_insn (target_piece, x);
1806 insns = get_insns ();
1809 emit_no_conflict_block (insns, target, op0, NULL_RTX,
1810 gen_rtx (unoptab->code, mode, copy_rtx (op0)));
1814 /* Open-code the complex negation operation. */
1815 else if (unoptab == neg_optab
1816 && (class == MODE_COMPLEX_FLOAT || class == MODE_COMPLEX_INT))
1822 /* Find the correct mode for the real and imaginary parts */
1823 enum machine_mode submode
1824 = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
1825 class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
1828 if (submode == BLKmode)
1832 target = gen_reg_rtx (mode);
1836 target_piece = gen_imagpart (submode, target);
1837 x = expand_unop (submode, unoptab,
1838 gen_imagpart (submode, op0),
1839 target_piece, unsignedp);
1840 if (target_piece != x)
1841 emit_move_insn (target_piece, x);
1843 target_piece = gen_realpart (submode, target);
1844 x = expand_unop (submode, unoptab,
1845 gen_realpart (submode, op0),
1846 target_piece, unsignedp);
1847 if (target_piece != x)
1848 emit_move_insn (target_piece, x);
1853 emit_no_conflict_block (seq, target, op0, 0,
1854 gen_rtx (unoptab->code, mode, copy_rtx (op0)));
1858 /* Now try a library call in this mode. */
1859 if (unoptab->handlers[(int) mode].libfunc)
1862 rtx funexp = unoptab->handlers[(int) mode].libfunc;
1867 /* Pass 1 for NO_QUEUE so we don't lose any increments
1868 if the libcall is cse'd or moved. */
1869 value = emit_library_call_value (unoptab->handlers[(int) mode].libfunc,
1870 NULL_RTX, 1, mode, 1, op0, mode);
1871 insns = get_insns ();
1874 target = gen_reg_rtx (mode);
1875 emit_libcall_block (insns, target, value,
1876 gen_rtx (unoptab->code, mode, op0));
1881 /* It can't be done in this mode. Can we do it in a wider mode? */
1883 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1885 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1886 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1888 if ((unoptab->handlers[(int) wider_mode].insn_code
1889 != CODE_FOR_nothing)
1890 || unoptab->handlers[(int) wider_mode].libfunc)
1894 /* For certain operations, we need not actually extend
1895 the narrow operand, as long as we will truncate the
1896 results to the same narrowness. */
1898 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
1899 (unoptab == neg_optab
1900 || unoptab == one_cmpl_optab)
1901 && class == MODE_INT);
1903 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
1908 if (class != MODE_INT)
1911 target = gen_reg_rtx (mode);
1912 convert_move (target, temp, 0);
1916 return gen_lowpart (mode, temp);
1919 delete_insns_since (last);
1927 /* Emit code to compute the absolute value of OP0, with result to
1928 TARGET if convenient. (TARGET may be 0.) The return value says
1929 where the result actually is to be found.
1931 MODE is the mode of the operand; the mode of the result is
1932 different but can be deduced from MODE.
1934 UNSIGNEDP is relevant for complex integer modes. */
1937 expand_complex_abs (mode, op0, target, unsignedp)
1938 enum machine_mode mode;
1943 enum mode_class class = GET_MODE_CLASS (mode);
1944 enum machine_mode wider_mode;
1946 rtx entry_last = get_last_insn ();
1950 /* Find the correct mode for the real and imaginary parts. */
1951 enum machine_mode submode
1952 = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
1953 class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
1956 if (submode == BLKmode)
1959 op0 = protect_from_queue (op0, 0);
1963 op0 = force_not_mem (op0);
1966 last = get_last_insn ();
1969 target = protect_from_queue (target, 1);
1971 if (abs_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1973 int icode = (int) abs_optab->handlers[(int) mode].insn_code;
1974 enum machine_mode mode0 = insn_operand_mode[icode][1];
1980 temp = gen_reg_rtx (submode);
1982 if (GET_MODE (xop0) != VOIDmode
1983 && GET_MODE (xop0) != mode0)
1984 xop0 = convert_to_mode (mode0, xop0, unsignedp);
1986 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
1988 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
1989 xop0 = copy_to_mode_reg (mode0, xop0);
1991 if (! (*insn_operand_predicate[icode][0]) (temp, submode))
1992 temp = gen_reg_rtx (submode);
1994 pat = GEN_FCN (icode) (temp, xop0);
1997 if (GET_CODE (pat) == SEQUENCE
1998 && ! add_equal_note (pat, temp, abs_optab->code, xop0, NULL_RTX))
2000 delete_insns_since (last);
2001 return expand_unop (mode, abs_optab, op0, NULL_RTX, unsignedp);
2009 delete_insns_since (last);
2012 /* It can't be done in this mode. Can we open-code it in a wider mode? */
2014 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2015 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2017 if (abs_optab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing)
2021 xop0 = convert_modes (wider_mode, mode, xop0, unsignedp);
2022 temp = expand_complex_abs (wider_mode, xop0, NULL_RTX, unsignedp);
2026 if (class != MODE_COMPLEX_INT)
2029 target = gen_reg_rtx (submode);
2030 convert_move (target, temp, 0);
2034 return gen_lowpart (submode, temp);
2037 delete_insns_since (last);
2041 /* Open-code the complex absolute-value operation
2042 if we can open-code sqrt. Otherwise it's not worth while. */
2043 if (sqrt_optab->handlers[(int) submode].insn_code != CODE_FOR_nothing)
2045 rtx real, imag, total;
2047 real = gen_realpart (submode, op0);
2048 imag = gen_imagpart (submode, op0);
2050 /* Square both parts. */
2051 real = expand_mult (submode, real, real, NULL_RTX, 0);
2052 imag = expand_mult (submode, imag, imag, NULL_RTX, 0);
2054 /* Sum the parts. */
2055 total = expand_binop (submode, add_optab, real, imag, 0,
2056 0, OPTAB_LIB_WIDEN);
2058 /* Get sqrt in TARGET. Set TARGET to where the result is. */
2059 target = expand_unop (submode, sqrt_optab, total, target, 0);
2061 delete_insns_since (last);
2066 /* Now try a library call in this mode. */
2067 if (abs_optab->handlers[(int) mode].libfunc)
2070 rtx funexp = abs_optab->handlers[(int) mode].libfunc;
2075 /* Pass 1 for NO_QUEUE so we don't lose any increments
2076 if the libcall is cse'd or moved. */
2077 value = emit_library_call_value (abs_optab->handlers[(int) mode].libfunc,
2078 NULL_RTX, 1, submode, 1, op0, mode);
2079 insns = get_insns ();
2082 target = gen_reg_rtx (submode);
2083 emit_libcall_block (insns, target, value,
2084 gen_rtx (abs_optab->code, mode, op0));
2089 /* It can't be done in this mode. Can we do it in a wider mode? */
2091 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2092 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2094 if ((abs_optab->handlers[(int) wider_mode].insn_code
2095 != CODE_FOR_nothing)
2096 || abs_optab->handlers[(int) wider_mode].libfunc)
2100 xop0 = convert_modes (wider_mode, mode, xop0, unsignedp);
2102 temp = expand_complex_abs (wider_mode, xop0, NULL_RTX, unsignedp);
2106 if (class != MODE_COMPLEX_INT)
2109 target = gen_reg_rtx (submode);
2110 convert_move (target, temp, 0);
2114 return gen_lowpart (submode, temp);
2117 delete_insns_since (last);
2121 delete_insns_since (entry_last);
2125 /* Generate an instruction whose insn-code is INSN_CODE,
2126 with two operands: an output TARGET and an input OP0.
2127 TARGET *must* be nonzero, and the output is always stored there.
2128 CODE is an rtx code such that (CODE OP0) is an rtx that describes
2129 the value that is stored into TARGET. */
2132 emit_unop_insn (icode, target, op0, code)
2139 enum machine_mode mode0 = insn_operand_mode[icode][1];
2142 temp = target = protect_from_queue (target, 1);
2144 op0 = protect_from_queue (op0, 0);
2147 op0 = force_not_mem (op0);
2149 /* Now, if insn does not accept our operands, put them into pseudos. */
2151 if (! (*insn_operand_predicate[icode][1]) (op0, mode0))
2152 op0 = copy_to_mode_reg (mode0, op0);
2154 if (! (*insn_operand_predicate[icode][0]) (temp, GET_MODE (temp))
2155 || (flag_force_mem && GET_CODE (temp) == MEM))
2156 temp = gen_reg_rtx (GET_MODE (temp));
2158 pat = GEN_FCN (icode) (temp, op0);
2160 if (GET_CODE (pat) == SEQUENCE && code != UNKNOWN)
2161 add_equal_note (pat, temp, code, op0, NULL_RTX);
2166 emit_move_insn (target, temp);
2169 /* Emit code to perform a series of operations on a multi-word quantity, one
2172 Such a block is preceded by a CLOBBER of the output, consists of multiple
2173 insns, each setting one word of the output, and followed by a SET copying
2174 the output to itself.
2176 Each of the insns setting words of the output receives a REG_NO_CONFLICT
2177 note indicating that it doesn't conflict with the (also multi-word)
2178 inputs. The entire block is surrounded by REG_LIBCALL and REG_RETVAL
2181 INSNS is a block of code generated to perform the operation, not including
2182 the CLOBBER and final copy. All insns that compute intermediate values
2183 are first emitted, followed by the block as described above. Only
2184 INSNs are allowed in the block; no library calls or jumps may be
2187 TARGET, OP0, and OP1 are the output and inputs of the operations,
2188 respectively. OP1 may be zero for a unary operation.
2190 EQUIV, if non-zero, is an expression to be placed into a REG_EQUAL note
2193 If TARGET is not a register, INSNS is simply emitted with no special
2196 The final insn emitted is returned. */
2199 emit_no_conflict_block (insns, target, op0, op1, equiv)
2205 rtx prev, next, first, last, insn;
2207 if (GET_CODE (target) != REG || reload_in_progress)
2208 return emit_insns (insns);
2210 /* First emit all insns that do not store into words of the output and remove
2211 these from the list. */
2212 for (insn = insns; insn; insn = next)
2217 next = NEXT_INSN (insn);
2219 if (GET_CODE (insn) != INSN)
2222 if (GET_CODE (PATTERN (insn)) == SET)
2223 set = PATTERN (insn);
2224 else if (GET_CODE (PATTERN (insn)) == PARALLEL)
2226 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
2227 if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET)
2229 set = XVECEXP (PATTERN (insn), 0, i);
2237 if (! reg_overlap_mentioned_p (target, SET_DEST (set)))
2239 if (PREV_INSN (insn))
2240 NEXT_INSN (PREV_INSN (insn)) = next;
2245 PREV_INSN (next) = PREV_INSN (insn);
2251 prev = get_last_insn ();
2253 /* Now write the CLOBBER of the output, followed by the setting of each
2254 of the words, followed by the final copy. */
2255 if (target != op0 && target != op1)
2256 emit_insn (gen_rtx (CLOBBER, VOIDmode, target));
2258 for (insn = insns; insn; insn = next)
2260 next = NEXT_INSN (insn);
2263 if (op1 && GET_CODE (op1) == REG)
2264 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_NO_CONFLICT, op1,
2267 if (op0 && GET_CODE (op0) == REG)
2268 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_NO_CONFLICT, op0,
2272 if (mov_optab->handlers[(int) GET_MODE (target)].insn_code
2273 != CODE_FOR_nothing)
2275 last = emit_move_insn (target, target);
2278 = gen_rtx (EXPR_LIST, REG_EQUAL, equiv, REG_NOTES (last));
2281 last = get_last_insn ();
2284 first = get_insns ();
2286 first = NEXT_INSN (prev);
2288 /* Encapsulate the block so it gets manipulated as a unit. */
2289 REG_NOTES (first) = gen_rtx (INSN_LIST, REG_LIBCALL, last,
2291 REG_NOTES (last) = gen_rtx (INSN_LIST, REG_RETVAL, first, REG_NOTES (last));
2296 /* Emit code to make a call to a constant function or a library call.
2298 INSNS is a list containing all insns emitted in the call.
2299 These insns leave the result in RESULT. Our block is to copy RESULT
2300 to TARGET, which is logically equivalent to EQUIV.
2302 We first emit any insns that set a pseudo on the assumption that these are
2303 loading constants into registers; doing so allows them to be safely cse'ed
2304 between blocks. Then we emit all the other insns in the block, followed by
2305 an insn to move RESULT to TARGET. This last insn will have a REQ_EQUAL
2306 note with an operand of EQUIV.
2308 Moving assignments to pseudos outside of the block is done to improve
2309 the generated code, but is not required to generate correct code,
2310 hence being unable to move an assignment is not grounds for not making
2311 a libcall block. There are two reasons why it is safe to leave these
2312 insns inside the block: First, we know that these pseudos cannot be
2313 used in generated RTL outside the block since they are created for
2314 temporary purposes within the block. Second, CSE will not record the
2315 values of anything set inside a libcall block, so we know they must
2316 be dead at the end of the block.
2318 Except for the first group of insns (the ones setting pseudos), the
2319 block is delimited by REG_RETVAL and REG_LIBCALL notes. */
2322 emit_libcall_block (insns, target, result, equiv)
2328 rtx prev, next, first, last, insn;
2330 /* First emit all insns that set pseudos. Remove them from the list as
2331 we go. Avoid insns that set pseudos which were referenced in previous
2332 insns. These can be generated by move_by_pieces, for example,
2333 to update an address. Similarly, avoid insns that reference things
2334 set in previous insns. */
2336 for (insn = insns; insn; insn = next)
2338 rtx set = single_set (insn);
2340 next = NEXT_INSN (insn);
2342 if (set != 0 && GET_CODE (SET_DEST (set)) == REG
2343 && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER
2345 || (! reg_mentioned_p (SET_DEST (set), PATTERN (insns))
2346 && ! reg_used_between_p (SET_DEST (set), insns, insn)
2347 && ! modified_in_p (SET_SRC (set), insns)
2348 && ! modified_between_p (SET_SRC (set), insns, insn))))
2350 if (PREV_INSN (insn))
2351 NEXT_INSN (PREV_INSN (insn)) = next;
2356 PREV_INSN (next) = PREV_INSN (insn);
2362 prev = get_last_insn ();
2364 /* Write the remaining insns followed by the final copy. */
2366 for (insn = insns; insn; insn = next)
2368 next = NEXT_INSN (insn);
2373 last = emit_move_insn (target, result);
2374 REG_NOTES (last) = gen_rtx (EXPR_LIST,
2375 REG_EQUAL, copy_rtx (equiv), REG_NOTES (last));
2378 first = get_insns ();
2380 first = NEXT_INSN (prev);
2382 /* Encapsulate the block so it gets manipulated as a unit. */
2383 REG_NOTES (first) = gen_rtx (INSN_LIST, REG_LIBCALL, last,
2385 REG_NOTES (last) = gen_rtx (INSN_LIST, REG_RETVAL, first, REG_NOTES (last));
2388 /* Generate code to store zero in X. */
2394 emit_move_insn (x, const0_rtx);
2397 /* Generate code to store 1 in X
2398 assuming it contains zero beforehand. */
2401 emit_0_to_1_insn (x)
2404 emit_move_insn (x, const1_rtx);
2407 /* Generate code to compare X with Y
2408 so that the condition codes are set.
2410 MODE is the mode of the inputs (in case they are const_int).
2411 UNSIGNEDP nonzero says that X and Y are unsigned;
2412 this matters if they need to be widened.
2414 If they have mode BLKmode, then SIZE specifies the size of both X and Y,
2415 and ALIGN specifies the known shared alignment of X and Y.
2417 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).
2418 It is ignored for fixed-point and block comparisons;
2419 it is used only for floating-point comparisons. */
2422 emit_cmp_insn (x, y, comparison, size, mode, unsignedp, align)
2424 enum rtx_code comparison;
2426 enum machine_mode mode;
2430 enum mode_class class;
2431 enum machine_mode wider_mode;
2433 class = GET_MODE_CLASS (mode);
2435 /* They could both be VOIDmode if both args are immediate constants,
2436 but we should fold that at an earlier stage.
2437 With no special code here, this will call abort,
2438 reminding the programmer to implement such folding. */
2440 if (mode != BLKmode && flag_force_mem)
2442 x = force_not_mem (x);
2443 y = force_not_mem (y);
2446 /* If we are inside an appropriately-short loop and one operand is an
2447 expensive constant, force it into a register. */
2448 if (CONSTANT_P (x) && preserve_subexpressions_p () && rtx_cost (x, COMPARE) > 2)
2449 x = force_reg (mode, x);
2451 if (CONSTANT_P (y) && preserve_subexpressions_p () && rtx_cost (y, COMPARE) > 2)
2452 y = force_reg (mode, y);
2454 /* Don't let both operands fail to indicate the mode. */
2455 if (GET_MODE (x) == VOIDmode && GET_MODE (y) == VOIDmode)
2456 x = force_reg (mode, x);
2458 /* Handle all BLKmode compares. */
2460 if (mode == BLKmode)
2463 x = protect_from_queue (x, 0);
2464 y = protect_from_queue (y, 0);
2468 #ifdef HAVE_cmpstrqi
2470 && GET_CODE (size) == CONST_INT
2471 && INTVAL (size) < (1 << GET_MODE_BITSIZE (QImode)))
2473 enum machine_mode result_mode
2474 = insn_operand_mode[(int) CODE_FOR_cmpstrqi][0];
2475 rtx result = gen_reg_rtx (result_mode);
2476 emit_insn (gen_cmpstrqi (result, x, y, size, GEN_INT (align)));
2477 emit_cmp_insn (result, const0_rtx, comparison, NULL_RTX,
2482 #ifdef HAVE_cmpstrhi
2484 && GET_CODE (size) == CONST_INT
2485 && INTVAL (size) < (1 << GET_MODE_BITSIZE (HImode)))
2487 enum machine_mode result_mode
2488 = insn_operand_mode[(int) CODE_FOR_cmpstrhi][0];
2489 rtx result = gen_reg_rtx (result_mode);
2490 emit_insn (gen_cmpstrhi (result, x, y, size, GEN_INT (align)));
2491 emit_cmp_insn (result, const0_rtx, comparison, NULL_RTX,
2496 #ifdef HAVE_cmpstrsi
2499 enum machine_mode result_mode
2500 = insn_operand_mode[(int) CODE_FOR_cmpstrsi][0];
2501 rtx result = gen_reg_rtx (result_mode);
2502 size = protect_from_queue (size, 0);
2503 emit_insn (gen_cmpstrsi (result, x, y,
2504 convert_to_mode (SImode, size, 1),
2506 emit_cmp_insn (result, const0_rtx, comparison, NULL_RTX,
2512 #ifdef TARGET_MEM_FUNCTIONS
2513 emit_library_call (memcmp_libfunc, 0,
2514 TYPE_MODE (integer_type_node), 3,
2515 XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
2518 emit_library_call (bcmp_libfunc, 0,
2519 TYPE_MODE (integer_type_node), 3,
2520 XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
2523 emit_cmp_insn (hard_libcall_value (TYPE_MODE (integer_type_node)),
2524 const0_rtx, comparison, NULL_RTX,
2525 TYPE_MODE (integer_type_node), 0, 0);
2530 /* Handle some compares against zero. */
2532 if (y == CONST0_RTX (mode)
2533 && tst_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2535 int icode = (int) tst_optab->handlers[(int) mode].insn_code;
2538 x = protect_from_queue (x, 0);
2539 y = protect_from_queue (y, 0);
2541 /* Now, if insn does accept these operands, put them into pseudos. */
2542 if (! (*insn_operand_predicate[icode][0])
2543 (x, insn_operand_mode[icode][0]))
2544 x = copy_to_mode_reg (insn_operand_mode[icode][0], x);
2546 emit_insn (GEN_FCN (icode) (x));
2550 /* Handle compares for which there is a directly suitable insn. */
2552 if (cmp_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2554 int icode = (int) cmp_optab->handlers[(int) mode].insn_code;
2557 x = protect_from_queue (x, 0);
2558 y = protect_from_queue (y, 0);
2560 /* Now, if insn doesn't accept these operands, put them into pseudos. */
2561 if (! (*insn_operand_predicate[icode][0])
2562 (x, insn_operand_mode[icode][0]))
2563 x = copy_to_mode_reg (insn_operand_mode[icode][0], x);
2565 if (! (*insn_operand_predicate[icode][1])
2566 (y, insn_operand_mode[icode][1]))
2567 y = copy_to_mode_reg (insn_operand_mode[icode][1], y);
2569 emit_insn (GEN_FCN (icode) (x, y));
2573 /* Try widening if we can find a direct insn that way. */
2575 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
2577 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2578 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2580 if (cmp_optab->handlers[(int) wider_mode].insn_code
2581 != CODE_FOR_nothing)
2583 x = protect_from_queue (x, 0);
2584 y = protect_from_queue (y, 0);
2585 x = convert_modes (wider_mode, mode, x, unsignedp);
2586 y = convert_modes (wider_mode, mode, y, unsignedp);
2587 emit_cmp_insn (x, y, comparison, NULL_RTX,
2588 wider_mode, unsignedp, align);
2594 /* Handle a lib call just for the mode we are using. */
2596 if (cmp_optab->handlers[(int) mode].libfunc
2597 && class != MODE_FLOAT)
2599 rtx libfunc = cmp_optab->handlers[(int) mode].libfunc;
2600 /* If we want unsigned, and this mode has a distinct unsigned
2601 comparison routine, use that. */
2602 if (unsignedp && ucmp_optab->handlers[(int) mode].libfunc)
2603 libfunc = ucmp_optab->handlers[(int) mode].libfunc;
2605 emit_library_call (libfunc, 1,
2606 word_mode, 2, x, mode, y, mode);
2608 /* Integer comparison returns a result that must be compared against 1,
2609 so that even if we do an unsigned compare afterward,
2610 there is still a value that can represent the result "less than". */
2612 emit_cmp_insn (hard_libcall_value (word_mode), const1_rtx,
2613 comparison, NULL_RTX, word_mode, unsignedp, 0);
2617 if (class == MODE_FLOAT)
2618 emit_float_lib_cmp (x, y, comparison);
2624 /* Nonzero if a compare of mode MODE can be done straightforwardly
2625 (without splitting it into pieces). */
2628 can_compare_p (mode)
2629 enum machine_mode mode;
2633 if (cmp_optab->handlers[(int)mode].insn_code != CODE_FOR_nothing)
2635 mode = GET_MODE_WIDER_MODE (mode);
2636 } while (mode != VOIDmode);
2641 /* Emit a library call comparison between floating point X and Y.
2642 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */
2645 emit_float_lib_cmp (x, y, comparison)
2647 enum rtx_code comparison;
2649 enum machine_mode mode = GET_MODE (x);
2656 libfunc = eqsf2_libfunc;
2660 libfunc = nesf2_libfunc;
2664 libfunc = gtsf2_libfunc;
2668 libfunc = gesf2_libfunc;
2672 libfunc = ltsf2_libfunc;
2676 libfunc = lesf2_libfunc;
2679 else if (mode == DFmode)
2683 libfunc = eqdf2_libfunc;
2687 libfunc = nedf2_libfunc;
2691 libfunc = gtdf2_libfunc;
2695 libfunc = gedf2_libfunc;
2699 libfunc = ltdf2_libfunc;
2703 libfunc = ledf2_libfunc;
2706 else if (mode == XFmode)
2710 libfunc = eqxf2_libfunc;
2714 libfunc = nexf2_libfunc;
2718 libfunc = gtxf2_libfunc;
2722 libfunc = gexf2_libfunc;
2726 libfunc = ltxf2_libfunc;
2730 libfunc = lexf2_libfunc;
2733 else if (mode == TFmode)
2737 libfunc = eqtf2_libfunc;
2741 libfunc = netf2_libfunc;
2745 libfunc = gttf2_libfunc;
2749 libfunc = getf2_libfunc;
2753 libfunc = lttf2_libfunc;
2757 libfunc = letf2_libfunc;
2762 enum machine_mode wider_mode;
2764 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2765 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2767 if ((cmp_optab->handlers[(int) wider_mode].insn_code
2768 != CODE_FOR_nothing)
2769 || (cmp_optab->handlers[(int) wider_mode].libfunc != 0))
2771 x = protect_from_queue (x, 0);
2772 y = protect_from_queue (y, 0);
2773 x = convert_to_mode (wider_mode, x, 0);
2774 y = convert_to_mode (wider_mode, y, 0);
2775 emit_float_lib_cmp (x, y, comparison);
2785 emit_library_call (libfunc, 1,
2786 word_mode, 2, x, mode, y, mode);
2788 emit_cmp_insn (hard_libcall_value (word_mode), const0_rtx, comparison,
2789 NULL_RTX, word_mode, 0, 0);
2792 /* Generate code to indirectly jump to a location given in the rtx LOC. */
2795 emit_indirect_jump (loc)
2798 if (! ((*insn_operand_predicate[(int)CODE_FOR_indirect_jump][0])
2800 loc = copy_to_mode_reg (Pmode, loc);
2802 emit_jump_insn (gen_indirect_jump (loc));
2806 /* These three functions generate an insn body and return it
2807 rather than emitting the insn.
2809 They do not protect from queued increments,
2810 because they may be used 1) in protect_from_queue itself
2811 and 2) in other passes where there is no queue. */
2813 /* Generate and return an insn body to add Y to X. */
2816 gen_add2_insn (x, y)
2819 int icode = (int) add_optab->handlers[(int) GET_MODE (x)].insn_code;
2821 if (! (*insn_operand_predicate[icode][0]) (x, insn_operand_mode[icode][0])
2822 || ! (*insn_operand_predicate[icode][1]) (x, insn_operand_mode[icode][1])
2823 || ! (*insn_operand_predicate[icode][2]) (y, insn_operand_mode[icode][2]))
2826 return (GEN_FCN (icode) (x, x, y));
2830 have_add2_insn (mode)
2831 enum machine_mode mode;
2833 return add_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
2836 /* Generate and return an insn body to subtract Y from X. */
2839 gen_sub2_insn (x, y)
2842 int icode = (int) sub_optab->handlers[(int) GET_MODE (x)].insn_code;
2844 if (! (*insn_operand_predicate[icode][0]) (x, insn_operand_mode[icode][0])
2845 || ! (*insn_operand_predicate[icode][1]) (x, insn_operand_mode[icode][1])
2846 || ! (*insn_operand_predicate[icode][2]) (y, insn_operand_mode[icode][2]))
2849 return (GEN_FCN (icode) (x, x, y));
2853 have_sub2_insn (mode)
2854 enum machine_mode mode;
2856 return sub_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
2859 /* Generate the body of an instruction to copy Y into X.
2860 It may be a SEQUENCE, if one insn isn't enough. */
2863 gen_move_insn (x, y)
2866 register enum machine_mode mode = GET_MODE (x);
2867 enum insn_code insn_code;
2870 if (mode == VOIDmode)
2871 mode = GET_MODE (y);
2873 insn_code = mov_optab->handlers[(int) mode].insn_code;
2875 /* Handle MODE_CC modes: If we don't have a special move insn for this mode,
2876 find a mode to do it in. If we have a movcc, use it. Otherwise,
2877 find the MODE_INT mode of the same width. */
2879 if (GET_MODE_CLASS (mode) == MODE_CC && insn_code == CODE_FOR_nothing)
2881 enum machine_mode tmode = VOIDmode;
2885 && mov_optab->handlers[(int) CCmode].insn_code != CODE_FOR_nothing)
2888 for (tmode = QImode; tmode != VOIDmode;
2889 tmode = GET_MODE_WIDER_MODE (tmode))
2890 if (GET_MODE_SIZE (tmode) == GET_MODE_SIZE (mode))
2893 if (tmode == VOIDmode)
2896 /* Get X and Y in TMODE. We can't use gen_lowpart here because it
2897 may call change_address which is not appropriate if we were
2898 called when a reload was in progress. We don't have to worry
2899 about changing the address since the size in bytes is supposed to
2900 be the same. Copy the MEM to change the mode and move any
2901 substitutions from the old MEM to the new one. */
2903 if (reload_in_progress)
2905 x = gen_lowpart_common (tmode, x1);
2906 if (x == 0 && GET_CODE (x1) == MEM)
2908 x = gen_rtx (MEM, tmode, XEXP (x1, 0));
2909 RTX_UNCHANGING_P (x) = RTX_UNCHANGING_P (x1);
2910 MEM_IN_STRUCT_P (x) = MEM_IN_STRUCT_P (x1);
2911 MEM_VOLATILE_P (x) = MEM_VOLATILE_P (x1);
2912 copy_replacements (x1, x);
2915 y = gen_lowpart_common (tmode, y1);
2916 if (y == 0 && GET_CODE (y1) == MEM)
2918 y = gen_rtx (MEM, tmode, XEXP (y1, 0));
2919 RTX_UNCHANGING_P (y) = RTX_UNCHANGING_P (y1);
2920 MEM_IN_STRUCT_P (y) = MEM_IN_STRUCT_P (y1);
2921 MEM_VOLATILE_P (y) = MEM_VOLATILE_P (y1);
2922 copy_replacements (y1, y);
2927 x = gen_lowpart (tmode, x);
2928 y = gen_lowpart (tmode, y);
2931 insn_code = mov_optab->handlers[(int) tmode].insn_code;
2932 return (GEN_FCN (insn_code) (x, y));
2936 emit_move_insn_1 (x, y);
2937 seq = gen_sequence ();
2942 /* Return the insn code used to extend FROM_MODE to TO_MODE.
2943 UNSIGNEDP specifies zero-extension instead of sign-extension. If
2944 no such operation exists, CODE_FOR_nothing will be returned. */
2947 can_extend_p (to_mode, from_mode, unsignedp)
2948 enum machine_mode to_mode, from_mode;
2951 return extendtab[(int) to_mode][(int) from_mode][unsignedp];
2954 /* Generate the body of an insn to extend Y (with mode MFROM)
2955 into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */
2958 gen_extend_insn (x, y, mto, mfrom, unsignedp)
2960 enum machine_mode mto, mfrom;
2963 return (GEN_FCN (extendtab[(int) mto][(int) mfrom][unsignedp]) (x, y));
2966 /* can_fix_p and can_float_p say whether the target machine
2967 can directly convert a given fixed point type to
2968 a given floating point type, or vice versa.
2969 The returned value is the CODE_FOR_... value to use,
2970 or CODE_FOR_nothing if these modes cannot be directly converted.
2972 *TRUNCP_PTR is set to 1 if it is necessary to output
2973 an explicit FTRUNC insn before the fix insn; otherwise 0. */
2975 static enum insn_code
2976 can_fix_p (fixmode, fltmode, unsignedp, truncp_ptr)
2977 enum machine_mode fltmode, fixmode;
2982 if (fixtrunctab[(int) fltmode][(int) fixmode][unsignedp] != CODE_FOR_nothing)
2983 return fixtrunctab[(int) fltmode][(int) fixmode][unsignedp];
2985 if (ftrunc_optab->handlers[(int) fltmode].insn_code != CODE_FOR_nothing)
2988 return fixtab[(int) fltmode][(int) fixmode][unsignedp];
2990 return CODE_FOR_nothing;
2993 static enum insn_code
2994 can_float_p (fltmode, fixmode, unsignedp)
2995 enum machine_mode fixmode, fltmode;
2998 return floattab[(int) fltmode][(int) fixmode][unsignedp];
3001 /* Generate code to convert FROM to floating point
3002 and store in TO. FROM must be fixed point and not VOIDmode.
3003 UNSIGNEDP nonzero means regard FROM as unsigned.
3004 Normally this is done by correcting the final value
3005 if it is negative. */
3008 expand_float (to, from, unsignedp)
3012 enum insn_code icode;
3013 register rtx target = to;
3014 enum machine_mode fmode, imode;
3016 /* Crash now, because we won't be able to decide which mode to use. */
3017 if (GET_MODE (from) == VOIDmode)
3020 /* Look for an insn to do the conversion. Do it in the specified
3021 modes if possible; otherwise convert either input, output or both to
3022 wider mode. If the integer mode is wider than the mode of FROM,
3023 we can do the conversion signed even if the input is unsigned. */
3025 for (imode = GET_MODE (from); imode != VOIDmode;
3026 imode = GET_MODE_WIDER_MODE (imode))
3027 for (fmode = GET_MODE (to); fmode != VOIDmode;
3028 fmode = GET_MODE_WIDER_MODE (fmode))
3030 int doing_unsigned = unsignedp;
3032 icode = can_float_p (fmode, imode, unsignedp);
3033 if (icode == CODE_FOR_nothing && imode != GET_MODE (from) && unsignedp)
3034 icode = can_float_p (fmode, imode, 0), doing_unsigned = 0;
3036 if (icode != CODE_FOR_nothing)
3038 to = protect_from_queue (to, 1);
3039 from = protect_from_queue (from, 0);
3041 if (imode != GET_MODE (from))
3042 from = convert_to_mode (imode, from, unsignedp);
3044 if (fmode != GET_MODE (to))
3045 target = gen_reg_rtx (fmode);
3047 emit_unop_insn (icode, target, from,
3048 doing_unsigned ? UNSIGNED_FLOAT : FLOAT);
3051 convert_move (to, target, 0);
3056 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
3058 /* Unsigned integer, and no way to convert directly.
3059 Convert as signed, then conditionally adjust the result. */
3062 rtx label = gen_label_rtx ();
3064 REAL_VALUE_TYPE offset;
3068 to = protect_from_queue (to, 1);
3069 from = protect_from_queue (from, 0);
3072 from = force_not_mem (from);
3074 /* Look for a usable floating mode FMODE wider than the source and at
3075 least as wide as the target. Using FMODE will avoid rounding woes
3076 with unsigned values greater than the signed maximum value. */
3077 for (fmode = GET_MODE (to); fmode != VOIDmode;
3078 fmode = GET_MODE_WIDER_MODE (fmode))
3079 if (GET_MODE_BITSIZE (GET_MODE (from)) < GET_MODE_BITSIZE (fmode)
3080 && can_float_p (fmode, GET_MODE (from), 0) != CODE_FOR_nothing)
3082 if (fmode == VOIDmode)
3084 /* There is no such mode. Pretend the target is wide enough.
3085 This may cause rounding problems, unfortunately. */
3086 fmode = GET_MODE (to);
3089 /* If we are about to do some arithmetic to correct for an
3090 unsigned operand, do it in a pseudo-register. */
3092 if (GET_MODE (to) != fmode
3093 || GET_CODE (to) != REG || REGNO (to) <= LAST_VIRTUAL_REGISTER)
3094 target = gen_reg_rtx (fmode);
3096 /* Convert as signed integer to floating. */
3097 expand_float (target, from, 0);
3099 /* If FROM is negative (and therefore TO is negative),
3100 correct its value by 2**bitwidth. */
3102 do_pending_stack_adjust ();
3103 emit_cmp_insn (from, const0_rtx, GE, NULL_RTX, GET_MODE (from), 0, 0);
3104 emit_jump_insn (gen_bge (label));
3105 /* On SCO 3.2.1, ldexp rejects values outside [0.5, 1).
3106 Rather than setting up a dconst_dot_5, let's hope SCO
3108 offset = REAL_VALUE_LDEXP (dconst1, GET_MODE_BITSIZE (GET_MODE (from)));
3109 temp = expand_binop (fmode, add_optab, target,
3110 immed_real_const_1 (offset, fmode),
3111 target, 0, OPTAB_LIB_WIDEN);
3113 emit_move_insn (target, temp);
3114 do_pending_stack_adjust ();
3120 /* No hardware instruction available; call a library rotine to convert from
3121 SImode, DImode, or TImode into SFmode, DFmode, XFmode, or TFmode. */
3127 to = protect_from_queue (to, 1);
3128 from = protect_from_queue (from, 0);
3130 if (GET_MODE_SIZE (GET_MODE (from)) < GET_MODE_SIZE (SImode))
3131 from = convert_to_mode (SImode, from, unsignedp);
3134 from = force_not_mem (from);
3136 if (GET_MODE (to) == SFmode)
3138 if (GET_MODE (from) == SImode)
3139 libfcn = floatsisf_libfunc;
3140 else if (GET_MODE (from) == DImode)
3141 libfcn = floatdisf_libfunc;
3142 else if (GET_MODE (from) == TImode)
3143 libfcn = floattisf_libfunc;
3147 else if (GET_MODE (to) == DFmode)
3149 if (GET_MODE (from) == SImode)
3150 libfcn = floatsidf_libfunc;
3151 else if (GET_MODE (from) == DImode)
3152 libfcn = floatdidf_libfunc;
3153 else if (GET_MODE (from) == TImode)
3154 libfcn = floattidf_libfunc;
3158 else if (GET_MODE (to) == XFmode)
3160 if (GET_MODE (from) == SImode)
3161 libfcn = floatsixf_libfunc;
3162 else if (GET_MODE (from) == DImode)
3163 libfcn = floatdixf_libfunc;
3164 else if (GET_MODE (from) == TImode)
3165 libfcn = floattixf_libfunc;
3169 else if (GET_MODE (to) == TFmode)
3171 if (GET_MODE (from) == SImode)
3172 libfcn = floatsitf_libfunc;
3173 else if (GET_MODE (from) == DImode)
3174 libfcn = floatditf_libfunc;
3175 else if (GET_MODE (from) == TImode)
3176 libfcn = floattitf_libfunc;
3185 value = emit_library_call_value (libfcn, NULL_RTX, 1,
3187 1, from, GET_MODE (from));
3188 insns = get_insns ();
3191 emit_libcall_block (insns, target, value,
3192 gen_rtx (FLOAT, GET_MODE (to), from));
3195 /* Copy result to requested destination
3196 if we have been computing in a temp location. */
3200 if (GET_MODE (target) == GET_MODE (to))
3201 emit_move_insn (to, target);
3203 convert_move (to, target, 0);
3207 /* expand_fix: generate code to convert FROM to fixed point
3208 and store in TO. FROM must be floating point. */
3214 rtx temp = gen_reg_rtx (GET_MODE (x));
3215 return expand_unop (GET_MODE (x), ftrunc_optab, x, temp, 0);
3219 expand_fix (to, from, unsignedp)
3220 register rtx to, from;
3223 enum insn_code icode;
3224 register rtx target = to;
3225 enum machine_mode fmode, imode;
3229 /* We first try to find a pair of modes, one real and one integer, at
3230 least as wide as FROM and TO, respectively, in which we can open-code
3231 this conversion. If the integer mode is wider than the mode of TO,
3232 we can do the conversion either signed or unsigned. */
3234 for (imode = GET_MODE (to); imode != VOIDmode;
3235 imode = GET_MODE_WIDER_MODE (imode))
3236 for (fmode = GET_MODE (from); fmode != VOIDmode;
3237 fmode = GET_MODE_WIDER_MODE (fmode))
3239 int doing_unsigned = unsignedp;
3241 icode = can_fix_p (imode, fmode, unsignedp, &must_trunc);
3242 if (icode == CODE_FOR_nothing && imode != GET_MODE (to) && unsignedp)
3243 icode = can_fix_p (imode, fmode, 0, &must_trunc), doing_unsigned = 0;
3245 if (icode != CODE_FOR_nothing)
3247 to = protect_from_queue (to, 1);
3248 from = protect_from_queue (from, 0);
3250 if (fmode != GET_MODE (from))
3251 from = convert_to_mode (fmode, from, 0);
3254 from = ftruncify (from);
3256 if (imode != GET_MODE (to))
3257 target = gen_reg_rtx (imode);
3259 emit_unop_insn (icode, target, from,
3260 doing_unsigned ? UNSIGNED_FIX : FIX);
3262 convert_move (to, target, unsignedp);
3267 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
3268 /* For an unsigned conversion, there is one more way to do it.
3269 If we have a signed conversion, we generate code that compares
3270 the real value to the largest representable positive number. If if
3271 is smaller, the conversion is done normally. Otherwise, subtract
3272 one plus the highest signed number, convert, and add it back.
3274 We only need to check all real modes, since we know we didn't find
3275 anything with a wider integer mode. */
3277 if (unsignedp && GET_MODE_BITSIZE (GET_MODE (to)) <= HOST_BITS_PER_WIDE_INT)
3278 for (fmode = GET_MODE (from); fmode != VOIDmode;
3279 fmode = GET_MODE_WIDER_MODE (fmode))
3280 /* Make sure we won't lose significant bits doing this. */
3281 if (GET_MODE_BITSIZE (fmode) > GET_MODE_BITSIZE (GET_MODE (to))
3282 && CODE_FOR_nothing != can_fix_p (GET_MODE (to), fmode, 0,
3286 REAL_VALUE_TYPE offset;
3287 rtx limit, lab1, lab2, insn;
3289 bitsize = GET_MODE_BITSIZE (GET_MODE (to));
3290 offset = REAL_VALUE_LDEXP (dconst1, bitsize - 1);
3291 limit = immed_real_const_1 (offset, fmode);
3292 lab1 = gen_label_rtx ();
3293 lab2 = gen_label_rtx ();
3296 to = protect_from_queue (to, 1);
3297 from = protect_from_queue (from, 0);
3300 from = force_not_mem (from);
3302 if (fmode != GET_MODE (from))
3303 from = convert_to_mode (fmode, from, 0);
3305 /* See if we need to do the subtraction. */
3306 do_pending_stack_adjust ();
3307 emit_cmp_insn (from, limit, GE, NULL_RTX, GET_MODE (from), 0, 0);
3308 emit_jump_insn (gen_bge (lab1));
3310 /* If not, do the signed "fix" and branch around fixup code. */
3311 expand_fix (to, from, 0);
3312 emit_jump_insn (gen_jump (lab2));
3315 /* Otherwise, subtract 2**(N-1), convert to signed number,
3316 then add 2**(N-1). Do the addition using XOR since this
3317 will often generate better code. */
3319 target = expand_binop (GET_MODE (from), sub_optab, from, limit,
3320 NULL_RTX, 0, OPTAB_LIB_WIDEN);
3321 expand_fix (to, target, 0);
3322 target = expand_binop (GET_MODE (to), xor_optab, to,
3323 GEN_INT ((HOST_WIDE_INT) 1 << (bitsize - 1)),
3324 to, 1, OPTAB_LIB_WIDEN);
3327 emit_move_insn (to, target);
3331 /* Make a place for a REG_NOTE and add it. */
3332 insn = emit_move_insn (to, to);
3333 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL,
3334 gen_rtx (UNSIGNED_FIX, GET_MODE (to),
3342 /* We can't do it with an insn, so use a library call. But first ensure
3343 that the mode of TO is at least as wide as SImode, since those are the
3344 only library calls we know about. */
3346 if (GET_MODE_SIZE (GET_MODE (to)) < GET_MODE_SIZE (SImode))
3348 target = gen_reg_rtx (SImode);
3350 expand_fix (target, from, unsignedp);
3352 else if (GET_MODE (from) == SFmode)
3354 if (GET_MODE (to) == SImode)
3355 libfcn = unsignedp ? fixunssfsi_libfunc : fixsfsi_libfunc;
3356 else if (GET_MODE (to) == DImode)
3357 libfcn = unsignedp ? fixunssfdi_libfunc : fixsfdi_libfunc;
3358 else if (GET_MODE (to) == TImode)
3359 libfcn = unsignedp ? fixunssfti_libfunc : fixsfti_libfunc;
3363 else if (GET_MODE (from) == DFmode)
3365 if (GET_MODE (to) == SImode)
3366 libfcn = unsignedp ? fixunsdfsi_libfunc : fixdfsi_libfunc;
3367 else if (GET_MODE (to) == DImode)
3368 libfcn = unsignedp ? fixunsdfdi_libfunc : fixdfdi_libfunc;
3369 else if (GET_MODE (to) == TImode)
3370 libfcn = unsignedp ? fixunsdfti_libfunc : fixdfti_libfunc;
3374 else if (GET_MODE (from) == XFmode)
3376 if (GET_MODE (to) == SImode)
3377 libfcn = unsignedp ? fixunsxfsi_libfunc : fixxfsi_libfunc;
3378 else if (GET_MODE (to) == DImode)
3379 libfcn = unsignedp ? fixunsxfdi_libfunc : fixxfdi_libfunc;
3380 else if (GET_MODE (to) == TImode)
3381 libfcn = unsignedp ? fixunsxfti_libfunc : fixxfti_libfunc;
3385 else if (GET_MODE (from) == TFmode)
3387 if (GET_MODE (to) == SImode)
3388 libfcn = unsignedp ? fixunstfsi_libfunc : fixtfsi_libfunc;
3389 else if (GET_MODE (to) == DImode)
3390 libfcn = unsignedp ? fixunstfdi_libfunc : fixtfdi_libfunc;
3391 else if (GET_MODE (to) == TImode)
3392 libfcn = unsignedp ? fixunstfti_libfunc : fixtfti_libfunc;
3403 to = protect_from_queue (to, 1);
3404 from = protect_from_queue (from, 0);
3407 from = force_not_mem (from);
3411 emit_library_call (libfcn, 1, GET_MODE (to), 1, from, GET_MODE (from));
3412 insns = get_insns ();
3415 emit_libcall_block (insns, target, hard_libcall_value (GET_MODE (to)),
3416 gen_rtx (unsignedp ? FIX : UNSIGNED_FIX,
3417 GET_MODE (to), from));
3420 if (GET_MODE (to) == GET_MODE (target))
3421 emit_move_insn (to, target);
3423 convert_move (to, target, 0);
3431 optab op = (optab) xmalloc (sizeof (struct optab));
3433 for (i = 0; i < NUM_MACHINE_MODES; i++)
3435 op->handlers[i].insn_code = CODE_FOR_nothing;
3436 op->handlers[i].libfunc = 0;
3439 if (code != UNKNOWN)
3440 code_to_optab[(int) code] = op;
3445 /* Initialize the libfunc fields of an entire group of entries in some
3446 optab. Each entry is set equal to a string consisting of a leading
3447 pair of underscores followed by a generic operation name followed by
3448 a mode name (downshifted to lower case) followed by a single character
3449 representing the number of operands for the given operation (which is
3450 usually one of the characters '2', '3', or '4').
3452 OPTABLE is the table in which libfunc fields are to be initialized.
3453 FIRST_MODE is the first machine mode index in the given optab to
3455 LAST_MODE is the last machine mode index in the given optab to
3457 OPNAME is the generic (string) name of the operation.
3458 SUFFIX is the character which specifies the number of operands for
3459 the given generic operation.
3463 init_libfuncs (optable, first_mode, last_mode, opname, suffix)
3464 register optab optable;
3465 register int first_mode;
3466 register int last_mode;
3467 register char *opname;
3468 register char suffix;
3471 register unsigned opname_len = strlen (opname);
3473 for (mode = first_mode; (int) mode <= (int) last_mode;
3474 mode = (enum machine_mode) ((int) mode + 1))
3476 register char *mname = mode_name[(int) mode];
3477 register unsigned mname_len = strlen (mname);
3478 register char *libfunc_name
3479 = (char *) xmalloc (2 + opname_len + mname_len + 1 + 1);
3486 for (q = opname; *q; )
3488 for (q = mname; *q; q++)
3489 *p++ = tolower (*q);
3492 optable->handlers[(int) mode].libfunc
3493 = gen_rtx (SYMBOL_REF, Pmode, libfunc_name);
3497 /* Initialize the libfunc fields of an entire group of entries in some
3498 optab which correspond to all integer mode operations. The parameters
3499 have the same meaning as similarly named ones for the `init_libfuncs'
3500 routine. (See above). */
3503 init_integral_libfuncs (optable, opname, suffix)
3504 register optab optable;
3505 register char *opname;
3506 register char suffix;
3508 init_libfuncs (optable, SImode, TImode, opname, suffix);
3511 /* Initialize the libfunc fields of an entire group of entries in some
3512 optab which correspond to all real mode operations. The parameters
3513 have the same meaning as similarly named ones for the `init_libfuncs'
3514 routine. (See above). */
3517 init_floating_libfuncs (optable, opname, suffix)
3518 register optab optable;
3519 register char *opname;
3520 register char suffix;
3522 init_libfuncs (optable, SFmode, TFmode, opname, suffix);
3525 /* Initialize the libfunc fields of an entire group of entries in some
3526 optab which correspond to all complex floating modes. The parameters
3527 have the same meaning as similarly named ones for the `init_libfuncs'
3528 routine. (See above). */
3531 init_complex_libfuncs (optable, opname, suffix)
3532 register optab optable;
3533 register char *opname;
3534 register char suffix;
3536 init_libfuncs (optable, SCmode, TCmode, opname, suffix);
3539 /* Call this once to initialize the contents of the optabs
3540 appropriately for the current target machine. */
3548 /* Start by initializing all tables to contain CODE_FOR_nothing. */
3550 for (p = fixtab[0][0];
3551 p < fixtab[0][0] + sizeof fixtab / sizeof (fixtab[0][0][0]);
3553 *p = CODE_FOR_nothing;
3555 for (p = fixtrunctab[0][0];
3556 p < fixtrunctab[0][0] + sizeof fixtrunctab / sizeof (fixtrunctab[0][0][0]);
3558 *p = CODE_FOR_nothing;
3560 for (p = floattab[0][0];
3561 p < floattab[0][0] + sizeof floattab / sizeof (floattab[0][0][0]);
3563 *p = CODE_FOR_nothing;
3565 for (p = extendtab[0][0];
3566 p < extendtab[0][0] + sizeof extendtab / sizeof extendtab[0][0][0];
3568 *p = CODE_FOR_nothing;
3570 for (i = 0; i < NUM_RTX_CODE; i++)
3571 setcc_gen_code[i] = CODE_FOR_nothing;
3573 add_optab = init_optab (PLUS);
3574 sub_optab = init_optab (MINUS);
3575 smul_optab = init_optab (MULT);
3576 smul_widen_optab = init_optab (UNKNOWN);
3577 umul_widen_optab = init_optab (UNKNOWN);
3578 sdiv_optab = init_optab (DIV);
3579 sdivmod_optab = init_optab (UNKNOWN);
3580 udiv_optab = init_optab (UDIV);
3581 udivmod_optab = init_optab (UNKNOWN);
3582 smod_optab = init_optab (MOD);
3583 umod_optab = init_optab (UMOD);
3584 flodiv_optab = init_optab (DIV);
3585 ftrunc_optab = init_optab (UNKNOWN);
3586 and_optab = init_optab (AND);
3587 ior_optab = init_optab (IOR);
3588 xor_optab = init_optab (XOR);
3589 ashl_optab = init_optab (ASHIFT);
3590 ashr_optab = init_optab (ASHIFTRT);
3591 lshl_optab = init_optab (LSHIFT);
3592 lshr_optab = init_optab (LSHIFTRT);
3593 rotl_optab = init_optab (ROTATE);
3594 rotr_optab = init_optab (ROTATERT);
3595 smin_optab = init_optab (SMIN);
3596 smax_optab = init_optab (SMAX);
3597 umin_optab = init_optab (UMIN);
3598 umax_optab = init_optab (UMAX);
3599 mov_optab = init_optab (UNKNOWN);
3600 movstrict_optab = init_optab (UNKNOWN);
3601 cmp_optab = init_optab (UNKNOWN);
3602 ucmp_optab = init_optab (UNKNOWN);
3603 tst_optab = init_optab (UNKNOWN);
3604 neg_optab = init_optab (NEG);
3605 abs_optab = init_optab (ABS);
3606 one_cmpl_optab = init_optab (NOT);
3607 ffs_optab = init_optab (FFS);
3608 sqrt_optab = init_optab (SQRT);
3609 sin_optab = init_optab (UNKNOWN);
3610 cos_optab = init_optab (UNKNOWN);
3611 strlen_optab = init_optab (UNKNOWN);
3613 for (i = 0; i < NUM_MACHINE_MODES; i++)
3615 movstr_optab[i] = CODE_FOR_nothing;
3617 #ifdef HAVE_SECONDARY_RELOADS
3618 reload_in_optab[i] = reload_out_optab[i] = CODE_FOR_nothing;
3622 /* Fill in the optabs with the insns we support. */
3625 #ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC
3626 /* This flag says the same insns that convert to a signed fixnum
3627 also convert validly to an unsigned one. */
3628 for (i = 0; i < NUM_MACHINE_MODES; i++)
3629 for (j = 0; j < NUM_MACHINE_MODES; j++)
3630 fixtrunctab[i][j][1] = fixtrunctab[i][j][0];
3633 #ifdef EXTRA_CC_MODES
3637 /* Initialize the optabs with the names of the library functions. */
3638 init_integral_libfuncs (add_optab, "add", '3');
3639 init_floating_libfuncs (add_optab, "add", '3');
3640 init_integral_libfuncs (sub_optab, "sub", '3');
3641 init_floating_libfuncs (sub_optab, "sub", '3');
3642 init_integral_libfuncs (smul_optab, "mul", '3');
3643 init_floating_libfuncs (smul_optab, "mul", '3');
3644 init_integral_libfuncs (sdiv_optab, "div", '3');
3645 init_integral_libfuncs (udiv_optab, "udiv", '3');
3646 init_integral_libfuncs (sdivmod_optab, "divmod", '4');
3647 init_integral_libfuncs (udivmod_optab, "udivmod", '4');
3648 init_integral_libfuncs (smod_optab, "mod", '3');
3649 init_integral_libfuncs (umod_optab, "umod", '3');
3650 init_floating_libfuncs (flodiv_optab, "div", '3');
3651 init_floating_libfuncs (ftrunc_optab, "ftrunc", '2');
3652 init_integral_libfuncs (and_optab, "and", '3');
3653 init_integral_libfuncs (ior_optab, "ior", '3');
3654 init_integral_libfuncs (xor_optab, "xor", '3');
3655 init_integral_libfuncs (ashl_optab, "ashl", '3');
3656 init_integral_libfuncs (ashr_optab, "ashr", '3');
3657 init_integral_libfuncs (lshl_optab, "lshl", '3');
3658 init_integral_libfuncs (lshr_optab, "lshr", '3');
3659 init_integral_libfuncs (rotl_optab, "rotl", '3');
3660 init_integral_libfuncs (rotr_optab, "rotr", '3');
3661 init_integral_libfuncs (smin_optab, "min", '3');
3662 init_floating_libfuncs (smin_optab, "min", '3');
3663 init_integral_libfuncs (smax_optab, "max", '3');
3664 init_floating_libfuncs (smax_optab, "max", '3');
3665 init_integral_libfuncs (umin_optab, "umin", '3');
3666 init_integral_libfuncs (umax_optab, "umax", '3');
3667 init_integral_libfuncs (neg_optab, "neg", '2');
3668 init_floating_libfuncs (neg_optab, "neg", '2');
3669 init_integral_libfuncs (one_cmpl_optab, "one_cmpl", '2');
3670 init_integral_libfuncs (ffs_optab, "ffs", '2');
3672 /* Comparison libcalls for integers MUST come in pairs, signed/unsigned. */
3673 init_integral_libfuncs (cmp_optab, "cmp", '2');
3674 init_integral_libfuncs (ucmp_optab, "ucmp", '2');
3675 init_floating_libfuncs (cmp_optab, "cmp", '2');
3677 #ifdef MULSI3_LIBCALL
3678 smul_optab->handlers[(int) SImode].libfunc
3679 = gen_rtx (SYMBOL_REF, Pmode, MULSI3_LIBCALL);
3681 #ifdef MULDI3_LIBCALL
3682 smul_optab->handlers[(int) DImode].libfunc
3683 = gen_rtx (SYMBOL_REF, Pmode, MULDI3_LIBCALL);
3685 #ifdef MULTI3_LIBCALL
3686 smul_optab->handlers[(int) TImode].libfunc
3687 = gen_rtx (SYMBOL_REF, Pmode, MULTI3_LIBCALL);
3690 #ifdef DIVSI3_LIBCALL
3691 sdiv_optab->handlers[(int) SImode].libfunc
3692 = gen_rtx (SYMBOL_REF, Pmode, DIVSI3_LIBCALL);
3694 #ifdef DIVDI3_LIBCALL
3695 sdiv_optab->handlers[(int) DImode].libfunc
3696 = gen_rtx (SYMBOL_REF, Pmode, DIVDI3_LIBCALL);
3698 #ifdef DIVTI3_LIBCALL
3699 sdiv_optab->handlers[(int) TImode].libfunc
3700 = gen_rtx (SYMBOL_REF, Pmode, DIVTI3_LIBCALL);
3703 #ifdef UDIVSI3_LIBCALL
3704 udiv_optab->handlers[(int) SImode].libfunc
3705 = gen_rtx (SYMBOL_REF, Pmode, UDIVSI3_LIBCALL);
3707 #ifdef UDIVDI3_LIBCALL
3708 udiv_optab->handlers[(int) DImode].libfunc
3709 = gen_rtx (SYMBOL_REF, Pmode, UDIVDI3_LIBCALL);
3711 #ifdef UDIVTI3_LIBCALL
3712 udiv_optab->handlers[(int) TImode].libfunc
3713 = gen_rtx (SYMBOL_REF, Pmode, UDIVTI3_LIBCALL);
3717 #ifdef MODSI3_LIBCALL
3718 smod_optab->handlers[(int) SImode].libfunc
3719 = gen_rtx (SYMBOL_REF, Pmode, MODSI3_LIBCALL);
3721 #ifdef MODDI3_LIBCALL
3722 smod_optab->handlers[(int) DImode].libfunc
3723 = gen_rtx (SYMBOL_REF, Pmode, MODDI3_LIBCALL);
3725 #ifdef MODTI3_LIBCALL
3726 smod_optab->handlers[(int) TImode].libfunc
3727 = gen_rtx (SYMBOL_REF, Pmode, MODTI3_LIBCALL);
3731 #ifdef UMODSI3_LIBCALL
3732 umod_optab->handlers[(int) SImode].libfunc
3733 = gen_rtx (SYMBOL_REF, Pmode, UMODSI3_LIBCALL);
3735 #ifdef UMODDI3_LIBCALL
3736 umod_optab->handlers[(int) DImode].libfunc
3737 = gen_rtx (SYMBOL_REF, Pmode, UMODDI3_LIBCALL);
3739 #ifdef UMODTI3_LIBCALL
3740 umod_optab->handlers[(int) TImode].libfunc
3741 = gen_rtx (SYMBOL_REF, Pmode, UMODTI3_LIBCALL);
3744 /* Define library calls for quad FP instructions */
3745 #ifdef ADDTF3_LIBCALL
3746 add_optab->handlers[(int) TFmode].libfunc
3747 = gen_rtx (SYMBOL_REF, Pmode, ADDTF3_LIBCALL);
3749 #ifdef SUBTF3_LIBCALL
3750 sub_optab->handlers[(int) TFmode].libfunc
3751 = gen_rtx (SYMBOL_REF, Pmode, SUBTF3_LIBCALL);
3753 #ifdef MULTF3_LIBCALL
3754 smul_optab->handlers[(int) TFmode].libfunc
3755 = gen_rtx (SYMBOL_REF, Pmode, MULTF3_LIBCALL);
3757 #ifdef DIVTF3_LIBCALL
3758 flodiv_optab->handlers[(int) TFmode].libfunc
3759 = gen_rtx (SYMBOL_REF, Pmode, DIVTF3_LIBCALL);
3761 #ifdef SQRTTF2_LIBCALL
3762 sqrt_optab->handlers[(int) TFmode].libfunc
3763 = gen_rtx (SYMBOL_REF, Pmode, SQRTTF2_LIBCALL);
3766 /* Use cabs for DC complex abs, since systems generally have cabs.
3767 Don't define any libcall for SCmode, so that cabs will be used. */
3768 abs_optab->handlers[(int) DCmode].libfunc
3769 = gen_rtx (SYMBOL_REF, Pmode, "cabs");
3771 /* The ffs function operates on `int'. */
3772 #ifndef INT_TYPE_SIZE
3773 #define INT_TYPE_SIZE BITS_PER_WORD
3775 ffs_optab->handlers[(int) mode_for_size (INT_TYPE_SIZE, MODE_INT, 0)] .libfunc
3776 = gen_rtx (SYMBOL_REF, Pmode, "ffs");
3778 extendsfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extendsfdf2");
3779 extendsfxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extendsfxf2");
3780 extendsftf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extendsftf2");
3781 extenddfxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extenddfxf2");
3782 extenddftf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extenddftf2");
3784 truncdfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__truncdfsf2");
3785 truncxfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__truncxfsf2");
3786 trunctfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__trunctfsf2");
3787 truncxfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__truncxfdf2");
3788 trunctfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__trunctfdf2");
3790 memcpy_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memcpy");
3791 bcopy_libfunc = gen_rtx (SYMBOL_REF, Pmode, "bcopy");
3792 memcmp_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memcmp");
3793 bcmp_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gcc_bcmp");
3794 memset_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memset");
3795 bzero_libfunc = gen_rtx (SYMBOL_REF, Pmode, "bzero");
3797 eqsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqsf2");
3798 nesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nesf2");
3799 gtsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtsf2");
3800 gesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gesf2");
3801 ltsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltsf2");
3802 lesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lesf2");
3804 eqdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqdf2");
3805 nedf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nedf2");
3806 gtdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtdf2");
3807 gedf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gedf2");
3808 ltdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltdf2");
3809 ledf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ledf2");
3811 eqxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqxf2");
3812 nexf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nexf2");
3813 gtxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtxf2");
3814 gexf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gexf2");
3815 ltxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltxf2");
3816 lexf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lexf2");
3818 eqtf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqtf2");
3819 netf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__netf2");
3820 gttf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gttf2");
3821 getf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__getf2");
3822 lttf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lttf2");
3823 letf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__letf2");
3825 /* Define library calls for quad FP instructions */
3826 #ifdef EQTF2_LIBCALL
3827 eqtf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, EQTF2_LIBCALL);
3829 #ifdef NETF2_LIBCALL
3830 netf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, NETF2_LIBCALL);
3832 #ifdef GTTF2_LIBCALL
3833 gttf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, GTTF2_LIBCALL);
3835 #ifdef GETF2_LIBCALL
3836 getf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, GETF2_LIBCALL);
3838 #ifdef LTTF2_LIBCALL
3839 lttf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, LTTF2_LIBCALL);
3841 #ifdef LETF2_LIBCALL
3842 letf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, LETF2_LIBCALL);
3845 floatsisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsisf");
3846 floatdisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatdisf");
3847 floattisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattisf");
3849 floatsidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsidf");
3850 floatdidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatdidf");
3851 floattidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattidf");
3853 floatsixf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsixf");
3854 floatdixf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatdixf");
3855 floattixf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattixf");
3857 floatsitf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsitf");
3858 floatditf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatditf");
3859 floattitf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattitf");
3861 fixsfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixsfsi");
3862 fixsfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixsfdi");
3863 fixsfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixsfti");
3865 fixdfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixdfsi");
3866 fixdfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixdfdi");
3867 fixdfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixdfti");
3869 fixxfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixxfsi");
3870 fixxfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixxfdi");
3871 fixxfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixxfti");
3873 fixtfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixtfsi");
3874 fixtfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixtfdi");
3875 fixtfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixtfti");
3877 fixunssfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunssfsi");
3878 fixunssfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunssfdi");
3879 fixunssfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunssfti");
3881 fixunsdfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsdfsi");
3882 fixunsdfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsdfdi");
3883 fixunsdfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsdfti");
3885 fixunsxfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsxfsi");
3886 fixunsxfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsxfdi");
3887 fixunsxfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsxfti");
3889 fixunstfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunstfsi");
3890 fixunstfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunstfdi");
3891 fixunstfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunstfti");
3893 /* Define library calls for quad FP instructions */
3894 #ifdef TRUNCTFSF2_LIBCALL
3895 trunctfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, TRUNCTFSF2_LIBCALL);
3897 #ifdef TRUNCTFDF2_LIBCALL
3898 trunctfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, TRUNCTFDF2_LIBCALL);
3900 #ifdef EXTENDSFTF2_LIBCALL
3901 extendsftf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, EXTENDSFTF2_LIBCALL);
3903 #ifdef EXTENDDFTF2_LIBCALL
3904 extenddftf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, EXTENDDFTF2_LIBCALL);
3906 #ifdef FLOATSITF2_LIBCALL
3907 floatsitf_libfunc = gen_rtx (SYMBOL_REF, Pmode, FLOATSITF2_LIBCALL);
3909 #ifdef FIX_TRUNCTFSI2_LIBCALL
3910 fixtfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, FIX_TRUNCTFSI2_LIBCALL);
3917 /* SCO 3.2 apparently has a broken ldexp. */
3930 #endif /* BROKEN_LDEXP */