1 /* Expand the basic unary and binary arithmetic operations, for GNU compiler.
2 Copyright (C) 1987, 88, 92-98, 1999 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, 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
26 /* Include insn-config.h before expr.h so that HAVE_conditional_move
27 is properly defined. */
28 #include "insn-config.h"
32 #include "insn-flags.h"
33 #include "insn-codes.h"
38 /* Each optab contains info on how this target machine
39 can perform a particular operation
40 for all sizes and kinds of operands.
42 The operation to be performed is often specified
43 by passing one of these optabs as an argument.
45 See expr.h for documentation of these optabs. */
50 optab smul_highpart_optab;
51 optab umul_highpart_optab;
52 optab smul_widen_optab;
53 optab umul_widen_optab;
76 optab movstrict_optab;
87 optab ucmp_optab; /* Used only for libcalls for unsigned comparisons. */
92 /* Tables of patterns for extending one integer mode to another. */
93 enum insn_code extendtab[MAX_MACHINE_MODE][MAX_MACHINE_MODE][2];
95 /* Tables of patterns for converting between fixed and floating point. */
96 enum insn_code fixtab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
97 enum insn_code fixtrunctab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
98 enum insn_code floattab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
100 /* Contains the optab used for each rtx code. */
101 optab code_to_optab[NUM_RTX_CODE + 1];
103 /* SYMBOL_REF rtx's for the library functions that are called
104 implicitly and not via optabs. */
106 rtx extendsfdf2_libfunc;
107 rtx extendsfxf2_libfunc;
108 rtx extendsftf2_libfunc;
109 rtx extenddfxf2_libfunc;
110 rtx extenddftf2_libfunc;
112 rtx truncdfsf2_libfunc;
113 rtx truncxfsf2_libfunc;
114 rtx trunctfsf2_libfunc;
115 rtx truncxfdf2_libfunc;
116 rtx trunctfdf2_libfunc;
128 rtx sjpopnthrow_libfunc;
129 rtx terminate_libfunc;
132 rtx eh_rtime_match_libfunc;
169 rtx floatsisf_libfunc;
170 rtx floatdisf_libfunc;
171 rtx floattisf_libfunc;
173 rtx floatsidf_libfunc;
174 rtx floatdidf_libfunc;
175 rtx floattidf_libfunc;
177 rtx floatsixf_libfunc;
178 rtx floatdixf_libfunc;
179 rtx floattixf_libfunc;
181 rtx floatsitf_libfunc;
182 rtx floatditf_libfunc;
183 rtx floattitf_libfunc;
201 rtx fixunssfsi_libfunc;
202 rtx fixunssfdi_libfunc;
203 rtx fixunssfti_libfunc;
205 rtx fixunsdfsi_libfunc;
206 rtx fixunsdfdi_libfunc;
207 rtx fixunsdfti_libfunc;
209 rtx fixunsxfsi_libfunc;
210 rtx fixunsxfdi_libfunc;
211 rtx fixunsxfti_libfunc;
213 rtx fixunstfsi_libfunc;
214 rtx fixunstfdi_libfunc;
215 rtx fixunstfti_libfunc;
217 rtx chkr_check_addr_libfunc;
218 rtx chkr_set_right_libfunc;
219 rtx chkr_copy_bitmap_libfunc;
220 rtx chkr_check_exec_libfunc;
221 rtx chkr_check_str_libfunc;
223 rtx profile_function_entry_libfunc;
224 rtx profile_function_exit_libfunc;
226 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
227 gives the gen_function to make a branch to test that condition. */
229 rtxfun bcc_gen_fctn[NUM_RTX_CODE];
231 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
232 gives the insn code to make a store-condition insn
233 to test that condition. */
235 enum insn_code setcc_gen_code[NUM_RTX_CODE];
237 #ifdef HAVE_conditional_move
238 /* Indexed by the machine mode, gives the insn code to make a conditional
239 move insn. This is not indexed by the rtx-code like bcc_gen_fctn and
240 setcc_gen_code to cut down on the number of named patterns. Consider a day
241 when a lot more rtx codes are conditional (eg: for the ARM). */
243 enum insn_code movcc_gen_code[NUM_MACHINE_MODES];
246 static int add_equal_note PROTO((rtx, rtx, enum rtx_code, rtx, rtx));
247 static rtx widen_operand PROTO((rtx, enum machine_mode,
248 enum machine_mode, int, int));
249 static int expand_cmplxdiv_straight PROTO((rtx, rtx, rtx, rtx,
250 rtx, rtx, enum machine_mode,
251 int, enum optab_methods,
252 enum mode_class, optab));
253 static int expand_cmplxdiv_wide PROTO((rtx, rtx, rtx, rtx,
254 rtx, rtx, enum machine_mode,
255 int, enum optab_methods,
256 enum mode_class, optab));
257 static enum insn_code can_fix_p PROTO((enum machine_mode, enum machine_mode,
259 static enum insn_code can_float_p PROTO((enum machine_mode, enum machine_mode,
261 static rtx ftruncify PROTO((rtx));
262 static optab init_optab PROTO((enum rtx_code));
263 static void init_libfuncs PROTO((optab, int, int, const char *, int));
264 static void init_integral_libfuncs PROTO((optab, const char *, int));
265 static void init_floating_libfuncs PROTO((optab, const char *, int));
266 #ifdef HAVE_conditional_trap
267 static void init_traps PROTO((void));
270 /* Add a REG_EQUAL note to the last insn in SEQ. TARGET is being set to
271 the result of operation CODE applied to OP0 (and OP1 if it is a binary
274 If the last insn does not set TARGET, don't do anything, but return 1.
276 If a previous insn sets TARGET and TARGET is one of OP0 or OP1,
277 don't add the REG_EQUAL note but return 0. Our caller can then try
278 again, ensuring that TARGET is not one of the operands. */
281 add_equal_note (seq, target, code, op0, op1)
291 if ((GET_RTX_CLASS (code) != '1' && GET_RTX_CLASS (code) != '2'
292 && GET_RTX_CLASS (code) != 'c' && GET_RTX_CLASS (code) != '<')
293 || GET_CODE (seq) != SEQUENCE
294 || (set = single_set (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1))) == 0
295 || GET_CODE (target) == ZERO_EXTRACT
296 || (! rtx_equal_p (SET_DEST (set), target)
297 /* For a STRICT_LOW_PART, the REG_NOTE applies to what is inside the
299 && (GET_CODE (SET_DEST (set)) != STRICT_LOW_PART
300 || ! rtx_equal_p (SUBREG_REG (XEXP (SET_DEST (set), 0)),
304 /* If TARGET is in OP0 or OP1, check if anything in SEQ sets TARGET
305 besides the last insn. */
306 if (reg_overlap_mentioned_p (target, op0)
307 || (op1 && reg_overlap_mentioned_p (target, op1)))
308 for (i = XVECLEN (seq, 0) - 2; i >= 0; i--)
309 if (reg_set_p (target, XVECEXP (seq, 0, i)))
312 if (GET_RTX_CLASS (code) == '1')
313 note = gen_rtx_fmt_e (code, GET_MODE (target), copy_rtx (op0));
315 note = gen_rtx_fmt_ee (code, GET_MODE (target), copy_rtx (op0), copy_rtx (op1));
317 set_unique_reg_note (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1), REG_EQUAL, note);
322 /* Widen OP to MODE and return the rtx for the widened operand. UNSIGNEDP
323 says whether OP is signed or unsigned. NO_EXTEND is nonzero if we need
324 not actually do a sign-extend or zero-extend, but can leave the
325 higher-order bits of the result rtx undefined, for example, in the case
326 of logical operations, but not right shifts. */
329 widen_operand (op, mode, oldmode, unsignedp, no_extend)
331 enum machine_mode mode, oldmode;
337 /* If we must extend do so. If OP is either a constant or a SUBREG
338 for a promoted object, also extend since it will be more efficient to
341 || GET_MODE (op) == VOIDmode
342 || (GET_CODE (op) == SUBREG && SUBREG_PROMOTED_VAR_P (op)))
343 return convert_modes (mode, oldmode, op, unsignedp);
345 /* If MODE is no wider than a single word, we return a paradoxical
347 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
348 return gen_rtx_SUBREG (mode, force_reg (GET_MODE (op), op), 0);
350 /* Otherwise, get an object of MODE, clobber it, and set the low-order
353 result = gen_reg_rtx (mode);
354 emit_insn (gen_rtx_CLOBBER (VOIDmode, result));
355 emit_move_insn (gen_lowpart (GET_MODE (op), result), op);
359 /* Generate code to perform a straightforward complex divide. */
362 expand_cmplxdiv_straight (rtx real0, rtx real1, rtx imag0, rtx imag1,
363 rtx realr, rtx imagr, enum machine_mode submode,
364 int unsignedp, enum optab_methods methods,
365 enum mode_class class, optab binoptab)
372 /* Don't fetch these from memory more than once. */
373 real0 = force_reg (submode, real0);
374 real1 = force_reg (submode, real1);
377 imag0 = force_reg (submode, imag0);
379 imag1 = force_reg (submode, imag1);
381 /* Divisor: c*c + d*d. */
382 temp1 = expand_binop (submode, smul_optab, real1, real1,
383 NULL_RTX, unsignedp, methods);
385 temp2 = expand_binop (submode, smul_optab, imag1, imag1,
386 NULL_RTX, unsignedp, methods);
388 if (temp1 == 0 || temp2 == 0)
391 divisor = expand_binop (submode, add_optab, temp1, temp2,
392 NULL_RTX, unsignedp, methods);
398 /* Mathematically, ((a)(c-id))/divisor. */
399 /* Computationally, (a+i0) / (c+id) = (ac/(cc+dd)) + i(-ad/(cc+dd)). */
401 /* Calculate the dividend. */
402 real_t = expand_binop (submode, smul_optab, real0, real1,
403 NULL_RTX, unsignedp, methods);
405 imag_t = expand_binop (submode, smul_optab, real0, imag1,
406 NULL_RTX, unsignedp, methods);
408 if (real_t == 0 || imag_t == 0)
411 imag_t = expand_unop (submode, neg_optab, imag_t,
412 NULL_RTX, unsignedp);
416 /* Mathematically, ((a+ib)(c-id))/divider. */
417 /* Calculate the dividend. */
418 temp1 = expand_binop (submode, smul_optab, real0, real1,
419 NULL_RTX, unsignedp, methods);
421 temp2 = expand_binop (submode, smul_optab, imag0, imag1,
422 NULL_RTX, unsignedp, methods);
424 if (temp1 == 0 || temp2 == 0)
427 real_t = expand_binop (submode, add_optab, temp1, temp2,
428 NULL_RTX, unsignedp, methods);
430 temp1 = expand_binop (submode, smul_optab, imag0, real1,
431 NULL_RTX, unsignedp, methods);
433 temp2 = expand_binop (submode, smul_optab, real0, imag1,
434 NULL_RTX, unsignedp, methods);
436 if (temp1 == 0 || temp2 == 0)
439 imag_t = expand_binop (submode, sub_optab, temp1, temp2,
440 NULL_RTX, unsignedp, methods);
442 if (real_t == 0 || imag_t == 0)
446 if (class == MODE_COMPLEX_FLOAT)
447 res = expand_binop (submode, binoptab, real_t, divisor,
448 realr, unsignedp, methods);
450 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
451 real_t, divisor, realr, unsignedp);
457 emit_move_insn (realr, res);
459 if (class == MODE_COMPLEX_FLOAT)
460 res = expand_binop (submode, binoptab, imag_t, divisor,
461 imagr, unsignedp, methods);
463 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
464 imag_t, divisor, imagr, unsignedp);
470 emit_move_insn (imagr, res);
475 /* Generate code to perform a wide-input-range-acceptable complex divide. */
478 expand_cmplxdiv_wide (rtx real0, rtx real1, rtx imag0, rtx imag1,
479 rtx realr, rtx imagr, enum machine_mode submode,
480 int unsignedp, enum optab_methods methods,
481 enum mode_class class, optab binoptab)
485 rtx temp1, temp2, lab1, lab2;
486 enum machine_mode mode;
490 /* Don't fetch these from memory more than once. */
491 real0 = force_reg (submode, real0);
492 real1 = force_reg (submode, real1);
495 imag0 = force_reg (submode, imag0);
497 imag1 = force_reg (submode, imag1);
499 temp1 = expand_unop (submode, abs_optab, real1, NULL_RTX,
502 temp2 = expand_unop (submode, abs_optab, imag1, NULL_RTX,
505 if (temp1 == 0 || temp2 == 0)
508 mode = GET_MODE (temp1);
509 align = GET_MODE_ALIGNMENT (mode);
510 lab1 = gen_label_rtx ();
511 emit_cmp_and_jump_insns (temp1, temp2, LT, NULL_RTX,
512 mode, unsignedp, align, lab1);
514 /* |c| >= |d|; use ratio d/c to scale dividend and divisor. */
516 if (class == MODE_COMPLEX_FLOAT)
517 ratio = expand_binop (submode, binoptab, imag1, real1,
518 NULL_RTX, unsignedp, methods);
520 ratio = expand_divmod (0, TRUNC_DIV_EXPR, submode,
521 imag1, real1, NULL_RTX, unsignedp);
526 /* Calculate divisor. */
528 temp1 = expand_binop (submode, smul_optab, imag1, ratio,
529 NULL_RTX, unsignedp, methods);
534 divisor = expand_binop (submode, add_optab, temp1, real1,
535 NULL_RTX, unsignedp, methods);
540 /* Calculate dividend. */
546 /* Compute a / (c+id) as a / (c+d(d/c)) + i (-a(d/c)) / (c+d(d/c)). */
548 imag_t = expand_binop (submode, smul_optab, real0, ratio,
549 NULL_RTX, unsignedp, methods);
554 imag_t = expand_unop (submode, neg_optab, imag_t,
555 NULL_RTX, unsignedp);
557 if (real_t == 0 || imag_t == 0)
562 /* Compute (a+ib)/(c+id) as
563 (a+b(d/c))/(c+d(d/c) + i(b-a(d/c))/(c+d(d/c)). */
565 temp1 = expand_binop (submode, smul_optab, imag0, ratio,
566 NULL_RTX, unsignedp, methods);
571 real_t = expand_binop (submode, add_optab, temp1, real0,
572 NULL_RTX, unsignedp, methods);
574 temp1 = expand_binop (submode, smul_optab, real0, ratio,
575 NULL_RTX, unsignedp, methods);
580 imag_t = expand_binop (submode, sub_optab, imag0, temp1,
581 NULL_RTX, unsignedp, methods);
583 if (real_t == 0 || imag_t == 0)
587 if (class == MODE_COMPLEX_FLOAT)
588 res = expand_binop (submode, binoptab, real_t, divisor,
589 realr, unsignedp, methods);
591 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
592 real_t, divisor, realr, unsignedp);
598 emit_move_insn (realr, res);
600 if (class == MODE_COMPLEX_FLOAT)
601 res = expand_binop (submode, binoptab, imag_t, divisor,
602 imagr, unsignedp, methods);
604 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
605 imag_t, divisor, imagr, unsignedp);
611 emit_move_insn (imagr, res);
613 lab2 = gen_label_rtx ();
614 emit_jump_insn (gen_jump (lab2));
619 /* |d| > |c|; use ratio c/d to scale dividend and divisor. */
621 if (class == MODE_COMPLEX_FLOAT)
622 ratio = expand_binop (submode, binoptab, real1, imag1,
623 NULL_RTX, unsignedp, methods);
625 ratio = expand_divmod (0, TRUNC_DIV_EXPR, submode,
626 real1, imag1, NULL_RTX, unsignedp);
631 /* Calculate divisor. */
633 temp1 = expand_binop (submode, smul_optab, real1, ratio,
634 NULL_RTX, unsignedp, methods);
639 divisor = expand_binop (submode, add_optab, temp1, imag1,
640 NULL_RTX, unsignedp, methods);
645 /* Calculate dividend. */
649 /* Compute a / (c+id) as a(c/d) / (c(c/d)+d) + i (-a) / (c(c/d)+d). */
651 real_t = expand_binop (submode, smul_optab, real0, ratio,
652 NULL_RTX, unsignedp, methods);
654 imag_t = expand_unop (submode, neg_optab, real0,
655 NULL_RTX, unsignedp);
657 if (real_t == 0 || imag_t == 0)
662 /* Compute (a+ib)/(c+id) as
663 (a(c/d)+b)/(c(c/d)+d) + i (b(c/d)-a)/(c(c/d)+d). */
665 temp1 = expand_binop (submode, smul_optab, real0, ratio,
666 NULL_RTX, unsignedp, methods);
671 real_t = expand_binop (submode, add_optab, temp1, imag0,
672 NULL_RTX, unsignedp, methods);
674 temp1 = expand_binop (submode, smul_optab, imag0, ratio,
675 NULL_RTX, unsignedp, methods);
680 imag_t = expand_binop (submode, sub_optab, temp1, real0,
681 NULL_RTX, unsignedp, methods);
683 if (real_t == 0 || imag_t == 0)
687 if (class == MODE_COMPLEX_FLOAT)
688 res = expand_binop (submode, binoptab, real_t, divisor,
689 realr, unsignedp, methods);
691 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
692 real_t, divisor, realr, unsignedp);
698 emit_move_insn (realr, res);
700 if (class == MODE_COMPLEX_FLOAT)
701 res = expand_binop (submode, binoptab, imag_t, divisor,
702 imagr, unsignedp, methods);
704 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
705 imag_t, divisor, imagr, unsignedp);
711 emit_move_insn (imagr, res);
718 /* Generate code to perform an operation specified by BINOPTAB
719 on operands OP0 and OP1, with result having machine-mode MODE.
721 UNSIGNEDP is for the case where we have to widen the operands
722 to perform the operation. It says to use zero-extension.
724 If TARGET is nonzero, the value
725 is generated there, if it is convenient to do so.
726 In all cases an rtx is returned for the locus of the value;
727 this may or may not be TARGET. */
730 expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods)
731 enum machine_mode mode;
736 enum optab_methods methods;
738 enum optab_methods next_methods
739 = (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN
740 ? OPTAB_WIDEN : methods);
741 enum mode_class class;
742 enum machine_mode wider_mode;
744 int commutative_op = 0;
745 int shift_op = (binoptab->code == ASHIFT
746 || binoptab->code == ASHIFTRT
747 || binoptab->code == LSHIFTRT
748 || binoptab->code == ROTATE
749 || binoptab->code == ROTATERT);
750 rtx entry_last = get_last_insn ();
753 class = GET_MODE_CLASS (mode);
755 op0 = protect_from_queue (op0, 0);
756 op1 = protect_from_queue (op1, 0);
758 target = protect_from_queue (target, 1);
762 op0 = force_not_mem (op0);
763 op1 = force_not_mem (op1);
766 /* If subtracting an integer constant, convert this into an addition of
767 the negated constant. */
769 if (binoptab == sub_optab && GET_CODE (op1) == CONST_INT)
771 op1 = negate_rtx (mode, op1);
772 binoptab = add_optab;
775 /* If we are inside an appropriately-short loop and one operand is an
776 expensive constant, force it into a register. */
777 if (CONSTANT_P (op0) && preserve_subexpressions_p ()
778 && rtx_cost (op0, binoptab->code) > 2)
779 op0 = force_reg (mode, op0);
781 if (CONSTANT_P (op1) && preserve_subexpressions_p ()
782 && ! shift_op && rtx_cost (op1, binoptab->code) > 2)
783 op1 = force_reg (mode, op1);
785 /* Record where to delete back to if we backtrack. */
786 last = get_last_insn ();
788 /* If operation is commutative,
789 try to make the first operand a register.
790 Even better, try to make it the same as the target.
791 Also try to make the last operand a constant. */
792 if (GET_RTX_CLASS (binoptab->code) == 'c'
793 || binoptab == smul_widen_optab
794 || binoptab == umul_widen_optab
795 || binoptab == smul_highpart_optab
796 || binoptab == umul_highpart_optab)
800 if (((target == 0 || GET_CODE (target) == REG)
801 ? ((GET_CODE (op1) == REG
802 && GET_CODE (op0) != REG)
804 : rtx_equal_p (op1, target))
805 || GET_CODE (op0) == CONST_INT)
813 /* If we can do it with a three-operand insn, do so. */
815 if (methods != OPTAB_MUST_WIDEN
816 && binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
818 int icode = (int) binoptab->handlers[(int) mode].insn_code;
819 enum machine_mode mode0 = insn_operand_mode[icode][1];
820 enum machine_mode mode1 = insn_operand_mode[icode][2];
822 rtx xop0 = op0, xop1 = op1;
827 temp = gen_reg_rtx (mode);
829 /* If it is a commutative operator and the modes would match
830 if we would swap the operands, we can save the conversions. */
833 if (GET_MODE (op0) != mode0 && GET_MODE (op1) != mode1
834 && GET_MODE (op0) == mode1 && GET_MODE (op1) == mode0)
838 tmp = op0; op0 = op1; op1 = tmp;
839 tmp = xop0; xop0 = xop1; xop1 = tmp;
843 /* In case the insn wants input operands in modes different from
844 the result, convert the operands. */
846 if (GET_MODE (op0) != VOIDmode
847 && GET_MODE (op0) != mode0
848 && mode0 != VOIDmode)
849 xop0 = convert_to_mode (mode0, xop0, unsignedp);
851 if (GET_MODE (xop1) != VOIDmode
852 && GET_MODE (xop1) != mode1
853 && mode1 != VOIDmode)
854 xop1 = convert_to_mode (mode1, xop1, unsignedp);
856 /* Now, if insn's predicates don't allow our operands, put them into
859 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0)
860 && mode0 != VOIDmode)
861 xop0 = copy_to_mode_reg (mode0, xop0);
863 if (! (*insn_operand_predicate[icode][2]) (xop1, mode1)
864 && mode1 != VOIDmode)
865 xop1 = copy_to_mode_reg (mode1, xop1);
867 if (! (*insn_operand_predicate[icode][0]) (temp, mode))
868 temp = gen_reg_rtx (mode);
870 pat = GEN_FCN (icode) (temp, xop0, xop1);
873 /* If PAT is a multi-insn sequence, try to add an appropriate
874 REG_EQUAL note to it. If we can't because TEMP conflicts with an
875 operand, call ourselves again, this time without a target. */
876 if (GET_CODE (pat) == SEQUENCE
877 && ! add_equal_note (pat, temp, binoptab->code, xop0, xop1))
879 delete_insns_since (last);
880 return expand_binop (mode, binoptab, op0, op1, NULL_RTX,
888 delete_insns_since (last);
891 /* If this is a multiply, see if we can do a widening operation that
892 takes operands of this mode and makes a wider mode. */
894 if (binoptab == smul_optab && GET_MODE_WIDER_MODE (mode) != VOIDmode
895 && (((unsignedp ? umul_widen_optab : smul_widen_optab)
896 ->handlers[(int) GET_MODE_WIDER_MODE (mode)].insn_code)
897 != CODE_FOR_nothing))
899 temp = expand_binop (GET_MODE_WIDER_MODE (mode),
900 unsignedp ? umul_widen_optab : smul_widen_optab,
901 op0, op1, NULL_RTX, unsignedp, OPTAB_DIRECT);
905 if (GET_MODE_CLASS (mode) == MODE_INT)
906 return gen_lowpart (mode, temp);
908 return convert_to_mode (mode, temp, unsignedp);
912 /* Look for a wider mode of the same class for which we think we
913 can open-code the operation. Check for a widening multiply at the
914 wider mode as well. */
916 if ((class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
917 && methods != OPTAB_DIRECT && methods != OPTAB_LIB)
918 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
919 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
921 if (binoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing
922 || (binoptab == smul_optab
923 && GET_MODE_WIDER_MODE (wider_mode) != VOIDmode
924 && (((unsignedp ? umul_widen_optab : smul_widen_optab)
925 ->handlers[(int) GET_MODE_WIDER_MODE (wider_mode)].insn_code)
926 != CODE_FOR_nothing)))
928 rtx xop0 = op0, xop1 = op1;
931 /* For certain integer operations, we need not actually extend
932 the narrow operands, as long as we will truncate
933 the results to the same narrowness. */
935 if ((binoptab == ior_optab || binoptab == and_optab
936 || binoptab == xor_optab
937 || binoptab == add_optab || binoptab == sub_optab
938 || binoptab == smul_optab || binoptab == ashl_optab)
939 && class == MODE_INT)
942 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp, no_extend);
944 /* The second operand of a shift must always be extended. */
945 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
946 no_extend && binoptab != ashl_optab);
948 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
949 unsignedp, OPTAB_DIRECT);
952 if (class != MODE_INT)
955 target = gen_reg_rtx (mode);
956 convert_move (target, temp, 0);
960 return gen_lowpart (mode, temp);
963 delete_insns_since (last);
967 /* These can be done a word at a time. */
968 if ((binoptab == and_optab || binoptab == ior_optab || binoptab == xor_optab)
970 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
971 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
977 /* If TARGET is the same as one of the operands, the REG_EQUAL note
978 won't be accurate, so use a new target. */
979 if (target == 0 || target == op0 || target == op1)
980 target = gen_reg_rtx (mode);
984 /* Do the actual arithmetic. */
985 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
987 rtx target_piece = operand_subword (target, i, 1, mode);
988 rtx x = expand_binop (word_mode, binoptab,
989 operand_subword_force (op0, i, mode),
990 operand_subword_force (op1, i, mode),
991 target_piece, unsignedp, next_methods);
996 if (target_piece != x)
997 emit_move_insn (target_piece, x);
1000 insns = get_insns ();
1003 if (i == GET_MODE_BITSIZE (mode) / BITS_PER_WORD)
1005 if (binoptab->code != UNKNOWN)
1007 = gen_rtx_fmt_ee (binoptab->code, mode,
1008 copy_rtx (op0), copy_rtx (op1));
1012 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
1017 /* Synthesize double word shifts from single word shifts. */
1018 if ((binoptab == lshr_optab || binoptab == ashl_optab
1019 || binoptab == ashr_optab)
1020 && class == MODE_INT
1021 && GET_CODE (op1) == CONST_INT
1022 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
1023 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
1024 && ashl_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
1025 && lshr_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
1027 rtx insns, inter, equiv_value;
1028 rtx into_target, outof_target;
1029 rtx into_input, outof_input;
1030 int shift_count, left_shift, outof_word;
1032 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1033 won't be accurate, so use a new target. */
1034 if (target == 0 || target == op0 || target == op1)
1035 target = gen_reg_rtx (mode);
1039 shift_count = INTVAL (op1);
1041 /* OUTOF_* is the word we are shifting bits away from, and
1042 INTO_* is the word that we are shifting bits towards, thus
1043 they differ depending on the direction of the shift and
1044 WORDS_BIG_ENDIAN. */
1046 left_shift = binoptab == ashl_optab;
1047 outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
1049 outof_target = operand_subword (target, outof_word, 1, mode);
1050 into_target = operand_subword (target, 1 - outof_word, 1, mode);
1052 outof_input = operand_subword_force (op0, outof_word, mode);
1053 into_input = operand_subword_force (op0, 1 - outof_word, mode);
1055 if (shift_count >= BITS_PER_WORD)
1057 inter = expand_binop (word_mode, binoptab,
1059 GEN_INT (shift_count - BITS_PER_WORD),
1060 into_target, unsignedp, next_methods);
1062 if (inter != 0 && inter != into_target)
1063 emit_move_insn (into_target, inter);
1065 /* For a signed right shift, we must fill the word we are shifting
1066 out of with copies of the sign bit. Otherwise it is zeroed. */
1067 if (inter != 0 && binoptab != ashr_optab)
1068 inter = CONST0_RTX (word_mode);
1069 else if (inter != 0)
1070 inter = expand_binop (word_mode, binoptab,
1072 GEN_INT (BITS_PER_WORD - 1),
1073 outof_target, unsignedp, next_methods);
1075 if (inter != 0 && inter != outof_target)
1076 emit_move_insn (outof_target, inter);
1081 optab reverse_unsigned_shift, unsigned_shift;
1083 /* For a shift of less then BITS_PER_WORD, to compute the carry,
1084 we must do a logical shift in the opposite direction of the
1087 reverse_unsigned_shift = (left_shift ? lshr_optab : ashl_optab);
1089 /* For a shift of less than BITS_PER_WORD, to compute the word
1090 shifted towards, we need to unsigned shift the orig value of
1093 unsigned_shift = (left_shift ? ashl_optab : lshr_optab);
1095 carries = expand_binop (word_mode, reverse_unsigned_shift,
1097 GEN_INT (BITS_PER_WORD - shift_count),
1098 0, unsignedp, next_methods);
1103 inter = expand_binop (word_mode, unsigned_shift, into_input,
1104 op1, 0, unsignedp, next_methods);
1107 inter = expand_binop (word_mode, ior_optab, carries, inter,
1108 into_target, unsignedp, next_methods);
1110 if (inter != 0 && inter != into_target)
1111 emit_move_insn (into_target, inter);
1114 inter = expand_binop (word_mode, binoptab, outof_input,
1115 op1, outof_target, unsignedp, next_methods);
1117 if (inter != 0 && inter != outof_target)
1118 emit_move_insn (outof_target, inter);
1121 insns = get_insns ();
1126 if (binoptab->code != UNKNOWN)
1127 equiv_value = gen_rtx_fmt_ee (binoptab->code, mode, op0, op1);
1131 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
1136 /* Synthesize double word rotates from single word shifts. */
1137 if ((binoptab == rotl_optab || binoptab == rotr_optab)
1138 && class == MODE_INT
1139 && GET_CODE (op1) == CONST_INT
1140 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
1141 && ashl_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
1142 && lshr_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
1144 rtx insns, equiv_value;
1145 rtx into_target, outof_target;
1146 rtx into_input, outof_input;
1148 int shift_count, left_shift, outof_word;
1150 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1151 won't be accurate, so use a new target. */
1152 if (target == 0 || target == op0 || target == op1)
1153 target = gen_reg_rtx (mode);
1157 shift_count = INTVAL (op1);
1159 /* OUTOF_* is the word we are shifting bits away from, and
1160 INTO_* is the word that we are shifting bits towards, thus
1161 they differ depending on the direction of the shift and
1162 WORDS_BIG_ENDIAN. */
1164 left_shift = (binoptab == rotl_optab);
1165 outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
1167 outof_target = operand_subword (target, outof_word, 1, mode);
1168 into_target = operand_subword (target, 1 - outof_word, 1, mode);
1170 outof_input = operand_subword_force (op0, outof_word, mode);
1171 into_input = operand_subword_force (op0, 1 - outof_word, mode);
1173 if (shift_count == BITS_PER_WORD)
1175 /* This is just a word swap. */
1176 emit_move_insn (outof_target, into_input);
1177 emit_move_insn (into_target, outof_input);
1182 rtx into_temp1, into_temp2, outof_temp1, outof_temp2;
1183 rtx first_shift_count, second_shift_count;
1184 optab reverse_unsigned_shift, unsigned_shift;
1186 reverse_unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
1187 ? lshr_optab : ashl_optab);
1189 unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
1190 ? ashl_optab : lshr_optab);
1192 if (shift_count > BITS_PER_WORD)
1194 first_shift_count = GEN_INT (shift_count - BITS_PER_WORD);
1195 second_shift_count = GEN_INT (2*BITS_PER_WORD - shift_count);
1199 first_shift_count = GEN_INT (BITS_PER_WORD - shift_count);
1200 second_shift_count = GEN_INT (shift_count);
1203 into_temp1 = expand_binop (word_mode, unsigned_shift,
1204 outof_input, first_shift_count,
1205 NULL_RTX, unsignedp, next_methods);
1206 into_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
1207 into_input, second_shift_count,
1208 into_target, unsignedp, next_methods);
1210 if (into_temp1 != 0 && into_temp2 != 0)
1211 inter = expand_binop (word_mode, ior_optab, into_temp1, into_temp2,
1212 into_target, unsignedp, next_methods);
1216 if (inter != 0 && inter != into_target)
1217 emit_move_insn (into_target, inter);
1219 outof_temp1 = expand_binop (word_mode, unsigned_shift,
1220 into_input, first_shift_count,
1221 NULL_RTX, unsignedp, next_methods);
1222 outof_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
1223 outof_input, second_shift_count,
1224 outof_target, unsignedp, next_methods);
1226 if (inter != 0 && outof_temp1 != 0 && outof_temp2 != 0)
1227 inter = expand_binop (word_mode, ior_optab,
1228 outof_temp1, outof_temp2,
1229 outof_target, unsignedp, next_methods);
1231 if (inter != 0 && inter != outof_target)
1232 emit_move_insn (outof_target, inter);
1235 insns = get_insns ();
1240 if (binoptab->code != UNKNOWN)
1241 equiv_value = gen_rtx_fmt_ee (binoptab->code, mode, op0, op1);
1245 /* We can't make this a no conflict block if this is a word swap,
1246 because the word swap case fails if the input and output values
1247 are in the same register. */
1248 if (shift_count != BITS_PER_WORD)
1249 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
1258 /* These can be done a word at a time by propagating carries. */
1259 if ((binoptab == add_optab || binoptab == sub_optab)
1260 && class == MODE_INT
1261 && GET_MODE_SIZE (mode) >= 2 * UNITS_PER_WORD
1262 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
1265 rtx carry_tmp = gen_reg_rtx (word_mode);
1266 optab otheroptab = binoptab == add_optab ? sub_optab : add_optab;
1267 int nwords = GET_MODE_BITSIZE (mode) / BITS_PER_WORD;
1268 rtx carry_in = NULL_RTX, carry_out = NULL_RTX;
1271 /* We can handle either a 1 or -1 value for the carry. If STORE_FLAG
1272 value is one of those, use it. Otherwise, use 1 since it is the
1273 one easiest to get. */
1274 #if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
1275 int normalizep = STORE_FLAG_VALUE;
1280 /* Prepare the operands. */
1281 xop0 = force_reg (mode, op0);
1282 xop1 = force_reg (mode, op1);
1284 if (target == 0 || GET_CODE (target) != REG
1285 || target == xop0 || target == xop1)
1286 target = gen_reg_rtx (mode);
1288 /* Indicate for flow that the entire target reg is being set. */
1289 if (GET_CODE (target) == REG)
1290 emit_insn (gen_rtx_CLOBBER (VOIDmode, target));
1292 /* Do the actual arithmetic. */
1293 for (i = 0; i < nwords; i++)
1295 int index = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i);
1296 rtx target_piece = operand_subword (target, index, 1, mode);
1297 rtx op0_piece = operand_subword_force (xop0, index, mode);
1298 rtx op1_piece = operand_subword_force (xop1, index, mode);
1301 /* Main add/subtract of the input operands. */
1302 x = expand_binop (word_mode, binoptab,
1303 op0_piece, op1_piece,
1304 target_piece, unsignedp, next_methods);
1310 /* Store carry from main add/subtract. */
1311 carry_out = gen_reg_rtx (word_mode);
1312 carry_out = emit_store_flag_force (carry_out,
1313 (binoptab == add_optab
1316 word_mode, 1, normalizep);
1321 /* Add/subtract previous carry to main result. */
1322 x = expand_binop (word_mode,
1323 normalizep == 1 ? binoptab : otheroptab,
1325 target_piece, 1, next_methods);
1328 else if (target_piece != x)
1329 emit_move_insn (target_piece, x);
1333 /* THIS CODE HAS NOT BEEN TESTED. */
1334 /* Get out carry from adding/subtracting carry in. */
1335 carry_tmp = emit_store_flag_force (carry_tmp,
1336 binoptab == add_optab
1339 word_mode, 1, normalizep);
1341 /* Logical-ior the two poss. carry together. */
1342 carry_out = expand_binop (word_mode, ior_optab,
1343 carry_out, carry_tmp,
1344 carry_out, 0, next_methods);
1350 carry_in = carry_out;
1353 if (i == GET_MODE_BITSIZE (mode) / BITS_PER_WORD)
1355 if (mov_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1357 rtx temp = emit_move_insn (target, target);
1359 set_unique_reg_note (temp,
1361 gen_rtx_fmt_ee (binoptab->code, mode,
1368 delete_insns_since (last);
1371 /* If we want to multiply two two-word values and have normal and widening
1372 multiplies of single-word values, we can do this with three smaller
1373 multiplications. Note that we do not make a REG_NO_CONFLICT block here
1374 because we are not operating on one word at a time.
1376 The multiplication proceeds as follows:
1377 _______________________
1378 [__op0_high_|__op0_low__]
1379 _______________________
1380 * [__op1_high_|__op1_low__]
1381 _______________________________________________
1382 _______________________
1383 (1) [__op0_low__*__op1_low__]
1384 _______________________
1385 (2a) [__op0_low__*__op1_high_]
1386 _______________________
1387 (2b) [__op0_high_*__op1_low__]
1388 _______________________
1389 (3) [__op0_high_*__op1_high_]
1392 This gives a 4-word result. Since we are only interested in the
1393 lower 2 words, partial result (3) and the upper words of (2a) and
1394 (2b) don't need to be calculated. Hence (2a) and (2b) can be
1395 calculated using non-widening multiplication.
1397 (1), however, needs to be calculated with an unsigned widening
1398 multiplication. If this operation is not directly supported we
1399 try using a signed widening multiplication and adjust the result.
1400 This adjustment works as follows:
1402 If both operands are positive then no adjustment is needed.
1404 If the operands have different signs, for example op0_low < 0 and
1405 op1_low >= 0, the instruction treats the most significant bit of
1406 op0_low as a sign bit instead of a bit with significance
1407 2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low
1408 with 2**BITS_PER_WORD - op0_low, and two's complements the
1409 result. Conclusion: We need to add op1_low * 2**BITS_PER_WORD to
1412 Similarly, if both operands are negative, we need to add
1413 (op0_low + op1_low) * 2**BITS_PER_WORD.
1415 We use a trick to adjust quickly. We logically shift op0_low right
1416 (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to
1417 op0_high (op1_high) before it is used to calculate 2b (2a). If no
1418 logical shift exists, we do an arithmetic right shift and subtract
1421 if (binoptab == smul_optab
1422 && class == MODE_INT
1423 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
1424 && smul_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
1425 && add_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
1426 && ((umul_widen_optab->handlers[(int) mode].insn_code
1427 != CODE_FOR_nothing)
1428 || (smul_widen_optab->handlers[(int) mode].insn_code
1429 != CODE_FOR_nothing)))
1431 int low = (WORDS_BIG_ENDIAN ? 1 : 0);
1432 int high = (WORDS_BIG_ENDIAN ? 0 : 1);
1433 rtx op0_high = operand_subword_force (op0, high, mode);
1434 rtx op0_low = operand_subword_force (op0, low, mode);
1435 rtx op1_high = operand_subword_force (op1, high, mode);
1436 rtx op1_low = operand_subword_force (op1, low, mode);
1438 rtx op0_xhigh = NULL_RTX;
1439 rtx op1_xhigh = NULL_RTX;
1441 /* If the target is the same as one of the inputs, don't use it. This
1442 prevents problems with the REG_EQUAL note. */
1443 if (target == op0 || target == op1
1444 || (target != 0 && GET_CODE (target) != REG))
1447 /* Multiply the two lower words to get a double-word product.
1448 If unsigned widening multiplication is available, use that;
1449 otherwise use the signed form and compensate. */
1451 if (umul_widen_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1453 product = expand_binop (mode, umul_widen_optab, op0_low, op1_low,
1454 target, 1, OPTAB_DIRECT);
1456 /* If we didn't succeed, delete everything we did so far. */
1458 delete_insns_since (last);
1460 op0_xhigh = op0_high, op1_xhigh = op1_high;
1464 && smul_widen_optab->handlers[(int) mode].insn_code
1465 != CODE_FOR_nothing)
1467 rtx wordm1 = GEN_INT (BITS_PER_WORD - 1);
1468 product = expand_binop (mode, smul_widen_optab, op0_low, op1_low,
1469 target, 1, OPTAB_DIRECT);
1470 op0_xhigh = expand_binop (word_mode, lshr_optab, op0_low, wordm1,
1471 NULL_RTX, 1, next_methods);
1473 op0_xhigh = expand_binop (word_mode, add_optab, op0_high,
1474 op0_xhigh, op0_xhigh, 0, next_methods);
1477 op0_xhigh = expand_binop (word_mode, ashr_optab, op0_low, wordm1,
1478 NULL_RTX, 0, next_methods);
1480 op0_xhigh = expand_binop (word_mode, sub_optab, op0_high,
1481 op0_xhigh, op0_xhigh, 0,
1485 op1_xhigh = expand_binop (word_mode, lshr_optab, op1_low, wordm1,
1486 NULL_RTX, 1, next_methods);
1488 op1_xhigh = expand_binop (word_mode, add_optab, op1_high,
1489 op1_xhigh, op1_xhigh, 0, next_methods);
1492 op1_xhigh = expand_binop (word_mode, ashr_optab, op1_low, wordm1,
1493 NULL_RTX, 0, next_methods);
1495 op1_xhigh = expand_binop (word_mode, sub_optab, op1_high,
1496 op1_xhigh, op1_xhigh, 0,
1501 /* If we have been able to directly compute the product of the
1502 low-order words of the operands and perform any required adjustments
1503 of the operands, we proceed by trying two more multiplications
1504 and then computing the appropriate sum.
1506 We have checked above that the required addition is provided.
1507 Full-word addition will normally always succeed, especially if
1508 it is provided at all, so we don't worry about its failure. The
1509 multiplication may well fail, however, so we do handle that. */
1511 if (product && op0_xhigh && op1_xhigh)
1513 rtx product_high = operand_subword (product, high, 1, mode);
1514 rtx temp = expand_binop (word_mode, binoptab, op0_low, op1_xhigh,
1515 NULL_RTX, 0, OPTAB_DIRECT);
1518 temp = expand_binop (word_mode, add_optab, temp, product_high,
1519 product_high, 0, next_methods);
1521 if (temp != 0 && temp != product_high)
1522 emit_move_insn (product_high, temp);
1525 temp = expand_binop (word_mode, binoptab, op1_low, op0_xhigh,
1526 NULL_RTX, 0, OPTAB_DIRECT);
1529 temp = expand_binop (word_mode, add_optab, temp,
1530 product_high, product_high,
1533 if (temp != 0 && temp != product_high)
1534 emit_move_insn (product_high, temp);
1538 if (mov_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1540 temp = emit_move_insn (product, product);
1541 set_unique_reg_note (temp,
1543 gen_rtx_fmt_ee (MULT, mode,
1551 /* If we get here, we couldn't do it for some reason even though we
1552 originally thought we could. Delete anything we've emitted in
1555 delete_insns_since (last);
1558 /* We need to open-code the complex type operations: '+, -, * and /' */
1560 /* At this point we allow operations between two similar complex
1561 numbers, and also if one of the operands is not a complex number
1562 but rather of MODE_FLOAT or MODE_INT. However, the caller
1563 must make sure that the MODE of the non-complex operand matches
1564 the SUBMODE of the complex operand. */
1566 if (class == MODE_COMPLEX_FLOAT || class == MODE_COMPLEX_INT)
1568 rtx real0 = 0, imag0 = 0;
1569 rtx real1 = 0, imag1 = 0;
1570 rtx realr, imagr, res;
1575 /* Find the correct mode for the real and imaginary parts */
1576 enum machine_mode submode
1577 = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
1578 class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
1581 if (submode == BLKmode)
1585 target = gen_reg_rtx (mode);
1589 realr = gen_realpart (submode, target);
1590 imagr = gen_imagpart (submode, target);
1592 if (GET_MODE (op0) == mode)
1594 real0 = gen_realpart (submode, op0);
1595 imag0 = gen_imagpart (submode, op0);
1600 if (GET_MODE (op1) == mode)
1602 real1 = gen_realpart (submode, op1);
1603 imag1 = gen_imagpart (submode, op1);
1608 if (real0 == 0 || real1 == 0 || ! (imag0 != 0|| imag1 != 0))
1611 switch (binoptab->code)
1614 /* (a+ib) + (c+id) = (a+c) + i(b+d) */
1616 /* (a+ib) - (c+id) = (a-c) + i(b-d) */
1617 res = expand_binop (submode, binoptab, real0, real1,
1618 realr, unsignedp, methods);
1622 else if (res != realr)
1623 emit_move_insn (realr, res);
1626 res = expand_binop (submode, binoptab, imag0, imag1,
1627 imagr, unsignedp, methods);
1630 else if (binoptab->code == MINUS)
1631 res = expand_unop (submode, neg_optab, imag1, imagr, unsignedp);
1637 else if (res != imagr)
1638 emit_move_insn (imagr, res);
1644 /* (a+ib) * (c+id) = (ac-bd) + i(ad+cb) */
1650 /* Don't fetch these from memory more than once. */
1651 real0 = force_reg (submode, real0);
1652 real1 = force_reg (submode, real1);
1653 imag0 = force_reg (submode, imag0);
1654 imag1 = force_reg (submode, imag1);
1656 temp1 = expand_binop (submode, binoptab, real0, real1, NULL_RTX,
1657 unsignedp, methods);
1659 temp2 = expand_binop (submode, binoptab, imag0, imag1, NULL_RTX,
1660 unsignedp, methods);
1662 if (temp1 == 0 || temp2 == 0)
1665 res = expand_binop (submode, sub_optab, temp1, temp2,
1666 realr, unsignedp, methods);
1670 else if (res != realr)
1671 emit_move_insn (realr, res);
1673 temp1 = expand_binop (submode, binoptab, real0, imag1,
1674 NULL_RTX, unsignedp, methods);
1676 temp2 = expand_binop (submode, binoptab, real1, imag0,
1677 NULL_RTX, unsignedp, methods);
1679 if (temp1 == 0 || temp2 == 0)
1682 res = expand_binop (submode, add_optab, temp1, temp2,
1683 imagr, unsignedp, methods);
1687 else if (res != imagr)
1688 emit_move_insn (imagr, res);
1694 /* Don't fetch these from memory more than once. */
1695 real0 = force_reg (submode, real0);
1696 real1 = force_reg (submode, real1);
1698 res = expand_binop (submode, binoptab, real0, real1,
1699 realr, unsignedp, methods);
1702 else if (res != realr)
1703 emit_move_insn (realr, res);
1706 res = expand_binop (submode, binoptab,
1707 real1, imag0, imagr, unsignedp, methods);
1709 res = expand_binop (submode, binoptab,
1710 real0, imag1, imagr, unsignedp, methods);
1714 else if (res != imagr)
1715 emit_move_insn (imagr, res);
1722 /* (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd)) */
1726 /* (a+ib) / (c+i0) = (a/c) + i(b/c) */
1728 /* Don't fetch these from memory more than once. */
1729 real1 = force_reg (submode, real1);
1731 /* Simply divide the real and imaginary parts by `c' */
1732 if (class == MODE_COMPLEX_FLOAT)
1733 res = expand_binop (submode, binoptab, real0, real1,
1734 realr, unsignedp, methods);
1736 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
1737 real0, real1, realr, unsignedp);
1741 else if (res != realr)
1742 emit_move_insn (realr, res);
1744 if (class == MODE_COMPLEX_FLOAT)
1745 res = expand_binop (submode, binoptab, imag0, real1,
1746 imagr, unsignedp, methods);
1748 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
1749 imag0, real1, imagr, unsignedp);
1753 else if (res != imagr)
1754 emit_move_insn (imagr, res);
1760 switch (flag_complex_divide_method)
1763 ok = expand_cmplxdiv_straight (real0, real1, imag0, imag1,
1764 realr, imagr, submode,
1770 ok = expand_cmplxdiv_wide (real0, real1, imag0, imag1,
1771 realr, imagr, submode,
1791 if (binoptab->code != UNKNOWN)
1793 = gen_rtx_fmt_ee (binoptab->code, mode,
1794 copy_rtx (op0), copy_rtx (op1));
1798 emit_no_conflict_block (seq, target, op0, op1, equiv_value);
1804 /* It can't be open-coded in this mode.
1805 Use a library call if one is available and caller says that's ok. */
1807 if (binoptab->handlers[(int) mode].libfunc
1808 && (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN))
1812 enum machine_mode op1_mode = mode;
1819 op1_mode = word_mode;
1820 /* Specify unsigned here,
1821 since negative shift counts are meaningless. */
1822 op1x = convert_to_mode (word_mode, op1, 1);
1825 if (GET_MODE (op0) != VOIDmode
1826 && GET_MODE (op0) != mode)
1827 op0 = convert_to_mode (mode, op0, unsignedp);
1829 /* Pass 1 for NO_QUEUE so we don't lose any increments
1830 if the libcall is cse'd or moved. */
1831 value = emit_library_call_value (binoptab->handlers[(int) mode].libfunc,
1832 NULL_RTX, 1, mode, 2,
1833 op0, mode, op1x, op1_mode);
1835 insns = get_insns ();
1838 target = gen_reg_rtx (mode);
1839 emit_libcall_block (insns, target, value,
1840 gen_rtx_fmt_ee (binoptab->code, mode, op0, op1));
1845 delete_insns_since (last);
1847 /* It can't be done in this mode. Can we do it in a wider mode? */
1849 if (! (methods == OPTAB_WIDEN || methods == OPTAB_LIB_WIDEN
1850 || methods == OPTAB_MUST_WIDEN))
1852 /* Caller says, don't even try. */
1853 delete_insns_since (entry_last);
1857 /* Compute the value of METHODS to pass to recursive calls.
1858 Don't allow widening to be tried recursively. */
1860 methods = (methods == OPTAB_LIB_WIDEN ? OPTAB_LIB : OPTAB_DIRECT);
1862 /* Look for a wider mode of the same class for which it appears we can do
1865 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1867 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1868 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1870 if ((binoptab->handlers[(int) wider_mode].insn_code
1871 != CODE_FOR_nothing)
1872 || (methods == OPTAB_LIB
1873 && binoptab->handlers[(int) wider_mode].libfunc))
1875 rtx xop0 = op0, xop1 = op1;
1878 /* For certain integer operations, we need not actually extend
1879 the narrow operands, as long as we will truncate
1880 the results to the same narrowness. */
1882 if ((binoptab == ior_optab || binoptab == and_optab
1883 || binoptab == xor_optab
1884 || binoptab == add_optab || binoptab == sub_optab
1885 || binoptab == smul_optab || binoptab == ashl_optab)
1886 && class == MODE_INT)
1889 xop0 = widen_operand (xop0, wider_mode, mode,
1890 unsignedp, no_extend);
1892 /* The second operand of a shift must always be extended. */
1893 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
1894 no_extend && binoptab != ashl_optab);
1896 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
1897 unsignedp, methods);
1900 if (class != MODE_INT)
1903 target = gen_reg_rtx (mode);
1904 convert_move (target, temp, 0);
1908 return gen_lowpart (mode, temp);
1911 delete_insns_since (last);
1916 delete_insns_since (entry_last);
1920 /* Expand a binary operator which has both signed and unsigned forms.
1921 UOPTAB is the optab for unsigned operations, and SOPTAB is for
1924 If we widen unsigned operands, we may use a signed wider operation instead
1925 of an unsigned wider operation, since the result would be the same. */
1928 sign_expand_binop (mode, uoptab, soptab, op0, op1, target, unsignedp, methods)
1929 enum machine_mode mode;
1930 optab uoptab, soptab;
1931 rtx op0, op1, target;
1933 enum optab_methods methods;
1936 optab direct_optab = unsignedp ? uoptab : soptab;
1937 struct optab wide_soptab;
1939 /* Do it without widening, if possible. */
1940 temp = expand_binop (mode, direct_optab, op0, op1, target,
1941 unsignedp, OPTAB_DIRECT);
1942 if (temp || methods == OPTAB_DIRECT)
1945 /* Try widening to a signed int. Make a fake signed optab that
1946 hides any signed insn for direct use. */
1947 wide_soptab = *soptab;
1948 wide_soptab.handlers[(int) mode].insn_code = CODE_FOR_nothing;
1949 wide_soptab.handlers[(int) mode].libfunc = 0;
1951 temp = expand_binop (mode, &wide_soptab, op0, op1, target,
1952 unsignedp, OPTAB_WIDEN);
1954 /* For unsigned operands, try widening to an unsigned int. */
1955 if (temp == 0 && unsignedp)
1956 temp = expand_binop (mode, uoptab, op0, op1, target,
1957 unsignedp, OPTAB_WIDEN);
1958 if (temp || methods == OPTAB_WIDEN)
1961 /* Use the right width lib call if that exists. */
1962 temp = expand_binop (mode, direct_optab, op0, op1, target, unsignedp, OPTAB_LIB);
1963 if (temp || methods == OPTAB_LIB)
1966 /* Must widen and use a lib call, use either signed or unsigned. */
1967 temp = expand_binop (mode, &wide_soptab, op0, op1, target,
1968 unsignedp, methods);
1972 return expand_binop (mode, uoptab, op0, op1, target,
1973 unsignedp, methods);
1977 /* Generate code to perform an operation specified by BINOPTAB
1978 on operands OP0 and OP1, with two results to TARG1 and TARG2.
1979 We assume that the order of the operands for the instruction
1980 is TARG0, OP0, OP1, TARG1, which would fit a pattern like
1981 [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
1983 Either TARG0 or TARG1 may be zero, but what that means is that
1984 the result is not actually wanted. We will generate it into
1985 a dummy pseudo-reg and discard it. They may not both be zero.
1987 Returns 1 if this operation can be performed; 0 if not. */
1990 expand_twoval_binop (binoptab, op0, op1, targ0, targ1, unsignedp)
1996 enum machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
1997 enum mode_class class;
1998 enum machine_mode wider_mode;
1999 rtx entry_last = get_last_insn ();
2002 class = GET_MODE_CLASS (mode);
2004 op0 = protect_from_queue (op0, 0);
2005 op1 = protect_from_queue (op1, 0);
2009 op0 = force_not_mem (op0);
2010 op1 = force_not_mem (op1);
2013 /* If we are inside an appropriately-short loop and one operand is an
2014 expensive constant, force it into a register. */
2015 if (CONSTANT_P (op0) && preserve_subexpressions_p ()
2016 && rtx_cost (op0, binoptab->code) > 2)
2017 op0 = force_reg (mode, op0);
2019 if (CONSTANT_P (op1) && preserve_subexpressions_p ()
2020 && rtx_cost (op1, binoptab->code) > 2)
2021 op1 = force_reg (mode, op1);
2024 targ0 = protect_from_queue (targ0, 1);
2026 targ0 = gen_reg_rtx (mode);
2028 targ1 = protect_from_queue (targ1, 1);
2030 targ1 = gen_reg_rtx (mode);
2032 /* Record where to go back to if we fail. */
2033 last = get_last_insn ();
2035 if (binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2037 int icode = (int) binoptab->handlers[(int) mode].insn_code;
2038 enum machine_mode mode0 = insn_operand_mode[icode][1];
2039 enum machine_mode mode1 = insn_operand_mode[icode][2];
2041 rtx xop0 = op0, xop1 = op1;
2043 /* In case this insn wants input operands in modes different from the
2044 result, convert the operands. */
2045 if (GET_MODE (op0) != VOIDmode && GET_MODE (op0) != mode0)
2046 xop0 = convert_to_mode (mode0, xop0, unsignedp);
2048 if (GET_MODE (op1) != VOIDmode && GET_MODE (op1) != mode1)
2049 xop1 = convert_to_mode (mode1, xop1, unsignedp);
2051 /* Now, if insn doesn't accept these operands, put them into pseudos. */
2052 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
2053 xop0 = copy_to_mode_reg (mode0, xop0);
2055 if (! (*insn_operand_predicate[icode][2]) (xop1, mode1))
2056 xop1 = copy_to_mode_reg (mode1, xop1);
2058 /* We could handle this, but we should always be called with a pseudo
2059 for our targets and all insns should take them as outputs. */
2060 if (! (*insn_operand_predicate[icode][0]) (targ0, mode)
2061 || ! (*insn_operand_predicate[icode][3]) (targ1, mode))
2064 pat = GEN_FCN (icode) (targ0, xop0, xop1, targ1);
2071 delete_insns_since (last);
2074 /* It can't be done in this mode. Can we do it in a wider mode? */
2076 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
2078 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2079 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2081 if (binoptab->handlers[(int) wider_mode].insn_code
2082 != CODE_FOR_nothing)
2084 register rtx t0 = gen_reg_rtx (wider_mode);
2085 register rtx t1 = gen_reg_rtx (wider_mode);
2087 if (expand_twoval_binop (binoptab,
2088 convert_modes (wider_mode, mode, op0,
2090 convert_modes (wider_mode, mode, op1,
2094 convert_move (targ0, t0, unsignedp);
2095 convert_move (targ1, t1, unsignedp);
2099 delete_insns_since (last);
2104 delete_insns_since (entry_last);
2108 /* Generate code to perform an operation specified by UNOPTAB
2109 on operand OP0, with result having machine-mode MODE.
2111 UNSIGNEDP is for the case where we have to widen the operands
2112 to perform the operation. It says to use zero-extension.
2114 If TARGET is nonzero, the value
2115 is generated there, if it is convenient to do so.
2116 In all cases an rtx is returned for the locus of the value;
2117 this may or may not be TARGET. */
2120 expand_unop (mode, unoptab, op0, target, unsignedp)
2121 enum machine_mode mode;
2127 enum mode_class class;
2128 enum machine_mode wider_mode;
2130 rtx last = get_last_insn ();
2133 class = GET_MODE_CLASS (mode);
2135 op0 = protect_from_queue (op0, 0);
2139 op0 = force_not_mem (op0);
2143 target = protect_from_queue (target, 1);
2145 if (unoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2147 int icode = (int) unoptab->handlers[(int) mode].insn_code;
2148 enum machine_mode mode0 = insn_operand_mode[icode][1];
2154 temp = gen_reg_rtx (mode);
2156 if (GET_MODE (xop0) != VOIDmode
2157 && GET_MODE (xop0) != mode0)
2158 xop0 = convert_to_mode (mode0, xop0, unsignedp);
2160 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
2162 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
2163 xop0 = copy_to_mode_reg (mode0, xop0);
2165 if (! (*insn_operand_predicate[icode][0]) (temp, mode))
2166 temp = gen_reg_rtx (mode);
2168 pat = GEN_FCN (icode) (temp, xop0);
2171 if (GET_CODE (pat) == SEQUENCE
2172 && ! add_equal_note (pat, temp, unoptab->code, xop0, NULL_RTX))
2174 delete_insns_since (last);
2175 return expand_unop (mode, unoptab, op0, NULL_RTX, unsignedp);
2183 delete_insns_since (last);
2186 /* It can't be done in this mode. Can we open-code it in a wider mode? */
2188 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
2189 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2190 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2192 if (unoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing)
2196 /* For certain operations, we need not actually extend
2197 the narrow operand, as long as we will truncate the
2198 results to the same narrowness. */
2200 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
2201 (unoptab == neg_optab
2202 || unoptab == one_cmpl_optab)
2203 && class == MODE_INT);
2205 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
2210 if (class != MODE_INT)
2213 target = gen_reg_rtx (mode);
2214 convert_move (target, temp, 0);
2218 return gen_lowpart (mode, temp);
2221 delete_insns_since (last);
2225 /* These can be done a word at a time. */
2226 if (unoptab == one_cmpl_optab
2227 && class == MODE_INT
2228 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
2229 && unoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
2234 if (target == 0 || target == op0)
2235 target = gen_reg_rtx (mode);
2239 /* Do the actual arithmetic. */
2240 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
2242 rtx target_piece = operand_subword (target, i, 1, mode);
2243 rtx x = expand_unop (word_mode, unoptab,
2244 operand_subword_force (op0, i, mode),
2245 target_piece, unsignedp);
2246 if (target_piece != x)
2247 emit_move_insn (target_piece, x);
2250 insns = get_insns ();
2253 emit_no_conflict_block (insns, target, op0, NULL_RTX,
2254 gen_rtx_fmt_e (unoptab->code, mode,
2259 /* Open-code the complex negation operation. */
2260 else if (unoptab == neg_optab
2261 && (class == MODE_COMPLEX_FLOAT || class == MODE_COMPLEX_INT))
2267 /* Find the correct mode for the real and imaginary parts */
2268 enum machine_mode submode
2269 = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
2270 class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
2273 if (submode == BLKmode)
2277 target = gen_reg_rtx (mode);
2281 target_piece = gen_imagpart (submode, target);
2282 x = expand_unop (submode, unoptab,
2283 gen_imagpart (submode, op0),
2284 target_piece, unsignedp);
2285 if (target_piece != x)
2286 emit_move_insn (target_piece, x);
2288 target_piece = gen_realpart (submode, target);
2289 x = expand_unop (submode, unoptab,
2290 gen_realpart (submode, op0),
2291 target_piece, unsignedp);
2292 if (target_piece != x)
2293 emit_move_insn (target_piece, x);
2298 emit_no_conflict_block (seq, target, op0, 0,
2299 gen_rtx_fmt_e (unoptab->code, mode,
2304 /* Now try a library call in this mode. */
2305 if (unoptab->handlers[(int) mode].libfunc)
2312 /* Pass 1 for NO_QUEUE so we don't lose any increments
2313 if the libcall is cse'd or moved. */
2314 value = emit_library_call_value (unoptab->handlers[(int) mode].libfunc,
2315 NULL_RTX, 1, mode, 1, op0, mode);
2316 insns = get_insns ();
2319 target = gen_reg_rtx (mode);
2320 emit_libcall_block (insns, target, value,
2321 gen_rtx_fmt_e (unoptab->code, mode, op0));
2326 /* It can't be done in this mode. Can we do it in a wider mode? */
2328 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
2330 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2331 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2333 if ((unoptab->handlers[(int) wider_mode].insn_code
2334 != CODE_FOR_nothing)
2335 || unoptab->handlers[(int) wider_mode].libfunc)
2339 /* For certain operations, we need not actually extend
2340 the narrow operand, as long as we will truncate the
2341 results to the same narrowness. */
2343 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
2344 (unoptab == neg_optab
2345 || unoptab == one_cmpl_optab)
2346 && class == MODE_INT);
2348 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
2353 if (class != MODE_INT)
2356 target = gen_reg_rtx (mode);
2357 convert_move (target, temp, 0);
2361 return gen_lowpart (mode, temp);
2364 delete_insns_since (last);
2369 /* If there is no negate operation, try doing a subtract from zero.
2370 The US Software GOFAST library needs this. */
2371 if (unoptab == neg_optab)
2374 temp = expand_binop (mode, sub_optab, CONST0_RTX (mode), op0,
2375 target, unsignedp, OPTAB_LIB_WIDEN);
2383 /* Emit code to compute the absolute value of OP0, with result to
2384 TARGET if convenient. (TARGET may be 0.) The return value says
2385 where the result actually is to be found.
2387 MODE is the mode of the operand; the mode of the result is
2388 different but can be deduced from MODE.
2393 expand_abs (mode, op0, target, safe)
2394 enum machine_mode mode;
2401 /* First try to do it with a special abs instruction. */
2402 temp = expand_unop (mode, abs_optab, op0, target, 0);
2406 /* If this machine has expensive jumps, we can do integer absolute
2407 value of X as (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)),
2408 where W is the width of MODE. */
2410 if (GET_MODE_CLASS (mode) == MODE_INT && BRANCH_COST >= 2)
2412 rtx extended = expand_shift (RSHIFT_EXPR, mode, op0,
2413 size_int (GET_MODE_BITSIZE (mode) - 1),
2416 temp = expand_binop (mode, xor_optab, extended, op0, target, 0,
2419 temp = expand_binop (mode, sub_optab, temp, extended, target, 0,
2426 /* If that does not win, use conditional jump and negate. */
2428 /* It is safe to use the target if it is the same
2429 as the source if this is also a pseudo register */
2430 if (op0 == target && GET_CODE (op0) == REG
2431 && REGNO (op0) >= FIRST_PSEUDO_REGISTER)
2434 op1 = gen_label_rtx ();
2435 if (target == 0 || ! safe
2436 || GET_MODE (target) != mode
2437 || (GET_CODE (target) == MEM && MEM_VOLATILE_P (target))
2438 || (GET_CODE (target) == REG
2439 && REGNO (target) < FIRST_PSEUDO_REGISTER))
2440 target = gen_reg_rtx (mode);
2442 emit_move_insn (target, op0);
2445 /* If this mode is an integer too wide to compare properly,
2446 compare word by word. Rely on CSE to optimize constant cases. */
2447 if (GET_MODE_CLASS (mode) == MODE_INT && ! can_compare_p (mode))
2448 do_jump_by_parts_greater_rtx (mode, 0, target, const0_rtx,
2452 temp = compare_from_rtx (target, CONST0_RTX (mode), GE, 0, mode,
2454 if (temp == const1_rtx)
2456 else if (temp != const0_rtx)
2458 if (bcc_gen_fctn[(int) GET_CODE (temp)] != 0)
2459 emit_jump_insn ((*bcc_gen_fctn[(int) GET_CODE (temp)]) (op1));
2465 op0 = expand_unop (mode, neg_optab, target, target, 0);
2467 emit_move_insn (target, op0);
2473 /* Emit code to compute the absolute value of OP0, with result to
2474 TARGET if convenient. (TARGET may be 0.) The return value says
2475 where the result actually is to be found.
2477 MODE is the mode of the operand; the mode of the result is
2478 different but can be deduced from MODE.
2480 UNSIGNEDP is relevant for complex integer modes. */
2483 expand_complex_abs (mode, op0, target, unsignedp)
2484 enum machine_mode mode;
2489 enum mode_class class = GET_MODE_CLASS (mode);
2490 enum machine_mode wider_mode;
2492 rtx entry_last = get_last_insn ();
2496 /* Find the correct mode for the real and imaginary parts. */
2497 enum machine_mode submode
2498 = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
2499 class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
2502 if (submode == BLKmode)
2505 op0 = protect_from_queue (op0, 0);
2509 op0 = force_not_mem (op0);
2512 last = get_last_insn ();
2515 target = protect_from_queue (target, 1);
2517 if (abs_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2519 int icode = (int) abs_optab->handlers[(int) mode].insn_code;
2520 enum machine_mode mode0 = insn_operand_mode[icode][1];
2526 temp = gen_reg_rtx (submode);
2528 if (GET_MODE (xop0) != VOIDmode
2529 && GET_MODE (xop0) != mode0)
2530 xop0 = convert_to_mode (mode0, xop0, unsignedp);
2532 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
2534 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
2535 xop0 = copy_to_mode_reg (mode0, xop0);
2537 if (! (*insn_operand_predicate[icode][0]) (temp, submode))
2538 temp = gen_reg_rtx (submode);
2540 pat = GEN_FCN (icode) (temp, xop0);
2543 if (GET_CODE (pat) == SEQUENCE
2544 && ! add_equal_note (pat, temp, abs_optab->code, xop0, NULL_RTX))
2546 delete_insns_since (last);
2547 return expand_unop (mode, abs_optab, op0, NULL_RTX, unsignedp);
2555 delete_insns_since (last);
2558 /* It can't be done in this mode. Can we open-code it in a wider mode? */
2560 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2561 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2563 if (abs_optab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing)
2567 xop0 = convert_modes (wider_mode, mode, xop0, unsignedp);
2568 temp = expand_complex_abs (wider_mode, xop0, NULL_RTX, unsignedp);
2572 if (class != MODE_COMPLEX_INT)
2575 target = gen_reg_rtx (submode);
2576 convert_move (target, temp, 0);
2580 return gen_lowpart (submode, temp);
2583 delete_insns_since (last);
2587 /* Open-code the complex absolute-value operation
2588 if we can open-code sqrt. Otherwise it's not worth while. */
2589 if (sqrt_optab->handlers[(int) submode].insn_code != CODE_FOR_nothing)
2591 rtx real, imag, total;
2593 real = gen_realpart (submode, op0);
2594 imag = gen_imagpart (submode, op0);
2596 /* Square both parts. */
2597 real = expand_mult (submode, real, real, NULL_RTX, 0);
2598 imag = expand_mult (submode, imag, imag, NULL_RTX, 0);
2600 /* Sum the parts. */
2601 total = expand_binop (submode, add_optab, real, imag, NULL_RTX,
2602 0, OPTAB_LIB_WIDEN);
2604 /* Get sqrt in TARGET. Set TARGET to where the result is. */
2605 target = expand_unop (submode, sqrt_optab, total, target, 0);
2607 delete_insns_since (last);
2612 /* Now try a library call in this mode. */
2613 if (abs_optab->handlers[(int) mode].libfunc)
2620 /* Pass 1 for NO_QUEUE so we don't lose any increments
2621 if the libcall is cse'd or moved. */
2622 value = emit_library_call_value (abs_optab->handlers[(int) mode].libfunc,
2623 NULL_RTX, 1, submode, 1, op0, mode);
2624 insns = get_insns ();
2627 target = gen_reg_rtx (submode);
2628 emit_libcall_block (insns, target, value,
2629 gen_rtx_fmt_e (abs_optab->code, mode, op0));
2634 /* It can't be done in this mode. Can we do it in a wider mode? */
2636 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2637 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2639 if ((abs_optab->handlers[(int) wider_mode].insn_code
2640 != CODE_FOR_nothing)
2641 || abs_optab->handlers[(int) wider_mode].libfunc)
2645 xop0 = convert_modes (wider_mode, mode, xop0, unsignedp);
2647 temp = expand_complex_abs (wider_mode, xop0, NULL_RTX, unsignedp);
2651 if (class != MODE_COMPLEX_INT)
2654 target = gen_reg_rtx (submode);
2655 convert_move (target, temp, 0);
2659 return gen_lowpart (submode, temp);
2662 delete_insns_since (last);
2666 delete_insns_since (entry_last);
2670 /* Generate an instruction whose insn-code is INSN_CODE,
2671 with two operands: an output TARGET and an input OP0.
2672 TARGET *must* be nonzero, and the output is always stored there.
2673 CODE is an rtx code such that (CODE OP0) is an rtx that describes
2674 the value that is stored into TARGET. */
2677 emit_unop_insn (icode, target, op0, code)
2684 enum machine_mode mode0 = insn_operand_mode[icode][1];
2687 temp = target = protect_from_queue (target, 1);
2689 op0 = protect_from_queue (op0, 0);
2691 /* Sign and zero extension from memory is often done specially on
2692 RISC machines, so forcing into a register here can pessimize
2694 if (flag_force_mem && code != SIGN_EXTEND && code != ZERO_EXTEND)
2695 op0 = force_not_mem (op0);
2697 /* Now, if insn does not accept our operands, put them into pseudos. */
2699 if (! (*insn_operand_predicate[icode][1]) (op0, mode0))
2700 op0 = copy_to_mode_reg (mode0, op0);
2702 if (! (*insn_operand_predicate[icode][0]) (temp, GET_MODE (temp))
2703 || (flag_force_mem && GET_CODE (temp) == MEM))
2704 temp = gen_reg_rtx (GET_MODE (temp));
2706 pat = GEN_FCN (icode) (temp, op0);
2708 if (GET_CODE (pat) == SEQUENCE && code != UNKNOWN)
2709 add_equal_note (pat, temp, code, op0, NULL_RTX);
2714 emit_move_insn (target, temp);
2717 /* Emit code to perform a series of operations on a multi-word quantity, one
2720 Such a block is preceded by a CLOBBER of the output, consists of multiple
2721 insns, each setting one word of the output, and followed by a SET copying
2722 the output to itself.
2724 Each of the insns setting words of the output receives a REG_NO_CONFLICT
2725 note indicating that it doesn't conflict with the (also multi-word)
2726 inputs. The entire block is surrounded by REG_LIBCALL and REG_RETVAL
2729 INSNS is a block of code generated to perform the operation, not including
2730 the CLOBBER and final copy. All insns that compute intermediate values
2731 are first emitted, followed by the block as described above.
2733 TARGET, OP0, and OP1 are the output and inputs of the operations,
2734 respectively. OP1 may be zero for a unary operation.
2736 EQUIV, if non-zero, is an expression to be placed into a REG_EQUAL note
2739 If TARGET is not a register, INSNS is simply emitted with no special
2740 processing. Likewise if anything in INSNS is not an INSN or if
2741 there is a libcall block inside INSNS.
2743 The final insn emitted is returned. */
2746 emit_no_conflict_block (insns, target, op0, op1, equiv)
2752 rtx prev, next, first, last, insn;
2754 if (GET_CODE (target) != REG || reload_in_progress)
2755 return emit_insns (insns);
2757 for (insn = insns; insn; insn = NEXT_INSN (insn))
2758 if (GET_CODE (insn) != INSN
2759 || find_reg_note (insn, REG_LIBCALL, NULL_RTX))
2760 return emit_insns (insns);
2762 /* First emit all insns that do not store into words of the output and remove
2763 these from the list. */
2764 for (insn = insns; insn; insn = next)
2769 next = NEXT_INSN (insn);
2771 if (GET_CODE (PATTERN (insn)) == SET)
2772 set = PATTERN (insn);
2773 else if (GET_CODE (PATTERN (insn)) == PARALLEL)
2775 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
2776 if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET)
2778 set = XVECEXP (PATTERN (insn), 0, i);
2786 if (! reg_overlap_mentioned_p (target, SET_DEST (set)))
2788 if (PREV_INSN (insn))
2789 NEXT_INSN (PREV_INSN (insn)) = next;
2794 PREV_INSN (next) = PREV_INSN (insn);
2800 prev = get_last_insn ();
2802 /* Now write the CLOBBER of the output, followed by the setting of each
2803 of the words, followed by the final copy. */
2804 if (target != op0 && target != op1)
2805 emit_insn (gen_rtx_CLOBBER (VOIDmode, target));
2807 for (insn = insns; insn; insn = next)
2809 next = NEXT_INSN (insn);
2812 if (op1 && GET_CODE (op1) == REG)
2813 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_NO_CONFLICT, op1,
2816 if (op0 && GET_CODE (op0) == REG)
2817 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_NO_CONFLICT, op0,
2821 if (mov_optab->handlers[(int) GET_MODE (target)].insn_code
2822 != CODE_FOR_nothing)
2824 last = emit_move_insn (target, target);
2826 set_unique_reg_note (last, REG_EQUAL, equiv);
2829 last = get_last_insn ();
2832 first = get_insns ();
2834 first = NEXT_INSN (prev);
2836 /* Encapsulate the block so it gets manipulated as a unit. */
2837 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last,
2839 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2844 /* Emit code to make a call to a constant function or a library call.
2846 INSNS is a list containing all insns emitted in the call.
2847 These insns leave the result in RESULT. Our block is to copy RESULT
2848 to TARGET, which is logically equivalent to EQUIV.
2850 We first emit any insns that set a pseudo on the assumption that these are
2851 loading constants into registers; doing so allows them to be safely cse'ed
2852 between blocks. Then we emit all the other insns in the block, followed by
2853 an insn to move RESULT to TARGET. This last insn will have a REQ_EQUAL
2854 note with an operand of EQUIV.
2856 Moving assignments to pseudos outside of the block is done to improve
2857 the generated code, but is not required to generate correct code,
2858 hence being unable to move an assignment is not grounds for not making
2859 a libcall block. There are two reasons why it is safe to leave these
2860 insns inside the block: First, we know that these pseudos cannot be
2861 used in generated RTL outside the block since they are created for
2862 temporary purposes within the block. Second, CSE will not record the
2863 values of anything set inside a libcall block, so we know they must
2864 be dead at the end of the block.
2866 Except for the first group of insns (the ones setting pseudos), the
2867 block is delimited by REG_RETVAL and REG_LIBCALL notes. */
2870 emit_libcall_block (insns, target, result, equiv)
2876 rtx prev, next, first, last, insn;
2878 /* look for any CALL_INSNs in this sequence, and attach a REG_EH_REGION
2879 reg note to indicate that this call cannot throw. (Unless there is
2880 already a REG_EH_REGION note.) */
2882 for (insn = insns; insn; insn = NEXT_INSN (insn))
2884 if (GET_CODE (insn) == CALL_INSN)
2886 rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
2887 if (note == NULL_RTX)
2888 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EH_REGION, GEN_INT (-1),
2893 /* First emit all insns that set pseudos. Remove them from the list as
2894 we go. Avoid insns that set pseudos which were referenced in previous
2895 insns. These can be generated by move_by_pieces, for example,
2896 to update an address. Similarly, avoid insns that reference things
2897 set in previous insns. */
2899 for (insn = insns; insn; insn = next)
2901 rtx set = single_set (insn);
2903 next = NEXT_INSN (insn);
2905 if (set != 0 && GET_CODE (SET_DEST (set)) == REG
2906 && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER
2908 || (! reg_mentioned_p (SET_DEST (set), PATTERN (insns))
2909 && ! reg_used_between_p (SET_DEST (set), insns, insn)
2910 && ! modified_in_p (SET_SRC (set), insns)
2911 && ! modified_between_p (SET_SRC (set), insns, insn))))
2913 if (PREV_INSN (insn))
2914 NEXT_INSN (PREV_INSN (insn)) = next;
2919 PREV_INSN (next) = PREV_INSN (insn);
2925 prev = get_last_insn ();
2927 /* Write the remaining insns followed by the final copy. */
2929 for (insn = insns; insn; insn = next)
2931 next = NEXT_INSN (insn);
2936 last = emit_move_insn (target, result);
2937 if (mov_optab->handlers[(int) GET_MODE (target)].insn_code
2938 != CODE_FOR_nothing)
2939 set_unique_reg_note (last, REG_EQUAL, copy_rtx (equiv));
2942 first = get_insns ();
2944 first = NEXT_INSN (prev);
2946 /* Encapsulate the block so it gets manipulated as a unit. */
2947 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last,
2949 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2952 /* Generate code to store zero in X. */
2958 emit_move_insn (x, const0_rtx);
2961 /* Generate code to store 1 in X
2962 assuming it contains zero beforehand. */
2965 emit_0_to_1_insn (x)
2968 emit_move_insn (x, const1_rtx);
2971 /* Generate code to compare X with Y
2972 so that the condition codes are set.
2974 MODE is the mode of the inputs (in case they are const_int).
2975 UNSIGNEDP nonzero says that X and Y are unsigned;
2976 this matters if they need to be widened.
2978 If they have mode BLKmode, then SIZE specifies the size of both X and Y,
2979 and ALIGN specifies the known shared alignment of X and Y.
2981 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).
2982 It is ignored for fixed-point and block comparisons;
2983 it is used only for floating-point comparisons. */
2986 emit_cmp_insn (x, y, comparison, size, mode, unsignedp, align)
2988 enum rtx_code comparison;
2990 enum machine_mode mode;
2994 enum mode_class class;
2995 enum machine_mode wider_mode;
2997 class = GET_MODE_CLASS (mode);
2999 /* They could both be VOIDmode if both args are immediate constants,
3000 but we should fold that at an earlier stage.
3001 With no special code here, this will call abort,
3002 reminding the programmer to implement such folding. */
3004 if (mode != BLKmode && flag_force_mem)
3006 x = force_not_mem (x);
3007 y = force_not_mem (y);
3010 /* If we are inside an appropriately-short loop and one operand is an
3011 expensive constant, force it into a register. */
3012 if (CONSTANT_P (x) && preserve_subexpressions_p () && rtx_cost (x, COMPARE) > 2)
3013 x = force_reg (mode, x);
3015 if (CONSTANT_P (y) && preserve_subexpressions_p () && rtx_cost (y, COMPARE) > 2)
3016 y = force_reg (mode, y);
3019 /* Abort if we have a non-canonical comparison. The RTL documentation
3020 states that canonical comparisons are required only for targets which
3022 if (CONSTANT_P (x) && ! CONSTANT_P (y))
3026 /* Don't let both operands fail to indicate the mode. */
3027 if (GET_MODE (x) == VOIDmode && GET_MODE (y) == VOIDmode)
3028 x = force_reg (mode, x);
3030 /* Handle all BLKmode compares. */
3032 if (mode == BLKmode)
3035 x = protect_from_queue (x, 0);
3036 y = protect_from_queue (y, 0);
3040 #ifdef HAVE_cmpstrqi
3042 && GET_CODE (size) == CONST_INT
3043 && INTVAL (size) < (1 << GET_MODE_BITSIZE (QImode)))
3045 enum machine_mode result_mode
3046 = insn_operand_mode[(int) CODE_FOR_cmpstrqi][0];
3047 rtx result = gen_reg_rtx (result_mode);
3048 emit_insn (gen_cmpstrqi (result, x, y, size, GEN_INT (align)));
3049 emit_cmp_insn (result, const0_rtx, comparison, NULL_RTX,
3054 #ifdef HAVE_cmpstrhi
3056 && GET_CODE (size) == CONST_INT
3057 && INTVAL (size) < (1 << GET_MODE_BITSIZE (HImode)))
3059 enum machine_mode result_mode
3060 = insn_operand_mode[(int) CODE_FOR_cmpstrhi][0];
3061 rtx result = gen_reg_rtx (result_mode);
3062 emit_insn (gen_cmpstrhi (result, x, y, size, GEN_INT (align)));
3063 emit_cmp_insn (result, const0_rtx, comparison, NULL_RTX,
3068 #ifdef HAVE_cmpstrsi
3071 enum machine_mode result_mode
3072 = insn_operand_mode[(int) CODE_FOR_cmpstrsi][0];
3073 rtx result = gen_reg_rtx (result_mode);
3074 size = protect_from_queue (size, 0);
3075 emit_insn (gen_cmpstrsi (result, x, y,
3076 convert_to_mode (SImode, size, 1),
3078 emit_cmp_insn (result, const0_rtx, comparison, NULL_RTX,
3086 #ifdef TARGET_MEM_FUNCTIONS
3087 emit_library_call (memcmp_libfunc, 0,
3088 TYPE_MODE (integer_type_node), 3,
3089 XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
3090 convert_to_mode (TYPE_MODE (sizetype), size,
3091 TREE_UNSIGNED (sizetype)),
3092 TYPE_MODE (sizetype));
3094 emit_library_call (bcmp_libfunc, 0,
3095 TYPE_MODE (integer_type_node), 3,
3096 XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
3097 convert_to_mode (TYPE_MODE (integer_type_node),
3099 TREE_UNSIGNED (integer_type_node)),
3100 TYPE_MODE (integer_type_node));
3103 /* Immediately move the result of the libcall into a pseudo
3104 register so reload doesn't clobber the value if it needs
3105 the return register for a spill reg. */
3106 result = gen_reg_rtx (TYPE_MODE (integer_type_node));
3107 emit_move_insn (result,
3108 hard_libcall_value (TYPE_MODE (integer_type_node)));
3109 emit_cmp_insn (result,
3110 const0_rtx, comparison, NULL_RTX,
3111 TYPE_MODE (integer_type_node), 0, 0);
3116 /* Handle some compares against zero. */
3118 if (y == CONST0_RTX (mode)
3119 && tst_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
3121 int icode = (int) tst_optab->handlers[(int) mode].insn_code;
3124 x = protect_from_queue (x, 0);
3125 y = protect_from_queue (y, 0);
3127 /* Now, if insn does accept these operands, put them into pseudos. */
3128 if (! (*insn_operand_predicate[icode][0])
3129 (x, insn_operand_mode[icode][0]))
3130 x = copy_to_mode_reg (insn_operand_mode[icode][0], x);
3132 emit_insn (GEN_FCN (icode) (x));
3136 /* Handle compares for which there is a directly suitable insn. */
3138 if (cmp_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
3140 int icode = (int) cmp_optab->handlers[(int) mode].insn_code;
3143 x = protect_from_queue (x, 0);
3144 y = protect_from_queue (y, 0);
3146 /* Now, if insn doesn't accept these operands, put them into pseudos. */
3147 if (! (*insn_operand_predicate[icode][0])
3148 (x, insn_operand_mode[icode][0]))
3149 x = copy_to_mode_reg (insn_operand_mode[icode][0], x);
3151 if (! (*insn_operand_predicate[icode][1])
3152 (y, insn_operand_mode[icode][1]))
3153 y = copy_to_mode_reg (insn_operand_mode[icode][1], y);
3155 emit_insn (GEN_FCN (icode) (x, y));
3159 /* Try widening if we can find a direct insn that way. */
3161 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
3163 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
3164 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
3166 if (cmp_optab->handlers[(int) wider_mode].insn_code
3167 != CODE_FOR_nothing)
3169 x = protect_from_queue (x, 0);
3170 y = protect_from_queue (y, 0);
3171 x = convert_modes (wider_mode, mode, x, unsignedp);
3172 y = convert_modes (wider_mode, mode, y, unsignedp);
3173 emit_cmp_insn (x, y, comparison, NULL_RTX,
3174 wider_mode, unsignedp, align);
3180 /* Handle a lib call just for the mode we are using. */
3182 if (cmp_optab->handlers[(int) mode].libfunc
3183 && class != MODE_FLOAT)
3185 rtx libfunc = cmp_optab->handlers[(int) mode].libfunc;
3188 /* If we want unsigned, and this mode has a distinct unsigned
3189 comparison routine, use that. */
3190 if (unsignedp && ucmp_optab->handlers[(int) mode].libfunc)
3191 libfunc = ucmp_optab->handlers[(int) mode].libfunc;
3193 emit_library_call (libfunc, 1,
3194 word_mode, 2, x, mode, y, mode);
3196 /* Immediately move the result of the libcall into a pseudo
3197 register so reload doesn't clobber the value if it needs
3198 the return register for a spill reg. */
3199 result = gen_reg_rtx (word_mode);
3200 emit_move_insn (result, hard_libcall_value (word_mode));
3202 /* Integer comparison returns a result that must be compared against 1,
3203 so that even if we do an unsigned compare afterward,
3204 there is still a value that can represent the result "less than". */
3205 emit_cmp_insn (result, const1_rtx,
3206 comparison, NULL_RTX, word_mode, unsignedp, 0);
3210 if (class == MODE_FLOAT)
3211 emit_float_lib_cmp (x, y, comparison);
3217 /* Generate code to compare X with Y so that the condition codes are
3218 set and to jump to LABEL if the condition is true. If X is a
3219 constant and Y is not a constant, then the comparison is swapped to
3220 ensure that the comparison RTL has the canonical form.
3222 UNSIGNEDP nonzero says that X and Y are unsigned; this matters if they
3223 need to be widened by emit_cmp_insn. UNSIGNEDP is also used to select
3224 the proper branch condition code.
3226 If X and Y have mode BLKmode, then SIZE specifies the size of both X and Y,
3227 and ALIGN specifies the known shared alignment of X and Y.
3229 MODE is the mode of the inputs (in case they are const_int).
3231 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). It will
3232 be passed unchanged to emit_cmp_insn, then potentially converted into an
3233 unsigned variant based on UNSIGNEDP to select a proper jump instruction. */
3236 emit_cmp_and_jump_insns (x, y, comparison, size, mode, unsignedp, align, label)
3238 enum rtx_code comparison;
3240 enum machine_mode mode;
3250 /* Swap operands and condition to ensure canonical RTL. */
3253 comparison = swap_condition (comparison);
3262 /* If OP0 is still a constant, then both X and Y must be constants. Force
3263 X into a register to avoid aborting in emit_cmp_insn due to non-canonical
3265 if (CONSTANT_P (op0))
3266 op0 = force_reg (mode, op0);
3269 emit_cmp_insn (op0, op1, comparison, size, mode, unsignedp, align);
3272 comparison = unsigned_condition (comparison);
3273 emit_jump_insn ((*bcc_gen_fctn[(int) comparison]) (label));
3277 /* Nonzero if a compare of mode MODE can be done straightforwardly
3278 (without splitting it into pieces). */
3281 can_compare_p (mode)
3282 enum machine_mode mode;
3286 if (cmp_optab->handlers[(int)mode].insn_code != CODE_FOR_nothing)
3288 mode = GET_MODE_WIDER_MODE (mode);
3289 } while (mode != VOIDmode);
3294 /* Emit a library call comparison between floating point X and Y.
3295 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */
3298 emit_float_lib_cmp (x, y, comparison)
3300 enum rtx_code comparison;
3302 enum machine_mode mode = GET_MODE (x);
3310 libfunc = eqhf2_libfunc;
3314 libfunc = nehf2_libfunc;
3318 libfunc = gthf2_libfunc;
3322 libfunc = gehf2_libfunc;
3326 libfunc = lthf2_libfunc;
3330 libfunc = lehf2_libfunc;
3336 else if (mode == SFmode)
3340 libfunc = eqsf2_libfunc;
3344 libfunc = nesf2_libfunc;
3348 libfunc = gtsf2_libfunc;
3352 libfunc = gesf2_libfunc;
3356 libfunc = ltsf2_libfunc;
3360 libfunc = lesf2_libfunc;
3366 else if (mode == DFmode)
3370 libfunc = eqdf2_libfunc;
3374 libfunc = nedf2_libfunc;
3378 libfunc = gtdf2_libfunc;
3382 libfunc = gedf2_libfunc;
3386 libfunc = ltdf2_libfunc;
3390 libfunc = ledf2_libfunc;
3396 else if (mode == XFmode)
3400 libfunc = eqxf2_libfunc;
3404 libfunc = nexf2_libfunc;
3408 libfunc = gtxf2_libfunc;
3412 libfunc = gexf2_libfunc;
3416 libfunc = ltxf2_libfunc;
3420 libfunc = lexf2_libfunc;
3426 else if (mode == TFmode)
3430 libfunc = eqtf2_libfunc;
3434 libfunc = netf2_libfunc;
3438 libfunc = gttf2_libfunc;
3442 libfunc = getf2_libfunc;
3446 libfunc = lttf2_libfunc;
3450 libfunc = letf2_libfunc;
3458 enum machine_mode wider_mode;
3460 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
3461 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
3463 if ((cmp_optab->handlers[(int) wider_mode].insn_code
3464 != CODE_FOR_nothing)
3465 || (cmp_optab->handlers[(int) wider_mode].libfunc != 0))
3467 x = protect_from_queue (x, 0);
3468 y = protect_from_queue (y, 0);
3469 x = convert_to_mode (wider_mode, x, 0);
3470 y = convert_to_mode (wider_mode, y, 0);
3471 emit_float_lib_cmp (x, y, comparison);
3481 emit_library_call (libfunc, 1,
3482 word_mode, 2, x, mode, y, mode);
3484 /* Immediately move the result of the libcall into a pseudo
3485 register so reload doesn't clobber the value if it needs
3486 the return register for a spill reg. */
3487 result = gen_reg_rtx (word_mode);
3488 emit_move_insn (result, hard_libcall_value (word_mode));
3490 emit_cmp_insn (result, const0_rtx, comparison,
3491 NULL_RTX, word_mode, 0, 0);
3494 /* Generate code to indirectly jump to a location given in the rtx LOC. */
3497 emit_indirect_jump (loc)
3500 if (! ((*insn_operand_predicate[(int)CODE_FOR_indirect_jump][0])
3502 loc = copy_to_mode_reg (Pmode, loc);
3504 emit_jump_insn (gen_indirect_jump (loc));
3508 #ifdef HAVE_conditional_move
3510 /* Emit a conditional move instruction if the machine supports one for that
3511 condition and machine mode.
3513 OP0 and OP1 are the operands that should be compared using CODE. CMODE is
3514 the mode to use should they be constants. If it is VOIDmode, they cannot
3517 OP2 should be stored in TARGET if the comparison is true, otherwise OP3
3518 should be stored there. MODE is the mode to use should they be constants.
3519 If it is VOIDmode, they cannot both be constants.
3521 The result is either TARGET (perhaps modified) or NULL_RTX if the operation
3522 is not supported. */
3525 emit_conditional_move (target, code, op0, op1, cmode, op2, op3, mode,
3530 enum machine_mode cmode;
3532 enum machine_mode mode;
3535 rtx tem, subtarget, comparison, insn;
3536 enum insn_code icode;
3538 /* If one operand is constant, make it the second one. Only do this
3539 if the other operand is not constant as well. */
3541 if ((CONSTANT_P (op0) && ! CONSTANT_P (op1))
3542 || (GET_CODE (op0) == CONST_INT && GET_CODE (op1) != CONST_INT))
3547 code = swap_condition (code);
3550 if (cmode == VOIDmode)
3551 cmode = GET_MODE (op0);
3553 if (((CONSTANT_P (op2) && ! CONSTANT_P (op3))
3554 || (GET_CODE (op2) == CONST_INT && GET_CODE (op3) != CONST_INT))
3555 && (GET_MODE_CLASS (GET_MODE (op1)) != MODE_FLOAT
3556 || TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT || flag_fast_math))
3561 code = reverse_condition (code);
3564 if (mode == VOIDmode)
3565 mode = GET_MODE (op2);
3567 icode = movcc_gen_code[mode];
3569 if (icode == CODE_FOR_nothing)
3574 op2 = force_not_mem (op2);
3575 op3 = force_not_mem (op3);
3579 target = protect_from_queue (target, 1);
3581 target = gen_reg_rtx (mode);
3587 op2 = protect_from_queue (op2, 0);
3588 op3 = protect_from_queue (op3, 0);
3590 /* If the insn doesn't accept these operands, put them in pseudos. */
3592 if (! (*insn_operand_predicate[icode][0])
3593 (subtarget, insn_operand_mode[icode][0]))
3594 subtarget = gen_reg_rtx (insn_operand_mode[icode][0]);
3596 if (! (*insn_operand_predicate[icode][2])
3597 (op2, insn_operand_mode[icode][2]))
3598 op2 = copy_to_mode_reg (insn_operand_mode[icode][2], op2);
3600 if (! (*insn_operand_predicate[icode][3])
3601 (op3, insn_operand_mode[icode][3]))
3602 op3 = copy_to_mode_reg (insn_operand_mode[icode][3], op3);
3604 /* Everything should now be in the suitable form, so emit the compare insn
3605 and then the conditional move. */
3608 = compare_from_rtx (op0, op1, code, unsignedp, cmode, NULL_RTX, 0);
3610 /* ??? Watch for const0_rtx (nop) and const_true_rtx (unconditional)? */
3611 if (GET_CODE (comparison) != code)
3612 /* This shouldn't happen. */
3615 insn = GEN_FCN (icode) (subtarget, comparison, op2, op3);
3617 /* If that failed, then give up. */
3623 if (subtarget != target)
3624 convert_move (target, subtarget, 0);
3629 /* Return non-zero if a conditional move of mode MODE is supported.
3631 This function is for combine so it can tell whether an insn that looks
3632 like a conditional move is actually supported by the hardware. If we
3633 guess wrong we lose a bit on optimization, but that's it. */
3634 /* ??? sparc64 supports conditionally moving integers values based on fp
3635 comparisons, and vice versa. How do we handle them? */
3638 can_conditionally_move_p (mode)
3639 enum machine_mode mode;
3641 if (movcc_gen_code[mode] != CODE_FOR_nothing)
3647 #endif /* HAVE_conditional_move */
3649 /* These three functions generate an insn body and return it
3650 rather than emitting the insn.
3652 They do not protect from queued increments,
3653 because they may be used 1) in protect_from_queue itself
3654 and 2) in other passes where there is no queue. */
3656 /* Generate and return an insn body to add Y to X. */
3659 gen_add2_insn (x, y)
3662 int icode = (int) add_optab->handlers[(int) GET_MODE (x)].insn_code;
3664 if (! (*insn_operand_predicate[icode][0]) (x, insn_operand_mode[icode][0])
3665 || ! (*insn_operand_predicate[icode][1]) (x, insn_operand_mode[icode][1])
3666 || ! (*insn_operand_predicate[icode][2]) (y, insn_operand_mode[icode][2]))
3669 return (GEN_FCN (icode) (x, x, y));
3673 have_add2_insn (mode)
3674 enum machine_mode mode;
3676 return add_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
3679 /* Generate and return an insn body to subtract Y from X. */
3682 gen_sub2_insn (x, y)
3685 int icode = (int) sub_optab->handlers[(int) GET_MODE (x)].insn_code;
3687 if (! (*insn_operand_predicate[icode][0]) (x, insn_operand_mode[icode][0])
3688 || ! (*insn_operand_predicate[icode][1]) (x, insn_operand_mode[icode][1])
3689 || ! (*insn_operand_predicate[icode][2]) (y, insn_operand_mode[icode][2]))
3692 return (GEN_FCN (icode) (x, x, y));
3696 have_sub2_insn (mode)
3697 enum machine_mode mode;
3699 return sub_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
3702 /* Generate the body of an instruction to copy Y into X.
3703 It may be a SEQUENCE, if one insn isn't enough. */
3706 gen_move_insn (x, y)
3709 register enum machine_mode mode = GET_MODE (x);
3710 enum insn_code insn_code;
3713 if (mode == VOIDmode)
3714 mode = GET_MODE (y);
3716 insn_code = mov_optab->handlers[(int) mode].insn_code;
3718 /* Handle MODE_CC modes: If we don't have a special move insn for this mode,
3719 find a mode to do it in. If we have a movcc, use it. Otherwise,
3720 find the MODE_INT mode of the same width. */
3722 if (GET_MODE_CLASS (mode) == MODE_CC && insn_code == CODE_FOR_nothing)
3724 enum machine_mode tmode = VOIDmode;
3728 && mov_optab->handlers[(int) CCmode].insn_code != CODE_FOR_nothing)
3731 for (tmode = QImode; tmode != VOIDmode;
3732 tmode = GET_MODE_WIDER_MODE (tmode))
3733 if (GET_MODE_SIZE (tmode) == GET_MODE_SIZE (mode))
3736 if (tmode == VOIDmode)
3739 /* Get X and Y in TMODE. We can't use gen_lowpart here because it
3740 may call change_address which is not appropriate if we were
3741 called when a reload was in progress. We don't have to worry
3742 about changing the address since the size in bytes is supposed to
3743 be the same. Copy the MEM to change the mode and move any
3744 substitutions from the old MEM to the new one. */
3746 if (reload_in_progress)
3748 x = gen_lowpart_common (tmode, x1);
3749 if (x == 0 && GET_CODE (x1) == MEM)
3751 x = gen_rtx_MEM (tmode, XEXP (x1, 0));
3752 RTX_UNCHANGING_P (x) = RTX_UNCHANGING_P (x1);
3753 MEM_COPY_ATTRIBUTES (x, x1);
3754 copy_replacements (x1, x);
3757 y = gen_lowpart_common (tmode, y1);
3758 if (y == 0 && GET_CODE (y1) == MEM)
3760 y = gen_rtx_MEM (tmode, XEXP (y1, 0));
3761 RTX_UNCHANGING_P (y) = RTX_UNCHANGING_P (y1);
3762 MEM_COPY_ATTRIBUTES (y, y1);
3763 copy_replacements (y1, y);
3768 x = gen_lowpart (tmode, x);
3769 y = gen_lowpart (tmode, y);
3772 insn_code = mov_optab->handlers[(int) tmode].insn_code;
3773 return (GEN_FCN (insn_code) (x, y));
3777 emit_move_insn_1 (x, y);
3778 seq = gen_sequence ();
3783 /* Return the insn code used to extend FROM_MODE to TO_MODE.
3784 UNSIGNEDP specifies zero-extension instead of sign-extension. If
3785 no such operation exists, CODE_FOR_nothing will be returned. */
3788 can_extend_p (to_mode, from_mode, unsignedp)
3789 enum machine_mode to_mode, from_mode;
3792 return extendtab[(int) to_mode][(int) from_mode][unsignedp];
3795 /* Generate the body of an insn to extend Y (with mode MFROM)
3796 into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */
3799 gen_extend_insn (x, y, mto, mfrom, unsignedp)
3801 enum machine_mode mto, mfrom;
3804 return (GEN_FCN (extendtab[(int) mto][(int) mfrom][unsignedp]) (x, y));
3807 /* can_fix_p and can_float_p say whether the target machine
3808 can directly convert a given fixed point type to
3809 a given floating point type, or vice versa.
3810 The returned value is the CODE_FOR_... value to use,
3811 or CODE_FOR_nothing if these modes cannot be directly converted.
3813 *TRUNCP_PTR is set to 1 if it is necessary to output
3814 an explicit FTRUNC insn before the fix insn; otherwise 0. */
3816 static enum insn_code
3817 can_fix_p (fixmode, fltmode, unsignedp, truncp_ptr)
3818 enum machine_mode fltmode, fixmode;
3823 if (fixtrunctab[(int) fltmode][(int) fixmode][unsignedp] != CODE_FOR_nothing)
3824 return fixtrunctab[(int) fltmode][(int) fixmode][unsignedp];
3826 if (ftrunc_optab->handlers[(int) fltmode].insn_code != CODE_FOR_nothing)
3829 return fixtab[(int) fltmode][(int) fixmode][unsignedp];
3831 return CODE_FOR_nothing;
3834 static enum insn_code
3835 can_float_p (fltmode, fixmode, unsignedp)
3836 enum machine_mode fixmode, fltmode;
3839 return floattab[(int) fltmode][(int) fixmode][unsignedp];
3842 /* Generate code to convert FROM to floating point
3843 and store in TO. FROM must be fixed point and not VOIDmode.
3844 UNSIGNEDP nonzero means regard FROM as unsigned.
3845 Normally this is done by correcting the final value
3846 if it is negative. */
3849 expand_float (to, from, unsignedp)
3853 enum insn_code icode;
3854 register rtx target = to;
3855 enum machine_mode fmode, imode;
3857 /* Crash now, because we won't be able to decide which mode to use. */
3858 if (GET_MODE (from) == VOIDmode)
3861 /* Look for an insn to do the conversion. Do it in the specified
3862 modes if possible; otherwise convert either input, output or both to
3863 wider mode. If the integer mode is wider than the mode of FROM,
3864 we can do the conversion signed even if the input is unsigned. */
3866 for (imode = GET_MODE (from); imode != VOIDmode;
3867 imode = GET_MODE_WIDER_MODE (imode))
3868 for (fmode = GET_MODE (to); fmode != VOIDmode;
3869 fmode = GET_MODE_WIDER_MODE (fmode))
3871 int doing_unsigned = unsignedp;
3873 icode = can_float_p (fmode, imode, unsignedp);
3874 if (icode == CODE_FOR_nothing && imode != GET_MODE (from) && unsignedp)
3875 icode = can_float_p (fmode, imode, 0), doing_unsigned = 0;
3877 if (icode != CODE_FOR_nothing)
3879 to = protect_from_queue (to, 1);
3880 from = protect_from_queue (from, 0);
3882 if (imode != GET_MODE (from))
3883 from = convert_to_mode (imode, from, unsignedp);
3885 if (fmode != GET_MODE (to))
3886 target = gen_reg_rtx (fmode);
3888 emit_unop_insn (icode, target, from,
3889 doing_unsigned ? UNSIGNED_FLOAT : FLOAT);
3892 convert_move (to, target, 0);
3897 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
3899 /* Unsigned integer, and no way to convert directly.
3900 Convert as signed, then conditionally adjust the result. */
3903 rtx label = gen_label_rtx ();
3905 REAL_VALUE_TYPE offset;
3909 to = protect_from_queue (to, 1);
3910 from = protect_from_queue (from, 0);
3913 from = force_not_mem (from);
3915 /* Look for a usable floating mode FMODE wider than the source and at
3916 least as wide as the target. Using FMODE will avoid rounding woes
3917 with unsigned values greater than the signed maximum value. */
3919 for (fmode = GET_MODE (to); fmode != VOIDmode;
3920 fmode = GET_MODE_WIDER_MODE (fmode))
3921 if (GET_MODE_BITSIZE (GET_MODE (from)) < GET_MODE_BITSIZE (fmode)
3922 && can_float_p (fmode, GET_MODE (from), 0) != CODE_FOR_nothing)
3925 if (fmode == VOIDmode)
3927 /* There is no such mode. Pretend the target is wide enough. */
3928 fmode = GET_MODE (to);
3930 /* Avoid double-rounding when TO is narrower than FROM. */
3931 if ((significand_size (fmode) + 1)
3932 < GET_MODE_BITSIZE (GET_MODE (from)))
3935 rtx neglabel = gen_label_rtx ();
3937 /* Don't use TARGET if it isn't a register, is a hard register,
3938 or is the wrong mode. */
3939 if (GET_CODE (target) != REG
3940 || REGNO (target) < FIRST_PSEUDO_REGISTER
3941 || GET_MODE (target) != fmode)
3942 target = gen_reg_rtx (fmode);
3944 imode = GET_MODE (from);
3945 do_pending_stack_adjust ();
3947 /* Test whether the sign bit is set. */
3948 emit_cmp_insn (from, const0_rtx, GE, NULL_RTX, imode, 0, 0);
3949 emit_jump_insn (gen_blt (neglabel));
3951 /* The sign bit is not set. Convert as signed. */
3952 expand_float (target, from, 0);
3953 emit_jump_insn (gen_jump (label));
3956 /* The sign bit is set.
3957 Convert to a usable (positive signed) value by shifting right
3958 one bit, while remembering if a nonzero bit was shifted
3959 out; i.e., compute (from & 1) | (from >> 1). */
3961 emit_label (neglabel);
3962 temp = expand_binop (imode, and_optab, from, const1_rtx,
3963 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3964 temp1 = expand_shift (RSHIFT_EXPR, imode, from, integer_one_node,
3966 temp = expand_binop (imode, ior_optab, temp, temp1, temp, 1,
3968 expand_float (target, temp, 0);
3970 /* Multiply by 2 to undo the shift above. */
3971 temp = expand_binop (fmode, add_optab, target, target,
3972 target, 0, OPTAB_LIB_WIDEN);
3974 emit_move_insn (target, temp);
3976 do_pending_stack_adjust ();
3982 /* If we are about to do some arithmetic to correct for an
3983 unsigned operand, do it in a pseudo-register. */
3985 if (GET_MODE (to) != fmode
3986 || GET_CODE (to) != REG || REGNO (to) < FIRST_PSEUDO_REGISTER)
3987 target = gen_reg_rtx (fmode);
3989 /* Convert as signed integer to floating. */
3990 expand_float (target, from, 0);
3992 /* If FROM is negative (and therefore TO is negative),
3993 correct its value by 2**bitwidth. */
3995 do_pending_stack_adjust ();
3996 emit_cmp_and_jump_insns (from, const0_rtx, GE, NULL_RTX, GET_MODE (from),
3999 /* On SCO 3.2.1, ldexp rejects values outside [0.5, 1).
4000 Rather than setting up a dconst_dot_5, let's hope SCO
4002 offset = REAL_VALUE_LDEXP (dconst1, GET_MODE_BITSIZE (GET_MODE (from)));
4003 temp = expand_binop (fmode, add_optab, target,
4004 CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode),
4005 target, 0, OPTAB_LIB_WIDEN);
4007 emit_move_insn (target, temp);
4009 do_pending_stack_adjust ();
4015 /* No hardware instruction available; call a library routine to convert from
4016 SImode, DImode, or TImode into SFmode, DFmode, XFmode, or TFmode. */
4022 to = protect_from_queue (to, 1);
4023 from = protect_from_queue (from, 0);
4025 if (GET_MODE_SIZE (GET_MODE (from)) < GET_MODE_SIZE (SImode))
4026 from = convert_to_mode (SImode, from, unsignedp);
4029 from = force_not_mem (from);
4031 if (GET_MODE (to) == SFmode)
4033 if (GET_MODE (from) == SImode)
4034 libfcn = floatsisf_libfunc;
4035 else if (GET_MODE (from) == DImode)
4036 libfcn = floatdisf_libfunc;
4037 else if (GET_MODE (from) == TImode)
4038 libfcn = floattisf_libfunc;
4042 else if (GET_MODE (to) == DFmode)
4044 if (GET_MODE (from) == SImode)
4045 libfcn = floatsidf_libfunc;
4046 else if (GET_MODE (from) == DImode)
4047 libfcn = floatdidf_libfunc;
4048 else if (GET_MODE (from) == TImode)
4049 libfcn = floattidf_libfunc;
4053 else if (GET_MODE (to) == XFmode)
4055 if (GET_MODE (from) == SImode)
4056 libfcn = floatsixf_libfunc;
4057 else if (GET_MODE (from) == DImode)
4058 libfcn = floatdixf_libfunc;
4059 else if (GET_MODE (from) == TImode)
4060 libfcn = floattixf_libfunc;
4064 else if (GET_MODE (to) == TFmode)
4066 if (GET_MODE (from) == SImode)
4067 libfcn = floatsitf_libfunc;
4068 else if (GET_MODE (from) == DImode)
4069 libfcn = floatditf_libfunc;
4070 else if (GET_MODE (from) == TImode)
4071 libfcn = floattitf_libfunc;
4080 value = emit_library_call_value (libfcn, NULL_RTX, 1,
4082 1, from, GET_MODE (from));
4083 insns = get_insns ();
4086 emit_libcall_block (insns, target, value,
4087 gen_rtx_FLOAT (GET_MODE (to), from));
4092 /* Copy result to requested destination
4093 if we have been computing in a temp location. */
4097 if (GET_MODE (target) == GET_MODE (to))
4098 emit_move_insn (to, target);
4100 convert_move (to, target, 0);
4104 /* expand_fix: generate code to convert FROM to fixed point
4105 and store in TO. FROM must be floating point. */
4111 rtx temp = gen_reg_rtx (GET_MODE (x));
4112 return expand_unop (GET_MODE (x), ftrunc_optab, x, temp, 0);
4116 expand_fix (to, from, unsignedp)
4117 register rtx to, from;
4120 enum insn_code icode;
4121 register rtx target = to;
4122 enum machine_mode fmode, imode;
4126 /* We first try to find a pair of modes, one real and one integer, at
4127 least as wide as FROM and TO, respectively, in which we can open-code
4128 this conversion. If the integer mode is wider than the mode of TO,
4129 we can do the conversion either signed or unsigned. */
4131 for (imode = GET_MODE (to); imode != VOIDmode;
4132 imode = GET_MODE_WIDER_MODE (imode))
4133 for (fmode = GET_MODE (from); fmode != VOIDmode;
4134 fmode = GET_MODE_WIDER_MODE (fmode))
4136 int doing_unsigned = unsignedp;
4138 icode = can_fix_p (imode, fmode, unsignedp, &must_trunc);
4139 if (icode == CODE_FOR_nothing && imode != GET_MODE (to) && unsignedp)
4140 icode = can_fix_p (imode, fmode, 0, &must_trunc), doing_unsigned = 0;
4142 if (icode != CODE_FOR_nothing)
4144 to = protect_from_queue (to, 1);
4145 from = protect_from_queue (from, 0);
4147 if (fmode != GET_MODE (from))
4148 from = convert_to_mode (fmode, from, 0);
4151 from = ftruncify (from);
4153 if (imode != GET_MODE (to))
4154 target = gen_reg_rtx (imode);
4156 emit_unop_insn (icode, target, from,
4157 doing_unsigned ? UNSIGNED_FIX : FIX);
4159 convert_move (to, target, unsignedp);
4164 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
4165 /* For an unsigned conversion, there is one more way to do it.
4166 If we have a signed conversion, we generate code that compares
4167 the real value to the largest representable positive number. If if
4168 is smaller, the conversion is done normally. Otherwise, subtract
4169 one plus the highest signed number, convert, and add it back.
4171 We only need to check all real modes, since we know we didn't find
4172 anything with a wider integer mode. */
4174 if (unsignedp && GET_MODE_BITSIZE (GET_MODE (to)) <= HOST_BITS_PER_WIDE_INT)
4175 for (fmode = GET_MODE (from); fmode != VOIDmode;
4176 fmode = GET_MODE_WIDER_MODE (fmode))
4177 /* Make sure we won't lose significant bits doing this. */
4178 if (GET_MODE_BITSIZE (fmode) > GET_MODE_BITSIZE (GET_MODE (to))
4179 && CODE_FOR_nothing != can_fix_p (GET_MODE (to), fmode, 0,
4183 REAL_VALUE_TYPE offset;
4184 rtx limit, lab1, lab2, insn;
4186 bitsize = GET_MODE_BITSIZE (GET_MODE (to));
4187 offset = REAL_VALUE_LDEXP (dconst1, bitsize - 1);
4188 limit = CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode);
4189 lab1 = gen_label_rtx ();
4190 lab2 = gen_label_rtx ();
4193 to = protect_from_queue (to, 1);
4194 from = protect_from_queue (from, 0);
4197 from = force_not_mem (from);
4199 if (fmode != GET_MODE (from))
4200 from = convert_to_mode (fmode, from, 0);
4202 /* See if we need to do the subtraction. */
4203 do_pending_stack_adjust ();
4204 emit_cmp_and_jump_insns (from, limit, GE, NULL_RTX, GET_MODE (from),
4207 /* If not, do the signed "fix" and branch around fixup code. */
4208 expand_fix (to, from, 0);
4209 emit_jump_insn (gen_jump (lab2));
4212 /* Otherwise, subtract 2**(N-1), convert to signed number,
4213 then add 2**(N-1). Do the addition using XOR since this
4214 will often generate better code. */
4216 target = expand_binop (GET_MODE (from), sub_optab, from, limit,
4217 NULL_RTX, 0, OPTAB_LIB_WIDEN);
4218 expand_fix (to, target, 0);
4219 target = expand_binop (GET_MODE (to), xor_optab, to,
4220 GEN_INT ((HOST_WIDE_INT) 1 << (bitsize - 1)),
4221 to, 1, OPTAB_LIB_WIDEN);
4224 emit_move_insn (to, target);
4228 if (mov_optab->handlers[(int) GET_MODE (to)].insn_code
4229 != CODE_FOR_nothing)
4231 /* Make a place for a REG_NOTE and add it. */
4232 insn = emit_move_insn (to, to);
4233 set_unique_reg_note (insn,
4235 gen_rtx_fmt_e (UNSIGNED_FIX,
4243 /* We can't do it with an insn, so use a library call. But first ensure
4244 that the mode of TO is at least as wide as SImode, since those are the
4245 only library calls we know about. */
4247 if (GET_MODE_SIZE (GET_MODE (to)) < GET_MODE_SIZE (SImode))
4249 target = gen_reg_rtx (SImode);
4251 expand_fix (target, from, unsignedp);
4253 else if (GET_MODE (from) == SFmode)
4255 if (GET_MODE (to) == SImode)
4256 libfcn = unsignedp ? fixunssfsi_libfunc : fixsfsi_libfunc;
4257 else if (GET_MODE (to) == DImode)
4258 libfcn = unsignedp ? fixunssfdi_libfunc : fixsfdi_libfunc;
4259 else if (GET_MODE (to) == TImode)
4260 libfcn = unsignedp ? fixunssfti_libfunc : fixsfti_libfunc;
4264 else if (GET_MODE (from) == DFmode)
4266 if (GET_MODE (to) == SImode)
4267 libfcn = unsignedp ? fixunsdfsi_libfunc : fixdfsi_libfunc;
4268 else if (GET_MODE (to) == DImode)
4269 libfcn = unsignedp ? fixunsdfdi_libfunc : fixdfdi_libfunc;
4270 else if (GET_MODE (to) == TImode)
4271 libfcn = unsignedp ? fixunsdfti_libfunc : fixdfti_libfunc;
4275 else if (GET_MODE (from) == XFmode)
4277 if (GET_MODE (to) == SImode)
4278 libfcn = unsignedp ? fixunsxfsi_libfunc : fixxfsi_libfunc;
4279 else if (GET_MODE (to) == DImode)
4280 libfcn = unsignedp ? fixunsxfdi_libfunc : fixxfdi_libfunc;
4281 else if (GET_MODE (to) == TImode)
4282 libfcn = unsignedp ? fixunsxfti_libfunc : fixxfti_libfunc;
4286 else if (GET_MODE (from) == TFmode)
4288 if (GET_MODE (to) == SImode)
4289 libfcn = unsignedp ? fixunstfsi_libfunc : fixtfsi_libfunc;
4290 else if (GET_MODE (to) == DImode)
4291 libfcn = unsignedp ? fixunstfdi_libfunc : fixtfdi_libfunc;
4292 else if (GET_MODE (to) == TImode)
4293 libfcn = unsignedp ? fixunstfti_libfunc : fixtfti_libfunc;
4305 to = protect_from_queue (to, 1);
4306 from = protect_from_queue (from, 0);
4309 from = force_not_mem (from);
4313 value = emit_library_call_value (libfcn, NULL_RTX, 1, GET_MODE (to),
4315 1, from, GET_MODE (from));
4316 insns = get_insns ();
4319 emit_libcall_block (insns, target, value,
4320 gen_rtx_fmt_e (unsignedp ? UNSIGNED_FIX : FIX,
4321 GET_MODE (to), from));
4326 if (GET_MODE (to) == GET_MODE (target))
4327 emit_move_insn (to, target);
4329 convert_move (to, target, 0);
4338 optab op = (optab) xmalloc (sizeof (struct optab));
4340 for (i = 0; i < NUM_MACHINE_MODES; i++)
4342 op->handlers[i].insn_code = CODE_FOR_nothing;
4343 op->handlers[i].libfunc = 0;
4346 if (code != UNKNOWN)
4347 code_to_optab[(int) code] = op;
4352 /* Initialize the libfunc fields of an entire group of entries in some
4353 optab. Each entry is set equal to a string consisting of a leading
4354 pair of underscores followed by a generic operation name followed by
4355 a mode name (downshifted to lower case) followed by a single character
4356 representing the number of operands for the given operation (which is
4357 usually one of the characters '2', '3', or '4').
4359 OPTABLE is the table in which libfunc fields are to be initialized.
4360 FIRST_MODE is the first machine mode index in the given optab to
4362 LAST_MODE is the last machine mode index in the given optab to
4364 OPNAME is the generic (string) name of the operation.
4365 SUFFIX is the character which specifies the number of operands for
4366 the given generic operation.
4370 init_libfuncs (optable, first_mode, last_mode, opname, suffix)
4371 register optab optable;
4372 register int first_mode;
4373 register int last_mode;
4374 register const char *opname;
4375 register int suffix;
4378 register unsigned opname_len = strlen (opname);
4380 for (mode = first_mode; (int) mode <= (int) last_mode;
4381 mode = (enum machine_mode) ((int) mode + 1))
4383 register char *mname = mode_name[(int) mode];
4384 register unsigned mname_len = strlen (mname);
4385 register char *libfunc_name
4386 = (char *) xmalloc (2 + opname_len + mname_len + 1 + 1);
4388 register const char *q;
4393 for (q = opname; *q; )
4395 for (q = mname; *q; q++)
4396 *p++ = tolower ((unsigned char)*q);
4399 optable->handlers[(int) mode].libfunc
4400 = gen_rtx_SYMBOL_REF (Pmode, libfunc_name);
4404 /* Initialize the libfunc fields of an entire group of entries in some
4405 optab which correspond to all integer mode operations. The parameters
4406 have the same meaning as similarly named ones for the `init_libfuncs'
4407 routine. (See above). */
4410 init_integral_libfuncs (optable, opname, suffix)
4411 register optab optable;
4412 register const char *opname;
4413 register int suffix;
4415 init_libfuncs (optable, SImode, TImode, opname, suffix);
4418 /* Initialize the libfunc fields of an entire group of entries in some
4419 optab which correspond to all real mode operations. The parameters
4420 have the same meaning as similarly named ones for the `init_libfuncs'
4421 routine. (See above). */
4424 init_floating_libfuncs (optable, opname, suffix)
4425 register optab optable;
4426 register const char *opname;
4427 register int suffix;
4429 init_libfuncs (optable, SFmode, TFmode, opname, suffix);
4433 /* Call this once to initialize the contents of the optabs
4434 appropriately for the current target machine. */
4440 #ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC
4446 /* Start by initializing all tables to contain CODE_FOR_nothing. */
4448 for (p = fixtab[0][0];
4449 p < fixtab[0][0] + sizeof fixtab / sizeof (fixtab[0][0][0]);
4451 *p = CODE_FOR_nothing;
4453 for (p = fixtrunctab[0][0];
4454 p < fixtrunctab[0][0] + sizeof fixtrunctab / sizeof (fixtrunctab[0][0][0]);
4456 *p = CODE_FOR_nothing;
4458 for (p = floattab[0][0];
4459 p < floattab[0][0] + sizeof floattab / sizeof (floattab[0][0][0]);
4461 *p = CODE_FOR_nothing;
4463 for (p = extendtab[0][0];
4464 p < extendtab[0][0] + sizeof extendtab / sizeof extendtab[0][0][0];
4466 *p = CODE_FOR_nothing;
4468 for (i = 0; i < NUM_RTX_CODE; i++)
4469 setcc_gen_code[i] = CODE_FOR_nothing;
4471 #ifdef HAVE_conditional_move
4472 for (i = 0; i < NUM_MACHINE_MODES; i++)
4473 movcc_gen_code[i] = CODE_FOR_nothing;
4476 add_optab = init_optab (PLUS);
4477 sub_optab = init_optab (MINUS);
4478 smul_optab = init_optab (MULT);
4479 smul_highpart_optab = init_optab (UNKNOWN);
4480 umul_highpart_optab = init_optab (UNKNOWN);
4481 smul_widen_optab = init_optab (UNKNOWN);
4482 umul_widen_optab = init_optab (UNKNOWN);
4483 sdiv_optab = init_optab (DIV);
4484 sdivmod_optab = init_optab (UNKNOWN);
4485 udiv_optab = init_optab (UDIV);
4486 udivmod_optab = init_optab (UNKNOWN);
4487 smod_optab = init_optab (MOD);
4488 umod_optab = init_optab (UMOD);
4489 flodiv_optab = init_optab (DIV);
4490 ftrunc_optab = init_optab (UNKNOWN);
4491 and_optab = init_optab (AND);
4492 ior_optab = init_optab (IOR);
4493 xor_optab = init_optab (XOR);
4494 ashl_optab = init_optab (ASHIFT);
4495 ashr_optab = init_optab (ASHIFTRT);
4496 lshr_optab = init_optab (LSHIFTRT);
4497 rotl_optab = init_optab (ROTATE);
4498 rotr_optab = init_optab (ROTATERT);
4499 smin_optab = init_optab (SMIN);
4500 smax_optab = init_optab (SMAX);
4501 umin_optab = init_optab (UMIN);
4502 umax_optab = init_optab (UMAX);
4503 mov_optab = init_optab (UNKNOWN);
4504 movstrict_optab = init_optab (UNKNOWN);
4505 cmp_optab = init_optab (UNKNOWN);
4506 ucmp_optab = init_optab (UNKNOWN);
4507 tst_optab = init_optab (UNKNOWN);
4508 neg_optab = init_optab (NEG);
4509 abs_optab = init_optab (ABS);
4510 one_cmpl_optab = init_optab (NOT);
4511 ffs_optab = init_optab (FFS);
4512 sqrt_optab = init_optab (SQRT);
4513 sin_optab = init_optab (UNKNOWN);
4514 cos_optab = init_optab (UNKNOWN);
4515 strlen_optab = init_optab (UNKNOWN);
4517 for (i = 0; i < NUM_MACHINE_MODES; i++)
4519 movstr_optab[i] = CODE_FOR_nothing;
4520 clrstr_optab[i] = CODE_FOR_nothing;
4522 #ifdef HAVE_SECONDARY_RELOADS
4523 reload_in_optab[i] = reload_out_optab[i] = CODE_FOR_nothing;
4527 /* Fill in the optabs with the insns we support. */
4530 #ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC
4531 /* This flag says the same insns that convert to a signed fixnum
4532 also convert validly to an unsigned one. */
4533 for (i = 0; i < NUM_MACHINE_MODES; i++)
4534 for (j = 0; j < NUM_MACHINE_MODES; j++)
4535 fixtrunctab[i][j][1] = fixtrunctab[i][j][0];
4538 #ifdef EXTRA_CC_MODES
4542 /* Initialize the optabs with the names of the library functions. */
4543 init_integral_libfuncs (add_optab, "add", '3');
4544 init_floating_libfuncs (add_optab, "add", '3');
4545 init_integral_libfuncs (sub_optab, "sub", '3');
4546 init_floating_libfuncs (sub_optab, "sub", '3');
4547 init_integral_libfuncs (smul_optab, "mul", '3');
4548 init_floating_libfuncs (smul_optab, "mul", '3');
4549 init_integral_libfuncs (sdiv_optab, "div", '3');
4550 init_integral_libfuncs (udiv_optab, "udiv", '3');
4551 init_integral_libfuncs (sdivmod_optab, "divmod", '4');
4552 init_integral_libfuncs (udivmod_optab, "udivmod", '4');
4553 init_integral_libfuncs (smod_optab, "mod", '3');
4554 init_integral_libfuncs (umod_optab, "umod", '3');
4555 init_floating_libfuncs (flodiv_optab, "div", '3');
4556 init_floating_libfuncs (ftrunc_optab, "ftrunc", '2');
4557 init_integral_libfuncs (and_optab, "and", '3');
4558 init_integral_libfuncs (ior_optab, "ior", '3');
4559 init_integral_libfuncs (xor_optab, "xor", '3');
4560 init_integral_libfuncs (ashl_optab, "ashl", '3');
4561 init_integral_libfuncs (ashr_optab, "ashr", '3');
4562 init_integral_libfuncs (lshr_optab, "lshr", '3');
4563 init_integral_libfuncs (smin_optab, "min", '3');
4564 init_floating_libfuncs (smin_optab, "min", '3');
4565 init_integral_libfuncs (smax_optab, "max", '3');
4566 init_floating_libfuncs (smax_optab, "max", '3');
4567 init_integral_libfuncs (umin_optab, "umin", '3');
4568 init_integral_libfuncs (umax_optab, "umax", '3');
4569 init_integral_libfuncs (neg_optab, "neg", '2');
4570 init_floating_libfuncs (neg_optab, "neg", '2');
4571 init_integral_libfuncs (one_cmpl_optab, "one_cmpl", '2');
4572 init_integral_libfuncs (ffs_optab, "ffs", '2');
4574 /* Comparison libcalls for integers MUST come in pairs, signed/unsigned. */
4575 init_integral_libfuncs (cmp_optab, "cmp", '2');
4576 init_integral_libfuncs (ucmp_optab, "ucmp", '2');
4577 init_floating_libfuncs (cmp_optab, "cmp", '2');
4579 #ifdef MULSI3_LIBCALL
4580 smul_optab->handlers[(int) SImode].libfunc
4581 = gen_rtx_SYMBOL_REF (Pmode, MULSI3_LIBCALL);
4583 #ifdef MULDI3_LIBCALL
4584 smul_optab->handlers[(int) DImode].libfunc
4585 = gen_rtx_SYMBOL_REF (Pmode, MULDI3_LIBCALL);
4588 #ifdef DIVSI3_LIBCALL
4589 sdiv_optab->handlers[(int) SImode].libfunc
4590 = gen_rtx_SYMBOL_REF (Pmode, DIVSI3_LIBCALL);
4592 #ifdef DIVDI3_LIBCALL
4593 sdiv_optab->handlers[(int) DImode].libfunc
4594 = gen_rtx_SYMBOL_REF (Pmode, DIVDI3_LIBCALL);
4597 #ifdef UDIVSI3_LIBCALL
4598 udiv_optab->handlers[(int) SImode].libfunc
4599 = gen_rtx_SYMBOL_REF (Pmode, UDIVSI3_LIBCALL);
4601 #ifdef UDIVDI3_LIBCALL
4602 udiv_optab->handlers[(int) DImode].libfunc
4603 = gen_rtx_SYMBOL_REF (Pmode, UDIVDI3_LIBCALL);
4606 #ifdef MODSI3_LIBCALL
4607 smod_optab->handlers[(int) SImode].libfunc
4608 = gen_rtx_SYMBOL_REF (Pmode, MODSI3_LIBCALL);
4610 #ifdef MODDI3_LIBCALL
4611 smod_optab->handlers[(int) DImode].libfunc
4612 = gen_rtx_SYMBOL_REF (Pmode, MODDI3_LIBCALL);
4615 #ifdef UMODSI3_LIBCALL
4616 umod_optab->handlers[(int) SImode].libfunc
4617 = gen_rtx_SYMBOL_REF (Pmode, UMODSI3_LIBCALL);
4619 #ifdef UMODDI3_LIBCALL
4620 umod_optab->handlers[(int) DImode].libfunc
4621 = gen_rtx_SYMBOL_REF (Pmode, UMODDI3_LIBCALL);
4624 /* Use cabs for DC complex abs, since systems generally have cabs.
4625 Don't define any libcall for SCmode, so that cabs will be used. */
4626 abs_optab->handlers[(int) DCmode].libfunc
4627 = gen_rtx_SYMBOL_REF (Pmode, "cabs");
4629 /* The ffs function operates on `int'. */
4630 #ifndef INT_TYPE_SIZE
4631 #define INT_TYPE_SIZE BITS_PER_WORD
4633 ffs_optab->handlers[(int) mode_for_size (INT_TYPE_SIZE, MODE_INT, 0)] .libfunc
4634 = gen_rtx_SYMBOL_REF (Pmode, "ffs");
4636 extendsfdf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__extendsfdf2");
4637 extendsfxf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__extendsfxf2");
4638 extendsftf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__extendsftf2");
4639 extenddfxf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__extenddfxf2");
4640 extenddftf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__extenddftf2");
4642 truncdfsf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__truncdfsf2");
4643 truncxfsf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__truncxfsf2");
4644 trunctfsf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__trunctfsf2");
4645 truncxfdf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__truncxfdf2");
4646 trunctfdf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__trunctfdf2");
4648 memcpy_libfunc = gen_rtx_SYMBOL_REF (Pmode, "memcpy");
4649 bcopy_libfunc = gen_rtx_SYMBOL_REF (Pmode, "bcopy");
4650 memcmp_libfunc = gen_rtx_SYMBOL_REF (Pmode, "memcmp");
4651 bcmp_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__gcc_bcmp");
4652 memset_libfunc = gen_rtx_SYMBOL_REF (Pmode, "memset");
4653 bzero_libfunc = gen_rtx_SYMBOL_REF (Pmode, "bzero");
4655 throw_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__throw");
4656 rethrow_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__rethrow");
4657 sjthrow_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__sjthrow");
4658 sjpopnthrow_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__sjpopnthrow");
4659 terminate_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__terminate");
4660 eh_rtime_match_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__eh_rtime_match");
4661 #ifndef DONT_USE_BUILTIN_SETJMP
4662 setjmp_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__builtin_setjmp");
4663 longjmp_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__builtin_longjmp");
4665 setjmp_libfunc = gen_rtx_SYMBOL_REF (Pmode, "setjmp");
4666 longjmp_libfunc = gen_rtx_SYMBOL_REF (Pmode, "longjmp");
4669 eqhf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__eqhf2");
4670 nehf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__nehf2");
4671 gthf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__gthf2");
4672 gehf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__gehf2");
4673 lthf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__lthf2");
4674 lehf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__lehf2");
4676 eqsf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__eqsf2");
4677 nesf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__nesf2");
4678 gtsf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__gtsf2");
4679 gesf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__gesf2");
4680 ltsf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__ltsf2");
4681 lesf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__lesf2");
4683 eqdf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__eqdf2");
4684 nedf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__nedf2");
4685 gtdf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__gtdf2");
4686 gedf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__gedf2");
4687 ltdf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__ltdf2");
4688 ledf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__ledf2");
4690 eqxf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__eqxf2");
4691 nexf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__nexf2");
4692 gtxf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__gtxf2");
4693 gexf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__gexf2");
4694 ltxf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__ltxf2");
4695 lexf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__lexf2");
4697 eqtf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__eqtf2");
4698 netf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__netf2");
4699 gttf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__gttf2");
4700 getf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__getf2");
4701 lttf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__lttf2");
4702 letf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__letf2");
4704 floatsisf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floatsisf");
4705 floatdisf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floatdisf");
4706 floattisf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floattisf");
4708 floatsidf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floatsidf");
4709 floatdidf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floatdidf");
4710 floattidf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floattidf");
4712 floatsixf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floatsixf");
4713 floatdixf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floatdixf");
4714 floattixf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floattixf");
4716 floatsitf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floatsitf");
4717 floatditf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floatditf");
4718 floattitf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floattitf");
4720 fixsfsi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixsfsi");
4721 fixsfdi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixsfdi");
4722 fixsfti_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixsfti");
4724 fixdfsi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixdfsi");
4725 fixdfdi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixdfdi");
4726 fixdfti_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixdfti");
4728 fixxfsi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixxfsi");
4729 fixxfdi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixxfdi");
4730 fixxfti_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixxfti");
4732 fixtfsi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixtfsi");
4733 fixtfdi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixtfdi");
4734 fixtfti_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixtfti");
4736 fixunssfsi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunssfsi");
4737 fixunssfdi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunssfdi");
4738 fixunssfti_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunssfti");
4740 fixunsdfsi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunsdfsi");
4741 fixunsdfdi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunsdfdi");
4742 fixunsdfti_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunsdfti");
4744 fixunsxfsi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunsxfsi");
4745 fixunsxfdi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunsxfdi");
4746 fixunsxfti_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunsxfti");
4748 fixunstfsi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunstfsi");
4749 fixunstfdi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunstfdi");
4750 fixunstfti_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunstfti");
4752 /* For check-memory-usage. */
4753 chkr_check_addr_libfunc = gen_rtx_SYMBOL_REF (Pmode, "chkr_check_addr");
4754 chkr_set_right_libfunc = gen_rtx_SYMBOL_REF (Pmode, "chkr_set_right");
4755 chkr_copy_bitmap_libfunc = gen_rtx_SYMBOL_REF (Pmode, "chkr_copy_bitmap");
4756 chkr_check_exec_libfunc = gen_rtx_SYMBOL_REF (Pmode, "chkr_check_exec");
4757 chkr_check_str_libfunc = gen_rtx_SYMBOL_REF (Pmode, "chkr_check_str");
4759 /* For function entry/exit instrumentation. */
4760 profile_function_entry_libfunc
4761 = gen_rtx_SYMBOL_REF (Pmode, "__cyg_profile_func_enter");
4762 profile_function_exit_libfunc
4763 = gen_rtx_SYMBOL_REF (Pmode, "__cyg_profile_func_exit");
4765 #ifdef HAVE_conditional_trap
4769 #ifdef INIT_TARGET_OPTABS
4770 /* Allow the target to add more libcalls or rename some, etc. */
4777 /* SCO 3.2 apparently has a broken ldexp. */
4790 #endif /* BROKEN_LDEXP */
4792 #ifdef HAVE_conditional_trap
4793 /* The insn generating function can not take an rtx_code argument.
4794 TRAP_RTX is used as an rtx argument. Its code is replaced with
4795 the code to be used in the trap insn and all other fields are
4798 ??? Will need to change to support garbage collection. */
4799 static rtx trap_rtx;
4804 if (HAVE_conditional_trap)
4805 trap_rtx = gen_rtx_fmt_ee (EQ, VOIDmode, NULL_RTX, NULL_RTX);
4809 /* Generate insns to trap with code TCODE if OP1 and OP2 satisfy condition
4810 CODE. Return 0 on failure. */
4813 gen_cond_trap (code, op1, op2, tcode)
4814 enum rtx_code code ATTRIBUTE_UNUSED;
4815 rtx op1, op2 ATTRIBUTE_UNUSED, tcode ATTRIBUTE_UNUSED;
4817 enum machine_mode mode = GET_MODE (op1);
4819 if (mode == VOIDmode)
4822 #ifdef HAVE_conditional_trap
4823 if (HAVE_conditional_trap
4824 && cmp_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
4827 emit_insn (GEN_FCN (cmp_optab->handlers[(int) mode].insn_code) (op1, op2));
4828 PUT_CODE (trap_rtx, code);
4829 insn = gen_conditional_trap (trap_rtx, tcode);