1 /* Expand the basic unary and binary arithmetic operations, for GNU compiler.
2 Copyright (C) 1987, 88, 92-98, 1999 Free Software Foundation, Inc.
4 This file is part of GNU CC.
6 GNU CC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU CC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU CC; see the file COPYING. If not, write to
18 the Free Software Foundation, 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
26 /* Include insn-config.h before expr.h so that HAVE_conditional_move
27 is properly defined. */
28 #include "insn-config.h"
32 #include "insn-flags.h"
33 #include "insn-codes.h"
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);
777 op0 = force_not_mem (op0);
778 op1 = force_not_mem (op1);
781 /* If subtracting an integer constant, convert this into an addition of
782 the negated constant. */
784 if (binoptab == sub_optab && GET_CODE (op1) == CONST_INT)
786 op1 = negate_rtx (mode, op1);
787 binoptab = add_optab;
790 /* If we are inside an appropriately-short loop and one operand is an
791 expensive constant, force it into a register. */
792 if (CONSTANT_P (op0) && preserve_subexpressions_p ()
793 && rtx_cost (op0, binoptab->code) > 2)
794 op0 = force_reg (mode, op0);
796 if (CONSTANT_P (op1) && preserve_subexpressions_p ()
797 && ! shift_op && rtx_cost (op1, binoptab->code) > 2)
798 op1 = force_reg (mode, op1);
800 /* Record where to delete back to if we backtrack. */
801 last = get_last_insn ();
803 /* If operation is commutative,
804 try to make the first operand a register.
805 Even better, try to make it the same as the target.
806 Also try to make the last operand a constant. */
807 if (GET_RTX_CLASS (binoptab->code) == 'c'
808 || binoptab == smul_widen_optab
809 || binoptab == umul_widen_optab
810 || binoptab == smul_highpart_optab
811 || binoptab == umul_highpart_optab)
815 if (((target == 0 || GET_CODE (target) == REG)
816 ? ((GET_CODE (op1) == REG
817 && GET_CODE (op0) != REG)
819 : rtx_equal_p (op1, target))
820 || GET_CODE (op0) == CONST_INT)
828 /* If we can do it with a three-operand insn, do so. */
830 if (methods != OPTAB_MUST_WIDEN
831 && binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
833 int icode = (int) binoptab->handlers[(int) mode].insn_code;
834 enum machine_mode mode0 = insn_operand_mode[icode][1];
835 enum machine_mode mode1 = insn_operand_mode[icode][2];
837 rtx xop0 = op0, xop1 = op1;
842 temp = gen_reg_rtx (mode);
844 /* If it is a commutative operator and the modes would match
845 if we would swap the operands, we can save the conversions. */
848 if (GET_MODE (op0) != mode0 && GET_MODE (op1) != mode1
849 && GET_MODE (op0) == mode1 && GET_MODE (op1) == mode0)
853 tmp = op0; op0 = op1; op1 = tmp;
854 tmp = xop0; xop0 = xop1; xop1 = tmp;
858 /* In case the insn wants input operands in modes different from
859 the result, convert the operands. */
861 if (GET_MODE (op0) != VOIDmode
862 && GET_MODE (op0) != mode0
863 && mode0 != VOIDmode)
864 xop0 = convert_to_mode (mode0, xop0, unsignedp);
866 if (GET_MODE (xop1) != VOIDmode
867 && GET_MODE (xop1) != mode1
868 && mode1 != VOIDmode)
869 xop1 = convert_to_mode (mode1, xop1, unsignedp);
871 /* Now, if insn's predicates don't allow our operands, put them into
874 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0)
875 && mode0 != VOIDmode)
876 xop0 = copy_to_mode_reg (mode0, xop0);
878 if (! (*insn_operand_predicate[icode][2]) (xop1, mode1)
879 && mode1 != VOIDmode)
880 xop1 = copy_to_mode_reg (mode1, xop1);
882 if (! (*insn_operand_predicate[icode][0]) (temp, mode))
883 temp = gen_reg_rtx (mode);
885 pat = GEN_FCN (icode) (temp, xop0, xop1);
888 /* If PAT is a multi-insn sequence, try to add an appropriate
889 REG_EQUAL note to it. If we can't because TEMP conflicts with an
890 operand, call ourselves again, this time without a target. */
891 if (GET_CODE (pat) == SEQUENCE
892 && ! add_equal_note (pat, temp, binoptab->code, xop0, xop1))
894 delete_insns_since (last);
895 return expand_binop (mode, binoptab, op0, op1, NULL_RTX,
903 delete_insns_since (last);
906 /* If this is a multiply, see if we can do a widening operation that
907 takes operands of this mode and makes a wider mode. */
909 if (binoptab == smul_optab && GET_MODE_WIDER_MODE (mode) != VOIDmode
910 && (((unsignedp ? umul_widen_optab : smul_widen_optab)
911 ->handlers[(int) GET_MODE_WIDER_MODE (mode)].insn_code)
912 != CODE_FOR_nothing))
914 temp = expand_binop (GET_MODE_WIDER_MODE (mode),
915 unsignedp ? umul_widen_optab : smul_widen_optab,
916 op0, op1, NULL_RTX, unsignedp, OPTAB_DIRECT);
920 if (GET_MODE_CLASS (mode) == MODE_INT)
921 return gen_lowpart (mode, temp);
923 return convert_to_mode (mode, temp, unsignedp);
927 /* Look for a wider mode of the same class for which we think we
928 can open-code the operation. Check for a widening multiply at the
929 wider mode as well. */
931 if ((class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
932 && methods != OPTAB_DIRECT && methods != OPTAB_LIB)
933 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
934 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
936 if (binoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing
937 || (binoptab == smul_optab
938 && GET_MODE_WIDER_MODE (wider_mode) != VOIDmode
939 && (((unsignedp ? umul_widen_optab : smul_widen_optab)
940 ->handlers[(int) GET_MODE_WIDER_MODE (wider_mode)].insn_code)
941 != CODE_FOR_nothing)))
943 rtx xop0 = op0, xop1 = op1;
946 /* For certain integer operations, we need not actually extend
947 the narrow operands, as long as we will truncate
948 the results to the same narrowness. */
950 if ((binoptab == ior_optab || binoptab == and_optab
951 || binoptab == xor_optab
952 || binoptab == add_optab || binoptab == sub_optab
953 || binoptab == smul_optab || binoptab == ashl_optab)
954 && class == MODE_INT)
957 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp, no_extend);
959 /* The second operand of a shift must always be extended. */
960 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
961 no_extend && binoptab != ashl_optab);
963 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
964 unsignedp, OPTAB_DIRECT);
967 if (class != MODE_INT)
970 target = gen_reg_rtx (mode);
971 convert_move (target, temp, 0);
975 return gen_lowpart (mode, temp);
978 delete_insns_since (last);
982 /* These can be done a word at a time. */
983 if ((binoptab == and_optab || binoptab == ior_optab || binoptab == xor_optab)
985 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
986 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
992 /* If TARGET is the same as one of the operands, the REG_EQUAL note
993 won't be accurate, so use a new target. */
994 if (target == 0 || target == op0 || target == op1)
995 target = gen_reg_rtx (mode);
999 /* Do the actual arithmetic. */
1000 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
1002 rtx target_piece = operand_subword (target, i, 1, mode);
1003 rtx x = expand_binop (word_mode, binoptab,
1004 operand_subword_force (op0, i, mode),
1005 operand_subword_force (op1, i, mode),
1006 target_piece, unsignedp, next_methods);
1011 if (target_piece != x)
1012 emit_move_insn (target_piece, x);
1015 insns = get_insns ();
1018 if (i == GET_MODE_BITSIZE (mode) / BITS_PER_WORD)
1020 if (binoptab->code != UNKNOWN)
1022 = gen_rtx_fmt_ee (binoptab->code, mode,
1023 copy_rtx (op0), copy_rtx (op1));
1027 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
1032 /* Synthesize double word shifts from single word shifts. */
1033 if ((binoptab == lshr_optab || binoptab == ashl_optab
1034 || binoptab == ashr_optab)
1035 && class == MODE_INT
1036 && GET_CODE (op1) == CONST_INT
1037 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
1038 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
1039 && ashl_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
1040 && lshr_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
1042 rtx insns, inter, equiv_value;
1043 rtx into_target, outof_target;
1044 rtx into_input, outof_input;
1045 int shift_count, left_shift, outof_word;
1047 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1048 won't be accurate, so use a new target. */
1049 if (target == 0 || target == op0 || target == op1)
1050 target = gen_reg_rtx (mode);
1054 shift_count = INTVAL (op1);
1056 /* OUTOF_* is the word we are shifting bits away from, and
1057 INTO_* is the word that we are shifting bits towards, thus
1058 they differ depending on the direction of the shift and
1059 WORDS_BIG_ENDIAN. */
1061 left_shift = binoptab == ashl_optab;
1062 outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
1064 outof_target = operand_subword (target, outof_word, 1, mode);
1065 into_target = operand_subword (target, 1 - outof_word, 1, mode);
1067 outof_input = operand_subword_force (op0, outof_word, mode);
1068 into_input = operand_subword_force (op0, 1 - outof_word, mode);
1070 if (shift_count >= BITS_PER_WORD)
1072 inter = expand_binop (word_mode, binoptab,
1074 GEN_INT (shift_count - BITS_PER_WORD),
1075 into_target, unsignedp, next_methods);
1077 if (inter != 0 && inter != into_target)
1078 emit_move_insn (into_target, inter);
1080 /* For a signed right shift, we must fill the word we are shifting
1081 out of with copies of the sign bit. Otherwise it is zeroed. */
1082 if (inter != 0 && binoptab != ashr_optab)
1083 inter = CONST0_RTX (word_mode);
1084 else if (inter != 0)
1085 inter = expand_binop (word_mode, binoptab,
1087 GEN_INT (BITS_PER_WORD - 1),
1088 outof_target, unsignedp, next_methods);
1090 if (inter != 0 && inter != outof_target)
1091 emit_move_insn (outof_target, inter);
1096 optab reverse_unsigned_shift, unsigned_shift;
1098 /* For a shift of less then BITS_PER_WORD, to compute the carry,
1099 we must do a logical shift in the opposite direction of the
1102 reverse_unsigned_shift = (left_shift ? lshr_optab : ashl_optab);
1104 /* For a shift of less than BITS_PER_WORD, to compute the word
1105 shifted towards, we need to unsigned shift the orig value of
1108 unsigned_shift = (left_shift ? ashl_optab : lshr_optab);
1110 carries = expand_binop (word_mode, reverse_unsigned_shift,
1112 GEN_INT (BITS_PER_WORD - shift_count),
1113 0, unsignedp, next_methods);
1118 inter = expand_binop (word_mode, unsigned_shift, into_input,
1119 op1, 0, unsignedp, next_methods);
1122 inter = expand_binop (word_mode, ior_optab, carries, inter,
1123 into_target, unsignedp, next_methods);
1125 if (inter != 0 && inter != into_target)
1126 emit_move_insn (into_target, inter);
1129 inter = expand_binop (word_mode, binoptab, outof_input,
1130 op1, outof_target, unsignedp, next_methods);
1132 if (inter != 0 && inter != outof_target)
1133 emit_move_insn (outof_target, inter);
1136 insns = get_insns ();
1141 if (binoptab->code != UNKNOWN)
1142 equiv_value = gen_rtx_fmt_ee (binoptab->code, mode, op0, op1);
1146 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
1151 /* Synthesize double word rotates from single word shifts. */
1152 if ((binoptab == rotl_optab || binoptab == rotr_optab)
1153 && class == MODE_INT
1154 && GET_CODE (op1) == CONST_INT
1155 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
1156 && ashl_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
1157 && lshr_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
1159 rtx insns, equiv_value;
1160 rtx into_target, outof_target;
1161 rtx into_input, outof_input;
1163 int shift_count, left_shift, outof_word;
1165 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1166 won't be accurate, so use a new target. */
1167 if (target == 0 || target == op0 || target == op1)
1168 target = gen_reg_rtx (mode);
1172 shift_count = INTVAL (op1);
1174 /* OUTOF_* is the word we are shifting bits away from, and
1175 INTO_* is the word that we are shifting bits towards, thus
1176 they differ depending on the direction of the shift and
1177 WORDS_BIG_ENDIAN. */
1179 left_shift = (binoptab == rotl_optab);
1180 outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
1182 outof_target = operand_subword (target, outof_word, 1, mode);
1183 into_target = operand_subword (target, 1 - outof_word, 1, mode);
1185 outof_input = operand_subword_force (op0, outof_word, mode);
1186 into_input = operand_subword_force (op0, 1 - outof_word, mode);
1188 if (shift_count == BITS_PER_WORD)
1190 /* This is just a word swap. */
1191 emit_move_insn (outof_target, into_input);
1192 emit_move_insn (into_target, outof_input);
1197 rtx into_temp1, into_temp2, outof_temp1, outof_temp2;
1198 rtx first_shift_count, second_shift_count;
1199 optab reverse_unsigned_shift, unsigned_shift;
1201 reverse_unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
1202 ? lshr_optab : ashl_optab);
1204 unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
1205 ? ashl_optab : lshr_optab);
1207 if (shift_count > BITS_PER_WORD)
1209 first_shift_count = GEN_INT (shift_count - BITS_PER_WORD);
1210 second_shift_count = GEN_INT (2*BITS_PER_WORD - shift_count);
1214 first_shift_count = GEN_INT (BITS_PER_WORD - shift_count);
1215 second_shift_count = GEN_INT (shift_count);
1218 into_temp1 = expand_binop (word_mode, unsigned_shift,
1219 outof_input, first_shift_count,
1220 NULL_RTX, unsignedp, next_methods);
1221 into_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
1222 into_input, second_shift_count,
1223 into_target, unsignedp, next_methods);
1225 if (into_temp1 != 0 && into_temp2 != 0)
1226 inter = expand_binop (word_mode, ior_optab, into_temp1, into_temp2,
1227 into_target, unsignedp, next_methods);
1231 if (inter != 0 && inter != into_target)
1232 emit_move_insn (into_target, inter);
1234 outof_temp1 = expand_binop (word_mode, unsigned_shift,
1235 into_input, first_shift_count,
1236 NULL_RTX, unsignedp, next_methods);
1237 outof_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
1238 outof_input, second_shift_count,
1239 outof_target, unsignedp, next_methods);
1241 if (inter != 0 && outof_temp1 != 0 && outof_temp2 != 0)
1242 inter = expand_binop (word_mode, ior_optab,
1243 outof_temp1, outof_temp2,
1244 outof_target, unsignedp, next_methods);
1246 if (inter != 0 && inter != outof_target)
1247 emit_move_insn (outof_target, inter);
1250 insns = get_insns ();
1255 if (binoptab->code != UNKNOWN)
1256 equiv_value = gen_rtx_fmt_ee (binoptab->code, mode, op0, op1);
1260 /* We can't make this a no conflict block if this is a word swap,
1261 because the word swap case fails if the input and output values
1262 are in the same register. */
1263 if (shift_count != BITS_PER_WORD)
1264 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
1273 /* These can be done a word at a time by propagating carries. */
1274 if ((binoptab == add_optab || binoptab == sub_optab)
1275 && class == MODE_INT
1276 && GET_MODE_SIZE (mode) >= 2 * UNITS_PER_WORD
1277 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
1280 rtx carry_tmp = gen_reg_rtx (word_mode);
1281 optab otheroptab = binoptab == add_optab ? sub_optab : add_optab;
1282 int nwords = GET_MODE_BITSIZE (mode) / BITS_PER_WORD;
1283 rtx carry_in = NULL_RTX, carry_out = NULL_RTX;
1286 /* We can handle either a 1 or -1 value for the carry. If STORE_FLAG
1287 value is one of those, use it. Otherwise, use 1 since it is the
1288 one easiest to get. */
1289 #if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
1290 int normalizep = STORE_FLAG_VALUE;
1295 /* Prepare the operands. */
1296 xop0 = force_reg (mode, op0);
1297 xop1 = force_reg (mode, op1);
1299 if (target == 0 || GET_CODE (target) != REG
1300 || target == xop0 || target == xop1)
1301 target = gen_reg_rtx (mode);
1303 /* Indicate for flow that the entire target reg is being set. */
1304 if (GET_CODE (target) == REG)
1305 emit_insn (gen_rtx_CLOBBER (VOIDmode, target));
1307 /* Do the actual arithmetic. */
1308 for (i = 0; i < nwords; i++)
1310 int index = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i);
1311 rtx target_piece = operand_subword (target, index, 1, mode);
1312 rtx op0_piece = operand_subword_force (xop0, index, mode);
1313 rtx op1_piece = operand_subword_force (xop1, index, mode);
1316 /* Main add/subtract of the input operands. */
1317 x = expand_binop (word_mode, binoptab,
1318 op0_piece, op1_piece,
1319 target_piece, unsignedp, next_methods);
1325 /* Store carry from main add/subtract. */
1326 carry_out = gen_reg_rtx (word_mode);
1327 carry_out = emit_store_flag_force (carry_out,
1328 (binoptab == add_optab
1331 word_mode, 1, normalizep);
1336 /* Add/subtract previous carry to main result. */
1337 x = expand_binop (word_mode,
1338 normalizep == 1 ? binoptab : otheroptab,
1340 target_piece, 1, next_methods);
1343 else if (target_piece != x)
1344 emit_move_insn (target_piece, x);
1348 /* THIS CODE HAS NOT BEEN TESTED. */
1349 /* Get out carry from adding/subtracting carry in. */
1350 carry_tmp = emit_store_flag_force (carry_tmp,
1351 binoptab == add_optab
1354 word_mode, 1, normalizep);
1356 /* Logical-ior the two poss. carry together. */
1357 carry_out = expand_binop (word_mode, ior_optab,
1358 carry_out, carry_tmp,
1359 carry_out, 0, next_methods);
1365 carry_in = carry_out;
1368 if (i == GET_MODE_BITSIZE (mode) / BITS_PER_WORD)
1370 if (mov_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1372 rtx temp = emit_move_insn (target, target);
1374 set_unique_reg_note (temp,
1376 gen_rtx_fmt_ee (binoptab->code, mode,
1383 delete_insns_since (last);
1386 /* If we want to multiply two two-word values and have normal and widening
1387 multiplies of single-word values, we can do this with three smaller
1388 multiplications. Note that we do not make a REG_NO_CONFLICT block here
1389 because we are not operating on one word at a time.
1391 The multiplication proceeds as follows:
1392 _______________________
1393 [__op0_high_|__op0_low__]
1394 _______________________
1395 * [__op1_high_|__op1_low__]
1396 _______________________________________________
1397 _______________________
1398 (1) [__op0_low__*__op1_low__]
1399 _______________________
1400 (2a) [__op0_low__*__op1_high_]
1401 _______________________
1402 (2b) [__op0_high_*__op1_low__]
1403 _______________________
1404 (3) [__op0_high_*__op1_high_]
1407 This gives a 4-word result. Since we are only interested in the
1408 lower 2 words, partial result (3) and the upper words of (2a) and
1409 (2b) don't need to be calculated. Hence (2a) and (2b) can be
1410 calculated using non-widening multiplication.
1412 (1), however, needs to be calculated with an unsigned widening
1413 multiplication. If this operation is not directly supported we
1414 try using a signed widening multiplication and adjust the result.
1415 This adjustment works as follows:
1417 If both operands are positive then no adjustment is needed.
1419 If the operands have different signs, for example op0_low < 0 and
1420 op1_low >= 0, the instruction treats the most significant bit of
1421 op0_low as a sign bit instead of a bit with significance
1422 2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low
1423 with 2**BITS_PER_WORD - op0_low, and two's complements the
1424 result. Conclusion: We need to add op1_low * 2**BITS_PER_WORD to
1427 Similarly, if both operands are negative, we need to add
1428 (op0_low + op1_low) * 2**BITS_PER_WORD.
1430 We use a trick to adjust quickly. We logically shift op0_low right
1431 (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to
1432 op0_high (op1_high) before it is used to calculate 2b (2a). If no
1433 logical shift exists, we do an arithmetic right shift and subtract
1436 if (binoptab == smul_optab
1437 && class == MODE_INT
1438 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
1439 && smul_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
1440 && add_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
1441 && ((umul_widen_optab->handlers[(int) mode].insn_code
1442 != CODE_FOR_nothing)
1443 || (smul_widen_optab->handlers[(int) mode].insn_code
1444 != CODE_FOR_nothing)))
1446 int low = (WORDS_BIG_ENDIAN ? 1 : 0);
1447 int high = (WORDS_BIG_ENDIAN ? 0 : 1);
1448 rtx op0_high = operand_subword_force (op0, high, mode);
1449 rtx op0_low = operand_subword_force (op0, low, mode);
1450 rtx op1_high = operand_subword_force (op1, high, mode);
1451 rtx op1_low = operand_subword_force (op1, low, mode);
1453 rtx op0_xhigh = NULL_RTX;
1454 rtx op1_xhigh = NULL_RTX;
1456 /* If the target is the same as one of the inputs, don't use it. This
1457 prevents problems with the REG_EQUAL note. */
1458 if (target == op0 || target == op1
1459 || (target != 0 && GET_CODE (target) != REG))
1462 /* Multiply the two lower words to get a double-word product.
1463 If unsigned widening multiplication is available, use that;
1464 otherwise use the signed form and compensate. */
1466 if (umul_widen_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1468 product = expand_binop (mode, umul_widen_optab, op0_low, op1_low,
1469 target, 1, OPTAB_DIRECT);
1471 /* If we didn't succeed, delete everything we did so far. */
1473 delete_insns_since (last);
1475 op0_xhigh = op0_high, op1_xhigh = op1_high;
1479 && smul_widen_optab->handlers[(int) mode].insn_code
1480 != CODE_FOR_nothing)
1482 rtx wordm1 = GEN_INT (BITS_PER_WORD - 1);
1483 product = expand_binop (mode, smul_widen_optab, op0_low, op1_low,
1484 target, 1, OPTAB_DIRECT);
1485 op0_xhigh = expand_binop (word_mode, lshr_optab, op0_low, wordm1,
1486 NULL_RTX, 1, next_methods);
1488 op0_xhigh = expand_binop (word_mode, add_optab, op0_high,
1489 op0_xhigh, op0_xhigh, 0, next_methods);
1492 op0_xhigh = expand_binop (word_mode, ashr_optab, op0_low, wordm1,
1493 NULL_RTX, 0, next_methods);
1495 op0_xhigh = expand_binop (word_mode, sub_optab, op0_high,
1496 op0_xhigh, op0_xhigh, 0,
1500 op1_xhigh = expand_binop (word_mode, lshr_optab, op1_low, wordm1,
1501 NULL_RTX, 1, next_methods);
1503 op1_xhigh = expand_binop (word_mode, add_optab, op1_high,
1504 op1_xhigh, op1_xhigh, 0, next_methods);
1507 op1_xhigh = expand_binop (word_mode, ashr_optab, op1_low, wordm1,
1508 NULL_RTX, 0, next_methods);
1510 op1_xhigh = expand_binop (word_mode, sub_optab, op1_high,
1511 op1_xhigh, op1_xhigh, 0,
1516 /* If we have been able to directly compute the product of the
1517 low-order words of the operands and perform any required adjustments
1518 of the operands, we proceed by trying two more multiplications
1519 and then computing the appropriate sum.
1521 We have checked above that the required addition is provided.
1522 Full-word addition will normally always succeed, especially if
1523 it is provided at all, so we don't worry about its failure. The
1524 multiplication may well fail, however, so we do handle that. */
1526 if (product && op0_xhigh && op1_xhigh)
1528 rtx product_high = operand_subword (product, high, 1, mode);
1529 rtx temp = expand_binop (word_mode, binoptab, op0_low, op1_xhigh,
1530 NULL_RTX, 0, OPTAB_DIRECT);
1533 temp = expand_binop (word_mode, add_optab, temp, product_high,
1534 product_high, 0, next_methods);
1536 if (temp != 0 && temp != product_high)
1537 emit_move_insn (product_high, temp);
1540 temp = expand_binop (word_mode, binoptab, op1_low, op0_xhigh,
1541 NULL_RTX, 0, OPTAB_DIRECT);
1544 temp = expand_binop (word_mode, add_optab, temp,
1545 product_high, product_high,
1548 if (temp != 0 && temp != product_high)
1549 emit_move_insn (product_high, temp);
1553 if (mov_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1555 temp = emit_move_insn (product, product);
1556 set_unique_reg_note (temp,
1558 gen_rtx_fmt_ee (MULT, mode,
1566 /* If we get here, we couldn't do it for some reason even though we
1567 originally thought we could. Delete anything we've emitted in
1570 delete_insns_since (last);
1573 /* We need to open-code the complex type operations: '+, -, * and /' */
1575 /* At this point we allow operations between two similar complex
1576 numbers, and also if one of the operands is not a complex number
1577 but rather of MODE_FLOAT or MODE_INT. However, the caller
1578 must make sure that the MODE of the non-complex operand matches
1579 the SUBMODE of the complex operand. */
1581 if (class == MODE_COMPLEX_FLOAT || class == MODE_COMPLEX_INT)
1583 rtx real0 = 0, imag0 = 0;
1584 rtx real1 = 0, imag1 = 0;
1585 rtx realr, imagr, res;
1590 /* Find the correct mode for the real and imaginary parts */
1591 enum machine_mode submode
1592 = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
1593 class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
1596 if (submode == BLKmode)
1600 target = gen_reg_rtx (mode);
1604 realr = gen_realpart (submode, target);
1605 imagr = gen_imagpart (submode, target);
1607 if (GET_MODE (op0) == mode)
1609 real0 = gen_realpart (submode, op0);
1610 imag0 = gen_imagpart (submode, op0);
1615 if (GET_MODE (op1) == mode)
1617 real1 = gen_realpart (submode, op1);
1618 imag1 = gen_imagpart (submode, op1);
1623 if (real0 == 0 || real1 == 0 || ! (imag0 != 0|| imag1 != 0))
1626 switch (binoptab->code)
1629 /* (a+ib) + (c+id) = (a+c) + i(b+d) */
1631 /* (a+ib) - (c+id) = (a-c) + i(b-d) */
1632 res = expand_binop (submode, binoptab, real0, real1,
1633 realr, unsignedp, methods);
1637 else if (res != realr)
1638 emit_move_insn (realr, res);
1641 res = expand_binop (submode, binoptab, imag0, imag1,
1642 imagr, unsignedp, methods);
1645 else if (binoptab->code == MINUS)
1646 res = expand_unop (submode, neg_optab, imag1, imagr, unsignedp);
1652 else if (res != imagr)
1653 emit_move_insn (imagr, res);
1659 /* (a+ib) * (c+id) = (ac-bd) + i(ad+cb) */
1665 /* Don't fetch these from memory more than once. */
1666 real0 = force_reg (submode, real0);
1667 real1 = force_reg (submode, real1);
1668 imag0 = force_reg (submode, imag0);
1669 imag1 = force_reg (submode, imag1);
1671 temp1 = expand_binop (submode, binoptab, real0, real1, NULL_RTX,
1672 unsignedp, methods);
1674 temp2 = expand_binop (submode, binoptab, imag0, imag1, NULL_RTX,
1675 unsignedp, methods);
1677 if (temp1 == 0 || temp2 == 0)
1680 res = expand_binop (submode, sub_optab, temp1, temp2,
1681 realr, unsignedp, methods);
1685 else if (res != realr)
1686 emit_move_insn (realr, res);
1688 temp1 = expand_binop (submode, binoptab, real0, imag1,
1689 NULL_RTX, unsignedp, methods);
1691 temp2 = expand_binop (submode, binoptab, real1, imag0,
1692 NULL_RTX, unsignedp, methods);
1694 if (temp1 == 0 || temp2 == 0)
1697 res = expand_binop (submode, add_optab, temp1, temp2,
1698 imagr, unsignedp, methods);
1702 else if (res != imagr)
1703 emit_move_insn (imagr, res);
1709 /* Don't fetch these from memory more than once. */
1710 real0 = force_reg (submode, real0);
1711 real1 = force_reg (submode, real1);
1713 res = expand_binop (submode, binoptab, real0, real1,
1714 realr, unsignedp, methods);
1717 else if (res != realr)
1718 emit_move_insn (realr, res);
1721 res = expand_binop (submode, binoptab,
1722 real1, imag0, imagr, unsignedp, methods);
1724 res = expand_binop (submode, binoptab,
1725 real0, imag1, imagr, unsignedp, methods);
1729 else if (res != imagr)
1730 emit_move_insn (imagr, res);
1737 /* (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd)) */
1741 /* (a+ib) / (c+i0) = (a/c) + i(b/c) */
1743 /* Don't fetch these from memory more than once. */
1744 real1 = force_reg (submode, real1);
1746 /* Simply divide the real and imaginary parts by `c' */
1747 if (class == MODE_COMPLEX_FLOAT)
1748 res = expand_binop (submode, binoptab, real0, real1,
1749 realr, unsignedp, methods);
1751 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
1752 real0, real1, realr, unsignedp);
1756 else if (res != realr)
1757 emit_move_insn (realr, res);
1759 if (class == MODE_COMPLEX_FLOAT)
1760 res = expand_binop (submode, binoptab, imag0, real1,
1761 imagr, unsignedp, methods);
1763 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
1764 imag0, real1, imagr, unsignedp);
1768 else if (res != imagr)
1769 emit_move_insn (imagr, res);
1775 switch (flag_complex_divide_method)
1778 ok = expand_cmplxdiv_straight (real0, real1, imag0, imag1,
1779 realr, imagr, submode,
1785 ok = expand_cmplxdiv_wide (real0, real1, imag0, imag1,
1786 realr, imagr, submode,
1806 if (binoptab->code != UNKNOWN)
1808 = gen_rtx_fmt_ee (binoptab->code, mode,
1809 copy_rtx (op0), copy_rtx (op1));
1813 emit_no_conflict_block (seq, target, op0, op1, equiv_value);
1819 /* It can't be open-coded in this mode.
1820 Use a library call if one is available and caller says that's ok. */
1822 if (binoptab->handlers[(int) mode].libfunc
1823 && (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN))
1827 enum machine_mode op1_mode = mode;
1834 op1_mode = word_mode;
1835 /* Specify unsigned here,
1836 since negative shift counts are meaningless. */
1837 op1x = convert_to_mode (word_mode, op1, 1);
1840 if (GET_MODE (op0) != VOIDmode
1841 && GET_MODE (op0) != mode)
1842 op0 = convert_to_mode (mode, op0, unsignedp);
1844 /* Pass 1 for NO_QUEUE so we don't lose any increments
1845 if the libcall is cse'd or moved. */
1846 value = emit_library_call_value (binoptab->handlers[(int) mode].libfunc,
1847 NULL_RTX, 1, mode, 2,
1848 op0, mode, op1x, op1_mode);
1850 insns = get_insns ();
1853 target = gen_reg_rtx (mode);
1854 emit_libcall_block (insns, target, value,
1855 gen_rtx_fmt_ee (binoptab->code, mode, op0, op1));
1860 delete_insns_since (last);
1862 /* It can't be done in this mode. Can we do it in a wider mode? */
1864 if (! (methods == OPTAB_WIDEN || methods == OPTAB_LIB_WIDEN
1865 || methods == OPTAB_MUST_WIDEN))
1867 /* Caller says, don't even try. */
1868 delete_insns_since (entry_last);
1872 /* Compute the value of METHODS to pass to recursive calls.
1873 Don't allow widening to be tried recursively. */
1875 methods = (methods == OPTAB_LIB_WIDEN ? OPTAB_LIB : OPTAB_DIRECT);
1877 /* Look for a wider mode of the same class for which it appears we can do
1880 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1882 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1883 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1885 if ((binoptab->handlers[(int) wider_mode].insn_code
1886 != CODE_FOR_nothing)
1887 || (methods == OPTAB_LIB
1888 && binoptab->handlers[(int) wider_mode].libfunc))
1890 rtx xop0 = op0, xop1 = op1;
1893 /* For certain integer operations, we need not actually extend
1894 the narrow operands, as long as we will truncate
1895 the results to the same narrowness. */
1897 if ((binoptab == ior_optab || binoptab == and_optab
1898 || binoptab == xor_optab
1899 || binoptab == add_optab || binoptab == sub_optab
1900 || binoptab == smul_optab || binoptab == ashl_optab)
1901 && class == MODE_INT)
1904 xop0 = widen_operand (xop0, wider_mode, mode,
1905 unsignedp, no_extend);
1907 /* The second operand of a shift must always be extended. */
1908 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
1909 no_extend && binoptab != ashl_optab);
1911 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
1912 unsignedp, methods);
1915 if (class != MODE_INT)
1918 target = gen_reg_rtx (mode);
1919 convert_move (target, temp, 0);
1923 return gen_lowpart (mode, temp);
1926 delete_insns_since (last);
1931 delete_insns_since (entry_last);
1935 /* Expand a binary operator which has both signed and unsigned forms.
1936 UOPTAB is the optab for unsigned operations, and SOPTAB is for
1939 If we widen unsigned operands, we may use a signed wider operation instead
1940 of an unsigned wider operation, since the result would be the same. */
1943 sign_expand_binop (mode, uoptab, soptab, op0, op1, target, unsignedp, methods)
1944 enum machine_mode mode;
1945 optab uoptab, soptab;
1946 rtx op0, op1, target;
1948 enum optab_methods methods;
1951 optab direct_optab = unsignedp ? uoptab : soptab;
1952 struct optab wide_soptab;
1954 /* Do it without widening, if possible. */
1955 temp = expand_binop (mode, direct_optab, op0, op1, target,
1956 unsignedp, OPTAB_DIRECT);
1957 if (temp || methods == OPTAB_DIRECT)
1960 /* Try widening to a signed int. Make a fake signed optab that
1961 hides any signed insn for direct use. */
1962 wide_soptab = *soptab;
1963 wide_soptab.handlers[(int) mode].insn_code = CODE_FOR_nothing;
1964 wide_soptab.handlers[(int) mode].libfunc = 0;
1966 temp = expand_binop (mode, &wide_soptab, op0, op1, target,
1967 unsignedp, OPTAB_WIDEN);
1969 /* For unsigned operands, try widening to an unsigned int. */
1970 if (temp == 0 && unsignedp)
1971 temp = expand_binop (mode, uoptab, op0, op1, target,
1972 unsignedp, OPTAB_WIDEN);
1973 if (temp || methods == OPTAB_WIDEN)
1976 /* Use the right width lib call if that exists. */
1977 temp = expand_binop (mode, direct_optab, op0, op1, target, unsignedp, OPTAB_LIB);
1978 if (temp || methods == OPTAB_LIB)
1981 /* Must widen and use a lib call, use either signed or unsigned. */
1982 temp = expand_binop (mode, &wide_soptab, op0, op1, target,
1983 unsignedp, methods);
1987 return expand_binop (mode, uoptab, op0, op1, target,
1988 unsignedp, methods);
1992 /* Generate code to perform an operation specified by BINOPTAB
1993 on operands OP0 and OP1, with two results to TARG1 and TARG2.
1994 We assume that the order of the operands for the instruction
1995 is TARG0, OP0, OP1, TARG1, which would fit a pattern like
1996 [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
1998 Either TARG0 or TARG1 may be zero, but what that means is that
1999 the result is not actually wanted. We will generate it into
2000 a dummy pseudo-reg and discard it. They may not both be zero.
2002 Returns 1 if this operation can be performed; 0 if not. */
2005 expand_twoval_binop (binoptab, op0, op1, targ0, targ1, unsignedp)
2011 enum machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
2012 enum mode_class class;
2013 enum machine_mode wider_mode;
2014 rtx entry_last = get_last_insn ();
2017 class = GET_MODE_CLASS (mode);
2019 op0 = protect_from_queue (op0, 0);
2020 op1 = protect_from_queue (op1, 0);
2024 op0 = force_not_mem (op0);
2025 op1 = force_not_mem (op1);
2028 /* If we are inside an appropriately-short loop and one operand is an
2029 expensive constant, force it into a register. */
2030 if (CONSTANT_P (op0) && preserve_subexpressions_p ()
2031 && rtx_cost (op0, binoptab->code) > 2)
2032 op0 = force_reg (mode, op0);
2034 if (CONSTANT_P (op1) && preserve_subexpressions_p ()
2035 && rtx_cost (op1, binoptab->code) > 2)
2036 op1 = force_reg (mode, op1);
2039 targ0 = protect_from_queue (targ0, 1);
2041 targ0 = gen_reg_rtx (mode);
2043 targ1 = protect_from_queue (targ1, 1);
2045 targ1 = gen_reg_rtx (mode);
2047 /* Record where to go back to if we fail. */
2048 last = get_last_insn ();
2050 if (binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2052 int icode = (int) binoptab->handlers[(int) mode].insn_code;
2053 enum machine_mode mode0 = insn_operand_mode[icode][1];
2054 enum machine_mode mode1 = insn_operand_mode[icode][2];
2056 rtx xop0 = op0, xop1 = op1;
2058 /* In case this insn wants input operands in modes different from the
2059 result, convert the operands. */
2060 if (GET_MODE (op0) != VOIDmode && GET_MODE (op0) != mode0)
2061 xop0 = convert_to_mode (mode0, xop0, unsignedp);
2063 if (GET_MODE (op1) != VOIDmode && GET_MODE (op1) != mode1)
2064 xop1 = convert_to_mode (mode1, xop1, unsignedp);
2066 /* Now, if insn doesn't accept these operands, put them into pseudos. */
2067 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
2068 xop0 = copy_to_mode_reg (mode0, xop0);
2070 if (! (*insn_operand_predicate[icode][2]) (xop1, mode1))
2071 xop1 = copy_to_mode_reg (mode1, xop1);
2073 /* We could handle this, but we should always be called with a pseudo
2074 for our targets and all insns should take them as outputs. */
2075 if (! (*insn_operand_predicate[icode][0]) (targ0, mode)
2076 || ! (*insn_operand_predicate[icode][3]) (targ1, mode))
2079 pat = GEN_FCN (icode) (targ0, xop0, xop1, targ1);
2086 delete_insns_since (last);
2089 /* It can't be done in this mode. Can we do it in a wider mode? */
2091 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
2093 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2094 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2096 if (binoptab->handlers[(int) wider_mode].insn_code
2097 != CODE_FOR_nothing)
2099 register rtx t0 = gen_reg_rtx (wider_mode);
2100 register rtx t1 = gen_reg_rtx (wider_mode);
2102 if (expand_twoval_binop (binoptab,
2103 convert_modes (wider_mode, mode, op0,
2105 convert_modes (wider_mode, mode, op1,
2109 convert_move (targ0, t0, unsignedp);
2110 convert_move (targ1, t1, unsignedp);
2114 delete_insns_since (last);
2119 delete_insns_since (entry_last);
2123 /* Generate code to perform an operation specified by UNOPTAB
2124 on operand OP0, with result having machine-mode MODE.
2126 UNSIGNEDP is for the case where we have to widen the operands
2127 to perform the operation. It says to use zero-extension.
2129 If TARGET is nonzero, the value
2130 is generated there, if it is convenient to do so.
2131 In all cases an rtx is returned for the locus of the value;
2132 this may or may not be TARGET. */
2135 expand_unop (mode, unoptab, op0, target, unsignedp)
2136 enum machine_mode mode;
2142 enum mode_class class;
2143 enum machine_mode wider_mode;
2145 rtx last = get_last_insn ();
2148 class = GET_MODE_CLASS (mode);
2150 op0 = protect_from_queue (op0, 0);
2154 op0 = force_not_mem (op0);
2158 target = protect_from_queue (target, 1);
2160 if (unoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2162 int icode = (int) unoptab->handlers[(int) mode].insn_code;
2163 enum machine_mode mode0 = insn_operand_mode[icode][1];
2169 temp = gen_reg_rtx (mode);
2171 if (GET_MODE (xop0) != VOIDmode
2172 && GET_MODE (xop0) != mode0)
2173 xop0 = convert_to_mode (mode0, xop0, unsignedp);
2175 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
2177 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
2178 xop0 = copy_to_mode_reg (mode0, xop0);
2180 if (! (*insn_operand_predicate[icode][0]) (temp, mode))
2181 temp = gen_reg_rtx (mode);
2183 pat = GEN_FCN (icode) (temp, xop0);
2186 if (GET_CODE (pat) == SEQUENCE
2187 && ! add_equal_note (pat, temp, unoptab->code, xop0, NULL_RTX))
2189 delete_insns_since (last);
2190 return expand_unop (mode, unoptab, op0, NULL_RTX, unsignedp);
2198 delete_insns_since (last);
2201 /* It can't be done in this mode. Can we open-code it in a wider mode? */
2203 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
2204 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2205 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2207 if (unoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing)
2211 /* For certain operations, we need not actually extend
2212 the narrow operand, as long as we will truncate the
2213 results to the same narrowness. */
2215 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
2216 (unoptab == neg_optab
2217 || unoptab == one_cmpl_optab)
2218 && class == MODE_INT);
2220 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
2225 if (class != MODE_INT)
2228 target = gen_reg_rtx (mode);
2229 convert_move (target, temp, 0);
2233 return gen_lowpart (mode, temp);
2236 delete_insns_since (last);
2240 /* These can be done a word at a time. */
2241 if (unoptab == one_cmpl_optab
2242 && class == MODE_INT
2243 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
2244 && unoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
2249 if (target == 0 || target == op0)
2250 target = gen_reg_rtx (mode);
2254 /* Do the actual arithmetic. */
2255 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
2257 rtx target_piece = operand_subword (target, i, 1, mode);
2258 rtx x = expand_unop (word_mode, unoptab,
2259 operand_subword_force (op0, i, mode),
2260 target_piece, unsignedp);
2261 if (target_piece != x)
2262 emit_move_insn (target_piece, x);
2265 insns = get_insns ();
2268 emit_no_conflict_block (insns, target, op0, NULL_RTX,
2269 gen_rtx_fmt_e (unoptab->code, mode,
2274 /* Open-code the complex negation operation. */
2275 else if (unoptab == neg_optab
2276 && (class == MODE_COMPLEX_FLOAT || class == MODE_COMPLEX_INT))
2282 /* Find the correct mode for the real and imaginary parts */
2283 enum machine_mode submode
2284 = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
2285 class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
2288 if (submode == BLKmode)
2292 target = gen_reg_rtx (mode);
2296 target_piece = gen_imagpart (submode, target);
2297 x = expand_unop (submode, unoptab,
2298 gen_imagpart (submode, op0),
2299 target_piece, unsignedp);
2300 if (target_piece != x)
2301 emit_move_insn (target_piece, x);
2303 target_piece = gen_realpart (submode, target);
2304 x = expand_unop (submode, unoptab,
2305 gen_realpart (submode, op0),
2306 target_piece, unsignedp);
2307 if (target_piece != x)
2308 emit_move_insn (target_piece, x);
2313 emit_no_conflict_block (seq, target, op0, 0,
2314 gen_rtx_fmt_e (unoptab->code, mode,
2319 /* Now try a library call in this mode. */
2320 if (unoptab->handlers[(int) mode].libfunc)
2327 /* Pass 1 for NO_QUEUE so we don't lose any increments
2328 if the libcall is cse'd or moved. */
2329 value = emit_library_call_value (unoptab->handlers[(int) mode].libfunc,
2330 NULL_RTX, 1, mode, 1, op0, mode);
2331 insns = get_insns ();
2334 target = gen_reg_rtx (mode);
2335 emit_libcall_block (insns, target, value,
2336 gen_rtx_fmt_e (unoptab->code, mode, op0));
2341 /* It can't be done in this mode. Can we do it in a wider mode? */
2343 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
2345 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2346 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2348 if ((unoptab->handlers[(int) wider_mode].insn_code
2349 != CODE_FOR_nothing)
2350 || unoptab->handlers[(int) wider_mode].libfunc)
2354 /* For certain operations, we need not actually extend
2355 the narrow operand, as long as we will truncate the
2356 results to the same narrowness. */
2358 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
2359 (unoptab == neg_optab
2360 || unoptab == one_cmpl_optab)
2361 && class == MODE_INT);
2363 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
2368 if (class != MODE_INT)
2371 target = gen_reg_rtx (mode);
2372 convert_move (target, temp, 0);
2376 return gen_lowpart (mode, temp);
2379 delete_insns_since (last);
2384 /* If there is no negate operation, try doing a subtract from zero.
2385 The US Software GOFAST library needs this. */
2386 if (unoptab == neg_optab)
2389 temp = expand_binop (mode, sub_optab, CONST0_RTX (mode), op0,
2390 target, unsignedp, OPTAB_LIB_WIDEN);
2398 /* Emit code to compute the absolute value of OP0, with result to
2399 TARGET if convenient. (TARGET may be 0.) The return value says
2400 where the result actually is to be found.
2402 MODE is the mode of the operand; the mode of the result is
2403 different but can be deduced from MODE.
2408 expand_abs (mode, op0, target, safe)
2409 enum machine_mode mode;
2416 /* First try to do it with a special abs instruction. */
2417 temp = expand_unop (mode, abs_optab, op0, target, 0);
2421 /* If this machine has expensive jumps, we can do integer absolute
2422 value of X as (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)),
2423 where W is the width of MODE. */
2425 if (GET_MODE_CLASS (mode) == MODE_INT && BRANCH_COST >= 2)
2427 rtx extended = expand_shift (RSHIFT_EXPR, mode, op0,
2428 size_int (GET_MODE_BITSIZE (mode) - 1),
2431 temp = expand_binop (mode, xor_optab, extended, op0, target, 0,
2434 temp = expand_binop (mode, sub_optab, temp, extended, target, 0,
2441 /* If that does not win, use conditional jump and negate. */
2443 /* It is safe to use the target if it is the same
2444 as the source if this is also a pseudo register */
2445 if (op0 == target && GET_CODE (op0) == REG
2446 && REGNO (op0) >= FIRST_PSEUDO_REGISTER)
2449 op1 = gen_label_rtx ();
2450 if (target == 0 || ! safe
2451 || GET_MODE (target) != mode
2452 || (GET_CODE (target) == MEM && MEM_VOLATILE_P (target))
2453 || (GET_CODE (target) == REG
2454 && REGNO (target) < FIRST_PSEUDO_REGISTER))
2455 target = gen_reg_rtx (mode);
2457 emit_move_insn (target, op0);
2460 /* If this mode is an integer too wide to compare properly,
2461 compare word by word. Rely on CSE to optimize constant cases. */
2462 if (GET_MODE_CLASS (mode) == MODE_INT && ! can_compare_p (mode))
2463 do_jump_by_parts_greater_rtx (mode, 0, target, const0_rtx,
2467 temp = compare_from_rtx (target, CONST0_RTX (mode), GE, 0, mode,
2469 if (temp == const1_rtx)
2471 else if (temp != const0_rtx)
2473 if (bcc_gen_fctn[(int) GET_CODE (temp)] != 0)
2474 emit_jump_insn ((*bcc_gen_fctn[(int) GET_CODE (temp)]) (op1));
2480 op0 = expand_unop (mode, neg_optab, target, target, 0);
2482 emit_move_insn (target, op0);
2488 /* Emit code to compute the absolute value of OP0, with result to
2489 TARGET if convenient. (TARGET may be 0.) The return value says
2490 where the result actually is to be found.
2492 MODE is the mode of the operand; the mode of the result is
2493 different but can be deduced from MODE.
2495 UNSIGNEDP is relevant for complex integer modes. */
2498 expand_complex_abs (mode, op0, target, unsignedp)
2499 enum machine_mode mode;
2504 enum mode_class class = GET_MODE_CLASS (mode);
2505 enum machine_mode wider_mode;
2507 rtx entry_last = get_last_insn ();
2511 /* Find the correct mode for the real and imaginary parts. */
2512 enum machine_mode submode
2513 = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
2514 class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
2517 if (submode == BLKmode)
2520 op0 = protect_from_queue (op0, 0);
2524 op0 = force_not_mem (op0);
2527 last = get_last_insn ();
2530 target = protect_from_queue (target, 1);
2532 if (abs_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2534 int icode = (int) abs_optab->handlers[(int) mode].insn_code;
2535 enum machine_mode mode0 = insn_operand_mode[icode][1];
2541 temp = gen_reg_rtx (submode);
2543 if (GET_MODE (xop0) != VOIDmode
2544 && GET_MODE (xop0) != mode0)
2545 xop0 = convert_to_mode (mode0, xop0, unsignedp);
2547 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
2549 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
2550 xop0 = copy_to_mode_reg (mode0, xop0);
2552 if (! (*insn_operand_predicate[icode][0]) (temp, submode))
2553 temp = gen_reg_rtx (submode);
2555 pat = GEN_FCN (icode) (temp, xop0);
2558 if (GET_CODE (pat) == SEQUENCE
2559 && ! add_equal_note (pat, temp, abs_optab->code, xop0, NULL_RTX))
2561 delete_insns_since (last);
2562 return expand_unop (mode, abs_optab, op0, NULL_RTX, unsignedp);
2570 delete_insns_since (last);
2573 /* It can't be done in this mode. Can we open-code it in a wider mode? */
2575 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2576 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2578 if (abs_optab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing)
2582 xop0 = convert_modes (wider_mode, mode, xop0, unsignedp);
2583 temp = expand_complex_abs (wider_mode, xop0, NULL_RTX, unsignedp);
2587 if (class != MODE_COMPLEX_INT)
2590 target = gen_reg_rtx (submode);
2591 convert_move (target, temp, 0);
2595 return gen_lowpart (submode, temp);
2598 delete_insns_since (last);
2602 /* Open-code the complex absolute-value operation
2603 if we can open-code sqrt. Otherwise it's not worth while. */
2604 if (sqrt_optab->handlers[(int) submode].insn_code != CODE_FOR_nothing)
2606 rtx real, imag, total;
2608 real = gen_realpart (submode, op0);
2609 imag = gen_imagpart (submode, op0);
2611 /* Square both parts. */
2612 real = expand_mult (submode, real, real, NULL_RTX, 0);
2613 imag = expand_mult (submode, imag, imag, NULL_RTX, 0);
2615 /* Sum the parts. */
2616 total = expand_binop (submode, add_optab, real, imag, NULL_RTX,
2617 0, OPTAB_LIB_WIDEN);
2619 /* Get sqrt in TARGET. Set TARGET to where the result is. */
2620 target = expand_unop (submode, sqrt_optab, total, target, 0);
2622 delete_insns_since (last);
2627 /* Now try a library call in this mode. */
2628 if (abs_optab->handlers[(int) mode].libfunc)
2635 /* Pass 1 for NO_QUEUE so we don't lose any increments
2636 if the libcall is cse'd or moved. */
2637 value = emit_library_call_value (abs_optab->handlers[(int) mode].libfunc,
2638 NULL_RTX, 1, submode, 1, op0, mode);
2639 insns = get_insns ();
2642 target = gen_reg_rtx (submode);
2643 emit_libcall_block (insns, target, value,
2644 gen_rtx_fmt_e (abs_optab->code, mode, op0));
2649 /* It can't be done in this mode. Can we do it in a wider mode? */
2651 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2652 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2654 if ((abs_optab->handlers[(int) wider_mode].insn_code
2655 != CODE_FOR_nothing)
2656 || abs_optab->handlers[(int) wider_mode].libfunc)
2660 xop0 = convert_modes (wider_mode, mode, xop0, unsignedp);
2662 temp = expand_complex_abs (wider_mode, xop0, NULL_RTX, unsignedp);
2666 if (class != MODE_COMPLEX_INT)
2669 target = gen_reg_rtx (submode);
2670 convert_move (target, temp, 0);
2674 return gen_lowpart (submode, temp);
2677 delete_insns_since (last);
2681 delete_insns_since (entry_last);
2685 /* Generate an instruction whose insn-code is INSN_CODE,
2686 with two operands: an output TARGET and an input OP0.
2687 TARGET *must* be nonzero, and the output is always stored there.
2688 CODE is an rtx code such that (CODE OP0) is an rtx that describes
2689 the value that is stored into TARGET. */
2692 emit_unop_insn (icode, target, op0, code)
2699 enum machine_mode mode0 = insn_operand_mode[icode][1];
2702 temp = target = protect_from_queue (target, 1);
2704 op0 = protect_from_queue (op0, 0);
2706 /* Sign and zero extension from memory is often done specially on
2707 RISC machines, so forcing into a register here can pessimize
2709 if (flag_force_mem && code != SIGN_EXTEND && code != ZERO_EXTEND)
2710 op0 = force_not_mem (op0);
2712 /* Now, if insn does not accept our operands, put them into pseudos. */
2714 if (! (*insn_operand_predicate[icode][1]) (op0, mode0))
2715 op0 = copy_to_mode_reg (mode0, op0);
2717 if (! (*insn_operand_predicate[icode][0]) (temp, GET_MODE (temp))
2718 || (flag_force_mem && GET_CODE (temp) == MEM))
2719 temp = gen_reg_rtx (GET_MODE (temp));
2721 pat = GEN_FCN (icode) (temp, op0);
2723 if (GET_CODE (pat) == SEQUENCE && code != UNKNOWN)
2724 add_equal_note (pat, temp, code, op0, NULL_RTX);
2729 emit_move_insn (target, temp);
2732 /* Emit code to perform a series of operations on a multi-word quantity, one
2735 Such a block is preceded by a CLOBBER of the output, consists of multiple
2736 insns, each setting one word of the output, and followed by a SET copying
2737 the output to itself.
2739 Each of the insns setting words of the output receives a REG_NO_CONFLICT
2740 note indicating that it doesn't conflict with the (also multi-word)
2741 inputs. The entire block is surrounded by REG_LIBCALL and REG_RETVAL
2744 INSNS is a block of code generated to perform the operation, not including
2745 the CLOBBER and final copy. All insns that compute intermediate values
2746 are first emitted, followed by the block as described above.
2748 TARGET, OP0, and OP1 are the output and inputs of the operations,
2749 respectively. OP1 may be zero for a unary operation.
2751 EQUIV, if non-zero, is an expression to be placed into a REG_EQUAL note
2754 If TARGET is not a register, INSNS is simply emitted with no special
2755 processing. Likewise if anything in INSNS is not an INSN or if
2756 there is a libcall block inside INSNS.
2758 The final insn emitted is returned. */
2761 emit_no_conflict_block (insns, target, op0, op1, equiv)
2767 rtx prev, next, first, last, insn;
2769 if (GET_CODE (target) != REG || reload_in_progress)
2770 return emit_insns (insns);
2772 for (insn = insns; insn; insn = NEXT_INSN (insn))
2773 if (GET_CODE (insn) != INSN
2774 || find_reg_note (insn, REG_LIBCALL, NULL_RTX))
2775 return emit_insns (insns);
2777 /* First emit all insns that do not store into words of the output and remove
2778 these from the list. */
2779 for (insn = insns; insn; insn = next)
2784 next = NEXT_INSN (insn);
2786 if (GET_CODE (PATTERN (insn)) == SET)
2787 set = PATTERN (insn);
2788 else if (GET_CODE (PATTERN (insn)) == PARALLEL)
2790 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
2791 if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET)
2793 set = XVECEXP (PATTERN (insn), 0, i);
2801 if (! reg_overlap_mentioned_p (target, SET_DEST (set)))
2803 if (PREV_INSN (insn))
2804 NEXT_INSN (PREV_INSN (insn)) = next;
2809 PREV_INSN (next) = PREV_INSN (insn);
2815 prev = get_last_insn ();
2817 /* Now write the CLOBBER of the output, followed by the setting of each
2818 of the words, followed by the final copy. */
2819 if (target != op0 && target != op1)
2820 emit_insn (gen_rtx_CLOBBER (VOIDmode, target));
2822 for (insn = insns; insn; insn = next)
2824 next = NEXT_INSN (insn);
2827 if (op1 && GET_CODE (op1) == REG)
2828 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_NO_CONFLICT, op1,
2831 if (op0 && GET_CODE (op0) == REG)
2832 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_NO_CONFLICT, op0,
2836 if (mov_optab->handlers[(int) GET_MODE (target)].insn_code
2837 != CODE_FOR_nothing)
2839 last = emit_move_insn (target, target);
2841 set_unique_reg_note (last, REG_EQUAL, equiv);
2844 last = get_last_insn ();
2847 first = get_insns ();
2849 first = NEXT_INSN (prev);
2851 /* Encapsulate the block so it gets manipulated as a unit. */
2852 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last,
2854 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2859 /* Emit code to make a call to a constant function or a library call.
2861 INSNS is a list containing all insns emitted in the call.
2862 These insns leave the result in RESULT. Our block is to copy RESULT
2863 to TARGET, which is logically equivalent to EQUIV.
2865 We first emit any insns that set a pseudo on the assumption that these are
2866 loading constants into registers; doing so allows them to be safely cse'ed
2867 between blocks. Then we emit all the other insns in the block, followed by
2868 an insn to move RESULT to TARGET. This last insn will have a REQ_EQUAL
2869 note with an operand of EQUIV.
2871 Moving assignments to pseudos outside of the block is done to improve
2872 the generated code, but is not required to generate correct code,
2873 hence being unable to move an assignment is not grounds for not making
2874 a libcall block. There are two reasons why it is safe to leave these
2875 insns inside the block: First, we know that these pseudos cannot be
2876 used in generated RTL outside the block since they are created for
2877 temporary purposes within the block. Second, CSE will not record the
2878 values of anything set inside a libcall block, so we know they must
2879 be dead at the end of the block.
2881 Except for the first group of insns (the ones setting pseudos), the
2882 block is delimited by REG_RETVAL and REG_LIBCALL notes. */
2885 emit_libcall_block (insns, target, result, equiv)
2891 rtx prev, next, first, last, insn;
2893 /* look for any CALL_INSNs in this sequence, and attach a REG_EH_REGION
2894 reg note to indicate that this call cannot throw. (Unless there is
2895 already a REG_EH_REGION note.) */
2897 for (insn = insns; insn; insn = NEXT_INSN (insn))
2899 if (GET_CODE (insn) == CALL_INSN)
2901 rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
2902 if (note == NULL_RTX)
2903 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EH_REGION, GEN_INT (-1),
2908 /* First emit all insns that set pseudos. Remove them from the list as
2909 we go. Avoid insns that set pseudos which were referenced in previous
2910 insns. These can be generated by move_by_pieces, for example,
2911 to update an address. Similarly, avoid insns that reference things
2912 set in previous insns. */
2914 for (insn = insns; insn; insn = next)
2916 rtx set = single_set (insn);
2918 next = NEXT_INSN (insn);
2920 if (set != 0 && GET_CODE (SET_DEST (set)) == REG
2921 && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER
2923 || (! reg_mentioned_p (SET_DEST (set), PATTERN (insns))
2924 && ! reg_used_between_p (SET_DEST (set), insns, insn)
2925 && ! modified_in_p (SET_SRC (set), insns)
2926 && ! modified_between_p (SET_SRC (set), insns, insn))))
2928 if (PREV_INSN (insn))
2929 NEXT_INSN (PREV_INSN (insn)) = next;
2934 PREV_INSN (next) = PREV_INSN (insn);
2940 prev = get_last_insn ();
2942 /* Write the remaining insns followed by the final copy. */
2944 for (insn = insns; insn; insn = next)
2946 next = NEXT_INSN (insn);
2951 last = emit_move_insn (target, result);
2952 if (mov_optab->handlers[(int) GET_MODE (target)].insn_code
2953 != CODE_FOR_nothing)
2954 set_unique_reg_note (last, REG_EQUAL, copy_rtx (equiv));
2957 first = get_insns ();
2959 first = NEXT_INSN (prev);
2961 /* Encapsulate the block so it gets manipulated as a unit. */
2962 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last,
2964 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2967 /* Generate code to store zero in X. */
2973 emit_move_insn (x, const0_rtx);
2976 /* Generate code to store 1 in X
2977 assuming it contains zero beforehand. */
2980 emit_0_to_1_insn (x)
2983 emit_move_insn (x, const1_rtx);
2986 /* Generate code to compare X with Y
2987 so that the condition codes are set.
2989 MODE is the mode of the inputs (in case they are const_int).
2990 UNSIGNEDP nonzero says that X and Y are unsigned;
2991 this matters if they need to be widened.
2993 If they have mode BLKmode, then SIZE specifies the size of both X and Y,
2994 and ALIGN specifies the known shared alignment of X and Y.
2996 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).
2997 It is ignored for fixed-point and block comparisons;
2998 it is used only for floating-point comparisons. */
3001 emit_cmp_insn (x, y, comparison, size, mode, unsignedp, align)
3003 enum rtx_code comparison;
3005 enum machine_mode mode;
3009 enum mode_class class;
3010 enum machine_mode wider_mode;
3012 class = GET_MODE_CLASS (mode);
3014 /* They could both be VOIDmode if both args are immediate constants,
3015 but we should fold that at an earlier stage.
3016 With no special code here, this will call abort,
3017 reminding the programmer to implement such folding. */
3019 if (mode != BLKmode && flag_force_mem)
3021 x = force_not_mem (x);
3022 y = force_not_mem (y);
3025 /* If we are inside an appropriately-short loop and one operand is an
3026 expensive constant, force it into a register. */
3027 if (CONSTANT_P (x) && preserve_subexpressions_p () && rtx_cost (x, COMPARE) > 2)
3028 x = force_reg (mode, x);
3030 if (CONSTANT_P (y) && preserve_subexpressions_p () && rtx_cost (y, COMPARE) > 2)
3031 y = force_reg (mode, y);
3034 /* Abort if we have a non-canonical comparison. The RTL documentation
3035 states that canonical comparisons are required only for targets which
3037 if (CONSTANT_P (x) && ! CONSTANT_P (y))
3041 /* Don't let both operands fail to indicate the mode. */
3042 if (GET_MODE (x) == VOIDmode && GET_MODE (y) == VOIDmode)
3043 x = force_reg (mode, x);
3045 /* Handle all BLKmode compares. */
3047 if (mode == BLKmode)
3050 x = protect_from_queue (x, 0);
3051 y = protect_from_queue (y, 0);
3055 #ifdef HAVE_cmpstrqi
3057 && GET_CODE (size) == CONST_INT
3058 && INTVAL (size) < (1 << GET_MODE_BITSIZE (QImode)))
3060 enum machine_mode result_mode
3061 = insn_operand_mode[(int) CODE_FOR_cmpstrqi][0];
3062 rtx result = gen_reg_rtx (result_mode);
3063 emit_insn (gen_cmpstrqi (result, x, y, size, GEN_INT (align)));
3064 emit_cmp_insn (result, const0_rtx, comparison, NULL_RTX,
3069 #ifdef HAVE_cmpstrhi
3071 && GET_CODE (size) == CONST_INT
3072 && INTVAL (size) < (1 << GET_MODE_BITSIZE (HImode)))
3074 enum machine_mode result_mode
3075 = insn_operand_mode[(int) CODE_FOR_cmpstrhi][0];
3076 rtx result = gen_reg_rtx (result_mode);
3077 emit_insn (gen_cmpstrhi (result, x, y, size, GEN_INT (align)));
3078 emit_cmp_insn (result, const0_rtx, comparison, NULL_RTX,
3083 #ifdef HAVE_cmpstrsi
3086 enum machine_mode result_mode
3087 = insn_operand_mode[(int) CODE_FOR_cmpstrsi][0];
3088 rtx result = gen_reg_rtx (result_mode);
3089 size = protect_from_queue (size, 0);
3090 emit_insn (gen_cmpstrsi (result, x, y,
3091 convert_to_mode (SImode, size, 1),
3093 emit_cmp_insn (result, const0_rtx, comparison, NULL_RTX,
3101 #ifdef TARGET_MEM_FUNCTIONS
3102 emit_library_call (memcmp_libfunc, 0,
3103 TYPE_MODE (integer_type_node), 3,
3104 XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
3105 convert_to_mode (TYPE_MODE (sizetype), size,
3106 TREE_UNSIGNED (sizetype)),
3107 TYPE_MODE (sizetype));
3109 emit_library_call (bcmp_libfunc, 0,
3110 TYPE_MODE (integer_type_node), 3,
3111 XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
3112 convert_to_mode (TYPE_MODE (integer_type_node),
3114 TREE_UNSIGNED (integer_type_node)),
3115 TYPE_MODE (integer_type_node));
3118 /* Immediately move the result of the libcall into a pseudo
3119 register so reload doesn't clobber the value if it needs
3120 the return register for a spill reg. */
3121 result = gen_reg_rtx (TYPE_MODE (integer_type_node));
3122 emit_move_insn (result,
3123 hard_libcall_value (TYPE_MODE (integer_type_node)));
3124 emit_cmp_insn (result,
3125 const0_rtx, comparison, NULL_RTX,
3126 TYPE_MODE (integer_type_node), 0, 0);
3131 /* Handle some compares against zero. */
3133 if (y == CONST0_RTX (mode)
3134 && tst_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
3136 int icode = (int) tst_optab->handlers[(int) mode].insn_code;
3139 x = protect_from_queue (x, 0);
3140 y = protect_from_queue (y, 0);
3142 /* Now, if insn does accept these operands, put them into pseudos. */
3143 if (! (*insn_operand_predicate[icode][0])
3144 (x, insn_operand_mode[icode][0]))
3145 x = copy_to_mode_reg (insn_operand_mode[icode][0], x);
3147 emit_insn (GEN_FCN (icode) (x));
3151 /* Handle compares for which there is a directly suitable insn. */
3153 if (cmp_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
3155 int icode = (int) cmp_optab->handlers[(int) mode].insn_code;
3158 x = protect_from_queue (x, 0);
3159 y = protect_from_queue (y, 0);
3161 /* Now, if insn doesn't accept these operands, put them into pseudos. */
3162 if (! (*insn_operand_predicate[icode][0])
3163 (x, insn_operand_mode[icode][0]))
3164 x = copy_to_mode_reg (insn_operand_mode[icode][0], x);
3166 if (! (*insn_operand_predicate[icode][1])
3167 (y, insn_operand_mode[icode][1]))
3168 y = copy_to_mode_reg (insn_operand_mode[icode][1], y);
3170 emit_insn (GEN_FCN (icode) (x, y));
3174 /* Try widening if we can find a direct insn that way. */
3176 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
3178 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
3179 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
3181 if (cmp_optab->handlers[(int) wider_mode].insn_code
3182 != CODE_FOR_nothing)
3184 x = protect_from_queue (x, 0);
3185 y = protect_from_queue (y, 0);
3186 x = convert_modes (wider_mode, mode, x, unsignedp);
3187 y = convert_modes (wider_mode, mode, y, unsignedp);
3188 emit_cmp_insn (x, y, comparison, NULL_RTX,
3189 wider_mode, unsignedp, align);
3195 /* Handle a lib call just for the mode we are using. */
3197 if (cmp_optab->handlers[(int) mode].libfunc
3198 && class != MODE_FLOAT)
3200 rtx libfunc = cmp_optab->handlers[(int) mode].libfunc;
3203 /* If we want unsigned, and this mode has a distinct unsigned
3204 comparison routine, use that. */
3205 if (unsignedp && ucmp_optab->handlers[(int) mode].libfunc)
3206 libfunc = ucmp_optab->handlers[(int) mode].libfunc;
3208 emit_library_call (libfunc, 1,
3209 word_mode, 2, x, mode, y, mode);
3211 /* Immediately move the result of the libcall into a pseudo
3212 register so reload doesn't clobber the value if it needs
3213 the return register for a spill reg. */
3214 result = gen_reg_rtx (word_mode);
3215 emit_move_insn (result, hard_libcall_value (word_mode));
3217 /* Integer comparison returns a result that must be compared against 1,
3218 so that even if we do an unsigned compare afterward,
3219 there is still a value that can represent the result "less than". */
3220 emit_cmp_insn (result, const1_rtx,
3221 comparison, NULL_RTX, word_mode, unsignedp, 0);
3225 if (class == MODE_FLOAT)
3226 emit_float_lib_cmp (x, y, comparison);
3232 /* Generate code to compare X with Y so that the condition codes are
3233 set and to jump to LABEL if the condition is true. If X is a
3234 constant and Y is not a constant, then the comparison is swapped to
3235 ensure that the comparison RTL has the canonical form.
3237 UNSIGNEDP nonzero says that X and Y are unsigned; this matters if they
3238 need to be widened by emit_cmp_insn. UNSIGNEDP is also used to select
3239 the proper branch condition code.
3241 If X and Y have mode BLKmode, then SIZE specifies the size of both X and Y,
3242 and ALIGN specifies the known shared alignment of X and Y.
3244 MODE is the mode of the inputs (in case they are const_int).
3246 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). It will
3247 be passed unchanged to emit_cmp_insn, then potentially converted into an
3248 unsigned variant based on UNSIGNEDP to select a proper jump instruction. */
3251 emit_cmp_and_jump_insns (x, y, comparison, size, mode, unsignedp, align, label)
3253 enum rtx_code comparison;
3255 enum machine_mode mode;
3265 /* Swap operands and condition to ensure canonical RTL. */
3268 comparison = swap_condition (comparison);
3277 /* If OP0 is still a constant, then both X and Y must be constants. Force
3278 X into a register to avoid aborting in emit_cmp_insn due to non-canonical
3280 if (CONSTANT_P (op0))
3281 op0 = force_reg (mode, op0);
3284 emit_cmp_insn (op0, op1, comparison, size, mode, unsignedp, align);
3287 comparison = unsigned_condition (comparison);
3288 emit_jump_insn ((*bcc_gen_fctn[(int) comparison]) (label));
3292 /* Nonzero if a compare of mode MODE can be done straightforwardly
3293 (without splitting it into pieces). */
3296 can_compare_p (mode)
3297 enum machine_mode mode;
3301 if (cmp_optab->handlers[(int)mode].insn_code != CODE_FOR_nothing)
3303 mode = GET_MODE_WIDER_MODE (mode);
3304 } while (mode != VOIDmode);
3309 /* Emit a library call comparison between floating point X and Y.
3310 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */
3313 emit_float_lib_cmp (x, y, comparison)
3315 enum rtx_code comparison;
3317 enum machine_mode mode = GET_MODE (x);
3325 libfunc = eqhf2_libfunc;
3329 libfunc = nehf2_libfunc;
3333 libfunc = gthf2_libfunc;
3337 libfunc = gehf2_libfunc;
3341 libfunc = lthf2_libfunc;
3345 libfunc = lehf2_libfunc;
3351 else if (mode == SFmode)
3355 libfunc = eqsf2_libfunc;
3359 libfunc = nesf2_libfunc;
3363 libfunc = gtsf2_libfunc;
3367 libfunc = gesf2_libfunc;
3371 libfunc = ltsf2_libfunc;
3375 libfunc = lesf2_libfunc;
3381 else if (mode == DFmode)
3385 libfunc = eqdf2_libfunc;
3389 libfunc = nedf2_libfunc;
3393 libfunc = gtdf2_libfunc;
3397 libfunc = gedf2_libfunc;
3401 libfunc = ltdf2_libfunc;
3405 libfunc = ledf2_libfunc;
3411 else if (mode == XFmode)
3415 libfunc = eqxf2_libfunc;
3419 libfunc = nexf2_libfunc;
3423 libfunc = gtxf2_libfunc;
3427 libfunc = gexf2_libfunc;
3431 libfunc = ltxf2_libfunc;
3435 libfunc = lexf2_libfunc;
3441 else if (mode == TFmode)
3445 libfunc = eqtf2_libfunc;
3449 libfunc = netf2_libfunc;
3453 libfunc = gttf2_libfunc;
3457 libfunc = getf2_libfunc;
3461 libfunc = lttf2_libfunc;
3465 libfunc = letf2_libfunc;
3473 enum machine_mode wider_mode;
3475 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
3476 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
3478 if ((cmp_optab->handlers[(int) wider_mode].insn_code
3479 != CODE_FOR_nothing)
3480 || (cmp_optab->handlers[(int) wider_mode].libfunc != 0))
3482 x = protect_from_queue (x, 0);
3483 y = protect_from_queue (y, 0);
3484 x = convert_to_mode (wider_mode, x, 0);
3485 y = convert_to_mode (wider_mode, y, 0);
3486 emit_float_lib_cmp (x, y, comparison);
3496 emit_library_call (libfunc, 1,
3497 word_mode, 2, x, mode, y, mode);
3499 /* Immediately move the result of the libcall into a pseudo
3500 register so reload doesn't clobber the value if it needs
3501 the return register for a spill reg. */
3502 result = gen_reg_rtx (word_mode);
3503 emit_move_insn (result, hard_libcall_value (word_mode));
3505 emit_cmp_insn (result, const0_rtx, comparison,
3506 NULL_RTX, word_mode, 0, 0);
3509 /* Generate code to indirectly jump to a location given in the rtx LOC. */
3512 emit_indirect_jump (loc)
3515 if (! ((*insn_operand_predicate[(int)CODE_FOR_indirect_jump][0])
3517 loc = copy_to_mode_reg (Pmode, loc);
3519 emit_jump_insn (gen_indirect_jump (loc));
3523 #ifdef HAVE_conditional_move
3525 /* Emit a conditional move instruction if the machine supports one for that
3526 condition and machine mode.
3528 OP0 and OP1 are the operands that should be compared using CODE. CMODE is
3529 the mode to use should they be constants. If it is VOIDmode, they cannot
3532 OP2 should be stored in TARGET if the comparison is true, otherwise OP3
3533 should be stored there. MODE is the mode to use should they be constants.
3534 If it is VOIDmode, they cannot both be constants.
3536 The result is either TARGET (perhaps modified) or NULL_RTX if the operation
3537 is not supported. */
3540 emit_conditional_move (target, code, op0, op1, cmode, op2, op3, mode,
3545 enum machine_mode cmode;
3547 enum machine_mode mode;
3550 rtx tem, subtarget, comparison, insn;
3551 enum insn_code icode;
3553 /* If one operand is constant, make it the second one. Only do this
3554 if the other operand is not constant as well. */
3556 if ((CONSTANT_P (op0) && ! CONSTANT_P (op1))
3557 || (GET_CODE (op0) == CONST_INT && GET_CODE (op1) != CONST_INT))
3562 code = swap_condition (code);
3565 if (cmode == VOIDmode)
3566 cmode = GET_MODE (op0);
3568 if (((CONSTANT_P (op2) && ! CONSTANT_P (op3))
3569 || (GET_CODE (op2) == CONST_INT && GET_CODE (op3) != CONST_INT))
3570 && (GET_MODE_CLASS (GET_MODE (op1)) != MODE_FLOAT
3571 || TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT || flag_fast_math))
3576 code = reverse_condition (code);
3579 if (mode == VOIDmode)
3580 mode = GET_MODE (op2);
3582 icode = movcc_gen_code[mode];
3584 if (icode == CODE_FOR_nothing)
3589 op2 = force_not_mem (op2);
3590 op3 = force_not_mem (op3);
3594 target = protect_from_queue (target, 1);
3596 target = gen_reg_rtx (mode);
3602 op2 = protect_from_queue (op2, 0);
3603 op3 = protect_from_queue (op3, 0);
3605 /* If the insn doesn't accept these operands, put them in pseudos. */
3607 if (! (*insn_operand_predicate[icode][0])
3608 (subtarget, insn_operand_mode[icode][0]))
3609 subtarget = gen_reg_rtx (insn_operand_mode[icode][0]);
3611 if (! (*insn_operand_predicate[icode][2])
3612 (op2, insn_operand_mode[icode][2]))
3613 op2 = copy_to_mode_reg (insn_operand_mode[icode][2], op2);
3615 if (! (*insn_operand_predicate[icode][3])
3616 (op3, insn_operand_mode[icode][3]))
3617 op3 = copy_to_mode_reg (insn_operand_mode[icode][3], op3);
3619 /* Everything should now be in the suitable form, so emit the compare insn
3620 and then the conditional move. */
3623 = compare_from_rtx (op0, op1, code, unsignedp, cmode, NULL_RTX, 0);
3625 /* ??? Watch for const0_rtx (nop) and const_true_rtx (unconditional)? */
3626 if (GET_CODE (comparison) != code)
3627 /* This shouldn't happen. */
3630 insn = GEN_FCN (icode) (subtarget, comparison, op2, op3);
3632 /* If that failed, then give up. */
3638 if (subtarget != target)
3639 convert_move (target, subtarget, 0);
3644 /* Return non-zero if a conditional move of mode MODE is supported.
3646 This function is for combine so it can tell whether an insn that looks
3647 like a conditional move is actually supported by the hardware. If we
3648 guess wrong we lose a bit on optimization, but that's it. */
3649 /* ??? sparc64 supports conditionally moving integers values based on fp
3650 comparisons, and vice versa. How do we handle them? */
3653 can_conditionally_move_p (mode)
3654 enum machine_mode mode;
3656 if (movcc_gen_code[mode] != CODE_FOR_nothing)
3662 #endif /* HAVE_conditional_move */
3664 /* These three functions generate an insn body and return it
3665 rather than emitting the insn.
3667 They do not protect from queued increments,
3668 because they may be used 1) in protect_from_queue itself
3669 and 2) in other passes where there is no queue. */
3671 /* Generate and return an insn body to add Y to X. */
3674 gen_add2_insn (x, y)
3677 int icode = (int) add_optab->handlers[(int) GET_MODE (x)].insn_code;
3679 if (! (*insn_operand_predicate[icode][0]) (x, insn_operand_mode[icode][0])
3680 || ! (*insn_operand_predicate[icode][1]) (x, insn_operand_mode[icode][1])
3681 || ! (*insn_operand_predicate[icode][2]) (y, insn_operand_mode[icode][2]))
3684 return (GEN_FCN (icode) (x, x, y));
3688 have_add2_insn (mode)
3689 enum machine_mode mode;
3691 return add_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
3694 /* Generate and return an insn body to subtract Y from X. */
3697 gen_sub2_insn (x, y)
3700 int icode = (int) sub_optab->handlers[(int) GET_MODE (x)].insn_code;
3702 if (! (*insn_operand_predicate[icode][0]) (x, insn_operand_mode[icode][0])
3703 || ! (*insn_operand_predicate[icode][1]) (x, insn_operand_mode[icode][1])
3704 || ! (*insn_operand_predicate[icode][2]) (y, insn_operand_mode[icode][2]))
3707 return (GEN_FCN (icode) (x, x, y));
3711 have_sub2_insn (mode)
3712 enum machine_mode mode;
3714 return sub_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
3717 /* Generate the body of an instruction to copy Y into X.
3718 It may be a SEQUENCE, if one insn isn't enough. */
3721 gen_move_insn (x, y)
3724 register enum machine_mode mode = GET_MODE (x);
3725 enum insn_code insn_code;
3728 if (mode == VOIDmode)
3729 mode = GET_MODE (y);
3731 insn_code = mov_optab->handlers[(int) mode].insn_code;
3733 /* Handle MODE_CC modes: If we don't have a special move insn for this mode,
3734 find a mode to do it in. If we have a movcc, use it. Otherwise,
3735 find the MODE_INT mode of the same width. */
3737 if (GET_MODE_CLASS (mode) == MODE_CC && insn_code == CODE_FOR_nothing)
3739 enum machine_mode tmode = VOIDmode;
3743 && mov_optab->handlers[(int) CCmode].insn_code != CODE_FOR_nothing)
3746 for (tmode = QImode; tmode != VOIDmode;
3747 tmode = GET_MODE_WIDER_MODE (tmode))
3748 if (GET_MODE_SIZE (tmode) == GET_MODE_SIZE (mode))
3751 if (tmode == VOIDmode)
3754 /* Get X and Y in TMODE. We can't use gen_lowpart here because it
3755 may call change_address which is not appropriate if we were
3756 called when a reload was in progress. We don't have to worry
3757 about changing the address since the size in bytes is supposed to
3758 be the same. Copy the MEM to change the mode and move any
3759 substitutions from the old MEM to the new one. */
3761 if (reload_in_progress)
3763 x = gen_lowpart_common (tmode, x1);
3764 if (x == 0 && GET_CODE (x1) == MEM)
3766 x = gen_rtx_MEM (tmode, XEXP (x1, 0));
3767 RTX_UNCHANGING_P (x) = RTX_UNCHANGING_P (x1);
3768 MEM_COPY_ATTRIBUTES (x, x1);
3769 copy_replacements (x1, x);
3772 y = gen_lowpart_common (tmode, y1);
3773 if (y == 0 && GET_CODE (y1) == MEM)
3775 y = gen_rtx_MEM (tmode, XEXP (y1, 0));
3776 RTX_UNCHANGING_P (y) = RTX_UNCHANGING_P (y1);
3777 MEM_COPY_ATTRIBUTES (y, y1);
3778 copy_replacements (y1, y);
3783 x = gen_lowpart (tmode, x);
3784 y = gen_lowpart (tmode, y);
3787 insn_code = mov_optab->handlers[(int) tmode].insn_code;
3788 return (GEN_FCN (insn_code) (x, y));
3792 emit_move_insn_1 (x, y);
3793 seq = gen_sequence ();
3798 /* Return the insn code used to extend FROM_MODE to TO_MODE.
3799 UNSIGNEDP specifies zero-extension instead of sign-extension. If
3800 no such operation exists, CODE_FOR_nothing will be returned. */
3803 can_extend_p (to_mode, from_mode, unsignedp)
3804 enum machine_mode to_mode, from_mode;
3807 return extendtab[(int) to_mode][(int) from_mode][unsignedp];
3810 /* Generate the body of an insn to extend Y (with mode MFROM)
3811 into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */
3814 gen_extend_insn (x, y, mto, mfrom, unsignedp)
3816 enum machine_mode mto, mfrom;
3819 return (GEN_FCN (extendtab[(int) mto][(int) mfrom][unsignedp]) (x, y));
3822 /* can_fix_p and can_float_p say whether the target machine
3823 can directly convert a given fixed point type to
3824 a given floating point type, or vice versa.
3825 The returned value is the CODE_FOR_... value to use,
3826 or CODE_FOR_nothing if these modes cannot be directly converted.
3828 *TRUNCP_PTR is set to 1 if it is necessary to output
3829 an explicit FTRUNC insn before the fix insn; otherwise 0. */
3831 static enum insn_code
3832 can_fix_p (fixmode, fltmode, unsignedp, truncp_ptr)
3833 enum machine_mode fltmode, fixmode;
3838 if (fixtrunctab[(int) fltmode][(int) fixmode][unsignedp] != CODE_FOR_nothing)
3839 return fixtrunctab[(int) fltmode][(int) fixmode][unsignedp];
3841 if (ftrunc_optab->handlers[(int) fltmode].insn_code != CODE_FOR_nothing)
3844 return fixtab[(int) fltmode][(int) fixmode][unsignedp];
3846 return CODE_FOR_nothing;
3849 static enum insn_code
3850 can_float_p (fltmode, fixmode, unsignedp)
3851 enum machine_mode fixmode, fltmode;
3854 return floattab[(int) fltmode][(int) fixmode][unsignedp];
3857 /* Generate code to convert FROM to floating point
3858 and store in TO. FROM must be fixed point and not VOIDmode.
3859 UNSIGNEDP nonzero means regard FROM as unsigned.
3860 Normally this is done by correcting the final value
3861 if it is negative. */
3864 expand_float (to, from, unsignedp)
3868 enum insn_code icode;
3869 register rtx target = to;
3870 enum machine_mode fmode, imode;
3872 /* Crash now, because we won't be able to decide which mode to use. */
3873 if (GET_MODE (from) == VOIDmode)
3876 /* Look for an insn to do the conversion. Do it in the specified
3877 modes if possible; otherwise convert either input, output or both to
3878 wider mode. If the integer mode is wider than the mode of FROM,
3879 we can do the conversion signed even if the input is unsigned. */
3881 for (imode = GET_MODE (from); imode != VOIDmode;
3882 imode = GET_MODE_WIDER_MODE (imode))
3883 for (fmode = GET_MODE (to); fmode != VOIDmode;
3884 fmode = GET_MODE_WIDER_MODE (fmode))
3886 int doing_unsigned = unsignedp;
3888 icode = can_float_p (fmode, imode, unsignedp);
3889 if (icode == CODE_FOR_nothing && imode != GET_MODE (from) && unsignedp)
3890 icode = can_float_p (fmode, imode, 0), doing_unsigned = 0;
3892 if (icode != CODE_FOR_nothing)
3894 to = protect_from_queue (to, 1);
3895 from = protect_from_queue (from, 0);
3897 if (imode != GET_MODE (from))
3898 from = convert_to_mode (imode, from, unsignedp);
3900 if (fmode != GET_MODE (to))
3901 target = gen_reg_rtx (fmode);
3903 emit_unop_insn (icode, target, from,
3904 doing_unsigned ? UNSIGNED_FLOAT : FLOAT);
3907 convert_move (to, target, 0);
3912 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
3914 /* Unsigned integer, and no way to convert directly.
3915 Convert as signed, then conditionally adjust the result. */
3918 rtx label = gen_label_rtx ();
3920 REAL_VALUE_TYPE offset;
3924 to = protect_from_queue (to, 1);
3925 from = protect_from_queue (from, 0);
3928 from = force_not_mem (from);
3930 /* Look for a usable floating mode FMODE wider than the source and at
3931 least as wide as the target. Using FMODE will avoid rounding woes
3932 with unsigned values greater than the signed maximum value. */
3934 for (fmode = GET_MODE (to); fmode != VOIDmode;
3935 fmode = GET_MODE_WIDER_MODE (fmode))
3936 if (GET_MODE_BITSIZE (GET_MODE (from)) < GET_MODE_BITSIZE (fmode)
3937 && can_float_p (fmode, GET_MODE (from), 0) != CODE_FOR_nothing)
3940 if (fmode == VOIDmode)
3942 /* There is no such mode. Pretend the target is wide enough. */
3943 fmode = GET_MODE (to);
3945 /* Avoid double-rounding when TO is narrower than FROM. */
3946 if ((significand_size (fmode) + 1)
3947 < GET_MODE_BITSIZE (GET_MODE (from)))
3950 rtx neglabel = gen_label_rtx ();
3952 /* Don't use TARGET if it isn't a register, is a hard register,
3953 or is the wrong mode. */
3954 if (GET_CODE (target) != REG
3955 || REGNO (target) < FIRST_PSEUDO_REGISTER
3956 || GET_MODE (target) != fmode)
3957 target = gen_reg_rtx (fmode);
3959 imode = GET_MODE (from);
3960 do_pending_stack_adjust ();
3962 /* Test whether the sign bit is set. */
3963 emit_cmp_insn (from, const0_rtx, GE, NULL_RTX, imode, 0, 0);
3964 emit_jump_insn (gen_blt (neglabel));
3966 /* The sign bit is not set. Convert as signed. */
3967 expand_float (target, from, 0);
3968 emit_jump_insn (gen_jump (label));
3971 /* The sign bit is set.
3972 Convert to a usable (positive signed) value by shifting right
3973 one bit, while remembering if a nonzero bit was shifted
3974 out; i.e., compute (from & 1) | (from >> 1). */
3976 emit_label (neglabel);
3977 temp = expand_binop (imode, and_optab, from, const1_rtx,
3978 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3979 temp1 = expand_shift (RSHIFT_EXPR, imode, from, integer_one_node,
3981 temp = expand_binop (imode, ior_optab, temp, temp1, temp, 1,
3983 expand_float (target, temp, 0);
3985 /* Multiply by 2 to undo the shift above. */
3986 temp = expand_binop (fmode, add_optab, target, target,
3987 target, 0, OPTAB_LIB_WIDEN);
3989 emit_move_insn (target, temp);
3991 do_pending_stack_adjust ();
3997 /* If we are about to do some arithmetic to correct for an
3998 unsigned operand, do it in a pseudo-register. */
4000 if (GET_MODE (to) != fmode
4001 || GET_CODE (to) != REG || REGNO (to) < FIRST_PSEUDO_REGISTER)
4002 target = gen_reg_rtx (fmode);
4004 /* Convert as signed integer to floating. */
4005 expand_float (target, from, 0);
4007 /* If FROM is negative (and therefore TO is negative),
4008 correct its value by 2**bitwidth. */
4010 do_pending_stack_adjust ();
4011 emit_cmp_and_jump_insns (from, const0_rtx, GE, NULL_RTX, GET_MODE (from),
4014 /* On SCO 3.2.1, ldexp rejects values outside [0.5, 1).
4015 Rather than setting up a dconst_dot_5, let's hope SCO
4017 offset = REAL_VALUE_LDEXP (dconst1, GET_MODE_BITSIZE (GET_MODE (from)));
4018 temp = expand_binop (fmode, add_optab, target,
4019 CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode),
4020 target, 0, OPTAB_LIB_WIDEN);
4022 emit_move_insn (target, temp);
4024 do_pending_stack_adjust ();
4030 /* No hardware instruction available; call a library routine to convert from
4031 SImode, DImode, or TImode into SFmode, DFmode, XFmode, or TFmode. */
4037 to = protect_from_queue (to, 1);
4038 from = protect_from_queue (from, 0);
4040 if (GET_MODE_SIZE (GET_MODE (from)) < GET_MODE_SIZE (SImode))
4041 from = convert_to_mode (SImode, from, unsignedp);
4044 from = force_not_mem (from);
4046 if (GET_MODE (to) == SFmode)
4048 if (GET_MODE (from) == SImode)
4049 libfcn = floatsisf_libfunc;
4050 else if (GET_MODE (from) == DImode)
4051 libfcn = floatdisf_libfunc;
4052 else if (GET_MODE (from) == TImode)
4053 libfcn = floattisf_libfunc;
4057 else if (GET_MODE (to) == DFmode)
4059 if (GET_MODE (from) == SImode)
4060 libfcn = floatsidf_libfunc;
4061 else if (GET_MODE (from) == DImode)
4062 libfcn = floatdidf_libfunc;
4063 else if (GET_MODE (from) == TImode)
4064 libfcn = floattidf_libfunc;
4068 else if (GET_MODE (to) == XFmode)
4070 if (GET_MODE (from) == SImode)
4071 libfcn = floatsixf_libfunc;
4072 else if (GET_MODE (from) == DImode)
4073 libfcn = floatdixf_libfunc;
4074 else if (GET_MODE (from) == TImode)
4075 libfcn = floattixf_libfunc;
4079 else if (GET_MODE (to) == TFmode)
4081 if (GET_MODE (from) == SImode)
4082 libfcn = floatsitf_libfunc;
4083 else if (GET_MODE (from) == DImode)
4084 libfcn = floatditf_libfunc;
4085 else if (GET_MODE (from) == TImode)
4086 libfcn = floattitf_libfunc;
4095 value = emit_library_call_value (libfcn, NULL_RTX, 1,
4097 1, from, GET_MODE (from));
4098 insns = get_insns ();
4101 emit_libcall_block (insns, target, value,
4102 gen_rtx_FLOAT (GET_MODE (to), from));
4107 /* Copy result to requested destination
4108 if we have been computing in a temp location. */
4112 if (GET_MODE (target) == GET_MODE (to))
4113 emit_move_insn (to, target);
4115 convert_move (to, target, 0);
4119 /* expand_fix: generate code to convert FROM to fixed point
4120 and store in TO. FROM must be floating point. */
4126 rtx temp = gen_reg_rtx (GET_MODE (x));
4127 return expand_unop (GET_MODE (x), ftrunc_optab, x, temp, 0);
4131 expand_fix (to, from, unsignedp)
4132 register rtx to, from;
4135 enum insn_code icode;
4136 register rtx target = to;
4137 enum machine_mode fmode, imode;
4141 /* We first try to find a pair of modes, one real and one integer, at
4142 least as wide as FROM and TO, respectively, in which we can open-code
4143 this conversion. If the integer mode is wider than the mode of TO,
4144 we can do the conversion either signed or unsigned. */
4146 for (imode = GET_MODE (to); imode != VOIDmode;
4147 imode = GET_MODE_WIDER_MODE (imode))
4148 for (fmode = GET_MODE (from); fmode != VOIDmode;
4149 fmode = GET_MODE_WIDER_MODE (fmode))
4151 int doing_unsigned = unsignedp;
4153 icode = can_fix_p (imode, fmode, unsignedp, &must_trunc);
4154 if (icode == CODE_FOR_nothing && imode != GET_MODE (to) && unsignedp)
4155 icode = can_fix_p (imode, fmode, 0, &must_trunc), doing_unsigned = 0;
4157 if (icode != CODE_FOR_nothing)
4159 to = protect_from_queue (to, 1);
4160 from = protect_from_queue (from, 0);
4162 if (fmode != GET_MODE (from))
4163 from = convert_to_mode (fmode, from, 0);
4166 from = ftruncify (from);
4168 if (imode != GET_MODE (to))
4169 target = gen_reg_rtx (imode);
4171 emit_unop_insn (icode, target, from,
4172 doing_unsigned ? UNSIGNED_FIX : FIX);
4174 convert_move (to, target, unsignedp);
4179 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
4180 /* For an unsigned conversion, there is one more way to do it.
4181 If we have a signed conversion, we generate code that compares
4182 the real value to the largest representable positive number. If if
4183 is smaller, the conversion is done normally. Otherwise, subtract
4184 one plus the highest signed number, convert, and add it back.
4186 We only need to check all real modes, since we know we didn't find
4187 anything with a wider integer mode. */
4189 if (unsignedp && GET_MODE_BITSIZE (GET_MODE (to)) <= HOST_BITS_PER_WIDE_INT)
4190 for (fmode = GET_MODE (from); fmode != VOIDmode;
4191 fmode = GET_MODE_WIDER_MODE (fmode))
4192 /* Make sure we won't lose significant bits doing this. */
4193 if (GET_MODE_BITSIZE (fmode) > GET_MODE_BITSIZE (GET_MODE (to))
4194 && CODE_FOR_nothing != can_fix_p (GET_MODE (to), fmode, 0,
4198 REAL_VALUE_TYPE offset;
4199 rtx limit, lab1, lab2, insn;
4201 bitsize = GET_MODE_BITSIZE (GET_MODE (to));
4202 offset = REAL_VALUE_LDEXP (dconst1, bitsize - 1);
4203 limit = CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode);
4204 lab1 = gen_label_rtx ();
4205 lab2 = gen_label_rtx ();
4208 to = protect_from_queue (to, 1);
4209 from = protect_from_queue (from, 0);
4212 from = force_not_mem (from);
4214 if (fmode != GET_MODE (from))
4215 from = convert_to_mode (fmode, from, 0);
4217 /* See if we need to do the subtraction. */
4218 do_pending_stack_adjust ();
4219 emit_cmp_and_jump_insns (from, limit, GE, NULL_RTX, GET_MODE (from),
4222 /* If not, do the signed "fix" and branch around fixup code. */
4223 expand_fix (to, from, 0);
4224 emit_jump_insn (gen_jump (lab2));
4227 /* Otherwise, subtract 2**(N-1), convert to signed number,
4228 then add 2**(N-1). Do the addition using XOR since this
4229 will often generate better code. */
4231 target = expand_binop (GET_MODE (from), sub_optab, from, limit,
4232 NULL_RTX, 0, OPTAB_LIB_WIDEN);
4233 expand_fix (to, target, 0);
4234 target = expand_binop (GET_MODE (to), xor_optab, to,
4235 GEN_INT ((HOST_WIDE_INT) 1 << (bitsize - 1)),
4236 to, 1, OPTAB_LIB_WIDEN);
4239 emit_move_insn (to, target);
4243 if (mov_optab->handlers[(int) GET_MODE (to)].insn_code
4244 != CODE_FOR_nothing)
4246 /* Make a place for a REG_NOTE and add it. */
4247 insn = emit_move_insn (to, to);
4248 set_unique_reg_note (insn,
4250 gen_rtx_fmt_e (UNSIGNED_FIX,
4258 /* We can't do it with an insn, so use a library call. But first ensure
4259 that the mode of TO is at least as wide as SImode, since those are the
4260 only library calls we know about. */
4262 if (GET_MODE_SIZE (GET_MODE (to)) < GET_MODE_SIZE (SImode))
4264 target = gen_reg_rtx (SImode);
4266 expand_fix (target, from, unsignedp);
4268 else if (GET_MODE (from) == SFmode)
4270 if (GET_MODE (to) == SImode)
4271 libfcn = unsignedp ? fixunssfsi_libfunc : fixsfsi_libfunc;
4272 else if (GET_MODE (to) == DImode)
4273 libfcn = unsignedp ? fixunssfdi_libfunc : fixsfdi_libfunc;
4274 else if (GET_MODE (to) == TImode)
4275 libfcn = unsignedp ? fixunssfti_libfunc : fixsfti_libfunc;
4279 else if (GET_MODE (from) == DFmode)
4281 if (GET_MODE (to) == SImode)
4282 libfcn = unsignedp ? fixunsdfsi_libfunc : fixdfsi_libfunc;
4283 else if (GET_MODE (to) == DImode)
4284 libfcn = unsignedp ? fixunsdfdi_libfunc : fixdfdi_libfunc;
4285 else if (GET_MODE (to) == TImode)
4286 libfcn = unsignedp ? fixunsdfti_libfunc : fixdfti_libfunc;
4290 else if (GET_MODE (from) == XFmode)
4292 if (GET_MODE (to) == SImode)
4293 libfcn = unsignedp ? fixunsxfsi_libfunc : fixxfsi_libfunc;
4294 else if (GET_MODE (to) == DImode)
4295 libfcn = unsignedp ? fixunsxfdi_libfunc : fixxfdi_libfunc;
4296 else if (GET_MODE (to) == TImode)
4297 libfcn = unsignedp ? fixunsxfti_libfunc : fixxfti_libfunc;
4301 else if (GET_MODE (from) == TFmode)
4303 if (GET_MODE (to) == SImode)
4304 libfcn = unsignedp ? fixunstfsi_libfunc : fixtfsi_libfunc;
4305 else if (GET_MODE (to) == DImode)
4306 libfcn = unsignedp ? fixunstfdi_libfunc : fixtfdi_libfunc;
4307 else if (GET_MODE (to) == TImode)
4308 libfcn = unsignedp ? fixunstfti_libfunc : fixtfti_libfunc;
4320 to = protect_from_queue (to, 1);
4321 from = protect_from_queue (from, 0);
4324 from = force_not_mem (from);
4328 value = emit_library_call_value (libfcn, NULL_RTX, 1, GET_MODE (to),
4330 1, from, GET_MODE (from));
4331 insns = get_insns ();
4334 emit_libcall_block (insns, target, value,
4335 gen_rtx_fmt_e (unsignedp ? UNSIGNED_FIX : FIX,
4336 GET_MODE (to), from));
4341 if (GET_MODE (to) == GET_MODE (target))
4342 emit_move_insn (to, target);
4344 convert_move (to, target, 0);
4353 optab op = (optab) xmalloc (sizeof (struct optab));
4355 for (i = 0; i < NUM_MACHINE_MODES; i++)
4357 op->handlers[i].insn_code = CODE_FOR_nothing;
4358 op->handlers[i].libfunc = 0;
4361 if (code != UNKNOWN)
4362 code_to_optab[(int) code] = op;
4367 /* Initialize the libfunc fields of an entire group of entries in some
4368 optab. Each entry is set equal to a string consisting of a leading
4369 pair of underscores followed by a generic operation name followed by
4370 a mode name (downshifted to lower case) followed by a single character
4371 representing the number of operands for the given operation (which is
4372 usually one of the characters '2', '3', or '4').
4374 OPTABLE is the table in which libfunc fields are to be initialized.
4375 FIRST_MODE is the first machine mode index in the given optab to
4377 LAST_MODE is the last machine mode index in the given optab to
4379 OPNAME is the generic (string) name of the operation.
4380 SUFFIX is the character which specifies the number of operands for
4381 the given generic operation.
4385 init_libfuncs (optable, first_mode, last_mode, opname, suffix)
4386 register optab optable;
4387 register int first_mode;
4388 register int last_mode;
4389 register const char *opname;
4390 register int suffix;
4393 register unsigned opname_len = strlen (opname);
4395 for (mode = first_mode; (int) mode <= (int) last_mode;
4396 mode = (enum machine_mode) ((int) mode + 1))
4398 register char *mname = mode_name[(int) mode];
4399 register unsigned mname_len = strlen (mname);
4400 register char *libfunc_name
4401 = (char *) xmalloc (2 + opname_len + mname_len + 1 + 1);
4403 register const char *q;
4408 for (q = opname; *q; )
4410 for (q = mname; *q; q++)
4411 *p++ = tolower ((unsigned char)*q);
4414 optable->handlers[(int) mode].libfunc
4415 = gen_rtx_SYMBOL_REF (Pmode, libfunc_name);
4419 /* Initialize the libfunc fields of an entire group of entries in some
4420 optab which correspond to all integer mode operations. The parameters
4421 have the same meaning as similarly named ones for the `init_libfuncs'
4422 routine. (See above). */
4425 init_integral_libfuncs (optable, opname, suffix)
4426 register optab optable;
4427 register const char *opname;
4428 register int suffix;
4430 init_libfuncs (optable, SImode, TImode, opname, suffix);
4433 /* Initialize the libfunc fields of an entire group of entries in some
4434 optab which correspond to all real mode operations. The parameters
4435 have the same meaning as similarly named ones for the `init_libfuncs'
4436 routine. (See above). */
4439 init_floating_libfuncs (optable, opname, suffix)
4440 register optab optable;
4441 register const char *opname;
4442 register int suffix;
4444 init_libfuncs (optable, SFmode, TFmode, opname, suffix);
4448 /* Call this once to initialize the contents of the optabs
4449 appropriately for the current target machine. */
4455 #ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC
4461 /* Start by initializing all tables to contain CODE_FOR_nothing. */
4463 for (p = fixtab[0][0];
4464 p < fixtab[0][0] + sizeof fixtab / sizeof (fixtab[0][0][0]);
4466 *p = CODE_FOR_nothing;
4468 for (p = fixtrunctab[0][0];
4469 p < fixtrunctab[0][0] + sizeof fixtrunctab / sizeof (fixtrunctab[0][0][0]);
4471 *p = CODE_FOR_nothing;
4473 for (p = floattab[0][0];
4474 p < floattab[0][0] + sizeof floattab / sizeof (floattab[0][0][0]);
4476 *p = CODE_FOR_nothing;
4478 for (p = extendtab[0][0];
4479 p < extendtab[0][0] + sizeof extendtab / sizeof extendtab[0][0][0];
4481 *p = CODE_FOR_nothing;
4483 for (i = 0; i < NUM_RTX_CODE; i++)
4484 setcc_gen_code[i] = CODE_FOR_nothing;
4486 #ifdef HAVE_conditional_move
4487 for (i = 0; i < NUM_MACHINE_MODES; i++)
4488 movcc_gen_code[i] = CODE_FOR_nothing;
4491 add_optab = init_optab (PLUS);
4492 sub_optab = init_optab (MINUS);
4493 smul_optab = init_optab (MULT);
4494 smul_highpart_optab = init_optab (UNKNOWN);
4495 umul_highpart_optab = init_optab (UNKNOWN);
4496 smul_widen_optab = init_optab (UNKNOWN);
4497 umul_widen_optab = init_optab (UNKNOWN);
4498 sdiv_optab = init_optab (DIV);
4499 sdivmod_optab = init_optab (UNKNOWN);
4500 udiv_optab = init_optab (UDIV);
4501 udivmod_optab = init_optab (UNKNOWN);
4502 smod_optab = init_optab (MOD);
4503 umod_optab = init_optab (UMOD);
4504 flodiv_optab = init_optab (DIV);
4505 ftrunc_optab = init_optab (UNKNOWN);
4506 and_optab = init_optab (AND);
4507 ior_optab = init_optab (IOR);
4508 xor_optab = init_optab (XOR);
4509 ashl_optab = init_optab (ASHIFT);
4510 ashr_optab = init_optab (ASHIFTRT);
4511 lshr_optab = init_optab (LSHIFTRT);
4512 rotl_optab = init_optab (ROTATE);
4513 rotr_optab = init_optab (ROTATERT);
4514 smin_optab = init_optab (SMIN);
4515 smax_optab = init_optab (SMAX);
4516 umin_optab = init_optab (UMIN);
4517 umax_optab = init_optab (UMAX);
4518 mov_optab = init_optab (UNKNOWN);
4519 movstrict_optab = init_optab (UNKNOWN);
4520 cmp_optab = init_optab (UNKNOWN);
4521 ucmp_optab = init_optab (UNKNOWN);
4522 tst_optab = init_optab (UNKNOWN);
4523 neg_optab = init_optab (NEG);
4524 abs_optab = init_optab (ABS);
4525 one_cmpl_optab = init_optab (NOT);
4526 ffs_optab = init_optab (FFS);
4527 sqrt_optab = init_optab (SQRT);
4528 sin_optab = init_optab (UNKNOWN);
4529 cos_optab = init_optab (UNKNOWN);
4530 strlen_optab = init_optab (UNKNOWN);
4532 for (i = 0; i < NUM_MACHINE_MODES; i++)
4534 movstr_optab[i] = CODE_FOR_nothing;
4535 clrstr_optab[i] = CODE_FOR_nothing;
4537 #ifdef HAVE_SECONDARY_RELOADS
4538 reload_in_optab[i] = reload_out_optab[i] = CODE_FOR_nothing;
4542 /* Fill in the optabs with the insns we support. */
4545 #ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC
4546 /* This flag says the same insns that convert to a signed fixnum
4547 also convert validly to an unsigned one. */
4548 for (i = 0; i < NUM_MACHINE_MODES; i++)
4549 for (j = 0; j < NUM_MACHINE_MODES; j++)
4550 fixtrunctab[i][j][1] = fixtrunctab[i][j][0];
4553 #ifdef EXTRA_CC_MODES
4557 /* Initialize the optabs with the names of the library functions. */
4558 init_integral_libfuncs (add_optab, "add", '3');
4559 init_floating_libfuncs (add_optab, "add", '3');
4560 init_integral_libfuncs (sub_optab, "sub", '3');
4561 init_floating_libfuncs (sub_optab, "sub", '3');
4562 init_integral_libfuncs (smul_optab, "mul", '3');
4563 init_floating_libfuncs (smul_optab, "mul", '3');
4564 init_integral_libfuncs (sdiv_optab, "div", '3');
4565 init_integral_libfuncs (udiv_optab, "udiv", '3');
4566 init_integral_libfuncs (sdivmod_optab, "divmod", '4');
4567 init_integral_libfuncs (udivmod_optab, "udivmod", '4');
4568 init_integral_libfuncs (smod_optab, "mod", '3');
4569 init_integral_libfuncs (umod_optab, "umod", '3');
4570 init_floating_libfuncs (flodiv_optab, "div", '3');
4571 init_floating_libfuncs (ftrunc_optab, "ftrunc", '2');
4572 init_integral_libfuncs (and_optab, "and", '3');
4573 init_integral_libfuncs (ior_optab, "ior", '3');
4574 init_integral_libfuncs (xor_optab, "xor", '3');
4575 init_integral_libfuncs (ashl_optab, "ashl", '3');
4576 init_integral_libfuncs (ashr_optab, "ashr", '3');
4577 init_integral_libfuncs (lshr_optab, "lshr", '3');
4578 init_integral_libfuncs (smin_optab, "min", '3');
4579 init_floating_libfuncs (smin_optab, "min", '3');
4580 init_integral_libfuncs (smax_optab, "max", '3');
4581 init_floating_libfuncs (smax_optab, "max", '3');
4582 init_integral_libfuncs (umin_optab, "umin", '3');
4583 init_integral_libfuncs (umax_optab, "umax", '3');
4584 init_integral_libfuncs (neg_optab, "neg", '2');
4585 init_floating_libfuncs (neg_optab, "neg", '2');
4586 init_integral_libfuncs (one_cmpl_optab, "one_cmpl", '2');
4587 init_integral_libfuncs (ffs_optab, "ffs", '2');
4589 /* Comparison libcalls for integers MUST come in pairs, signed/unsigned. */
4590 init_integral_libfuncs (cmp_optab, "cmp", '2');
4591 init_integral_libfuncs (ucmp_optab, "ucmp", '2');
4592 init_floating_libfuncs (cmp_optab, "cmp", '2');
4594 #ifdef MULSI3_LIBCALL
4595 smul_optab->handlers[(int) SImode].libfunc
4596 = gen_rtx_SYMBOL_REF (Pmode, MULSI3_LIBCALL);
4598 #ifdef MULDI3_LIBCALL
4599 smul_optab->handlers[(int) DImode].libfunc
4600 = gen_rtx_SYMBOL_REF (Pmode, MULDI3_LIBCALL);
4603 #ifdef DIVSI3_LIBCALL
4604 sdiv_optab->handlers[(int) SImode].libfunc
4605 = gen_rtx_SYMBOL_REF (Pmode, DIVSI3_LIBCALL);
4607 #ifdef DIVDI3_LIBCALL
4608 sdiv_optab->handlers[(int) DImode].libfunc
4609 = gen_rtx_SYMBOL_REF (Pmode, DIVDI3_LIBCALL);
4612 #ifdef UDIVSI3_LIBCALL
4613 udiv_optab->handlers[(int) SImode].libfunc
4614 = gen_rtx_SYMBOL_REF (Pmode, UDIVSI3_LIBCALL);
4616 #ifdef UDIVDI3_LIBCALL
4617 udiv_optab->handlers[(int) DImode].libfunc
4618 = gen_rtx_SYMBOL_REF (Pmode, UDIVDI3_LIBCALL);
4621 #ifdef MODSI3_LIBCALL
4622 smod_optab->handlers[(int) SImode].libfunc
4623 = gen_rtx_SYMBOL_REF (Pmode, MODSI3_LIBCALL);
4625 #ifdef MODDI3_LIBCALL
4626 smod_optab->handlers[(int) DImode].libfunc
4627 = gen_rtx_SYMBOL_REF (Pmode, MODDI3_LIBCALL);
4630 #ifdef UMODSI3_LIBCALL
4631 umod_optab->handlers[(int) SImode].libfunc
4632 = gen_rtx_SYMBOL_REF (Pmode, UMODSI3_LIBCALL);
4634 #ifdef UMODDI3_LIBCALL
4635 umod_optab->handlers[(int) DImode].libfunc
4636 = gen_rtx_SYMBOL_REF (Pmode, UMODDI3_LIBCALL);
4639 /* Use cabs for DC complex abs, since systems generally have cabs.
4640 Don't define any libcall for SCmode, so that cabs will be used. */
4641 abs_optab->handlers[(int) DCmode].libfunc
4642 = gen_rtx_SYMBOL_REF (Pmode, "cabs");
4644 /* The ffs function operates on `int'. */
4645 #ifndef INT_TYPE_SIZE
4646 #define INT_TYPE_SIZE BITS_PER_WORD
4648 ffs_optab->handlers[(int) mode_for_size (INT_TYPE_SIZE, MODE_INT, 0)] .libfunc
4649 = gen_rtx_SYMBOL_REF (Pmode, "ffs");
4651 extendsfdf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__extendsfdf2");
4652 extendsfxf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__extendsfxf2");
4653 extendsftf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__extendsftf2");
4654 extenddfxf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__extenddfxf2");
4655 extenddftf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__extenddftf2");
4657 truncdfsf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__truncdfsf2");
4658 truncxfsf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__truncxfsf2");
4659 trunctfsf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__trunctfsf2");
4660 truncxfdf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__truncxfdf2");
4661 trunctfdf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__trunctfdf2");
4663 memcpy_libfunc = gen_rtx_SYMBOL_REF (Pmode, "memcpy");
4664 bcopy_libfunc = gen_rtx_SYMBOL_REF (Pmode, "bcopy");
4665 memcmp_libfunc = gen_rtx_SYMBOL_REF (Pmode, "memcmp");
4666 bcmp_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__gcc_bcmp");
4667 memset_libfunc = gen_rtx_SYMBOL_REF (Pmode, "memset");
4668 bzero_libfunc = gen_rtx_SYMBOL_REF (Pmode, "bzero");
4670 throw_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__throw");
4671 rethrow_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__rethrow");
4672 sjthrow_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__sjthrow");
4673 sjpopnthrow_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__sjpopnthrow");
4674 terminate_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__terminate");
4675 eh_rtime_match_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__eh_rtime_match");
4676 #ifndef DONT_USE_BUILTIN_SETJMP
4677 setjmp_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__builtin_setjmp");
4678 longjmp_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__builtin_longjmp");
4680 setjmp_libfunc = gen_rtx_SYMBOL_REF (Pmode, "setjmp");
4681 longjmp_libfunc = gen_rtx_SYMBOL_REF (Pmode, "longjmp");
4684 eqhf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__eqhf2");
4685 nehf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__nehf2");
4686 gthf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__gthf2");
4687 gehf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__gehf2");
4688 lthf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__lthf2");
4689 lehf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__lehf2");
4691 eqsf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__eqsf2");
4692 nesf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__nesf2");
4693 gtsf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__gtsf2");
4694 gesf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__gesf2");
4695 ltsf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__ltsf2");
4696 lesf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__lesf2");
4698 eqdf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__eqdf2");
4699 nedf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__nedf2");
4700 gtdf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__gtdf2");
4701 gedf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__gedf2");
4702 ltdf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__ltdf2");
4703 ledf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__ledf2");
4705 eqxf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__eqxf2");
4706 nexf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__nexf2");
4707 gtxf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__gtxf2");
4708 gexf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__gexf2");
4709 ltxf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__ltxf2");
4710 lexf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__lexf2");
4712 eqtf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__eqtf2");
4713 netf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__netf2");
4714 gttf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__gttf2");
4715 getf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__getf2");
4716 lttf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__lttf2");
4717 letf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__letf2");
4719 floatsisf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floatsisf");
4720 floatdisf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floatdisf");
4721 floattisf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floattisf");
4723 floatsidf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floatsidf");
4724 floatdidf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floatdidf");
4725 floattidf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floattidf");
4727 floatsixf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floatsixf");
4728 floatdixf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floatdixf");
4729 floattixf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floattixf");
4731 floatsitf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floatsitf");
4732 floatditf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floatditf");
4733 floattitf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floattitf");
4735 fixsfsi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixsfsi");
4736 fixsfdi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixsfdi");
4737 fixsfti_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixsfti");
4739 fixdfsi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixdfsi");
4740 fixdfdi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixdfdi");
4741 fixdfti_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixdfti");
4743 fixxfsi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixxfsi");
4744 fixxfdi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixxfdi");
4745 fixxfti_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixxfti");
4747 fixtfsi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixtfsi");
4748 fixtfdi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixtfdi");
4749 fixtfti_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixtfti");
4751 fixunssfsi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunssfsi");
4752 fixunssfdi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunssfdi");
4753 fixunssfti_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunssfti");
4755 fixunsdfsi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunsdfsi");
4756 fixunsdfdi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunsdfdi");
4757 fixunsdfti_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunsdfti");
4759 fixunsxfsi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunsxfsi");
4760 fixunsxfdi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunsxfdi");
4761 fixunsxfti_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunsxfti");
4763 fixunstfsi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunstfsi");
4764 fixunstfdi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunstfdi");
4765 fixunstfti_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunstfti");
4767 /* For check-memory-usage. */
4768 chkr_check_addr_libfunc = gen_rtx_SYMBOL_REF (Pmode, "chkr_check_addr");
4769 chkr_set_right_libfunc = gen_rtx_SYMBOL_REF (Pmode, "chkr_set_right");
4770 chkr_copy_bitmap_libfunc = gen_rtx_SYMBOL_REF (Pmode, "chkr_copy_bitmap");
4771 chkr_check_exec_libfunc = gen_rtx_SYMBOL_REF (Pmode, "chkr_check_exec");
4772 chkr_check_str_libfunc = gen_rtx_SYMBOL_REF (Pmode, "chkr_check_str");
4774 /* For function entry/exit instrumentation. */
4775 profile_function_entry_libfunc
4776 = gen_rtx_SYMBOL_REF (Pmode, "__cyg_profile_func_enter");
4777 profile_function_exit_libfunc
4778 = gen_rtx_SYMBOL_REF (Pmode, "__cyg_profile_func_exit");
4780 #ifdef HAVE_conditional_trap
4784 #ifdef INIT_TARGET_OPTABS
4785 /* Allow the target to add more libcalls or rename some, etc. */
4792 /* SCO 3.2 apparently has a broken ldexp. */
4805 #endif /* BROKEN_LDEXP */
4807 #ifdef HAVE_conditional_trap
4808 /* The insn generating function can not take an rtx_code argument.
4809 TRAP_RTX is used as an rtx argument. Its code is replaced with
4810 the code to be used in the trap insn and all other fields are
4813 ??? Will need to change to support garbage collection. */
4814 static rtx trap_rtx;
4819 if (HAVE_conditional_trap)
4820 trap_rtx = gen_rtx_fmt_ee (EQ, VOIDmode, NULL_RTX, NULL_RTX);
4824 /* Generate insns to trap with code TCODE if OP1 and OP2 satisfy condition
4825 CODE. Return 0 on failure. */
4828 gen_cond_trap (code, op1, op2, tcode)
4829 enum rtx_code code ATTRIBUTE_UNUSED;
4830 rtx op1, op2 ATTRIBUTE_UNUSED, tcode ATTRIBUTE_UNUSED;
4832 enum machine_mode mode = GET_MODE (op1);
4834 if (mode == VOIDmode)
4837 #ifdef HAVE_conditional_trap
4838 if (HAVE_conditional_trap
4839 && cmp_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
4842 emit_insn (GEN_FCN (cmp_optab->handlers[(int) mode].insn_code) (op1, op2));
4843 PUT_CODE (trap_rtx, code);
4844 insn = gen_conditional_trap (trap_rtx, tcode);