1 /* Expand the basic unary and binary arithmetic operations, for GNU compiler.
2 Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000 Free Software Foundation, Inc.
5 This file is part of GNU CC.
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
27 /* Include insn-config.h before expr.h so that HAVE_conditional_move
28 is properly defined. */
29 #include "insn-config.h"
33 #include "insn-flags.h"
34 #include "insn-codes.h"
39 /* Each optab contains info on how this target machine
40 can perform a particular operation
41 for all sizes and kinds of operands.
43 The operation to be performed is often specified
44 by passing one of these optabs as an argument.
46 See expr.h for documentation of these optabs. */
51 optab smul_highpart_optab;
52 optab umul_highpart_optab;
53 optab smul_widen_optab;
54 optab umul_widen_optab;
77 optab movstrict_optab;
88 optab ucmp_optab; /* Used only for libcalls for unsigned comparisons. */
93 /* Tables of patterns for extending one integer mode to another. */
94 enum insn_code extendtab[MAX_MACHINE_MODE][MAX_MACHINE_MODE][2];
96 /* Tables of patterns for converting between fixed and floating point. */
97 enum insn_code fixtab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
98 enum insn_code fixtrunctab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
99 enum insn_code floattab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
101 /* Contains the optab used for each rtx code. */
102 optab code_to_optab[NUM_RTX_CODE + 1];
104 /* SYMBOL_REF rtx's for the library functions that are called
105 implicitly and not via optabs. */
107 rtx extendsfdf2_libfunc;
108 rtx extendsfxf2_libfunc;
109 rtx extendsftf2_libfunc;
110 rtx extenddfxf2_libfunc;
111 rtx extenddftf2_libfunc;
113 rtx truncdfsf2_libfunc;
114 rtx truncxfsf2_libfunc;
115 rtx trunctfsf2_libfunc;
116 rtx truncxfdf2_libfunc;
117 rtx trunctfdf2_libfunc;
129 rtx sjpopnthrow_libfunc;
130 rtx terminate_libfunc;
133 rtx eh_rtime_match_libfunc;
170 rtx floatsisf_libfunc;
171 rtx floatdisf_libfunc;
172 rtx floattisf_libfunc;
174 rtx floatsidf_libfunc;
175 rtx floatdidf_libfunc;
176 rtx floattidf_libfunc;
178 rtx floatsixf_libfunc;
179 rtx floatdixf_libfunc;
180 rtx floattixf_libfunc;
182 rtx floatsitf_libfunc;
183 rtx floatditf_libfunc;
184 rtx floattitf_libfunc;
202 rtx fixunssfsi_libfunc;
203 rtx fixunssfdi_libfunc;
204 rtx fixunssfti_libfunc;
206 rtx fixunsdfsi_libfunc;
207 rtx fixunsdfdi_libfunc;
208 rtx fixunsdfti_libfunc;
210 rtx fixunsxfsi_libfunc;
211 rtx fixunsxfdi_libfunc;
212 rtx fixunsxfti_libfunc;
214 rtx fixunstfsi_libfunc;
215 rtx fixunstfdi_libfunc;
216 rtx fixunstfti_libfunc;
218 rtx chkr_check_addr_libfunc;
219 rtx chkr_set_right_libfunc;
220 rtx chkr_copy_bitmap_libfunc;
221 rtx chkr_check_exec_libfunc;
222 rtx chkr_check_str_libfunc;
224 rtx profile_function_entry_libfunc;
225 rtx profile_function_exit_libfunc;
227 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
228 gives the gen_function to make a branch to test that condition. */
230 rtxfun bcc_gen_fctn[NUM_RTX_CODE];
232 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
233 gives the insn code to make a store-condition insn
234 to test that condition. */
236 enum insn_code setcc_gen_code[NUM_RTX_CODE];
238 #ifdef HAVE_conditional_move
239 /* Indexed by the machine mode, gives the insn code to make a conditional
240 move insn. This is not indexed by the rtx-code like bcc_gen_fctn and
241 setcc_gen_code to cut down on the number of named patterns. Consider a day
242 when a lot more rtx codes are conditional (eg: for the ARM). */
244 enum insn_code movcc_gen_code[NUM_MACHINE_MODES];
247 static int add_equal_note PROTO((rtx, rtx, enum rtx_code, rtx, rtx));
248 static rtx widen_operand PROTO((rtx, enum machine_mode,
249 enum machine_mode, int, int));
250 static int expand_cmplxdiv_straight PROTO((rtx, rtx, rtx, rtx,
251 rtx, rtx, enum machine_mode,
252 int, enum optab_methods,
253 enum mode_class, optab));
254 static int expand_cmplxdiv_wide PROTO((rtx, rtx, rtx, rtx,
255 rtx, rtx, enum machine_mode,
256 int, enum optab_methods,
257 enum mode_class, optab));
258 static enum insn_code can_fix_p PROTO((enum machine_mode, enum machine_mode,
260 static enum insn_code can_float_p PROTO((enum machine_mode, enum machine_mode,
262 static rtx ftruncify PROTO((rtx));
263 static optab init_optab PROTO((enum rtx_code));
264 static void init_libfuncs PROTO((optab, int, int, const char *, int));
265 static void init_integral_libfuncs PROTO((optab, const char *, int));
266 static void init_floating_libfuncs PROTO((optab, const char *, int));
267 #ifdef HAVE_conditional_trap
268 static void init_traps PROTO((void));
271 /* Add a REG_EQUAL note to the last insn in SEQ. TARGET is being set to
272 the result of operation CODE applied to OP0 (and OP1 if it is a binary
275 If the last insn does not set TARGET, don't do anything, but return 1.
277 If a previous insn sets TARGET and TARGET is one of OP0 or OP1,
278 don't add the REG_EQUAL note but return 0. Our caller can then try
279 again, ensuring that TARGET is not one of the operands. */
282 add_equal_note (seq, target, code, op0, op1)
292 if ((GET_RTX_CLASS (code) != '1' && GET_RTX_CLASS (code) != '2'
293 && GET_RTX_CLASS (code) != 'c' && GET_RTX_CLASS (code) != '<')
294 || GET_CODE (seq) != SEQUENCE
295 || (set = single_set (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1))) == 0
296 || GET_CODE (target) == ZERO_EXTRACT
297 || (! rtx_equal_p (SET_DEST (set), target)
298 /* For a STRICT_LOW_PART, the REG_NOTE applies to what is inside the
300 && (GET_CODE (SET_DEST (set)) != STRICT_LOW_PART
301 || ! rtx_equal_p (SUBREG_REG (XEXP (SET_DEST (set), 0)),
305 /* If TARGET is in OP0 or OP1, check if anything in SEQ sets TARGET
306 besides the last insn. */
307 if (reg_overlap_mentioned_p (target, op0)
308 || (op1 && reg_overlap_mentioned_p (target, op1)))
309 for (i = XVECLEN (seq, 0) - 2; i >= 0; i--)
310 if (reg_set_p (target, XVECEXP (seq, 0, i)))
313 if (GET_RTX_CLASS (code) == '1')
314 note = gen_rtx_fmt_e (code, GET_MODE (target), copy_rtx (op0));
316 note = gen_rtx_fmt_ee (code, GET_MODE (target), copy_rtx (op0), copy_rtx (op1));
318 set_unique_reg_note (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1), REG_EQUAL, note);
323 /* Widen OP to MODE and return the rtx for the widened operand. UNSIGNEDP
324 says whether OP is signed or unsigned. NO_EXTEND is nonzero if we need
325 not actually do a sign-extend or zero-extend, but can leave the
326 higher-order bits of the result rtx undefined, for example, in the case
327 of logical operations, but not right shifts. */
330 widen_operand (op, mode, oldmode, unsignedp, no_extend)
332 enum machine_mode mode, oldmode;
338 /* If we must extend do so. If OP is either a constant or a SUBREG
339 for a promoted object, also extend since it will be more efficient to
342 || GET_MODE (op) == VOIDmode
343 || (GET_CODE (op) == SUBREG && SUBREG_PROMOTED_VAR_P (op)))
344 return convert_modes (mode, oldmode, op, unsignedp);
346 /* If MODE is no wider than a single word, we return a paradoxical
348 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
349 return gen_rtx_SUBREG (mode, force_reg (GET_MODE (op), op), 0);
351 /* Otherwise, get an object of MODE, clobber it, and set the low-order
354 result = gen_reg_rtx (mode);
355 emit_insn (gen_rtx_CLOBBER (VOIDmode, result));
356 emit_move_insn (gen_lowpart (GET_MODE (op), result), op);
360 /* Generate code to perform a straightforward complex divide. */
363 expand_cmplxdiv_straight (real0, real1, imag0, imag1, realr, imagr, submode,
364 unsignedp, methods, class, binoptab)
365 rtx real0, real1, imag0, imag1, realr, imagr;
366 enum machine_mode submode;
368 enum optab_methods methods;
369 enum mode_class class;
377 /* Don't fetch these from memory more than once. */
378 real0 = force_reg (submode, real0);
379 real1 = force_reg (submode, real1);
382 imag0 = force_reg (submode, imag0);
384 imag1 = force_reg (submode, imag1);
386 /* Divisor: c*c + d*d. */
387 temp1 = expand_binop (submode, smul_optab, real1, real1,
388 NULL_RTX, unsignedp, methods);
390 temp2 = expand_binop (submode, smul_optab, imag1, imag1,
391 NULL_RTX, unsignedp, methods);
393 if (temp1 == 0 || temp2 == 0)
396 divisor = expand_binop (submode, add_optab, temp1, temp2,
397 NULL_RTX, unsignedp, methods);
403 /* Mathematically, ((a)(c-id))/divisor. */
404 /* Computationally, (a+i0) / (c+id) = (ac/(cc+dd)) + i(-ad/(cc+dd)). */
406 /* Calculate the dividend. */
407 real_t = expand_binop (submode, smul_optab, real0, real1,
408 NULL_RTX, unsignedp, methods);
410 imag_t = expand_binop (submode, smul_optab, real0, imag1,
411 NULL_RTX, unsignedp, methods);
413 if (real_t == 0 || imag_t == 0)
416 imag_t = expand_unop (submode, neg_optab, imag_t,
417 NULL_RTX, unsignedp);
421 /* Mathematically, ((a+ib)(c-id))/divider. */
422 /* Calculate the dividend. */
423 temp1 = expand_binop (submode, smul_optab, real0, real1,
424 NULL_RTX, unsignedp, methods);
426 temp2 = expand_binop (submode, smul_optab, imag0, imag1,
427 NULL_RTX, unsignedp, methods);
429 if (temp1 == 0 || temp2 == 0)
432 real_t = expand_binop (submode, add_optab, temp1, temp2,
433 NULL_RTX, unsignedp, methods);
435 temp1 = expand_binop (submode, smul_optab, imag0, real1,
436 NULL_RTX, unsignedp, methods);
438 temp2 = expand_binop (submode, smul_optab, real0, imag1,
439 NULL_RTX, unsignedp, methods);
441 if (temp1 == 0 || temp2 == 0)
444 imag_t = expand_binop (submode, sub_optab, temp1, temp2,
445 NULL_RTX, unsignedp, methods);
447 if (real_t == 0 || imag_t == 0)
451 if (class == MODE_COMPLEX_FLOAT)
452 res = expand_binop (submode, binoptab, real_t, divisor,
453 realr, unsignedp, methods);
455 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
456 real_t, divisor, realr, unsignedp);
462 emit_move_insn (realr, res);
464 if (class == MODE_COMPLEX_FLOAT)
465 res = expand_binop (submode, binoptab, imag_t, divisor,
466 imagr, unsignedp, methods);
468 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
469 imag_t, divisor, imagr, unsignedp);
475 emit_move_insn (imagr, res);
480 /* Generate code to perform a wide-input-range-acceptable complex divide. */
483 expand_cmplxdiv_wide (real0, real1, imag0, imag1, realr, imagr, submode,
484 unsignedp, methods, class, binoptab)
485 rtx real0, real1, imag0, imag1, realr, imagr;
486 enum machine_mode submode;
488 enum optab_methods methods;
489 enum mode_class class;
494 rtx temp1, temp2, lab1, lab2;
495 enum machine_mode mode;
499 /* Don't fetch these from memory more than once. */
500 real0 = force_reg (submode, real0);
501 real1 = force_reg (submode, real1);
504 imag0 = force_reg (submode, imag0);
506 imag1 = force_reg (submode, imag1);
508 /* XXX What's an "unsigned" complex number? */
516 temp1 = expand_abs (submode, real1, NULL_RTX, 1);
517 temp2 = expand_abs (submode, imag1, NULL_RTX, 1);
520 if (temp1 == 0 || temp2 == 0)
523 mode = GET_MODE (temp1);
524 align = GET_MODE_ALIGNMENT (mode);
525 lab1 = gen_label_rtx ();
526 emit_cmp_and_jump_insns (temp1, temp2, LT, NULL_RTX,
527 mode, unsignedp, align, lab1);
529 /* |c| >= |d|; use ratio d/c to scale dividend and divisor. */
531 if (class == MODE_COMPLEX_FLOAT)
532 ratio = expand_binop (submode, binoptab, imag1, real1,
533 NULL_RTX, unsignedp, methods);
535 ratio = expand_divmod (0, TRUNC_DIV_EXPR, submode,
536 imag1, real1, NULL_RTX, unsignedp);
541 /* Calculate divisor. */
543 temp1 = expand_binop (submode, smul_optab, imag1, ratio,
544 NULL_RTX, unsignedp, methods);
549 divisor = expand_binop (submode, add_optab, temp1, real1,
550 NULL_RTX, unsignedp, methods);
555 /* Calculate dividend. */
561 /* Compute a / (c+id) as a / (c+d(d/c)) + i (-a(d/c)) / (c+d(d/c)). */
563 imag_t = expand_binop (submode, smul_optab, real0, ratio,
564 NULL_RTX, unsignedp, methods);
569 imag_t = expand_unop (submode, neg_optab, imag_t,
570 NULL_RTX, unsignedp);
572 if (real_t == 0 || imag_t == 0)
577 /* Compute (a+ib)/(c+id) as
578 (a+b(d/c))/(c+d(d/c) + i(b-a(d/c))/(c+d(d/c)). */
580 temp1 = expand_binop (submode, smul_optab, imag0, ratio,
581 NULL_RTX, unsignedp, methods);
586 real_t = expand_binop (submode, add_optab, temp1, real0,
587 NULL_RTX, unsignedp, methods);
589 temp1 = expand_binop (submode, smul_optab, real0, ratio,
590 NULL_RTX, unsignedp, methods);
595 imag_t = expand_binop (submode, sub_optab, imag0, temp1,
596 NULL_RTX, unsignedp, methods);
598 if (real_t == 0 || imag_t == 0)
602 if (class == MODE_COMPLEX_FLOAT)
603 res = expand_binop (submode, binoptab, real_t, divisor,
604 realr, unsignedp, methods);
606 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
607 real_t, divisor, realr, unsignedp);
613 emit_move_insn (realr, res);
615 if (class == MODE_COMPLEX_FLOAT)
616 res = expand_binop (submode, binoptab, imag_t, divisor,
617 imagr, unsignedp, methods);
619 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
620 imag_t, divisor, imagr, unsignedp);
626 emit_move_insn (imagr, res);
628 lab2 = gen_label_rtx ();
629 emit_jump_insn (gen_jump (lab2));
634 /* |d| > |c|; use ratio c/d to scale dividend and divisor. */
636 if (class == MODE_COMPLEX_FLOAT)
637 ratio = expand_binop (submode, binoptab, real1, imag1,
638 NULL_RTX, unsignedp, methods);
640 ratio = expand_divmod (0, TRUNC_DIV_EXPR, submode,
641 real1, imag1, NULL_RTX, unsignedp);
646 /* Calculate divisor. */
648 temp1 = expand_binop (submode, smul_optab, real1, ratio,
649 NULL_RTX, unsignedp, methods);
654 divisor = expand_binop (submode, add_optab, temp1, imag1,
655 NULL_RTX, unsignedp, methods);
660 /* Calculate dividend. */
664 /* Compute a / (c+id) as a(c/d) / (c(c/d)+d) + i (-a) / (c(c/d)+d). */
666 real_t = expand_binop (submode, smul_optab, real0, ratio,
667 NULL_RTX, unsignedp, methods);
669 imag_t = expand_unop (submode, neg_optab, real0,
670 NULL_RTX, unsignedp);
672 if (real_t == 0 || imag_t == 0)
677 /* Compute (a+ib)/(c+id) as
678 (a(c/d)+b)/(c(c/d)+d) + i (b(c/d)-a)/(c(c/d)+d). */
680 temp1 = expand_binop (submode, smul_optab, real0, ratio,
681 NULL_RTX, unsignedp, methods);
686 real_t = expand_binop (submode, add_optab, temp1, imag0,
687 NULL_RTX, unsignedp, methods);
689 temp1 = expand_binop (submode, smul_optab, imag0, ratio,
690 NULL_RTX, unsignedp, methods);
695 imag_t = expand_binop (submode, sub_optab, temp1, real0,
696 NULL_RTX, unsignedp, methods);
698 if (real_t == 0 || imag_t == 0)
702 if (class == MODE_COMPLEX_FLOAT)
703 res = expand_binop (submode, binoptab, real_t, divisor,
704 realr, unsignedp, methods);
706 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
707 real_t, divisor, realr, unsignedp);
713 emit_move_insn (realr, res);
715 if (class == MODE_COMPLEX_FLOAT)
716 res = expand_binop (submode, binoptab, imag_t, divisor,
717 imagr, unsignedp, methods);
719 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
720 imag_t, divisor, imagr, unsignedp);
726 emit_move_insn (imagr, res);
733 /* Generate code to perform an operation specified by BINOPTAB
734 on operands OP0 and OP1, with result having machine-mode MODE.
736 UNSIGNEDP is for the case where we have to widen the operands
737 to perform the operation. It says to use zero-extension.
739 If TARGET is nonzero, the value
740 is generated there, if it is convenient to do so.
741 In all cases an rtx is returned for the locus of the value;
742 this may or may not be TARGET. */
745 expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods)
746 enum machine_mode mode;
751 enum optab_methods methods;
753 enum optab_methods next_methods
754 = (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN
755 ? OPTAB_WIDEN : methods);
756 enum mode_class class;
757 enum machine_mode wider_mode;
759 int commutative_op = 0;
760 int shift_op = (binoptab->code == ASHIFT
761 || binoptab->code == ASHIFTRT
762 || binoptab->code == LSHIFTRT
763 || binoptab->code == ROTATE
764 || binoptab->code == ROTATERT);
765 rtx entry_last = get_last_insn ();
768 class = GET_MODE_CLASS (mode);
770 op0 = protect_from_queue (op0, 0);
771 op1 = protect_from_queue (op1, 0);
773 target = protect_from_queue (target, 1);
775 if (flag_propolice_protection
776 && binoptab->code == PLUS
777 && op0 == virtual_stack_vars_rtx
778 && GET_CODE(op1) == CONST_INT)
780 int icode = (int) binoptab->handlers[(int) mode].insn_code;
784 temp = gen_reg_rtx (mode);
786 if (! (*insn_operand_predicate[icode][0]) (temp, mode))
787 temp = gen_reg_rtx (mode);
789 emit_insn (gen_rtx_SET (VOIDmode, temp,
790 gen_rtx_PLUS (GET_MODE (op0), op0, op1)));
796 op0 = force_not_mem (op0);
797 op1 = force_not_mem (op1);
800 /* If subtracting an integer constant, convert this into an addition of
801 the negated constant. */
803 if (binoptab == sub_optab && GET_CODE (op1) == CONST_INT)
805 op1 = negate_rtx (mode, op1);
806 binoptab = add_optab;
809 /* If we are inside an appropriately-short loop and one operand is an
810 expensive constant, force it into a register. */
811 if (CONSTANT_P (op0) && preserve_subexpressions_p ()
812 && rtx_cost (op0, binoptab->code) > 2)
813 op0 = force_reg (mode, op0);
815 if (CONSTANT_P (op1) && preserve_subexpressions_p ()
816 && ! shift_op && rtx_cost (op1, binoptab->code) > 2)
817 op1 = force_reg (mode, op1);
819 /* Record where to delete back to if we backtrack. */
820 last = get_last_insn ();
822 /* If operation is commutative,
823 try to make the first operand a register.
824 Even better, try to make it the same as the target.
825 Also try to make the last operand a constant. */
826 if (GET_RTX_CLASS (binoptab->code) == 'c'
827 || binoptab == smul_widen_optab
828 || binoptab == umul_widen_optab
829 || binoptab == smul_highpart_optab
830 || binoptab == umul_highpart_optab)
834 if (((target == 0 || GET_CODE (target) == REG)
835 ? ((GET_CODE (op1) == REG
836 && GET_CODE (op0) != REG)
838 : rtx_equal_p (op1, target))
839 || GET_CODE (op0) == CONST_INT)
847 /* If we can do it with a three-operand insn, do so. */
849 if (methods != OPTAB_MUST_WIDEN
850 && binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
852 int icode = (int) binoptab->handlers[(int) mode].insn_code;
853 enum machine_mode mode0 = insn_operand_mode[icode][1];
854 enum machine_mode mode1 = insn_operand_mode[icode][2];
856 rtx xop0 = op0, xop1 = op1;
861 temp = gen_reg_rtx (mode);
863 /* If it is a commutative operator and the modes would match
864 if we would swap the operands, we can save the conversions. */
867 if (GET_MODE (op0) != mode0 && GET_MODE (op1) != mode1
868 && GET_MODE (op0) == mode1 && GET_MODE (op1) == mode0)
872 tmp = op0; op0 = op1; op1 = tmp;
873 tmp = xop0; xop0 = xop1; xop1 = tmp;
877 /* In case the insn wants input operands in modes different from
878 the result, convert the operands. */
880 if (GET_MODE (op0) != VOIDmode
881 && GET_MODE (op0) != mode0
882 && mode0 != VOIDmode)
883 xop0 = convert_to_mode (mode0, xop0, unsignedp);
885 if (GET_MODE (xop1) != VOIDmode
886 && GET_MODE (xop1) != mode1
887 && mode1 != VOIDmode)
888 xop1 = convert_to_mode (mode1, xop1, unsignedp);
890 /* Now, if insn's predicates don't allow our operands, put them into
893 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0)
894 && mode0 != VOIDmode)
895 xop0 = copy_to_mode_reg (mode0, xop0);
897 if (! (*insn_operand_predicate[icode][2]) (xop1, mode1)
898 && mode1 != VOIDmode)
899 xop1 = copy_to_mode_reg (mode1, xop1);
901 if (! (*insn_operand_predicate[icode][0]) (temp, mode))
902 temp = gen_reg_rtx (mode);
904 pat = GEN_FCN (icode) (temp, xop0, xop1);
907 /* If PAT is a multi-insn sequence, try to add an appropriate
908 REG_EQUAL note to it. If we can't because TEMP conflicts with an
909 operand, call ourselves again, this time without a target. */
910 if (GET_CODE (pat) == SEQUENCE
911 && ! add_equal_note (pat, temp, binoptab->code, xop0, xop1))
913 delete_insns_since (last);
914 return expand_binop (mode, binoptab, op0, op1, NULL_RTX,
922 delete_insns_since (last);
925 /* If this is a multiply, see if we can do a widening operation that
926 takes operands of this mode and makes a wider mode. */
928 if (binoptab == smul_optab && GET_MODE_WIDER_MODE (mode) != VOIDmode
929 && (((unsignedp ? umul_widen_optab : smul_widen_optab)
930 ->handlers[(int) GET_MODE_WIDER_MODE (mode)].insn_code)
931 != CODE_FOR_nothing))
933 temp = expand_binop (GET_MODE_WIDER_MODE (mode),
934 unsignedp ? umul_widen_optab : smul_widen_optab,
935 op0, op1, NULL_RTX, unsignedp, OPTAB_DIRECT);
939 if (GET_MODE_CLASS (mode) == MODE_INT)
940 return gen_lowpart (mode, temp);
942 return convert_to_mode (mode, temp, unsignedp);
946 /* Look for a wider mode of the same class for which we think we
947 can open-code the operation. Check for a widening multiply at the
948 wider mode as well. */
950 if ((class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
951 && methods != OPTAB_DIRECT && methods != OPTAB_LIB)
952 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
953 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
955 if (binoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing
956 || (binoptab == smul_optab
957 && GET_MODE_WIDER_MODE (wider_mode) != VOIDmode
958 && (((unsignedp ? umul_widen_optab : smul_widen_optab)
959 ->handlers[(int) GET_MODE_WIDER_MODE (wider_mode)].insn_code)
960 != CODE_FOR_nothing)))
962 rtx xop0 = op0, xop1 = op1;
965 /* For certain integer operations, we need not actually extend
966 the narrow operands, as long as we will truncate
967 the results to the same narrowness. */
969 if ((binoptab == ior_optab || binoptab == and_optab
970 || binoptab == xor_optab
971 || binoptab == add_optab || binoptab == sub_optab
972 || binoptab == smul_optab || binoptab == ashl_optab)
973 && class == MODE_INT)
976 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp, no_extend);
978 /* The second operand of a shift must always be extended. */
979 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
980 no_extend && binoptab != ashl_optab);
982 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
983 unsignedp, OPTAB_DIRECT);
986 if (class != MODE_INT)
989 target = gen_reg_rtx (mode);
990 convert_move (target, temp, 0);
994 return gen_lowpart (mode, temp);
997 delete_insns_since (last);
1001 /* These can be done a word at a time. */
1002 if ((binoptab == and_optab || binoptab == ior_optab || binoptab == xor_optab)
1003 && class == MODE_INT
1004 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
1005 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
1011 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1012 won't be accurate, so use a new target. */
1013 if (target == 0 || target == op0 || target == op1)
1014 target = gen_reg_rtx (mode);
1018 /* Do the actual arithmetic. */
1019 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
1021 rtx target_piece = operand_subword (target, i, 1, mode);
1022 rtx x = expand_binop (word_mode, binoptab,
1023 operand_subword_force (op0, i, mode),
1024 operand_subword_force (op1, i, mode),
1025 target_piece, unsignedp, next_methods);
1030 if (target_piece != x)
1031 emit_move_insn (target_piece, x);
1034 insns = get_insns ();
1037 if (i == GET_MODE_BITSIZE (mode) / BITS_PER_WORD)
1039 if (binoptab->code != UNKNOWN)
1041 = gen_rtx_fmt_ee (binoptab->code, mode,
1042 copy_rtx (op0), copy_rtx (op1));
1046 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
1051 /* Synthesize double word shifts from single word shifts. */
1052 if ((binoptab == lshr_optab || binoptab == ashl_optab
1053 || binoptab == ashr_optab)
1054 && class == MODE_INT
1055 && GET_CODE (op1) == CONST_INT
1056 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
1057 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
1058 && ashl_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
1059 && lshr_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
1061 rtx insns, inter, equiv_value;
1062 rtx into_target, outof_target;
1063 rtx into_input, outof_input;
1064 int shift_count, left_shift, outof_word;
1066 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1067 won't be accurate, so use a new target. */
1068 if (target == 0 || target == op0 || target == op1)
1069 target = gen_reg_rtx (mode);
1073 shift_count = INTVAL (op1);
1075 /* OUTOF_* is the word we are shifting bits away from, and
1076 INTO_* is the word that we are shifting bits towards, thus
1077 they differ depending on the direction of the shift and
1078 WORDS_BIG_ENDIAN. */
1080 left_shift = binoptab == ashl_optab;
1081 outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
1083 outof_target = operand_subword (target, outof_word, 1, mode);
1084 into_target = operand_subword (target, 1 - outof_word, 1, mode);
1086 outof_input = operand_subword_force (op0, outof_word, mode);
1087 into_input = operand_subword_force (op0, 1 - outof_word, mode);
1089 if (shift_count >= BITS_PER_WORD)
1091 inter = expand_binop (word_mode, binoptab,
1093 GEN_INT (shift_count - BITS_PER_WORD),
1094 into_target, unsignedp, next_methods);
1096 if (inter != 0 && inter != into_target)
1097 emit_move_insn (into_target, inter);
1099 /* For a signed right shift, we must fill the word we are shifting
1100 out of with copies of the sign bit. Otherwise it is zeroed. */
1101 if (inter != 0 && binoptab != ashr_optab)
1102 inter = CONST0_RTX (word_mode);
1103 else if (inter != 0)
1104 inter = expand_binop (word_mode, binoptab,
1106 GEN_INT (BITS_PER_WORD - 1),
1107 outof_target, unsignedp, next_methods);
1109 if (inter != 0 && inter != outof_target)
1110 emit_move_insn (outof_target, inter);
1115 optab reverse_unsigned_shift, unsigned_shift;
1117 /* For a shift of less then BITS_PER_WORD, to compute the carry,
1118 we must do a logical shift in the opposite direction of the
1121 reverse_unsigned_shift = (left_shift ? lshr_optab : ashl_optab);
1123 /* For a shift of less than BITS_PER_WORD, to compute the word
1124 shifted towards, we need to unsigned shift the orig value of
1127 unsigned_shift = (left_shift ? ashl_optab : lshr_optab);
1129 carries = expand_binop (word_mode, reverse_unsigned_shift,
1131 GEN_INT (BITS_PER_WORD - shift_count),
1132 0, unsignedp, next_methods);
1137 inter = expand_binop (word_mode, unsigned_shift, into_input,
1138 op1, 0, unsignedp, next_methods);
1141 inter = expand_binop (word_mode, ior_optab, carries, inter,
1142 into_target, unsignedp, next_methods);
1144 if (inter != 0 && inter != into_target)
1145 emit_move_insn (into_target, inter);
1148 inter = expand_binop (word_mode, binoptab, outof_input,
1149 op1, outof_target, unsignedp, next_methods);
1151 if (inter != 0 && inter != outof_target)
1152 emit_move_insn (outof_target, inter);
1155 insns = get_insns ();
1160 if (binoptab->code != UNKNOWN)
1161 equiv_value = gen_rtx_fmt_ee (binoptab->code, mode, op0, op1);
1165 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
1170 /* Synthesize double word rotates from single word shifts. */
1171 if ((binoptab == rotl_optab || binoptab == rotr_optab)
1172 && class == MODE_INT
1173 && GET_CODE (op1) == CONST_INT
1174 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
1175 && ashl_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
1176 && lshr_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
1178 rtx insns, equiv_value;
1179 rtx into_target, outof_target;
1180 rtx into_input, outof_input;
1182 int shift_count, left_shift, outof_word;
1184 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1185 won't be accurate, so use a new target. */
1186 if (target == 0 || target == op0 || target == op1)
1187 target = gen_reg_rtx (mode);
1191 shift_count = INTVAL (op1);
1193 /* OUTOF_* is the word we are shifting bits away from, and
1194 INTO_* is the word that we are shifting bits towards, thus
1195 they differ depending on the direction of the shift and
1196 WORDS_BIG_ENDIAN. */
1198 left_shift = (binoptab == rotl_optab);
1199 outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
1201 outof_target = operand_subword (target, outof_word, 1, mode);
1202 into_target = operand_subword (target, 1 - outof_word, 1, mode);
1204 outof_input = operand_subword_force (op0, outof_word, mode);
1205 into_input = operand_subword_force (op0, 1 - outof_word, mode);
1207 if (shift_count == BITS_PER_WORD)
1209 /* This is just a word swap. */
1210 emit_move_insn (outof_target, into_input);
1211 emit_move_insn (into_target, outof_input);
1216 rtx into_temp1, into_temp2, outof_temp1, outof_temp2;
1217 rtx first_shift_count, second_shift_count;
1218 optab reverse_unsigned_shift, unsigned_shift;
1220 reverse_unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
1221 ? lshr_optab : ashl_optab);
1223 unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
1224 ? ashl_optab : lshr_optab);
1226 if (shift_count > BITS_PER_WORD)
1228 first_shift_count = GEN_INT (shift_count - BITS_PER_WORD);
1229 second_shift_count = GEN_INT (2*BITS_PER_WORD - shift_count);
1233 first_shift_count = GEN_INT (BITS_PER_WORD - shift_count);
1234 second_shift_count = GEN_INT (shift_count);
1237 into_temp1 = expand_binop (word_mode, unsigned_shift,
1238 outof_input, first_shift_count,
1239 NULL_RTX, unsignedp, next_methods);
1240 into_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
1241 into_input, second_shift_count,
1242 into_target, unsignedp, next_methods);
1244 if (into_temp1 != 0 && into_temp2 != 0)
1245 inter = expand_binop (word_mode, ior_optab, into_temp1, into_temp2,
1246 into_target, unsignedp, next_methods);
1250 if (inter != 0 && inter != into_target)
1251 emit_move_insn (into_target, inter);
1253 outof_temp1 = expand_binop (word_mode, unsigned_shift,
1254 into_input, first_shift_count,
1255 NULL_RTX, unsignedp, next_methods);
1256 outof_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
1257 outof_input, second_shift_count,
1258 outof_target, unsignedp, next_methods);
1260 if (inter != 0 && outof_temp1 != 0 && outof_temp2 != 0)
1261 inter = expand_binop (word_mode, ior_optab,
1262 outof_temp1, outof_temp2,
1263 outof_target, unsignedp, next_methods);
1265 if (inter != 0 && inter != outof_target)
1266 emit_move_insn (outof_target, inter);
1269 insns = get_insns ();
1274 if (binoptab->code != UNKNOWN)
1275 equiv_value = gen_rtx_fmt_ee (binoptab->code, mode, op0, op1);
1279 /* We can't make this a no conflict block if this is a word swap,
1280 because the word swap case fails if the input and output values
1281 are in the same register. */
1282 if (shift_count != BITS_PER_WORD)
1283 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
1292 /* These can be done a word at a time by propagating carries. */
1293 if ((binoptab == add_optab || binoptab == sub_optab)
1294 && class == MODE_INT
1295 && GET_MODE_SIZE (mode) >= 2 * UNITS_PER_WORD
1296 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
1299 rtx carry_tmp = gen_reg_rtx (word_mode);
1300 optab otheroptab = binoptab == add_optab ? sub_optab : add_optab;
1301 int nwords = GET_MODE_BITSIZE (mode) / BITS_PER_WORD;
1302 rtx carry_in = NULL_RTX, carry_out = NULL_RTX;
1305 /* We can handle either a 1 or -1 value for the carry. If STORE_FLAG
1306 value is one of those, use it. Otherwise, use 1 since it is the
1307 one easiest to get. */
1308 #if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
1309 int normalizep = STORE_FLAG_VALUE;
1314 /* Prepare the operands. */
1315 xop0 = force_reg (mode, op0);
1316 xop1 = force_reg (mode, op1);
1318 if (target == 0 || GET_CODE (target) != REG
1319 || target == xop0 || target == xop1)
1320 target = gen_reg_rtx (mode);
1322 /* Indicate for flow that the entire target reg is being set. */
1323 if (GET_CODE (target) == REG)
1324 emit_insn (gen_rtx_CLOBBER (VOIDmode, target));
1326 /* Do the actual arithmetic. */
1327 for (i = 0; i < nwords; i++)
1329 int index = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i);
1330 rtx target_piece = operand_subword (target, index, 1, mode);
1331 rtx op0_piece = operand_subword_force (xop0, index, mode);
1332 rtx op1_piece = operand_subword_force (xop1, index, mode);
1335 /* Main add/subtract of the input operands. */
1336 x = expand_binop (word_mode, binoptab,
1337 op0_piece, op1_piece,
1338 target_piece, unsignedp, next_methods);
1344 /* Store carry from main add/subtract. */
1345 carry_out = gen_reg_rtx (word_mode);
1346 carry_out = emit_store_flag_force (carry_out,
1347 (binoptab == add_optab
1350 word_mode, 1, normalizep);
1355 /* Add/subtract previous carry to main result. */
1356 x = expand_binop (word_mode,
1357 normalizep == 1 ? binoptab : otheroptab,
1359 target_piece, 1, next_methods);
1362 else if (target_piece != x)
1363 emit_move_insn (target_piece, x);
1367 /* THIS CODE HAS NOT BEEN TESTED. */
1368 /* Get out carry from adding/subtracting carry in. */
1369 carry_tmp = emit_store_flag_force (carry_tmp,
1370 binoptab == add_optab
1373 word_mode, 1, normalizep);
1375 /* Logical-ior the two poss. carry together. */
1376 carry_out = expand_binop (word_mode, ior_optab,
1377 carry_out, carry_tmp,
1378 carry_out, 0, next_methods);
1384 carry_in = carry_out;
1387 if (i == GET_MODE_BITSIZE (mode) / BITS_PER_WORD)
1389 if (mov_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1391 rtx temp = emit_move_insn (target, target);
1393 set_unique_reg_note (temp,
1395 gen_rtx_fmt_ee (binoptab->code, mode,
1402 delete_insns_since (last);
1405 /* If we want to multiply two two-word values and have normal and widening
1406 multiplies of single-word values, we can do this with three smaller
1407 multiplications. Note that we do not make a REG_NO_CONFLICT block here
1408 because we are not operating on one word at a time.
1410 The multiplication proceeds as follows:
1411 _______________________
1412 [__op0_high_|__op0_low__]
1413 _______________________
1414 * [__op1_high_|__op1_low__]
1415 _______________________________________________
1416 _______________________
1417 (1) [__op0_low__*__op1_low__]
1418 _______________________
1419 (2a) [__op0_low__*__op1_high_]
1420 _______________________
1421 (2b) [__op0_high_*__op1_low__]
1422 _______________________
1423 (3) [__op0_high_*__op1_high_]
1426 This gives a 4-word result. Since we are only interested in the
1427 lower 2 words, partial result (3) and the upper words of (2a) and
1428 (2b) don't need to be calculated. Hence (2a) and (2b) can be
1429 calculated using non-widening multiplication.
1431 (1), however, needs to be calculated with an unsigned widening
1432 multiplication. If this operation is not directly supported we
1433 try using a signed widening multiplication and adjust the result.
1434 This adjustment works as follows:
1436 If both operands are positive then no adjustment is needed.
1438 If the operands have different signs, for example op0_low < 0 and
1439 op1_low >= 0, the instruction treats the most significant bit of
1440 op0_low as a sign bit instead of a bit with significance
1441 2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low
1442 with 2**BITS_PER_WORD - op0_low, and two's complements the
1443 result. Conclusion: We need to add op1_low * 2**BITS_PER_WORD to
1446 Similarly, if both operands are negative, we need to add
1447 (op0_low + op1_low) * 2**BITS_PER_WORD.
1449 We use a trick to adjust quickly. We logically shift op0_low right
1450 (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to
1451 op0_high (op1_high) before it is used to calculate 2b (2a). If no
1452 logical shift exists, we do an arithmetic right shift and subtract
1455 if (binoptab == smul_optab
1456 && class == MODE_INT
1457 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
1458 && smul_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
1459 && add_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
1460 && ((umul_widen_optab->handlers[(int) mode].insn_code
1461 != CODE_FOR_nothing)
1462 || (smul_widen_optab->handlers[(int) mode].insn_code
1463 != CODE_FOR_nothing)))
1465 int low = (WORDS_BIG_ENDIAN ? 1 : 0);
1466 int high = (WORDS_BIG_ENDIAN ? 0 : 1);
1467 rtx op0_high = operand_subword_force (op0, high, mode);
1468 rtx op0_low = operand_subword_force (op0, low, mode);
1469 rtx op1_high = operand_subword_force (op1, high, mode);
1470 rtx op1_low = operand_subword_force (op1, low, mode);
1472 rtx op0_xhigh = NULL_RTX;
1473 rtx op1_xhigh = NULL_RTX;
1475 /* If the target is the same as one of the inputs, don't use it. This
1476 prevents problems with the REG_EQUAL note. */
1477 if (target == op0 || target == op1
1478 || (target != 0 && GET_CODE (target) != REG))
1481 /* Multiply the two lower words to get a double-word product.
1482 If unsigned widening multiplication is available, use that;
1483 otherwise use the signed form and compensate. */
1485 if (umul_widen_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1487 product = expand_binop (mode, umul_widen_optab, op0_low, op1_low,
1488 target, 1, OPTAB_DIRECT);
1490 /* If we didn't succeed, delete everything we did so far. */
1492 delete_insns_since (last);
1494 op0_xhigh = op0_high, op1_xhigh = op1_high;
1498 && smul_widen_optab->handlers[(int) mode].insn_code
1499 != CODE_FOR_nothing)
1501 rtx wordm1 = GEN_INT (BITS_PER_WORD - 1);
1502 product = expand_binop (mode, smul_widen_optab, op0_low, op1_low,
1503 target, 1, OPTAB_DIRECT);
1504 op0_xhigh = expand_binop (word_mode, lshr_optab, op0_low, wordm1,
1505 NULL_RTX, 1, next_methods);
1507 op0_xhigh = expand_binop (word_mode, add_optab, op0_high,
1508 op0_xhigh, op0_xhigh, 0, next_methods);
1511 op0_xhigh = expand_binop (word_mode, ashr_optab, op0_low, wordm1,
1512 NULL_RTX, 0, next_methods);
1514 op0_xhigh = expand_binop (word_mode, sub_optab, op0_high,
1515 op0_xhigh, op0_xhigh, 0,
1519 op1_xhigh = expand_binop (word_mode, lshr_optab, op1_low, wordm1,
1520 NULL_RTX, 1, next_methods);
1522 op1_xhigh = expand_binop (word_mode, add_optab, op1_high,
1523 op1_xhigh, op1_xhigh, 0, next_methods);
1526 op1_xhigh = expand_binop (word_mode, ashr_optab, op1_low, wordm1,
1527 NULL_RTX, 0, next_methods);
1529 op1_xhigh = expand_binop (word_mode, sub_optab, op1_high,
1530 op1_xhigh, op1_xhigh, 0,
1535 /* If we have been able to directly compute the product of the
1536 low-order words of the operands and perform any required adjustments
1537 of the operands, we proceed by trying two more multiplications
1538 and then computing the appropriate sum.
1540 We have checked above that the required addition is provided.
1541 Full-word addition will normally always succeed, especially if
1542 it is provided at all, so we don't worry about its failure. The
1543 multiplication may well fail, however, so we do handle that. */
1545 if (product && op0_xhigh && op1_xhigh)
1547 rtx product_high = operand_subword (product, high, 1, mode);
1548 rtx temp = expand_binop (word_mode, binoptab, op0_low, op1_xhigh,
1549 NULL_RTX, 0, OPTAB_DIRECT);
1552 temp = expand_binop (word_mode, add_optab, temp, product_high,
1553 product_high, 0, next_methods);
1555 if (temp != 0 && temp != product_high)
1556 emit_move_insn (product_high, temp);
1559 temp = expand_binop (word_mode, binoptab, op1_low, op0_xhigh,
1560 NULL_RTX, 0, OPTAB_DIRECT);
1563 temp = expand_binop (word_mode, add_optab, temp,
1564 product_high, product_high,
1567 if (temp != 0 && temp != product_high)
1568 emit_move_insn (product_high, temp);
1572 if (mov_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1574 temp = emit_move_insn (product, product);
1575 set_unique_reg_note (temp,
1577 gen_rtx_fmt_ee (MULT, mode,
1585 /* If we get here, we couldn't do it for some reason even though we
1586 originally thought we could. Delete anything we've emitted in
1589 delete_insns_since (last);
1592 /* We need to open-code the complex type operations: '+, -, * and /' */
1594 /* At this point we allow operations between two similar complex
1595 numbers, and also if one of the operands is not a complex number
1596 but rather of MODE_FLOAT or MODE_INT. However, the caller
1597 must make sure that the MODE of the non-complex operand matches
1598 the SUBMODE of the complex operand. */
1600 if (class == MODE_COMPLEX_FLOAT || class == MODE_COMPLEX_INT)
1602 rtx real0 = 0, imag0 = 0;
1603 rtx real1 = 0, imag1 = 0;
1604 rtx realr, imagr, res;
1609 /* Find the correct mode for the real and imaginary parts */
1610 enum machine_mode submode
1611 = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
1612 class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
1615 if (submode == BLKmode)
1619 target = gen_reg_rtx (mode);
1623 realr = gen_realpart (submode, target);
1624 imagr = gen_imagpart (submode, target);
1626 if (GET_MODE (op0) == mode)
1628 real0 = gen_realpart (submode, op0);
1629 imag0 = gen_imagpart (submode, op0);
1634 if (GET_MODE (op1) == mode)
1636 real1 = gen_realpart (submode, op1);
1637 imag1 = gen_imagpart (submode, op1);
1642 if (real0 == 0 || real1 == 0 || ! (imag0 != 0|| imag1 != 0))
1645 switch (binoptab->code)
1648 /* (a+ib) + (c+id) = (a+c) + i(b+d) */
1650 /* (a+ib) - (c+id) = (a-c) + i(b-d) */
1651 res = expand_binop (submode, binoptab, real0, real1,
1652 realr, unsignedp, methods);
1656 else if (res != realr)
1657 emit_move_insn (realr, res);
1660 res = expand_binop (submode, binoptab, imag0, imag1,
1661 imagr, unsignedp, methods);
1664 else if (binoptab->code == MINUS)
1665 res = expand_unop (submode, neg_optab, imag1, imagr, unsignedp);
1671 else if (res != imagr)
1672 emit_move_insn (imagr, res);
1678 /* (a+ib) * (c+id) = (ac-bd) + i(ad+cb) */
1684 /* Don't fetch these from memory more than once. */
1685 real0 = force_reg (submode, real0);
1686 real1 = force_reg (submode, real1);
1687 imag0 = force_reg (submode, imag0);
1688 imag1 = force_reg (submode, imag1);
1690 temp1 = expand_binop (submode, binoptab, real0, real1, NULL_RTX,
1691 unsignedp, methods);
1693 temp2 = expand_binop (submode, binoptab, imag0, imag1, NULL_RTX,
1694 unsignedp, methods);
1696 if (temp1 == 0 || temp2 == 0)
1699 res = expand_binop (submode, sub_optab, temp1, temp2,
1700 realr, unsignedp, methods);
1704 else if (res != realr)
1705 emit_move_insn (realr, res);
1707 temp1 = expand_binop (submode, binoptab, real0, imag1,
1708 NULL_RTX, unsignedp, methods);
1710 temp2 = expand_binop (submode, binoptab, real1, imag0,
1711 NULL_RTX, unsignedp, methods);
1713 if (temp1 == 0 || temp2 == 0)
1716 res = expand_binop (submode, add_optab, temp1, temp2,
1717 imagr, unsignedp, methods);
1721 else if (res != imagr)
1722 emit_move_insn (imagr, res);
1728 /* Don't fetch these from memory more than once. */
1729 real0 = force_reg (submode, real0);
1730 real1 = force_reg (submode, real1);
1732 res = expand_binop (submode, binoptab, real0, real1,
1733 realr, unsignedp, methods);
1736 else if (res != realr)
1737 emit_move_insn (realr, res);
1740 res = expand_binop (submode, binoptab,
1741 real1, imag0, imagr, unsignedp, methods);
1743 res = expand_binop (submode, binoptab,
1744 real0, imag1, imagr, unsignedp, methods);
1748 else if (res != imagr)
1749 emit_move_insn (imagr, res);
1756 /* (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd)) */
1760 /* (a+ib) / (c+i0) = (a/c) + i(b/c) */
1762 /* Don't fetch these from memory more than once. */
1763 real1 = force_reg (submode, real1);
1765 /* Simply divide the real and imaginary parts by `c' */
1766 if (class == MODE_COMPLEX_FLOAT)
1767 res = expand_binop (submode, binoptab, real0, real1,
1768 realr, unsignedp, methods);
1770 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
1771 real0, real1, realr, unsignedp);
1775 else if (res != realr)
1776 emit_move_insn (realr, res);
1778 if (class == MODE_COMPLEX_FLOAT)
1779 res = expand_binop (submode, binoptab, imag0, real1,
1780 imagr, unsignedp, methods);
1782 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
1783 imag0, real1, imagr, unsignedp);
1787 else if (res != imagr)
1788 emit_move_insn (imagr, res);
1794 switch (flag_complex_divide_method)
1797 ok = expand_cmplxdiv_straight (real0, real1, imag0, imag1,
1798 realr, imagr, submode,
1804 ok = expand_cmplxdiv_wide (real0, real1, imag0, imag1,
1805 realr, imagr, submode,
1825 if (binoptab->code != UNKNOWN)
1827 = gen_rtx_fmt_ee (binoptab->code, mode,
1828 copy_rtx (op0), copy_rtx (op1));
1832 emit_no_conflict_block (seq, target, op0, op1, equiv_value);
1838 /* It can't be open-coded in this mode.
1839 Use a library call if one is available and caller says that's ok. */
1841 if (binoptab->handlers[(int) mode].libfunc
1842 && (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN))
1846 enum machine_mode op1_mode = mode;
1853 op1_mode = word_mode;
1854 /* Specify unsigned here,
1855 since negative shift counts are meaningless. */
1856 op1x = convert_to_mode (word_mode, op1, 1);
1859 if (GET_MODE (op0) != VOIDmode
1860 && GET_MODE (op0) != mode)
1861 op0 = convert_to_mode (mode, op0, unsignedp);
1863 /* Pass 1 for NO_QUEUE so we don't lose any increments
1864 if the libcall is cse'd or moved. */
1865 value = emit_library_call_value (binoptab->handlers[(int) mode].libfunc,
1866 NULL_RTX, 1, mode, 2,
1867 op0, mode, op1x, op1_mode);
1869 insns = get_insns ();
1872 target = gen_reg_rtx (mode);
1873 emit_libcall_block (insns, target, value,
1874 gen_rtx_fmt_ee (binoptab->code, mode, op0, op1));
1879 delete_insns_since (last);
1881 /* It can't be done in this mode. Can we do it in a wider mode? */
1883 if (! (methods == OPTAB_WIDEN || methods == OPTAB_LIB_WIDEN
1884 || methods == OPTAB_MUST_WIDEN))
1886 /* Caller says, don't even try. */
1887 delete_insns_since (entry_last);
1891 /* Compute the value of METHODS to pass to recursive calls.
1892 Don't allow widening to be tried recursively. */
1894 methods = (methods == OPTAB_LIB_WIDEN ? OPTAB_LIB : OPTAB_DIRECT);
1896 /* Look for a wider mode of the same class for which it appears we can do
1899 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1901 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1902 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1904 if ((binoptab->handlers[(int) wider_mode].insn_code
1905 != CODE_FOR_nothing)
1906 || (methods == OPTAB_LIB
1907 && binoptab->handlers[(int) wider_mode].libfunc))
1909 rtx xop0 = op0, xop1 = op1;
1912 /* For certain integer operations, we need not actually extend
1913 the narrow operands, as long as we will truncate
1914 the results to the same narrowness. */
1916 if ((binoptab == ior_optab || binoptab == and_optab
1917 || binoptab == xor_optab
1918 || binoptab == add_optab || binoptab == sub_optab
1919 || binoptab == smul_optab || binoptab == ashl_optab)
1920 && class == MODE_INT)
1923 xop0 = widen_operand (xop0, wider_mode, mode,
1924 unsignedp, no_extend);
1926 /* The second operand of a shift must always be extended. */
1927 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
1928 no_extend && binoptab != ashl_optab);
1930 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
1931 unsignedp, methods);
1934 if (class != MODE_INT)
1937 target = gen_reg_rtx (mode);
1938 convert_move (target, temp, 0);
1942 return gen_lowpart (mode, temp);
1945 delete_insns_since (last);
1950 delete_insns_since (entry_last);
1954 /* Expand a binary operator which has both signed and unsigned forms.
1955 UOPTAB is the optab for unsigned operations, and SOPTAB is for
1958 If we widen unsigned operands, we may use a signed wider operation instead
1959 of an unsigned wider operation, since the result would be the same. */
1962 sign_expand_binop (mode, uoptab, soptab, op0, op1, target, unsignedp, methods)
1963 enum machine_mode mode;
1964 optab uoptab, soptab;
1965 rtx op0, op1, target;
1967 enum optab_methods methods;
1970 optab direct_optab = unsignedp ? uoptab : soptab;
1971 struct optab wide_soptab;
1973 /* Do it without widening, if possible. */
1974 temp = expand_binop (mode, direct_optab, op0, op1, target,
1975 unsignedp, OPTAB_DIRECT);
1976 if (temp || methods == OPTAB_DIRECT)
1979 /* Try widening to a signed int. Make a fake signed optab that
1980 hides any signed insn for direct use. */
1981 wide_soptab = *soptab;
1982 wide_soptab.handlers[(int) mode].insn_code = CODE_FOR_nothing;
1983 wide_soptab.handlers[(int) mode].libfunc = 0;
1985 temp = expand_binop (mode, &wide_soptab, op0, op1, target,
1986 unsignedp, OPTAB_WIDEN);
1988 /* For unsigned operands, try widening to an unsigned int. */
1989 if (temp == 0 && unsignedp)
1990 temp = expand_binop (mode, uoptab, op0, op1, target,
1991 unsignedp, OPTAB_WIDEN);
1992 if (temp || methods == OPTAB_WIDEN)
1995 /* Use the right width lib call if that exists. */
1996 temp = expand_binop (mode, direct_optab, op0, op1, target, unsignedp, OPTAB_LIB);
1997 if (temp || methods == OPTAB_LIB)
2000 /* Must widen and use a lib call, use either signed or unsigned. */
2001 temp = expand_binop (mode, &wide_soptab, op0, op1, target,
2002 unsignedp, methods);
2006 return expand_binop (mode, uoptab, op0, op1, target,
2007 unsignedp, methods);
2011 /* Generate code to perform an operation specified by BINOPTAB
2012 on operands OP0 and OP1, with two results to TARG1 and TARG2.
2013 We assume that the order of the operands for the instruction
2014 is TARG0, OP0, OP1, TARG1, which would fit a pattern like
2015 [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
2017 Either TARG0 or TARG1 may be zero, but what that means is that
2018 the result is not actually wanted. We will generate it into
2019 a dummy pseudo-reg and discard it. They may not both be zero.
2021 Returns 1 if this operation can be performed; 0 if not. */
2024 expand_twoval_binop (binoptab, op0, op1, targ0, targ1, unsignedp)
2030 enum machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
2031 enum mode_class class;
2032 enum machine_mode wider_mode;
2033 rtx entry_last = get_last_insn ();
2036 class = GET_MODE_CLASS (mode);
2038 op0 = protect_from_queue (op0, 0);
2039 op1 = protect_from_queue (op1, 0);
2043 op0 = force_not_mem (op0);
2044 op1 = force_not_mem (op1);
2047 /* If we are inside an appropriately-short loop and one operand is an
2048 expensive constant, force it into a register. */
2049 if (CONSTANT_P (op0) && preserve_subexpressions_p ()
2050 && rtx_cost (op0, binoptab->code) > 2)
2051 op0 = force_reg (mode, op0);
2053 if (CONSTANT_P (op1) && preserve_subexpressions_p ()
2054 && rtx_cost (op1, binoptab->code) > 2)
2055 op1 = force_reg (mode, op1);
2058 targ0 = protect_from_queue (targ0, 1);
2060 targ0 = gen_reg_rtx (mode);
2062 targ1 = protect_from_queue (targ1, 1);
2064 targ1 = gen_reg_rtx (mode);
2066 /* Record where to go back to if we fail. */
2067 last = get_last_insn ();
2069 if (binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2071 int icode = (int) binoptab->handlers[(int) mode].insn_code;
2072 enum machine_mode mode0 = insn_operand_mode[icode][1];
2073 enum machine_mode mode1 = insn_operand_mode[icode][2];
2075 rtx xop0 = op0, xop1 = op1;
2077 /* In case this insn wants input operands in modes different from the
2078 result, convert the operands. */
2079 if (GET_MODE (op0) != VOIDmode && GET_MODE (op0) != mode0)
2080 xop0 = convert_to_mode (mode0, xop0, unsignedp);
2082 if (GET_MODE (op1) != VOIDmode && GET_MODE (op1) != mode1)
2083 xop1 = convert_to_mode (mode1, xop1, unsignedp);
2085 /* Now, if insn doesn't accept these operands, put them into pseudos. */
2086 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
2087 xop0 = copy_to_mode_reg (mode0, xop0);
2089 if (! (*insn_operand_predicate[icode][2]) (xop1, mode1))
2090 xop1 = copy_to_mode_reg (mode1, xop1);
2092 /* We could handle this, but we should always be called with a pseudo
2093 for our targets and all insns should take them as outputs. */
2094 if (! (*insn_operand_predicate[icode][0]) (targ0, mode)
2095 || ! (*insn_operand_predicate[icode][3]) (targ1, mode))
2098 pat = GEN_FCN (icode) (targ0, xop0, xop1, targ1);
2105 delete_insns_since (last);
2108 /* It can't be done in this mode. Can we do it in a wider mode? */
2110 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
2112 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2113 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2115 if (binoptab->handlers[(int) wider_mode].insn_code
2116 != CODE_FOR_nothing)
2118 register rtx t0 = gen_reg_rtx (wider_mode);
2119 register rtx t1 = gen_reg_rtx (wider_mode);
2121 if (expand_twoval_binop (binoptab,
2122 convert_modes (wider_mode, mode, op0,
2124 convert_modes (wider_mode, mode, op1,
2128 convert_move (targ0, t0, unsignedp);
2129 convert_move (targ1, t1, unsignedp);
2133 delete_insns_since (last);
2138 delete_insns_since (entry_last);
2142 /* Generate code to perform an operation specified by UNOPTAB
2143 on operand OP0, with result having machine-mode MODE.
2145 UNSIGNEDP is for the case where we have to widen the operands
2146 to perform the operation. It says to use zero-extension.
2148 If TARGET is nonzero, the value
2149 is generated there, if it is convenient to do so.
2150 In all cases an rtx is returned for the locus of the value;
2151 this may or may not be TARGET. */
2154 expand_unop (mode, unoptab, op0, target, unsignedp)
2155 enum machine_mode mode;
2161 enum mode_class class;
2162 enum machine_mode wider_mode;
2164 rtx last = get_last_insn ();
2167 class = GET_MODE_CLASS (mode);
2169 op0 = protect_from_queue (op0, 0);
2173 op0 = force_not_mem (op0);
2177 target = protect_from_queue (target, 1);
2179 if (unoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2181 int icode = (int) unoptab->handlers[(int) mode].insn_code;
2182 enum machine_mode mode0 = insn_operand_mode[icode][1];
2188 temp = gen_reg_rtx (mode);
2190 if (GET_MODE (xop0) != VOIDmode
2191 && GET_MODE (xop0) != mode0)
2192 xop0 = convert_to_mode (mode0, xop0, unsignedp);
2194 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
2196 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
2197 xop0 = copy_to_mode_reg (mode0, xop0);
2199 if (! (*insn_operand_predicate[icode][0]) (temp, mode))
2200 temp = gen_reg_rtx (mode);
2202 pat = GEN_FCN (icode) (temp, xop0);
2205 if (GET_CODE (pat) == SEQUENCE
2206 && ! add_equal_note (pat, temp, unoptab->code, xop0, NULL_RTX))
2208 delete_insns_since (last);
2209 return expand_unop (mode, unoptab, op0, NULL_RTX, unsignedp);
2217 delete_insns_since (last);
2220 /* It can't be done in this mode. Can we open-code it in a wider mode? */
2222 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
2223 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2224 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2226 if (unoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing)
2230 /* For certain operations, we need not actually extend
2231 the narrow operand, as long as we will truncate the
2232 results to the same narrowness. */
2234 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
2235 (unoptab == neg_optab
2236 || unoptab == one_cmpl_optab)
2237 && class == MODE_INT);
2239 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
2244 if (class != MODE_INT)
2247 target = gen_reg_rtx (mode);
2248 convert_move (target, temp, 0);
2252 return gen_lowpart (mode, temp);
2255 delete_insns_since (last);
2259 /* These can be done a word at a time. */
2260 if (unoptab == one_cmpl_optab
2261 && class == MODE_INT
2262 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
2263 && unoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
2268 if (target == 0 || target == op0)
2269 target = gen_reg_rtx (mode);
2273 /* Do the actual arithmetic. */
2274 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
2276 rtx target_piece = operand_subword (target, i, 1, mode);
2277 rtx x = expand_unop (word_mode, unoptab,
2278 operand_subword_force (op0, i, mode),
2279 target_piece, unsignedp);
2280 if (target_piece != x)
2281 emit_move_insn (target_piece, x);
2284 insns = get_insns ();
2287 emit_no_conflict_block (insns, target, op0, NULL_RTX,
2288 gen_rtx_fmt_e (unoptab->code, mode,
2293 /* Open-code the complex negation operation. */
2294 else if (unoptab == neg_optab
2295 && (class == MODE_COMPLEX_FLOAT || class == MODE_COMPLEX_INT))
2301 /* Find the correct mode for the real and imaginary parts */
2302 enum machine_mode submode
2303 = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
2304 class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
2307 if (submode == BLKmode)
2311 target = gen_reg_rtx (mode);
2315 target_piece = gen_imagpart (submode, target);
2316 x = expand_unop (submode, unoptab,
2317 gen_imagpart (submode, op0),
2318 target_piece, unsignedp);
2319 if (target_piece != x)
2320 emit_move_insn (target_piece, x);
2322 target_piece = gen_realpart (submode, target);
2323 x = expand_unop (submode, unoptab,
2324 gen_realpart (submode, op0),
2325 target_piece, unsignedp);
2326 if (target_piece != x)
2327 emit_move_insn (target_piece, x);
2332 emit_no_conflict_block (seq, target, op0, 0,
2333 gen_rtx_fmt_e (unoptab->code, mode,
2338 /* Now try a library call in this mode. */
2339 if (unoptab->handlers[(int) mode].libfunc)
2346 /* Pass 1 for NO_QUEUE so we don't lose any increments
2347 if the libcall is cse'd or moved. */
2348 value = emit_library_call_value (unoptab->handlers[(int) mode].libfunc,
2349 NULL_RTX, 1, mode, 1, op0, mode);
2350 insns = get_insns ();
2353 target = gen_reg_rtx (mode);
2354 emit_libcall_block (insns, target, value,
2355 gen_rtx_fmt_e (unoptab->code, mode, op0));
2360 /* It can't be done in this mode. Can we do it in a wider mode? */
2362 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
2364 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2365 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2367 if ((unoptab->handlers[(int) wider_mode].insn_code
2368 != CODE_FOR_nothing)
2369 || unoptab->handlers[(int) wider_mode].libfunc)
2373 /* For certain operations, we need not actually extend
2374 the narrow operand, as long as we will truncate the
2375 results to the same narrowness. */
2377 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
2378 (unoptab == neg_optab
2379 || unoptab == one_cmpl_optab)
2380 && class == MODE_INT);
2382 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
2387 if (class != MODE_INT)
2390 target = gen_reg_rtx (mode);
2391 convert_move (target, temp, 0);
2395 return gen_lowpart (mode, temp);
2398 delete_insns_since (last);
2403 /* If there is no negate operation, try doing a subtract from zero.
2404 The US Software GOFAST library needs this. */
2405 if (unoptab == neg_optab)
2408 temp = expand_binop (mode, sub_optab, CONST0_RTX (mode), op0,
2409 target, unsignedp, OPTAB_LIB_WIDEN);
2417 /* Emit code to compute the absolute value of OP0, with result to
2418 TARGET if convenient. (TARGET may be 0.) The return value says
2419 where the result actually is to be found.
2421 MODE is the mode of the operand; the mode of the result is
2422 different but can be deduced from MODE.
2427 expand_abs (mode, op0, target, safe)
2428 enum machine_mode mode;
2435 /* First try to do it with a special abs instruction. */
2436 temp = expand_unop (mode, abs_optab, op0, target, 0);
2440 /* If this machine has expensive jumps, we can do integer absolute
2441 value of X as (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)),
2442 where W is the width of MODE. */
2444 if (GET_MODE_CLASS (mode) == MODE_INT && BRANCH_COST >= 2)
2446 rtx extended = expand_shift (RSHIFT_EXPR, mode, op0,
2447 size_int (GET_MODE_BITSIZE (mode) - 1),
2450 temp = expand_binop (mode, xor_optab, extended, op0, target, 0,
2453 temp = expand_binop (mode, sub_optab, temp, extended, target, 0,
2460 /* If that does not win, use conditional jump and negate. */
2462 /* It is safe to use the target if it is the same
2463 as the source if this is also a pseudo register */
2464 if (op0 == target && GET_CODE (op0) == REG
2465 && REGNO (op0) >= FIRST_PSEUDO_REGISTER)
2468 op1 = gen_label_rtx ();
2469 if (target == 0 || ! safe
2470 || GET_MODE (target) != mode
2471 || (GET_CODE (target) == MEM && MEM_VOLATILE_P (target))
2472 || (GET_CODE (target) == REG
2473 && REGNO (target) < FIRST_PSEUDO_REGISTER))
2474 target = gen_reg_rtx (mode);
2476 emit_move_insn (target, op0);
2479 /* If this mode is an integer too wide to compare properly,
2480 compare word by word. Rely on CSE to optimize constant cases. */
2481 if (GET_MODE_CLASS (mode) == MODE_INT && ! can_compare_p (mode))
2482 do_jump_by_parts_greater_rtx (mode, 0, target, const0_rtx,
2486 temp = compare_from_rtx (target, CONST0_RTX (mode), GE, 0, mode,
2488 if (temp == const1_rtx)
2490 else if (temp != const0_rtx)
2492 if (bcc_gen_fctn[(int) GET_CODE (temp)] != 0)
2493 emit_jump_insn ((*bcc_gen_fctn[(int) GET_CODE (temp)]) (op1));
2499 op0 = expand_unop (mode, neg_optab, target, target, 0);
2501 emit_move_insn (target, op0);
2507 /* Emit code to compute the absolute value of OP0, with result to
2508 TARGET if convenient. (TARGET may be 0.) The return value says
2509 where the result actually is to be found.
2511 MODE is the mode of the operand; the mode of the result is
2512 different but can be deduced from MODE.
2514 UNSIGNEDP is relevant for complex integer modes. */
2517 expand_complex_abs (mode, op0, target, unsignedp)
2518 enum machine_mode mode;
2523 enum mode_class class = GET_MODE_CLASS (mode);
2524 enum machine_mode wider_mode;
2526 rtx entry_last = get_last_insn ();
2530 /* Find the correct mode for the real and imaginary parts. */
2531 enum machine_mode submode
2532 = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
2533 class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
2536 if (submode == BLKmode)
2539 op0 = protect_from_queue (op0, 0);
2543 op0 = force_not_mem (op0);
2546 last = get_last_insn ();
2549 target = protect_from_queue (target, 1);
2551 if (abs_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2553 int icode = (int) abs_optab->handlers[(int) mode].insn_code;
2554 enum machine_mode mode0 = insn_operand_mode[icode][1];
2560 temp = gen_reg_rtx (submode);
2562 if (GET_MODE (xop0) != VOIDmode
2563 && GET_MODE (xop0) != mode0)
2564 xop0 = convert_to_mode (mode0, xop0, unsignedp);
2566 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
2568 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
2569 xop0 = copy_to_mode_reg (mode0, xop0);
2571 if (! (*insn_operand_predicate[icode][0]) (temp, submode))
2572 temp = gen_reg_rtx (submode);
2574 pat = GEN_FCN (icode) (temp, xop0);
2577 if (GET_CODE (pat) == SEQUENCE
2578 && ! add_equal_note (pat, temp, abs_optab->code, xop0, NULL_RTX))
2580 delete_insns_since (last);
2581 return expand_unop (mode, abs_optab, op0, NULL_RTX, unsignedp);
2589 delete_insns_since (last);
2592 /* It can't be done in this mode. Can we open-code it in a wider mode? */
2594 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2595 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2597 if (abs_optab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing)
2601 xop0 = convert_modes (wider_mode, mode, xop0, unsignedp);
2602 temp = expand_complex_abs (wider_mode, xop0, NULL_RTX, unsignedp);
2606 if (class != MODE_COMPLEX_INT)
2609 target = gen_reg_rtx (submode);
2610 convert_move (target, temp, 0);
2614 return gen_lowpart (submode, temp);
2617 delete_insns_since (last);
2621 /* Open-code the complex absolute-value operation
2622 if we can open-code sqrt. Otherwise it's not worth while. */
2623 if (sqrt_optab->handlers[(int) submode].insn_code != CODE_FOR_nothing)
2625 rtx real, imag, total;
2627 real = gen_realpart (submode, op0);
2628 imag = gen_imagpart (submode, op0);
2630 /* Square both parts. */
2631 real = expand_mult (submode, real, real, NULL_RTX, 0);
2632 imag = expand_mult (submode, imag, imag, NULL_RTX, 0);
2634 /* Sum the parts. */
2635 total = expand_binop (submode, add_optab, real, imag, NULL_RTX,
2636 0, OPTAB_LIB_WIDEN);
2638 /* Get sqrt in TARGET. Set TARGET to where the result is. */
2639 target = expand_unop (submode, sqrt_optab, total, target, 0);
2641 delete_insns_since (last);
2646 /* Now try a library call in this mode. */
2647 if (abs_optab->handlers[(int) mode].libfunc)
2654 /* Pass 1 for NO_QUEUE so we don't lose any increments
2655 if the libcall is cse'd or moved. */
2656 value = emit_library_call_value (abs_optab->handlers[(int) mode].libfunc,
2657 NULL_RTX, 1, submode, 1, op0, mode);
2658 insns = get_insns ();
2661 target = gen_reg_rtx (submode);
2662 emit_libcall_block (insns, target, value,
2663 gen_rtx_fmt_e (abs_optab->code, mode, op0));
2668 /* It can't be done in this mode. Can we do it in a wider mode? */
2670 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2671 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2673 if ((abs_optab->handlers[(int) wider_mode].insn_code
2674 != CODE_FOR_nothing)
2675 || abs_optab->handlers[(int) wider_mode].libfunc)
2679 xop0 = convert_modes (wider_mode, mode, xop0, unsignedp);
2681 temp = expand_complex_abs (wider_mode, xop0, NULL_RTX, unsignedp);
2685 if (class != MODE_COMPLEX_INT)
2688 target = gen_reg_rtx (submode);
2689 convert_move (target, temp, 0);
2693 return gen_lowpart (submode, temp);
2696 delete_insns_since (last);
2700 delete_insns_since (entry_last);
2704 /* Generate an instruction whose insn-code is INSN_CODE,
2705 with two operands: an output TARGET and an input OP0.
2706 TARGET *must* be nonzero, and the output is always stored there.
2707 CODE is an rtx code such that (CODE OP0) is an rtx that describes
2708 the value that is stored into TARGET. */
2711 emit_unop_insn (icode, target, op0, code)
2718 enum machine_mode mode0 = insn_operand_mode[icode][1];
2721 temp = target = protect_from_queue (target, 1);
2723 op0 = protect_from_queue (op0, 0);
2725 /* Sign and zero extension from memory is often done specially on
2726 RISC machines, so forcing into a register here can pessimize
2728 if (flag_force_mem && code != SIGN_EXTEND && code != ZERO_EXTEND)
2729 op0 = force_not_mem (op0);
2731 /* Now, if insn does not accept our operands, put them into pseudos. */
2733 if (! (*insn_operand_predicate[icode][1]) (op0, mode0))
2734 op0 = copy_to_mode_reg (mode0, op0);
2736 if (! (*insn_operand_predicate[icode][0]) (temp, GET_MODE (temp))
2737 || (flag_force_mem && GET_CODE (temp) == MEM))
2738 temp = gen_reg_rtx (GET_MODE (temp));
2740 pat = GEN_FCN (icode) (temp, op0);
2742 if (GET_CODE (pat) == SEQUENCE && code != UNKNOWN)
2743 add_equal_note (pat, temp, code, op0, NULL_RTX);
2748 emit_move_insn (target, temp);
2751 /* Emit code to perform a series of operations on a multi-word quantity, one
2754 Such a block is preceded by a CLOBBER of the output, consists of multiple
2755 insns, each setting one word of the output, and followed by a SET copying
2756 the output to itself.
2758 Each of the insns setting words of the output receives a REG_NO_CONFLICT
2759 note indicating that it doesn't conflict with the (also multi-word)
2760 inputs. The entire block is surrounded by REG_LIBCALL and REG_RETVAL
2763 INSNS is a block of code generated to perform the operation, not including
2764 the CLOBBER and final copy. All insns that compute intermediate values
2765 are first emitted, followed by the block as described above.
2767 TARGET, OP0, and OP1 are the output and inputs of the operations,
2768 respectively. OP1 may be zero for a unary operation.
2770 EQUIV, if non-zero, is an expression to be placed into a REG_EQUAL note
2773 If TARGET is not a register, INSNS is simply emitted with no special
2774 processing. Likewise if anything in INSNS is not an INSN or if
2775 there is a libcall block inside INSNS.
2777 The final insn emitted is returned. */
2780 emit_no_conflict_block (insns, target, op0, op1, equiv)
2786 rtx prev, next, first, last, insn;
2788 if (GET_CODE (target) != REG || reload_in_progress)
2789 return emit_insns (insns);
2791 for (insn = insns; insn; insn = NEXT_INSN (insn))
2792 if (GET_CODE (insn) != INSN
2793 || find_reg_note (insn, REG_LIBCALL, NULL_RTX))
2794 return emit_insns (insns);
2796 /* First emit all insns that do not store into words of the output and remove
2797 these from the list. */
2798 for (insn = insns; insn; insn = next)
2803 next = NEXT_INSN (insn);
2805 if (GET_CODE (PATTERN (insn)) == SET)
2806 set = PATTERN (insn);
2807 else if (GET_CODE (PATTERN (insn)) == PARALLEL)
2809 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
2810 if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET)
2812 set = XVECEXP (PATTERN (insn), 0, i);
2820 if (! reg_overlap_mentioned_p (target, SET_DEST (set)))
2822 if (PREV_INSN (insn))
2823 NEXT_INSN (PREV_INSN (insn)) = next;
2828 PREV_INSN (next) = PREV_INSN (insn);
2834 prev = get_last_insn ();
2836 /* Now write the CLOBBER of the output, followed by the setting of each
2837 of the words, followed by the final copy. */
2838 if (target != op0 && target != op1)
2839 emit_insn (gen_rtx_CLOBBER (VOIDmode, target));
2841 for (insn = insns; insn; insn = next)
2843 next = NEXT_INSN (insn);
2846 if (op1 && GET_CODE (op1) == REG)
2847 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_NO_CONFLICT, op1,
2850 if (op0 && GET_CODE (op0) == REG)
2851 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_NO_CONFLICT, op0,
2855 if (mov_optab->handlers[(int) GET_MODE (target)].insn_code
2856 != CODE_FOR_nothing)
2858 last = emit_move_insn (target, target);
2860 set_unique_reg_note (last, REG_EQUAL, equiv);
2863 last = get_last_insn ();
2866 first = get_insns ();
2868 first = NEXT_INSN (prev);
2870 /* Encapsulate the block so it gets manipulated as a unit. */
2871 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last,
2873 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2878 /* Emit code to make a call to a constant function or a library call.
2880 INSNS is a list containing all insns emitted in the call.
2881 These insns leave the result in RESULT. Our block is to copy RESULT
2882 to TARGET, which is logically equivalent to EQUIV.
2884 We first emit any insns that set a pseudo on the assumption that these are
2885 loading constants into registers; doing so allows them to be safely cse'ed
2886 between blocks. Then we emit all the other insns in the block, followed by
2887 an insn to move RESULT to TARGET. This last insn will have a REQ_EQUAL
2888 note with an operand of EQUIV.
2890 Moving assignments to pseudos outside of the block is done to improve
2891 the generated code, but is not required to generate correct code,
2892 hence being unable to move an assignment is not grounds for not making
2893 a libcall block. There are two reasons why it is safe to leave these
2894 insns inside the block: First, we know that these pseudos cannot be
2895 used in generated RTL outside the block since they are created for
2896 temporary purposes within the block. Second, CSE will not record the
2897 values of anything set inside a libcall block, so we know they must
2898 be dead at the end of the block.
2900 Except for the first group of insns (the ones setting pseudos), the
2901 block is delimited by REG_RETVAL and REG_LIBCALL notes. */
2904 emit_libcall_block (insns, target, result, equiv)
2910 rtx final_dest = target;
2911 rtx prev, next, first, last, insn;
2913 /* If this is a reg with REG_USERVAR_P set, then it could possibly turn
2914 into a MEM later. Protect the libcall block from this change. */
2915 if (! REG_P (target) || REG_USERVAR_P (target))
2916 target = gen_reg_rtx (GET_MODE (target));
2918 /* look for any CALL_INSNs in this sequence, and attach a REG_EH_REGION
2919 reg note to indicate that this call cannot throw. (Unless there is
2920 already a REG_EH_REGION note.) */
2922 for (insn = insns; insn; insn = NEXT_INSN (insn))
2924 if (GET_CODE (insn) == CALL_INSN)
2926 rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
2927 if (note == NULL_RTX)
2928 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EH_REGION, GEN_INT (-1),
2933 /* First emit all insns that set pseudos. Remove them from the list as
2934 we go. Avoid insns that set pseudos which were referenced in previous
2935 insns. These can be generated by move_by_pieces, for example,
2936 to update an address. Similarly, avoid insns that reference things
2937 set in previous insns. */
2939 for (insn = insns; insn; insn = next)
2941 rtx set = single_set (insn);
2943 next = NEXT_INSN (insn);
2945 if (set != 0 && GET_CODE (SET_DEST (set)) == REG
2946 && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER
2948 || (! reg_mentioned_p (SET_DEST (set), PATTERN (insns))
2949 && ! reg_used_between_p (SET_DEST (set), insns, insn)
2950 && ! modified_in_p (SET_SRC (set), insns)
2951 && ! modified_between_p (SET_SRC (set), insns, insn))))
2953 if (PREV_INSN (insn))
2954 NEXT_INSN (PREV_INSN (insn)) = next;
2959 PREV_INSN (next) = PREV_INSN (insn);
2965 prev = get_last_insn ();
2967 /* Write the remaining insns followed by the final copy. */
2969 for (insn = insns; insn; insn = next)
2971 next = NEXT_INSN (insn);
2976 last = emit_move_insn (target, result);
2977 if (mov_optab->handlers[(int) GET_MODE (target)].insn_code
2978 != CODE_FOR_nothing)
2979 set_unique_reg_note (last, REG_EQUAL, copy_rtx (equiv));
2981 if (final_dest != target)
2982 emit_move_insn (final_dest, target);
2985 first = get_insns ();
2987 first = NEXT_INSN (prev);
2989 /* Encapsulate the block so it gets manipulated as a unit. */
2990 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last,
2992 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2995 /* Generate code to store zero in X. */
3001 emit_move_insn (x, const0_rtx);
3004 /* Generate code to store 1 in X
3005 assuming it contains zero beforehand. */
3008 emit_0_to_1_insn (x)
3011 emit_move_insn (x, const1_rtx);
3014 /* Generate code to compare X with Y
3015 so that the condition codes are set.
3017 MODE is the mode of the inputs (in case they are const_int).
3018 UNSIGNEDP nonzero says that X and Y are unsigned;
3019 this matters if they need to be widened.
3021 If they have mode BLKmode, then SIZE specifies the size of both X and Y,
3022 and ALIGN specifies the known shared alignment of X and Y.
3024 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).
3025 It is ignored for fixed-point and block comparisons;
3026 it is used only for floating-point comparisons. */
3029 emit_cmp_insn (x, y, comparison, size, mode, unsignedp, align)
3031 enum rtx_code comparison;
3033 enum machine_mode mode;
3037 enum mode_class class;
3038 enum machine_mode wider_mode;
3040 class = GET_MODE_CLASS (mode);
3042 /* They could both be VOIDmode if both args are immediate constants,
3043 but we should fold that at an earlier stage.
3044 With no special code here, this will call abort,
3045 reminding the programmer to implement such folding. */
3047 if (mode != BLKmode && flag_force_mem)
3049 x = force_not_mem (x);
3050 y = force_not_mem (y);
3053 /* If we are inside an appropriately-short loop and one operand is an
3054 expensive constant, force it into a register. */
3055 if (CONSTANT_P (x) && preserve_subexpressions_p () && rtx_cost (x, COMPARE) > 2)
3056 x = force_reg (mode, x);
3058 if (CONSTANT_P (y) && preserve_subexpressions_p () && rtx_cost (y, COMPARE) > 2)
3059 y = force_reg (mode, y);
3062 /* Abort if we have a non-canonical comparison. The RTL documentation
3063 states that canonical comparisons are required only for targets which
3065 if (CONSTANT_P (x) && ! CONSTANT_P (y))
3069 /* Don't let both operands fail to indicate the mode. */
3070 if (GET_MODE (x) == VOIDmode && GET_MODE (y) == VOIDmode)
3071 x = force_reg (mode, x);
3073 /* Handle all BLKmode compares. */
3075 if (mode == BLKmode)
3078 x = protect_from_queue (x, 0);
3079 y = protect_from_queue (y, 0);
3083 #ifdef HAVE_cmpstrqi
3085 && GET_CODE (size) == CONST_INT
3086 && INTVAL (size) < (1 << GET_MODE_BITSIZE (QImode)))
3088 enum machine_mode result_mode
3089 = insn_operand_mode[(int) CODE_FOR_cmpstrqi][0];
3090 rtx result = gen_reg_rtx (result_mode);
3091 emit_insn (gen_cmpstrqi (result, x, y, size, GEN_INT (align)));
3092 emit_cmp_insn (result, const0_rtx, comparison, NULL_RTX,
3097 #ifdef HAVE_cmpstrhi
3099 && GET_CODE (size) == CONST_INT
3100 && INTVAL (size) < (1 << GET_MODE_BITSIZE (HImode)))
3102 enum machine_mode result_mode
3103 = insn_operand_mode[(int) CODE_FOR_cmpstrhi][0];
3104 rtx result = gen_reg_rtx (result_mode);
3105 emit_insn (gen_cmpstrhi (result, x, y, size, GEN_INT (align)));
3106 emit_cmp_insn (result, const0_rtx, comparison, NULL_RTX,
3111 #ifdef HAVE_cmpstrsi
3114 enum machine_mode result_mode
3115 = insn_operand_mode[(int) CODE_FOR_cmpstrsi][0];
3116 rtx result = gen_reg_rtx (result_mode);
3117 size = protect_from_queue (size, 0);
3118 emit_insn (gen_cmpstrsi (result, x, y,
3119 convert_to_mode (SImode, size, 1),
3121 emit_cmp_insn (result, const0_rtx, comparison, NULL_RTX,
3129 #ifdef TARGET_MEM_FUNCTIONS
3130 emit_library_call (memcmp_libfunc, 0,
3131 TYPE_MODE (integer_type_node), 3,
3132 XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
3133 convert_to_mode (TYPE_MODE (sizetype), size,
3134 TREE_UNSIGNED (sizetype)),
3135 TYPE_MODE (sizetype));
3137 emit_library_call (bcmp_libfunc, 0,
3138 TYPE_MODE (integer_type_node), 3,
3139 XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
3140 convert_to_mode (TYPE_MODE (integer_type_node),
3142 TREE_UNSIGNED (integer_type_node)),
3143 TYPE_MODE (integer_type_node));
3146 /* Immediately move the result of the libcall into a pseudo
3147 register so reload doesn't clobber the value if it needs
3148 the return register for a spill reg. */
3149 result = gen_reg_rtx (TYPE_MODE (integer_type_node));
3150 emit_move_insn (result,
3151 hard_libcall_value (TYPE_MODE (integer_type_node)));
3152 emit_cmp_insn (result,
3153 const0_rtx, comparison, NULL_RTX,
3154 TYPE_MODE (integer_type_node), 0, 0);
3159 /* Handle some compares against zero. */
3161 if (y == CONST0_RTX (mode)
3162 && tst_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
3164 int icode = (int) tst_optab->handlers[(int) mode].insn_code;
3167 x = protect_from_queue (x, 0);
3168 y = protect_from_queue (y, 0);
3170 /* Now, if insn does accept these operands, put them into pseudos. */
3171 if (! (*insn_operand_predicate[icode][0])
3172 (x, insn_operand_mode[icode][0]))
3173 x = copy_to_mode_reg (insn_operand_mode[icode][0], x);
3175 emit_insn (GEN_FCN (icode) (x));
3179 /* Handle compares for which there is a directly suitable insn. */
3181 if (cmp_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
3183 int icode = (int) cmp_optab->handlers[(int) mode].insn_code;
3186 x = protect_from_queue (x, 0);
3187 y = protect_from_queue (y, 0);
3189 /* Now, if insn doesn't accept these operands, put them into pseudos. */
3190 if (! (*insn_operand_predicate[icode][0])
3191 (x, insn_operand_mode[icode][0]))
3192 x = copy_to_mode_reg (insn_operand_mode[icode][0], x);
3194 if (! (*insn_operand_predicate[icode][1])
3195 (y, insn_operand_mode[icode][1]))
3196 y = copy_to_mode_reg (insn_operand_mode[icode][1], y);
3198 emit_insn (GEN_FCN (icode) (x, y));
3202 /* Try widening if we can find a direct insn that way. */
3204 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
3206 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
3207 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
3209 if (cmp_optab->handlers[(int) wider_mode].insn_code
3210 != CODE_FOR_nothing)
3212 x = protect_from_queue (x, 0);
3213 y = protect_from_queue (y, 0);
3214 x = convert_modes (wider_mode, mode, x, unsignedp);
3215 y = convert_modes (wider_mode, mode, y, unsignedp);
3216 emit_cmp_insn (x, y, comparison, NULL_RTX,
3217 wider_mode, unsignedp, align);
3223 /* Handle a lib call just for the mode we are using. */
3225 if (cmp_optab->handlers[(int) mode].libfunc
3226 && class != MODE_FLOAT)
3228 rtx libfunc = cmp_optab->handlers[(int) mode].libfunc;
3231 /* If we want unsigned, and this mode has a distinct unsigned
3232 comparison routine, use that. */
3233 if (unsignedp && ucmp_optab->handlers[(int) mode].libfunc)
3234 libfunc = ucmp_optab->handlers[(int) mode].libfunc;
3236 emit_library_call (libfunc, 1,
3237 word_mode, 2, x, mode, y, mode);
3239 /* Immediately move the result of the libcall into a pseudo
3240 register so reload doesn't clobber the value if it needs
3241 the return register for a spill reg. */
3242 result = gen_reg_rtx (word_mode);
3243 emit_move_insn (result, hard_libcall_value (word_mode));
3245 /* Integer comparison returns a result that must be compared against 1,
3246 so that even if we do an unsigned compare afterward,
3247 there is still a value that can represent the result "less than". */
3248 emit_cmp_insn (result, const1_rtx,
3249 comparison, NULL_RTX, word_mode, unsignedp, 0);
3253 if (class == MODE_FLOAT)
3254 emit_float_lib_cmp (x, y, comparison);
3260 /* Generate code to compare X with Y so that the condition codes are
3261 set and to jump to LABEL if the condition is true. If X is a
3262 constant and Y is not a constant, then the comparison is swapped to
3263 ensure that the comparison RTL has the canonical form.
3265 UNSIGNEDP nonzero says that X and Y are unsigned; this matters if they
3266 need to be widened by emit_cmp_insn. UNSIGNEDP is also used to select
3267 the proper branch condition code.
3269 If X and Y have mode BLKmode, then SIZE specifies the size of both X and Y,
3270 and ALIGN specifies the known shared alignment of X and Y.
3272 MODE is the mode of the inputs (in case they are const_int).
3274 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). It will
3275 be passed unchanged to emit_cmp_insn, then potentially converted into an
3276 unsigned variant based on UNSIGNEDP to select a proper jump instruction. */
3279 emit_cmp_and_jump_insns (x, y, comparison, size, mode, unsignedp, align, label)
3281 enum rtx_code comparison;
3283 enum machine_mode mode;
3293 /* Swap operands and condition to ensure canonical RTL. */
3296 comparison = swap_condition (comparison);
3305 /* If OP0 is still a constant, then both X and Y must be constants. Force
3306 X into a register to avoid aborting in emit_cmp_insn due to non-canonical
3308 if (CONSTANT_P (op0))
3309 op0 = force_reg (mode, op0);
3312 emit_cmp_insn (op0, op1, comparison, size, mode, unsignedp, align);
3315 comparison = unsigned_condition (comparison);
3316 emit_jump_insn ((*bcc_gen_fctn[(int) comparison]) (label));
3320 /* Nonzero if a compare of mode MODE can be done straightforwardly
3321 (without splitting it into pieces). */
3324 can_compare_p (mode)
3325 enum machine_mode mode;
3329 if (cmp_optab->handlers[(int)mode].insn_code != CODE_FOR_nothing)
3331 mode = GET_MODE_WIDER_MODE (mode);
3332 } while (mode != VOIDmode);
3337 /* Emit a library call comparison between floating point X and Y.
3338 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */
3341 emit_float_lib_cmp (x, y, comparison)
3343 enum rtx_code comparison;
3345 enum machine_mode mode = GET_MODE (x);
3353 libfunc = eqhf2_libfunc;
3357 libfunc = nehf2_libfunc;
3361 libfunc = gthf2_libfunc;
3365 libfunc = gehf2_libfunc;
3369 libfunc = lthf2_libfunc;
3373 libfunc = lehf2_libfunc;
3379 else if (mode == SFmode)
3383 libfunc = eqsf2_libfunc;
3387 libfunc = nesf2_libfunc;
3391 libfunc = gtsf2_libfunc;
3395 libfunc = gesf2_libfunc;
3399 libfunc = ltsf2_libfunc;
3403 libfunc = lesf2_libfunc;
3409 else if (mode == DFmode)
3413 libfunc = eqdf2_libfunc;
3417 libfunc = nedf2_libfunc;
3421 libfunc = gtdf2_libfunc;
3425 libfunc = gedf2_libfunc;
3429 libfunc = ltdf2_libfunc;
3433 libfunc = ledf2_libfunc;
3439 else if (mode == XFmode)
3443 libfunc = eqxf2_libfunc;
3447 libfunc = nexf2_libfunc;
3451 libfunc = gtxf2_libfunc;
3455 libfunc = gexf2_libfunc;
3459 libfunc = ltxf2_libfunc;
3463 libfunc = lexf2_libfunc;
3469 else if (mode == TFmode)
3473 libfunc = eqtf2_libfunc;
3477 libfunc = netf2_libfunc;
3481 libfunc = gttf2_libfunc;
3485 libfunc = getf2_libfunc;
3489 libfunc = lttf2_libfunc;
3493 libfunc = letf2_libfunc;
3501 enum machine_mode wider_mode;
3503 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
3504 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
3506 if ((cmp_optab->handlers[(int) wider_mode].insn_code
3507 != CODE_FOR_nothing)
3508 || (cmp_optab->handlers[(int) wider_mode].libfunc != 0))
3510 x = protect_from_queue (x, 0);
3511 y = protect_from_queue (y, 0);
3512 x = convert_to_mode (wider_mode, x, 0);
3513 y = convert_to_mode (wider_mode, y, 0);
3514 emit_float_lib_cmp (x, y, comparison);
3524 emit_library_call (libfunc, 1,
3525 word_mode, 2, x, mode, y, mode);
3527 /* Immediately move the result of the libcall into a pseudo
3528 register so reload doesn't clobber the value if it needs
3529 the return register for a spill reg. */
3530 result = gen_reg_rtx (word_mode);
3531 emit_move_insn (result, hard_libcall_value (word_mode));
3533 emit_cmp_insn (result, const0_rtx, comparison,
3534 NULL_RTX, word_mode, 0, 0);
3537 /* Generate code to indirectly jump to a location given in the rtx LOC. */
3540 emit_indirect_jump (loc)
3543 if (! ((*insn_operand_predicate[(int)CODE_FOR_indirect_jump][0])
3545 loc = copy_to_mode_reg (Pmode, loc);
3547 emit_jump_insn (gen_indirect_jump (loc));
3551 #ifdef HAVE_conditional_move
3553 /* Emit a conditional move instruction if the machine supports one for that
3554 condition and machine mode.
3556 OP0 and OP1 are the operands that should be compared using CODE. CMODE is
3557 the mode to use should they be constants. If it is VOIDmode, they cannot
3560 OP2 should be stored in TARGET if the comparison is true, otherwise OP3
3561 should be stored there. MODE is the mode to use should they be constants.
3562 If it is VOIDmode, they cannot both be constants.
3564 The result is either TARGET (perhaps modified) or NULL_RTX if the operation
3565 is not supported. */
3568 emit_conditional_move (target, code, op0, op1, cmode, op2, op3, mode,
3573 enum machine_mode cmode;
3575 enum machine_mode mode;
3578 rtx tem, subtarget, comparison, insn;
3579 enum insn_code icode;
3581 /* If one operand is constant, make it the second one. Only do this
3582 if the other operand is not constant as well. */
3584 if ((CONSTANT_P (op0) && ! CONSTANT_P (op1))
3585 || (GET_CODE (op0) == CONST_INT && GET_CODE (op1) != CONST_INT))
3590 code = swap_condition (code);
3593 if (cmode == VOIDmode)
3594 cmode = GET_MODE (op0);
3596 if (((CONSTANT_P (op2) && ! CONSTANT_P (op3))
3597 || (GET_CODE (op2) == CONST_INT && GET_CODE (op3) != CONST_INT))
3598 && (GET_MODE_CLASS (GET_MODE (op1)) != MODE_FLOAT
3599 || TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT || flag_fast_math))
3604 code = reverse_condition (code);
3607 if (mode == VOIDmode)
3608 mode = GET_MODE (op2);
3610 icode = movcc_gen_code[mode];
3612 if (icode == CODE_FOR_nothing)
3617 op2 = force_not_mem (op2);
3618 op3 = force_not_mem (op3);
3622 target = protect_from_queue (target, 1);
3624 target = gen_reg_rtx (mode);
3630 op2 = protect_from_queue (op2, 0);
3631 op3 = protect_from_queue (op3, 0);
3633 /* If the insn doesn't accept these operands, put them in pseudos. */
3635 if (! (*insn_operand_predicate[icode][0])
3636 (subtarget, insn_operand_mode[icode][0]))
3637 subtarget = gen_reg_rtx (insn_operand_mode[icode][0]);
3639 if (! (*insn_operand_predicate[icode][2])
3640 (op2, insn_operand_mode[icode][2]))
3641 op2 = copy_to_mode_reg (insn_operand_mode[icode][2], op2);
3643 if (! (*insn_operand_predicate[icode][3])
3644 (op3, insn_operand_mode[icode][3]))
3645 op3 = copy_to_mode_reg (insn_operand_mode[icode][3], op3);
3647 /* Everything should now be in the suitable form, so emit the compare insn
3648 and then the conditional move. */
3651 = compare_from_rtx (op0, op1, code, unsignedp, cmode, NULL_RTX, 0);
3653 /* ??? Watch for const0_rtx (nop) and const_true_rtx (unconditional)? */
3654 if (GET_CODE (comparison) != code)
3655 /* This shouldn't happen. */
3658 insn = GEN_FCN (icode) (subtarget, comparison, op2, op3);
3660 /* If that failed, then give up. */
3666 if (subtarget != target)
3667 convert_move (target, subtarget, 0);
3672 /* Return non-zero if a conditional move of mode MODE is supported.
3674 This function is for combine so it can tell whether an insn that looks
3675 like a conditional move is actually supported by the hardware. If we
3676 guess wrong we lose a bit on optimization, but that's it. */
3677 /* ??? sparc64 supports conditionally moving integers values based on fp
3678 comparisons, and vice versa. How do we handle them? */
3681 can_conditionally_move_p (mode)
3682 enum machine_mode mode;
3684 if (movcc_gen_code[mode] != CODE_FOR_nothing)
3690 #endif /* HAVE_conditional_move */
3692 /* These three functions generate an insn body and return it
3693 rather than emitting the insn.
3695 They do not protect from queued increments,
3696 because they may be used 1) in protect_from_queue itself
3697 and 2) in other passes where there is no queue. */
3699 /* Generate and return an insn body to add Y to X. */
3702 gen_add2_insn (x, y)
3705 int icode = (int) add_optab->handlers[(int) GET_MODE (x)].insn_code;
3707 if (! (*insn_operand_predicate[icode][0]) (x, insn_operand_mode[icode][0])
3708 || ! (*insn_operand_predicate[icode][1]) (x, insn_operand_mode[icode][1])
3709 || ! (*insn_operand_predicate[icode][2]) (y, insn_operand_mode[icode][2]))
3712 return (GEN_FCN (icode) (x, x, y));
3716 have_add2_insn (mode)
3717 enum machine_mode mode;
3719 return add_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
3722 /* Generate and return an insn body to subtract Y from X. */
3725 gen_sub2_insn (x, y)
3728 int icode = (int) sub_optab->handlers[(int) GET_MODE (x)].insn_code;
3730 if (! (*insn_operand_predicate[icode][0]) (x, insn_operand_mode[icode][0])
3731 || ! (*insn_operand_predicate[icode][1]) (x, insn_operand_mode[icode][1])
3732 || ! (*insn_operand_predicate[icode][2]) (y, insn_operand_mode[icode][2]))
3735 return (GEN_FCN (icode) (x, x, y));
3739 have_sub2_insn (mode)
3740 enum machine_mode mode;
3742 return sub_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
3745 /* Generate the body of an instruction to copy Y into X.
3746 It may be a SEQUENCE, if one insn isn't enough. */
3749 gen_move_insn (x, y)
3752 register enum machine_mode mode = GET_MODE (x);
3753 enum insn_code insn_code;
3756 if (mode == VOIDmode)
3757 mode = GET_MODE (y);
3759 insn_code = mov_optab->handlers[(int) mode].insn_code;
3761 /* Handle MODE_CC modes: If we don't have a special move insn for this mode,
3762 find a mode to do it in. If we have a movcc, use it. Otherwise,
3763 find the MODE_INT mode of the same width. */
3765 if (GET_MODE_CLASS (mode) == MODE_CC && insn_code == CODE_FOR_nothing)
3767 enum machine_mode tmode = VOIDmode;
3771 && mov_optab->handlers[(int) CCmode].insn_code != CODE_FOR_nothing)
3774 for (tmode = QImode; tmode != VOIDmode;
3775 tmode = GET_MODE_WIDER_MODE (tmode))
3776 if (GET_MODE_SIZE (tmode) == GET_MODE_SIZE (mode))
3779 if (tmode == VOIDmode)
3782 /* Get X and Y in TMODE. We can't use gen_lowpart here because it
3783 may call change_address which is not appropriate if we were
3784 called when a reload was in progress. We don't have to worry
3785 about changing the address since the size in bytes is supposed to
3786 be the same. Copy the MEM to change the mode and move any
3787 substitutions from the old MEM to the new one. */
3789 if (reload_in_progress)
3791 x = gen_lowpart_common (tmode, x1);
3792 if (x == 0 && GET_CODE (x1) == MEM)
3794 x = gen_rtx_MEM (tmode, XEXP (x1, 0));
3795 RTX_UNCHANGING_P (x) = RTX_UNCHANGING_P (x1);
3796 MEM_COPY_ATTRIBUTES (x, x1);
3797 copy_replacements (x1, x);
3800 y = gen_lowpart_common (tmode, y1);
3801 if (y == 0 && GET_CODE (y1) == MEM)
3803 y = gen_rtx_MEM (tmode, XEXP (y1, 0));
3804 RTX_UNCHANGING_P (y) = RTX_UNCHANGING_P (y1);
3805 MEM_COPY_ATTRIBUTES (y, y1);
3806 copy_replacements (y1, y);
3811 x = gen_lowpart (tmode, x);
3812 y = gen_lowpart (tmode, y);
3815 insn_code = mov_optab->handlers[(int) tmode].insn_code;
3816 return (GEN_FCN (insn_code) (x, y));
3820 emit_move_insn_1 (x, y);
3821 seq = gen_sequence ();
3826 /* Return the insn code used to extend FROM_MODE to TO_MODE.
3827 UNSIGNEDP specifies zero-extension instead of sign-extension. If
3828 no such operation exists, CODE_FOR_nothing will be returned. */
3831 can_extend_p (to_mode, from_mode, unsignedp)
3832 enum machine_mode to_mode, from_mode;
3835 return extendtab[(int) to_mode][(int) from_mode][unsignedp];
3838 /* Generate the body of an insn to extend Y (with mode MFROM)
3839 into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */
3842 gen_extend_insn (x, y, mto, mfrom, unsignedp)
3844 enum machine_mode mto, mfrom;
3847 return (GEN_FCN (extendtab[(int) mto][(int) mfrom][unsignedp]) (x, y));
3850 /* can_fix_p and can_float_p say whether the target machine
3851 can directly convert a given fixed point type to
3852 a given floating point type, or vice versa.
3853 The returned value is the CODE_FOR_... value to use,
3854 or CODE_FOR_nothing if these modes cannot be directly converted.
3856 *TRUNCP_PTR is set to 1 if it is necessary to output
3857 an explicit FTRUNC insn before the fix insn; otherwise 0. */
3859 static enum insn_code
3860 can_fix_p (fixmode, fltmode, unsignedp, truncp_ptr)
3861 enum machine_mode fltmode, fixmode;
3866 if (fixtrunctab[(int) fltmode][(int) fixmode][unsignedp] != CODE_FOR_nothing)
3867 return fixtrunctab[(int) fltmode][(int) fixmode][unsignedp];
3869 if (ftrunc_optab->handlers[(int) fltmode].insn_code != CODE_FOR_nothing)
3872 return fixtab[(int) fltmode][(int) fixmode][unsignedp];
3874 return CODE_FOR_nothing;
3877 static enum insn_code
3878 can_float_p (fltmode, fixmode, unsignedp)
3879 enum machine_mode fixmode, fltmode;
3882 return floattab[(int) fltmode][(int) fixmode][unsignedp];
3885 /* Generate code to convert FROM to floating point
3886 and store in TO. FROM must be fixed point and not VOIDmode.
3887 UNSIGNEDP nonzero means regard FROM as unsigned.
3888 Normally this is done by correcting the final value
3889 if it is negative. */
3892 expand_float (to, from, unsignedp)
3896 enum insn_code icode;
3897 register rtx target = to;
3898 enum machine_mode fmode, imode;
3900 /* Crash now, because we won't be able to decide which mode to use. */
3901 if (GET_MODE (from) == VOIDmode)
3904 /* Look for an insn to do the conversion. Do it in the specified
3905 modes if possible; otherwise convert either input, output or both to
3906 wider mode. If the integer mode is wider than the mode of FROM,
3907 we can do the conversion signed even if the input is unsigned. */
3909 for (imode = GET_MODE (from); imode != VOIDmode;
3910 imode = GET_MODE_WIDER_MODE (imode))
3911 for (fmode = GET_MODE (to); fmode != VOIDmode;
3912 fmode = GET_MODE_WIDER_MODE (fmode))
3914 int doing_unsigned = unsignedp;
3916 icode = can_float_p (fmode, imode, unsignedp);
3917 if (icode == CODE_FOR_nothing && imode != GET_MODE (from) && unsignedp)
3918 icode = can_float_p (fmode, imode, 0), doing_unsigned = 0;
3920 if (icode != CODE_FOR_nothing)
3922 to = protect_from_queue (to, 1);
3923 from = protect_from_queue (from, 0);
3925 if (imode != GET_MODE (from))
3926 from = convert_to_mode (imode, from, unsignedp);
3928 if (fmode != GET_MODE (to))
3929 target = gen_reg_rtx (fmode);
3931 emit_unop_insn (icode, target, from,
3932 doing_unsigned ? UNSIGNED_FLOAT : FLOAT);
3935 convert_move (to, target, 0);
3940 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
3942 /* Unsigned integer, and no way to convert directly.
3943 Convert as signed, then conditionally adjust the result. */
3946 rtx label = gen_label_rtx ();
3948 REAL_VALUE_TYPE offset;
3952 to = protect_from_queue (to, 1);
3953 from = protect_from_queue (from, 0);
3956 from = force_not_mem (from);
3958 /* Look for a usable floating mode FMODE wider than the source and at
3959 least as wide as the target. Using FMODE will avoid rounding woes
3960 with unsigned values greater than the signed maximum value. */
3962 for (fmode = GET_MODE (to); fmode != VOIDmode;
3963 fmode = GET_MODE_WIDER_MODE (fmode))
3964 if (GET_MODE_BITSIZE (GET_MODE (from)) < GET_MODE_BITSIZE (fmode)
3965 && can_float_p (fmode, GET_MODE (from), 0) != CODE_FOR_nothing)
3968 if (fmode == VOIDmode)
3970 /* There is no such mode. Pretend the target is wide enough. */
3971 fmode = GET_MODE (to);
3973 /* Avoid double-rounding when TO is narrower than FROM. */
3974 if ((significand_size (fmode) + 1)
3975 < GET_MODE_BITSIZE (GET_MODE (from)))
3978 rtx neglabel = gen_label_rtx ();
3980 /* Don't use TARGET if it isn't a register, is a hard register,
3981 or is the wrong mode. */
3982 if (GET_CODE (target) != REG
3983 || REGNO (target) < FIRST_PSEUDO_REGISTER
3984 || GET_MODE (target) != fmode)
3985 target = gen_reg_rtx (fmode);
3987 imode = GET_MODE (from);
3988 do_pending_stack_adjust ();
3990 /* Test whether the sign bit is set. */
3991 emit_cmp_insn (from, const0_rtx, GE, NULL_RTX, imode, 0, 0);
3992 emit_jump_insn (gen_blt (neglabel));
3994 /* The sign bit is not set. Convert as signed. */
3995 expand_float (target, from, 0);
3996 emit_jump_insn (gen_jump (label));
3999 /* The sign bit is set.
4000 Convert to a usable (positive signed) value by shifting right
4001 one bit, while remembering if a nonzero bit was shifted
4002 out; i.e., compute (from & 1) | (from >> 1). */
4004 emit_label (neglabel);
4005 temp = expand_binop (imode, and_optab, from, const1_rtx,
4006 NULL_RTX, 1, OPTAB_LIB_WIDEN);
4007 temp1 = expand_shift (RSHIFT_EXPR, imode, from, integer_one_node,
4009 temp = expand_binop (imode, ior_optab, temp, temp1, temp, 1,
4011 expand_float (target, temp, 0);
4013 /* Multiply by 2 to undo the shift above. */
4014 temp = expand_binop (fmode, add_optab, target, target,
4015 target, 0, OPTAB_LIB_WIDEN);
4017 emit_move_insn (target, temp);
4019 do_pending_stack_adjust ();
4025 /* If we are about to do some arithmetic to correct for an
4026 unsigned operand, do it in a pseudo-register. */
4028 if (GET_MODE (to) != fmode
4029 || GET_CODE (to) != REG || REGNO (to) < FIRST_PSEUDO_REGISTER)
4030 target = gen_reg_rtx (fmode);
4032 /* Convert as signed integer to floating. */
4033 expand_float (target, from, 0);
4035 /* If FROM is negative (and therefore TO is negative),
4036 correct its value by 2**bitwidth. */
4038 do_pending_stack_adjust ();
4039 emit_cmp_and_jump_insns (from, const0_rtx, GE, NULL_RTX, GET_MODE (from),
4042 /* On SCO 3.2.1, ldexp rejects values outside [0.5, 1).
4043 Rather than setting up a dconst_dot_5, let's hope SCO
4045 offset = REAL_VALUE_LDEXP (dconst1, GET_MODE_BITSIZE (GET_MODE (from)));
4046 temp = expand_binop (fmode, add_optab, target,
4047 CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode),
4048 target, 0, OPTAB_LIB_WIDEN);
4050 emit_move_insn (target, temp);
4052 do_pending_stack_adjust ();
4058 /* No hardware instruction available; call a library routine to convert from
4059 SImode, DImode, or TImode into SFmode, DFmode, XFmode, or TFmode. */
4065 to = protect_from_queue (to, 1);
4066 from = protect_from_queue (from, 0);
4068 if (GET_MODE_SIZE (GET_MODE (from)) < GET_MODE_SIZE (SImode))
4069 from = convert_to_mode (SImode, from, unsignedp);
4072 from = force_not_mem (from);
4074 if (GET_MODE (to) == SFmode)
4076 if (GET_MODE (from) == SImode)
4077 libfcn = floatsisf_libfunc;
4078 else if (GET_MODE (from) == DImode)
4079 libfcn = floatdisf_libfunc;
4080 else if (GET_MODE (from) == TImode)
4081 libfcn = floattisf_libfunc;
4085 else if (GET_MODE (to) == DFmode)
4087 if (GET_MODE (from) == SImode)
4088 libfcn = floatsidf_libfunc;
4089 else if (GET_MODE (from) == DImode)
4090 libfcn = floatdidf_libfunc;
4091 else if (GET_MODE (from) == TImode)
4092 libfcn = floattidf_libfunc;
4096 else if (GET_MODE (to) == XFmode)
4098 if (GET_MODE (from) == SImode)
4099 libfcn = floatsixf_libfunc;
4100 else if (GET_MODE (from) == DImode)
4101 libfcn = floatdixf_libfunc;
4102 else if (GET_MODE (from) == TImode)
4103 libfcn = floattixf_libfunc;
4107 else if (GET_MODE (to) == TFmode)
4109 if (GET_MODE (from) == SImode)
4110 libfcn = floatsitf_libfunc;
4111 else if (GET_MODE (from) == DImode)
4112 libfcn = floatditf_libfunc;
4113 else if (GET_MODE (from) == TImode)
4114 libfcn = floattitf_libfunc;
4123 value = emit_library_call_value (libfcn, NULL_RTX, 1,
4125 1, from, GET_MODE (from));
4126 insns = get_insns ();
4129 emit_libcall_block (insns, target, value,
4130 gen_rtx_FLOAT (GET_MODE (to), from));
4135 /* Copy result to requested destination
4136 if we have been computing in a temp location. */
4140 if (GET_MODE (target) == GET_MODE (to))
4141 emit_move_insn (to, target);
4143 convert_move (to, target, 0);
4147 /* expand_fix: generate code to convert FROM to fixed point
4148 and store in TO. FROM must be floating point. */
4154 rtx temp = gen_reg_rtx (GET_MODE (x));
4155 return expand_unop (GET_MODE (x), ftrunc_optab, x, temp, 0);
4159 expand_fix (to, from, unsignedp)
4160 register rtx to, from;
4163 enum insn_code icode;
4164 register rtx target = to;
4165 enum machine_mode fmode, imode;
4169 /* We first try to find a pair of modes, one real and one integer, at
4170 least as wide as FROM and TO, respectively, in which we can open-code
4171 this conversion. If the integer mode is wider than the mode of TO,
4172 we can do the conversion either signed or unsigned. */
4174 for (imode = GET_MODE (to); imode != VOIDmode;
4175 imode = GET_MODE_WIDER_MODE (imode))
4176 for (fmode = GET_MODE (from); fmode != VOIDmode;
4177 fmode = GET_MODE_WIDER_MODE (fmode))
4179 int doing_unsigned = unsignedp;
4181 icode = can_fix_p (imode, fmode, unsignedp, &must_trunc);
4182 if (icode == CODE_FOR_nothing && imode != GET_MODE (to) && unsignedp)
4183 icode = can_fix_p (imode, fmode, 0, &must_trunc), doing_unsigned = 0;
4185 if (icode != CODE_FOR_nothing)
4187 to = protect_from_queue (to, 1);
4188 from = protect_from_queue (from, 0);
4190 if (fmode != GET_MODE (from))
4191 from = convert_to_mode (fmode, from, 0);
4194 from = ftruncify (from);
4196 if (imode != GET_MODE (to))
4197 target = gen_reg_rtx (imode);
4199 emit_unop_insn (icode, target, from,
4200 doing_unsigned ? UNSIGNED_FIX : FIX);
4202 convert_move (to, target, unsignedp);
4207 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
4208 /* For an unsigned conversion, there is one more way to do it.
4209 If we have a signed conversion, we generate code that compares
4210 the real value to the largest representable positive number. If if
4211 is smaller, the conversion is done normally. Otherwise, subtract
4212 one plus the highest signed number, convert, and add it back.
4214 We only need to check all real modes, since we know we didn't find
4215 anything with a wider integer mode. */
4217 if (unsignedp && GET_MODE_BITSIZE (GET_MODE (to)) <= HOST_BITS_PER_WIDE_INT)
4218 for (fmode = GET_MODE (from); fmode != VOIDmode;
4219 fmode = GET_MODE_WIDER_MODE (fmode))
4220 /* Make sure we won't lose significant bits doing this. */
4221 if (GET_MODE_BITSIZE (fmode) > GET_MODE_BITSIZE (GET_MODE (to))
4222 && CODE_FOR_nothing != can_fix_p (GET_MODE (to), fmode, 0,
4226 REAL_VALUE_TYPE offset;
4227 rtx limit, lab1, lab2, insn;
4229 bitsize = GET_MODE_BITSIZE (GET_MODE (to));
4230 offset = REAL_VALUE_LDEXP (dconst1, bitsize - 1);
4231 limit = CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode);
4232 lab1 = gen_label_rtx ();
4233 lab2 = gen_label_rtx ();
4236 to = protect_from_queue (to, 1);
4237 from = protect_from_queue (from, 0);
4240 from = force_not_mem (from);
4242 if (fmode != GET_MODE (from))
4243 from = convert_to_mode (fmode, from, 0);
4245 /* See if we need to do the subtraction. */
4246 do_pending_stack_adjust ();
4247 emit_cmp_and_jump_insns (from, limit, GE, NULL_RTX, GET_MODE (from),
4250 /* If not, do the signed "fix" and branch around fixup code. */
4251 expand_fix (to, from, 0);
4252 emit_jump_insn (gen_jump (lab2));
4255 /* Otherwise, subtract 2**(N-1), convert to signed number,
4256 then add 2**(N-1). Do the addition using XOR since this
4257 will often generate better code. */
4259 target = expand_binop (GET_MODE (from), sub_optab, from, limit,
4260 NULL_RTX, 0, OPTAB_LIB_WIDEN);
4261 expand_fix (to, target, 0);
4262 target = expand_binop (GET_MODE (to), xor_optab, to,
4263 GEN_INT ((HOST_WIDE_INT) 1 << (bitsize - 1)),
4264 to, 1, OPTAB_LIB_WIDEN);
4267 emit_move_insn (to, target);
4271 if (mov_optab->handlers[(int) GET_MODE (to)].insn_code
4272 != CODE_FOR_nothing)
4274 /* Make a place for a REG_NOTE and add it. */
4275 insn = emit_move_insn (to, to);
4276 set_unique_reg_note (insn,
4278 gen_rtx_fmt_e (UNSIGNED_FIX,
4286 /* We can't do it with an insn, so use a library call. But first ensure
4287 that the mode of TO is at least as wide as SImode, since those are the
4288 only library calls we know about. */
4290 if (GET_MODE_SIZE (GET_MODE (to)) < GET_MODE_SIZE (SImode))
4292 target = gen_reg_rtx (SImode);
4294 expand_fix (target, from, unsignedp);
4296 else if (GET_MODE (from) == SFmode)
4298 if (GET_MODE (to) == SImode)
4299 libfcn = unsignedp ? fixunssfsi_libfunc : fixsfsi_libfunc;
4300 else if (GET_MODE (to) == DImode)
4301 libfcn = unsignedp ? fixunssfdi_libfunc : fixsfdi_libfunc;
4302 else if (GET_MODE (to) == TImode)
4303 libfcn = unsignedp ? fixunssfti_libfunc : fixsfti_libfunc;
4307 else if (GET_MODE (from) == DFmode)
4309 if (GET_MODE (to) == SImode)
4310 libfcn = unsignedp ? fixunsdfsi_libfunc : fixdfsi_libfunc;
4311 else if (GET_MODE (to) == DImode)
4312 libfcn = unsignedp ? fixunsdfdi_libfunc : fixdfdi_libfunc;
4313 else if (GET_MODE (to) == TImode)
4314 libfcn = unsignedp ? fixunsdfti_libfunc : fixdfti_libfunc;
4318 else if (GET_MODE (from) == XFmode)
4320 if (GET_MODE (to) == SImode)
4321 libfcn = unsignedp ? fixunsxfsi_libfunc : fixxfsi_libfunc;
4322 else if (GET_MODE (to) == DImode)
4323 libfcn = unsignedp ? fixunsxfdi_libfunc : fixxfdi_libfunc;
4324 else if (GET_MODE (to) == TImode)
4325 libfcn = unsignedp ? fixunsxfti_libfunc : fixxfti_libfunc;
4329 else if (GET_MODE (from) == TFmode)
4331 if (GET_MODE (to) == SImode)
4332 libfcn = unsignedp ? fixunstfsi_libfunc : fixtfsi_libfunc;
4333 else if (GET_MODE (to) == DImode)
4334 libfcn = unsignedp ? fixunstfdi_libfunc : fixtfdi_libfunc;
4335 else if (GET_MODE (to) == TImode)
4336 libfcn = unsignedp ? fixunstfti_libfunc : fixtfti_libfunc;
4348 to = protect_from_queue (to, 1);
4349 from = protect_from_queue (from, 0);
4352 from = force_not_mem (from);
4356 value = emit_library_call_value (libfcn, NULL_RTX, 1, GET_MODE (to),
4358 1, from, GET_MODE (from));
4359 insns = get_insns ();
4362 emit_libcall_block (insns, target, value,
4363 gen_rtx_fmt_e (unsignedp ? UNSIGNED_FIX : FIX,
4364 GET_MODE (to), from));
4369 if (GET_MODE (to) == GET_MODE (target))
4370 emit_move_insn (to, target);
4372 convert_move (to, target, 0);
4381 optab op = (optab) xmalloc (sizeof (struct optab));
4383 for (i = 0; i < NUM_MACHINE_MODES; i++)
4385 op->handlers[i].insn_code = CODE_FOR_nothing;
4386 op->handlers[i].libfunc = 0;
4389 if (code != UNKNOWN)
4390 code_to_optab[(int) code] = op;
4395 /* Initialize the libfunc fields of an entire group of entries in some
4396 optab. Each entry is set equal to a string consisting of a leading
4397 pair of underscores followed by a generic operation name followed by
4398 a mode name (downshifted to lower case) followed by a single character
4399 representing the number of operands for the given operation (which is
4400 usually one of the characters '2', '3', or '4').
4402 OPTABLE is the table in which libfunc fields are to be initialized.
4403 FIRST_MODE is the first machine mode index in the given optab to
4405 LAST_MODE is the last machine mode index in the given optab to
4407 OPNAME is the generic (string) name of the operation.
4408 SUFFIX is the character which specifies the number of operands for
4409 the given generic operation.
4413 init_libfuncs (optable, first_mode, last_mode, opname, suffix)
4414 register optab optable;
4415 register int first_mode;
4416 register int last_mode;
4417 register const char *opname;
4418 register int suffix;
4421 register unsigned opname_len = strlen (opname);
4423 for (mode = first_mode; (int) mode <= (int) last_mode;
4424 mode = (enum machine_mode) ((int) mode + 1))
4426 register char *mname = mode_name[(int) mode];
4427 register unsigned mname_len = strlen (mname);
4428 register char *libfunc_name
4429 = (char *) xmalloc (2 + opname_len + mname_len + 1 + 1);
4431 register const char *q;
4436 for (q = opname; *q; )
4438 for (q = mname; *q; q++)
4439 *p++ = tolower ((unsigned char)*q);
4442 optable->handlers[(int) mode].libfunc
4443 = gen_rtx_SYMBOL_REF (Pmode, libfunc_name);
4447 /* Initialize the libfunc fields of an entire group of entries in some
4448 optab which correspond to all integer mode operations. The parameters
4449 have the same meaning as similarly named ones for the `init_libfuncs'
4450 routine. (See above). */
4453 init_integral_libfuncs (optable, opname, suffix)
4454 register optab optable;
4455 register const char *opname;
4456 register int suffix;
4458 init_libfuncs (optable, SImode, TImode, opname, suffix);
4461 /* Initialize the libfunc fields of an entire group of entries in some
4462 optab which correspond to all real mode operations. The parameters
4463 have the same meaning as similarly named ones for the `init_libfuncs'
4464 routine. (See above). */
4467 init_floating_libfuncs (optable, opname, suffix)
4468 register optab optable;
4469 register const char *opname;
4470 register int suffix;
4472 init_libfuncs (optable, SFmode, TFmode, opname, suffix);
4476 /* Call this once to initialize the contents of the optabs
4477 appropriately for the current target machine. */
4483 #ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC
4489 /* Start by initializing all tables to contain CODE_FOR_nothing. */
4491 for (p = fixtab[0][0];
4492 p < fixtab[0][0] + sizeof fixtab / sizeof (fixtab[0][0][0]);
4494 *p = CODE_FOR_nothing;
4496 for (p = fixtrunctab[0][0];
4497 p < fixtrunctab[0][0] + sizeof fixtrunctab / sizeof (fixtrunctab[0][0][0]);
4499 *p = CODE_FOR_nothing;
4501 for (p = floattab[0][0];
4502 p < floattab[0][0] + sizeof floattab / sizeof (floattab[0][0][0]);
4504 *p = CODE_FOR_nothing;
4506 for (p = extendtab[0][0];
4507 p < extendtab[0][0] + sizeof extendtab / sizeof extendtab[0][0][0];
4509 *p = CODE_FOR_nothing;
4511 for (i = 0; i < NUM_RTX_CODE; i++)
4512 setcc_gen_code[i] = CODE_FOR_nothing;
4514 #ifdef HAVE_conditional_move
4515 for (i = 0; i < NUM_MACHINE_MODES; i++)
4516 movcc_gen_code[i] = CODE_FOR_nothing;
4519 add_optab = init_optab (PLUS);
4520 sub_optab = init_optab (MINUS);
4521 smul_optab = init_optab (MULT);
4522 smul_highpart_optab = init_optab (UNKNOWN);
4523 umul_highpart_optab = init_optab (UNKNOWN);
4524 smul_widen_optab = init_optab (UNKNOWN);
4525 umul_widen_optab = init_optab (UNKNOWN);
4526 sdiv_optab = init_optab (DIV);
4527 sdivmod_optab = init_optab (UNKNOWN);
4528 udiv_optab = init_optab (UDIV);
4529 udivmod_optab = init_optab (UNKNOWN);
4530 smod_optab = init_optab (MOD);
4531 umod_optab = init_optab (UMOD);
4532 flodiv_optab = init_optab (DIV);
4533 ftrunc_optab = init_optab (UNKNOWN);
4534 and_optab = init_optab (AND);
4535 ior_optab = init_optab (IOR);
4536 xor_optab = init_optab (XOR);
4537 ashl_optab = init_optab (ASHIFT);
4538 ashr_optab = init_optab (ASHIFTRT);
4539 lshr_optab = init_optab (LSHIFTRT);
4540 rotl_optab = init_optab (ROTATE);
4541 rotr_optab = init_optab (ROTATERT);
4542 smin_optab = init_optab (SMIN);
4543 smax_optab = init_optab (SMAX);
4544 umin_optab = init_optab (UMIN);
4545 umax_optab = init_optab (UMAX);
4546 mov_optab = init_optab (UNKNOWN);
4547 movstrict_optab = init_optab (UNKNOWN);
4548 cmp_optab = init_optab (UNKNOWN);
4549 ucmp_optab = init_optab (UNKNOWN);
4550 tst_optab = init_optab (UNKNOWN);
4551 neg_optab = init_optab (NEG);
4552 abs_optab = init_optab (ABS);
4553 one_cmpl_optab = init_optab (NOT);
4554 ffs_optab = init_optab (FFS);
4555 sqrt_optab = init_optab (SQRT);
4556 sin_optab = init_optab (UNKNOWN);
4557 cos_optab = init_optab (UNKNOWN);
4558 strlen_optab = init_optab (UNKNOWN);
4560 for (i = 0; i < NUM_MACHINE_MODES; i++)
4562 movstr_optab[i] = CODE_FOR_nothing;
4563 clrstr_optab[i] = CODE_FOR_nothing;
4565 #ifdef HAVE_SECONDARY_RELOADS
4566 reload_in_optab[i] = reload_out_optab[i] = CODE_FOR_nothing;
4570 /* Fill in the optabs with the insns we support. */
4573 #ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC
4574 /* This flag says the same insns that convert to a signed fixnum
4575 also convert validly to an unsigned one. */
4576 for (i = 0; i < NUM_MACHINE_MODES; i++)
4577 for (j = 0; j < NUM_MACHINE_MODES; j++)
4578 fixtrunctab[i][j][1] = fixtrunctab[i][j][0];
4581 #ifdef EXTRA_CC_MODES
4585 /* Initialize the optabs with the names of the library functions. */
4586 init_integral_libfuncs (add_optab, "add", '3');
4587 init_floating_libfuncs (add_optab, "add", '3');
4588 init_integral_libfuncs (sub_optab, "sub", '3');
4589 init_floating_libfuncs (sub_optab, "sub", '3');
4590 init_integral_libfuncs (smul_optab, "mul", '3');
4591 init_floating_libfuncs (smul_optab, "mul", '3');
4592 init_integral_libfuncs (sdiv_optab, "div", '3');
4593 init_integral_libfuncs (udiv_optab, "udiv", '3');
4594 init_integral_libfuncs (sdivmod_optab, "divmod", '4');
4595 init_integral_libfuncs (udivmod_optab, "udivmod", '4');
4596 init_integral_libfuncs (smod_optab, "mod", '3');
4597 init_integral_libfuncs (umod_optab, "umod", '3');
4598 init_floating_libfuncs (flodiv_optab, "div", '3');
4599 init_floating_libfuncs (ftrunc_optab, "ftrunc", '2');
4600 init_integral_libfuncs (and_optab, "and", '3');
4601 init_integral_libfuncs (ior_optab, "ior", '3');
4602 init_integral_libfuncs (xor_optab, "xor", '3');
4603 init_integral_libfuncs (ashl_optab, "ashl", '3');
4604 init_integral_libfuncs (ashr_optab, "ashr", '3');
4605 init_integral_libfuncs (lshr_optab, "lshr", '3');
4606 init_integral_libfuncs (smin_optab, "min", '3');
4607 init_floating_libfuncs (smin_optab, "min", '3');
4608 init_integral_libfuncs (smax_optab, "max", '3');
4609 init_floating_libfuncs (smax_optab, "max", '3');
4610 init_integral_libfuncs (umin_optab, "umin", '3');
4611 init_integral_libfuncs (umax_optab, "umax", '3');
4612 init_integral_libfuncs (neg_optab, "neg", '2');
4613 init_floating_libfuncs (neg_optab, "neg", '2');
4614 init_integral_libfuncs (one_cmpl_optab, "one_cmpl", '2');
4615 init_integral_libfuncs (ffs_optab, "ffs", '2');
4617 /* Comparison libcalls for integers MUST come in pairs, signed/unsigned. */
4618 init_integral_libfuncs (cmp_optab, "cmp", '2');
4619 init_integral_libfuncs (ucmp_optab, "ucmp", '2');
4620 init_floating_libfuncs (cmp_optab, "cmp", '2');
4622 #ifdef MULSI3_LIBCALL
4623 smul_optab->handlers[(int) SImode].libfunc
4624 = gen_rtx_SYMBOL_REF (Pmode, MULSI3_LIBCALL);
4626 #ifdef MULDI3_LIBCALL
4627 smul_optab->handlers[(int) DImode].libfunc
4628 = gen_rtx_SYMBOL_REF (Pmode, MULDI3_LIBCALL);
4631 #ifdef DIVSI3_LIBCALL
4632 sdiv_optab->handlers[(int) SImode].libfunc
4633 = gen_rtx_SYMBOL_REF (Pmode, DIVSI3_LIBCALL);
4635 #ifdef DIVDI3_LIBCALL
4636 sdiv_optab->handlers[(int) DImode].libfunc
4637 = gen_rtx_SYMBOL_REF (Pmode, DIVDI3_LIBCALL);
4640 #ifdef UDIVSI3_LIBCALL
4641 udiv_optab->handlers[(int) SImode].libfunc
4642 = gen_rtx_SYMBOL_REF (Pmode, UDIVSI3_LIBCALL);
4644 #ifdef UDIVDI3_LIBCALL
4645 udiv_optab->handlers[(int) DImode].libfunc
4646 = gen_rtx_SYMBOL_REF (Pmode, UDIVDI3_LIBCALL);
4649 #ifdef MODSI3_LIBCALL
4650 smod_optab->handlers[(int) SImode].libfunc
4651 = gen_rtx_SYMBOL_REF (Pmode, MODSI3_LIBCALL);
4653 #ifdef MODDI3_LIBCALL
4654 smod_optab->handlers[(int) DImode].libfunc
4655 = gen_rtx_SYMBOL_REF (Pmode, MODDI3_LIBCALL);
4658 #ifdef UMODSI3_LIBCALL
4659 umod_optab->handlers[(int) SImode].libfunc
4660 = gen_rtx_SYMBOL_REF (Pmode, UMODSI3_LIBCALL);
4662 #ifdef UMODDI3_LIBCALL
4663 umod_optab->handlers[(int) DImode].libfunc
4664 = gen_rtx_SYMBOL_REF (Pmode, UMODDI3_LIBCALL);
4667 /* Use cabs for DC complex abs, since systems generally have cabs.
4668 Don't define any libcall for SCmode, so that cabs will be used. */
4669 abs_optab->handlers[(int) DCmode].libfunc
4670 = gen_rtx_SYMBOL_REF (Pmode, "cabs");
4672 /* The ffs function operates on `int'. */
4673 #ifndef INT_TYPE_SIZE
4674 #define INT_TYPE_SIZE BITS_PER_WORD
4676 ffs_optab->handlers[(int) mode_for_size (INT_TYPE_SIZE, MODE_INT, 0)] .libfunc
4677 = gen_rtx_SYMBOL_REF (Pmode, "ffs");
4679 extendsfdf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__extendsfdf2");
4680 extendsfxf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__extendsfxf2");
4681 extendsftf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__extendsftf2");
4682 extenddfxf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__extenddfxf2");
4683 extenddftf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__extenddftf2");
4685 truncdfsf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__truncdfsf2");
4686 truncxfsf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__truncxfsf2");
4687 trunctfsf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__trunctfsf2");
4688 truncxfdf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__truncxfdf2");
4689 trunctfdf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__trunctfdf2");
4691 memcpy_libfunc = gen_rtx_SYMBOL_REF (Pmode, "memcpy");
4692 bcopy_libfunc = gen_rtx_SYMBOL_REF (Pmode, "bcopy");
4693 memcmp_libfunc = gen_rtx_SYMBOL_REF (Pmode, "memcmp");
4694 bcmp_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__gcc_bcmp");
4695 memset_libfunc = gen_rtx_SYMBOL_REF (Pmode, "memset");
4696 bzero_libfunc = gen_rtx_SYMBOL_REF (Pmode, "bzero");
4698 throw_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__throw");
4699 rethrow_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__rethrow");
4700 sjthrow_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__sjthrow");
4701 sjpopnthrow_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__sjpopnthrow");
4702 terminate_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__terminate");
4703 eh_rtime_match_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__eh_rtime_match");
4704 #ifndef DONT_USE_BUILTIN_SETJMP
4705 setjmp_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__builtin_setjmp");
4706 longjmp_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__builtin_longjmp");
4708 setjmp_libfunc = gen_rtx_SYMBOL_REF (Pmode, "setjmp");
4709 longjmp_libfunc = gen_rtx_SYMBOL_REF (Pmode, "longjmp");
4712 eqhf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__eqhf2");
4713 nehf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__nehf2");
4714 gthf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__gthf2");
4715 gehf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__gehf2");
4716 lthf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__lthf2");
4717 lehf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__lehf2");
4719 eqsf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__eqsf2");
4720 nesf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__nesf2");
4721 gtsf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__gtsf2");
4722 gesf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__gesf2");
4723 ltsf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__ltsf2");
4724 lesf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__lesf2");
4726 eqdf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__eqdf2");
4727 nedf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__nedf2");
4728 gtdf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__gtdf2");
4729 gedf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__gedf2");
4730 ltdf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__ltdf2");
4731 ledf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__ledf2");
4733 eqxf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__eqxf2");
4734 nexf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__nexf2");
4735 gtxf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__gtxf2");
4736 gexf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__gexf2");
4737 ltxf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__ltxf2");
4738 lexf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__lexf2");
4740 eqtf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__eqtf2");
4741 netf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__netf2");
4742 gttf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__gttf2");
4743 getf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__getf2");
4744 lttf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__lttf2");
4745 letf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__letf2");
4747 floatsisf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floatsisf");
4748 floatdisf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floatdisf");
4749 floattisf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floattisf");
4751 floatsidf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floatsidf");
4752 floatdidf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floatdidf");
4753 floattidf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floattidf");
4755 floatsixf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floatsixf");
4756 floatdixf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floatdixf");
4757 floattixf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floattixf");
4759 floatsitf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floatsitf");
4760 floatditf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floatditf");
4761 floattitf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floattitf");
4763 fixsfsi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixsfsi");
4764 fixsfdi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixsfdi");
4765 fixsfti_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixsfti");
4767 fixdfsi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixdfsi");
4768 fixdfdi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixdfdi");
4769 fixdfti_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixdfti");
4771 fixxfsi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixxfsi");
4772 fixxfdi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixxfdi");
4773 fixxfti_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixxfti");
4775 fixtfsi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixtfsi");
4776 fixtfdi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixtfdi");
4777 fixtfti_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixtfti");
4779 fixunssfsi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunssfsi");
4780 fixunssfdi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunssfdi");
4781 fixunssfti_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunssfti");
4783 fixunsdfsi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunsdfsi");
4784 fixunsdfdi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunsdfdi");
4785 fixunsdfti_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunsdfti");
4787 fixunsxfsi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunsxfsi");
4788 fixunsxfdi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunsxfdi");
4789 fixunsxfti_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunsxfti");
4791 fixunstfsi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunstfsi");
4792 fixunstfdi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunstfdi");
4793 fixunstfti_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunstfti");
4795 /* For check-memory-usage. */
4796 chkr_check_addr_libfunc = gen_rtx_SYMBOL_REF (Pmode, "chkr_check_addr");
4797 chkr_set_right_libfunc = gen_rtx_SYMBOL_REF (Pmode, "chkr_set_right");
4798 chkr_copy_bitmap_libfunc = gen_rtx_SYMBOL_REF (Pmode, "chkr_copy_bitmap");
4799 chkr_check_exec_libfunc = gen_rtx_SYMBOL_REF (Pmode, "chkr_check_exec");
4800 chkr_check_str_libfunc = gen_rtx_SYMBOL_REF (Pmode, "chkr_check_str");
4802 /* For function entry/exit instrumentation. */
4803 profile_function_entry_libfunc
4804 = gen_rtx_SYMBOL_REF (Pmode, "__cyg_profile_func_enter");
4805 profile_function_exit_libfunc
4806 = gen_rtx_SYMBOL_REF (Pmode, "__cyg_profile_func_exit");
4808 #ifdef HAVE_conditional_trap
4812 #ifdef INIT_TARGET_OPTABS
4813 /* Allow the target to add more libcalls or rename some, etc. */
4820 /* SCO 3.2 apparently has a broken ldexp. */
4833 #endif /* BROKEN_LDEXP */
4835 #ifdef HAVE_conditional_trap
4836 /* The insn generating function can not take an rtx_code argument.
4837 TRAP_RTX is used as an rtx argument. Its code is replaced with
4838 the code to be used in the trap insn and all other fields are
4841 ??? Will need to change to support garbage collection. */
4842 static rtx trap_rtx;
4847 if (HAVE_conditional_trap)
4848 trap_rtx = gen_rtx_fmt_ee (EQ, VOIDmode, NULL_RTX, NULL_RTX);
4852 /* Generate insns to trap with code TCODE if OP1 and OP2 satisfy condition
4853 CODE. Return 0 on failure. */
4856 gen_cond_trap (code, op1, op2, tcode)
4857 enum rtx_code code ATTRIBUTE_UNUSED;
4858 rtx op1, op2 ATTRIBUTE_UNUSED, tcode ATTRIBUTE_UNUSED;
4860 enum machine_mode mode = GET_MODE (op1);
4862 if (mode == VOIDmode)
4865 #ifdef HAVE_conditional_trap
4866 if (HAVE_conditional_trap
4867 && cmp_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
4870 emit_insn (GEN_FCN (cmp_optab->handlers[(int) mode].insn_code) (op1, op2));
4871 PUT_CODE (trap_rtx, code);
4872 insn = gen_conditional_trap (trap_rtx, tcode);